Skip to content

Commit 3c47722

Browse files
topofocusclaude
andcommitted
Merge ver_10 into master
Using -X theirs strategy to preserve all changes from ver_10. Removed conflict files that were deleted in ver_10. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2 parents c9e1f22 + 147309f commit 3c47722

224 files changed

Lines changed: 13329 additions & 4080 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
*.gem
22
*.rbc
3+
*.swp
4+
*.swo
35
/.config
46
/coverage/
57
/InstalledFiles

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ gemspec
1111

1212
gem 'rspec'
1313
gem 'rspec-its'
14+
gem 'rspec-given'
1415
gem 'rspec-collection_matchers'
1516
gem 'guard'
1617
gem 'guard-rspec'

Gemfile.lock

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,41 @@
11
PATH
22
remote: .
33
specs:
4-
ib-api (972.5.2)
4+
ib-api (10.19.1)
55
activemodel
66
activesupport (>= 6.0)
77
ox
88
terminal-table
9+
workflow (~> 3.1)
10+
zeitwerk
911

1012
GEM
1113
remote: https://rubygems.org/
1214
specs:
13-
activemodel (7.0.4.2)
14-
activesupport (= 7.0.4.2)
15-
activesupport (7.0.4.2)
15+
activemodel (7.1.3.4)
16+
activesupport (= 7.1.3.4)
17+
activesupport (7.1.3.4)
18+
base64
19+
bigdecimal
1620
concurrent-ruby (~> 1.0, >= 1.0.2)
21+
connection_pool (>= 2.2.5)
22+
drb
1723
i18n (>= 1.6, < 2)
1824
minitest (>= 5.1)
25+
mutex_m
1926
tzinfo (~> 2.0)
27+
base64 (0.2.0)
28+
bigdecimal (3.1.8)
2029
coderay (1.1.3)
21-
concurrent-ruby (1.2.0)
22-
diff-lcs (1.5.0)
23-
ffi (1.15.5)
30+
concurrent-ruby (1.3.3)
31+
connection_pool (2.4.1)
32+
diff-lcs (1.5.1)
33+
drb (2.2.1)
34+
ffi (1.17.0-x86_64-linux-gnu)
2435
formatador (1.1.0)
25-
guard (2.18.0)
36+
given_core (3.8.2)
37+
sorcerer (>= 0.3.7)
38+
guard (2.18.1)
2639
formatador (>= 0.2.4)
2740
listen (>= 2.7, < 4.0)
2841
lumberjack (>= 1.0.12, < 2.0)
@@ -36,51 +49,58 @@ GEM
3649
guard (~> 2.1)
3750
guard-compat (~> 1.1)
3851
rspec (>= 2.99.0, < 4.0)
39-
i18n (1.12.0)
52+
i18n (1.14.5)
4053
concurrent-ruby (~> 1.0)
41-
listen (3.8.0)
54+
listen (3.9.0)
4255
rb-fsevent (~> 0.10, >= 0.10.3)
4356
rb-inotify (~> 0.9, >= 0.9.10)
44-
lumberjack (1.2.8)
45-
method_source (1.0.0)
46-
minitest (5.17.0)
57+
lumberjack (1.2.10)
58+
method_source (1.1.0)
59+
minitest (5.24.1)
60+
mutex_m (0.2.0)
4761
nenv (0.3.0)
4862
notiffany (0.1.3)
4963
nenv (~> 0.1)
5064
shellany (~> 0.0)
51-
ox (2.14.14)
65+
ox (2.14.18)
5266
pry (0.14.2)
5367
coderay (~> 1.1)
5468
method_source (~> 1.0)
55-
rake (13.0.6)
69+
rake (13.2.1)
5670
rb-fsevent (0.11.2)
57-
rb-inotify (0.10.1)
71+
rb-inotify (0.11.1)
5872
ffi (~> 1.0)
59-
rspec (3.12.0)
60-
rspec-core (~> 3.12.0)
61-
rspec-expectations (~> 3.12.0)
62-
rspec-mocks (~> 3.12.0)
63-
rspec-collection_matchers (1.2.0)
73+
rspec (3.13.0)
74+
rspec-core (~> 3.13.0)
75+
rspec-expectations (~> 3.13.0)
76+
rspec-mocks (~> 3.13.0)
77+
rspec-collection_matchers (1.2.1)
6478
rspec-expectations (>= 2.99.0.beta1)
65-
rspec-core (3.12.1)
66-
rspec-support (~> 3.12.0)
67-
rspec-expectations (3.12.2)
79+
rspec-core (3.13.0)
80+
rspec-support (~> 3.13.0)
81+
rspec-expectations (3.13.1)
6882
diff-lcs (>= 1.2.0, < 2.0)
69-
rspec-support (~> 3.12.0)
83+
rspec-support (~> 3.13.0)
84+
rspec-given (3.8.2)
85+
given_core (= 3.8.2)
86+
rspec (>= 2.14.0)
7087
rspec-its (1.3.0)
7188
rspec-core (>= 3.0.0)
7289
rspec-expectations (>= 3.0.0)
73-
rspec-mocks (3.12.3)
90+
rspec-mocks (3.13.1)
7491
diff-lcs (>= 1.2.0, < 2.0)
75-
rspec-support (~> 3.12.0)
76-
rspec-support (3.12.0)
92+
rspec-support (~> 3.13.0)
93+
rspec-support (3.13.1)
7794
shellany (0.0.1)
95+
sorcerer (2.0.1)
7896
terminal-table (3.0.2)
7997
unicode-display_width (>= 1.1.1, < 3)
80-
thor (1.2.1)
98+
thor (1.3.1)
8199
tzinfo (2.0.6)
82100
concurrent-ruby (~> 1.0)
83-
unicode-display_width (2.4.2)
101+
unicode-display_width (2.5.0)
102+
workflow (3.1.1)
103+
zeitwerk (2.6.16)
84104

85105
PLATFORMS
86106
x86_64-linux
@@ -93,6 +113,7 @@ DEPENDENCIES
93113
rake (~> 13.0)
94114
rspec
95115
rspec-collection_matchers
116+
rspec-given
96117
rspec-its
97118

98119
BUNDLED WITH

README.md

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# ib-api
22
Ruby interface to Interactive Brokers' TWS API
33

4-
Reimplementation of the basic functions of ib-ruby
4+
Reimplementation of ib-ruby
5+
6+
---
7+
__STATUS: Gem-Release is still pending
58

69
---
710

@@ -13,9 +16,7 @@ Try the V10 branch (TWS V 10.19 and above)
1316
__Documentation: [https://ib-ruby.github.io/ib-doc/](https://ib-ruby.github.io/ib-doc/)__ (_work in progress_)
1417

1518
----
16-
`ib-ruby` offers a modular access to the TWS-API-Interface of Interactive Brokers.
17-
18-
`ib-api` provides a simple interface to low-level TWS API-calls.
19+
`ib-api` offers a modular access to the TWS-API-Interface of Interactive Brokers.
1920

2021
----
2122

@@ -25,7 +26,7 @@ Install in the usual way
2526
$ gem install ib-api
2627
```
2728

28-
In its plain vanilla usage, it just exchanges messages with the TWS. Any response is stored in the `recieved-Array`.
29+
In its plain vanilla usage, it just exchanges messages with the TWS. Any response is stored in the `received-array`.
2930

3031
It needs just a few lines of code to place an order
3132

@@ -54,53 +55,43 @@ puts ib.recieved[:OrderStatus].to_human
5455

5556
```
5657

57-
##### User-specific Actions
58-
Besides storing any TWS-response in an array, callbacks are implemented.
58+
## Plugins
59+
60+
**IB-API** ships with simple plugins to facilitate automations
5961

60-
The user subscribes to a certain response and defines the actions in a typically ruby manner. These actions
61-
can be defined globaly
6262
```ruby
63-
ib = IB::Connection.new do |tws|
64-
# Subscribe to TWS alerts/errors and order-related messages
65-
tws.subscribe(:Alert, :OpenOrder, :OrderStatus, :OpenOrderEnd) { |msg| puts msg.to_human }
66-
end
63+
require 'ib-api'
64+
# connect with default parameters
65+
ib = IB::Connection.new do | c |
66+
c.activate_plugin "verify"
67+
end
6768

69+
g = IB::Stock.new symbol: 'GE'
70+
puts g.verify.first.attributes
71+
{:symbol=>"GE", :sec_type=>"STK", :last_trading_day=>"", :strike=>0.0, :right=>"", :exchange=>"SMART", :currency=>"USD", :local_symbol=>"GE", :trading_class=>"GE", :con_id=>498843743, :multiplier=>0, :primary_exchange=>"NYSE", }
6872
```
6973

70-
or occationally
74+
Currently implemented plugins
75+
76+
* connection-tools: ensure that a connection is established and active
77+
* verify: get contract details from the tws
78+
* symbols: use predefined symbols
79+
* managed-accounts: fetch and organize account- and portfoliovalues
80+
* advanced-account: perform account-based previewing, opening, modifying and closing of Positions
81+
* process-orders: account-based bookkeeping of orders
82+
* auto-adjust: properly adjust the orderprice to the next valid min-tick of the contract
83+
* market-price: fetch the current market-price of a contract
84+
* eod: retrieve EOD-Data for the given contract
85+
* greeks: read current option greeks
86+
* roll: easy rolling of futures and options
87+
* option-chain: build option-chains for given strikes and expiries
88+
* spread-prototypes: create limit, stop, market, etc. orders through prototypes
89+
* probability-of-expiring: calculate the probability of expiring for the option-contract
90+
7191

72-
```ruby
73-
# first define actions
74-
q = Queue.new # Initialize as Queue
75-
request_id = nil # declare variable
76-
a = ib.subscribe(:Alert, :ContractData, :ContractDataEnd ) do |msg|
77-
case msg
78-
when Messages::Incoming::Alert
79-
q.close if msg.code == 200 # No security found
80-
when Messages::Incoming::ContractData # security returned
81-
q.push msg.contract if msg.request_id == request_id
82-
when Messages::Incoming::ContractDataEnd
83-
q.close if msg.request_id == request_id
84-
end # case
85-
end
86-
# perform request
87-
request_id = ib.send_message :RequestContractData, :contract => Stock.new(symbol: 'T')
88-
89-
while contract = q.pop
90-
puts contract.as_table
91-
end
92-
┌───────┬────────┬──────────┬──────────┬────────┬────────────┬───────────────┬───────┬────────┬──────────┐
93-
│ │ symbol │ con_id │ exchange │ expiry │ multiplier │ trading-class │ right │ strike │ currency │
94-
╞═══════╪════════╪══════════╪══════════╪════════╪════════════╪═══════════════╪═══════╪════════╪══════════╡
95-
StockT37018770SMART │ │ │ T │ │ │ USD
96-
└───────┴────────┴──────────┴──────────┴────────┴────────────┴───────────────┴───────┴────────┴──────────┘
97-
98-
ib.unsubscribe a # release subscriptions
99-
100-
```
10192
## Minimal TWS-Version
10293

103-
`ib-api` is tested via the _stable IB-Gateway_ (Version 10.12) and should work with any current tws-installation.
94+
`ib-api` is tested via the _stable IB-Gateway_ (Version 10.19) and should work with any current tws-installation.
10495

10596
## Tests
10697

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
972.5.2
1+
10.19.1

api.gemspec

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,12 @@ Gem::Specification.new do |spec|
4242
spec.add_dependency 'activemodel'
4343
spec.add_dependency 'ox'
4444
spec.add_dependency 'terminal-table'
45+
spec.add_dependency 'zeitwerk'
46+
spec.add_dependency 'workflow', '~> 3.1'
47+
# spec.add_dependency 'dry-schema'
48+
# spec.add_dependency 'dry-struct'
49+
# spec.add_dependency 'dry-core'
50+
# spec.add_dependency 'dry-configurable'
51+
# spec.add_dependency 'dry-monads' # future use
52+
4553
end

bin/console

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#!/usr/bin/env ruby
2+
### loads the active-orient environment
3+
### and starts an interactive shell
24
###
35
### Parameter: t)ws | g)ateway (or number of port ) Default: Gateway ,
46
### client_id , Default 2000
@@ -18,7 +20,7 @@ class Array
1820
# => [16, 17, 21, 20, 19, 8, 7]
1921
# 2.5.0 :007 > C.received[:OpenOrder].contract.to_human
2022
# => ["<Bag: IECombo SMART USD legs: >", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: WFC USD>", "<Stock: WFC USD>"]
21-
23+
#
2224
# its included only in the console, for inspection purposes
2325

2426
def method_missing(method, *key)
@@ -29,15 +31,19 @@ class Array
2931
end
3032
end # Array
3133

34+
class Object
35+
def inspect
36+
respond_to?(:to_human) ? to_human : super
37+
end
38+
end
3239

3340
# read items from console.yml
34-
read_yml = -> (key) do
41+
read_yml = -> (key) do
3542
YAML::load_file( File.expand_path('../console.yml',__FILE__))[key]
3643
end
3744

38-
3945
puts
40-
puts ">> IB-Core Interactive Console <<"
46+
puts ">> IB-API Interactive Console <<"
4147
puts '-'* 45
4248
puts
4349
puts "Namespace is IB ! "
@@ -46,44 +52,45 @@ read_yml = -> (key) do
4652
include IB
4753
require 'irb'
4854
client_id = ARGV[1] || read_yml[:client_id]
49-
specified_port = ARGV[0] || 'Gateway'
50-
port = case specified_port
51-
when Integer
52-
specified_port # just use the number
55+
specified_host = ARGV[0] || 'Gateway'
56+
host = case specified_host
5357
when /^[gG]/
5458
read_yml[:gateway]
5559
when /^[Tt]/
5660
read_yml[:tws]
61+
else
62+
raise "Specify target from console.yml: `g|t` instead of #{specified_host}"
5763
end
58-
5964
ARGV.clear
6065

61-
## The Block takes instructions which are executed after initializing all instance-variables
62-
## and prior to the connection-process
63-
## Here we just subscribe to some events
64-
C = Connection.new client_id: client_id, port: port do |c| # future use__ , optional_capacities: "+PACEAPI" do |c|
66+
C = Connection.new client_id: client_id, host: host
67+
C.logger.level = Logger::WARN
6568

66-
c.subscribe( :ContractData, :BondContractData) { |msg| c.logger.info { msg.contract.to_human } }
67-
c.subscribe( :Alert, :ContractDataEnd, :ManagedAccounts, :OrderStatus ) {| m| c.logger.info { m.to_human } }
68-
c.subscribe( :PortfolioValue, :AccountValue, :OrderStatus, :OpenOrderEnd, :ExecutionData ) {| m| c.logger.info { m.to_human }}
69-
# c.subscribe :ManagedAccounts do |msg|
70-
# puts "------------------------------ Managed Accounts ----------------------------------"
71-
# puts "Detected Accounts: #{msg.acounts.account.join(' -- ')} "
72-
# puts
73-
# end
69+
C.subscribe(:Alert){ |m| puts "A: "+ m.message }
70+
C.subscribe(:AccountUpdateTime){ }
71+
72+
C.received = true
73+
C.activate_plugin :connection_tools, :symbols, :market_price,
74+
"order-prototypes", "spread-prototypes",
75+
"advanced_account", 'process_orders'
76+
C.logger.level = Logger::INFO
77+
puts C.workflow_state
78+
C.get_account_data
79+
C.request_open_orders
80+
C.logger.level = Logger::ERROR
81+
puts "Connection established on #{host}"
7482

75-
c.subscribe( :OpenOrder){ |msg| puts "Open Order detected and stored: C.received[:OpenOrders] " }
76-
end
77-
#C.logger.level = Logger::FATAL
7883
unless C.received[:OpenOrder].blank?
79-
puts "------------------------------- OpenOrders ----------------------------------"
80-
puts C.received[:OpenOrder].to_human.join "\n"
84+
puts "---------------------------------------- OpenOrders -------------------------------------------"
85+
puts C.clients.map{ |c| c.orders.map &:to_human }.flatten.join("\n")
8186
end
82-
puts "Connection established on Port #{port}, client_id #{client_id} used"
87+
puts ""
88+
puts Terminal::Table.new title: 'Active Plugins',
89+
rows: C.plugins.delete_if{ |x| x =~ /\// }.sort.each_slice(4),
90+
style: { border: :unicode }
8391
puts
8492
puts "----> C points to the connection-instance"
8593
puts
86-
puts "some basic Messages are subscribed and accordingly displayed"
8794
puts '-'* 45
8895

8996
IRB.start(__FILE__)

0 commit comments

Comments
 (0)