ib-api 972.5 → 972.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/Gemfile.lock +36 -41
- data/README.md +21 -13
- data/VERSION +1 -1
- data/api.gemspec +2 -0
- data/bin/console +15 -17
- data/bin/console.yml +1 -1
- data/lib/extensions/class-extensions.rb +9 -0
- data/lib/ib/base_properties.rb +22 -1
- data/lib/ib/connection.rb +122 -100
- data/lib/ib/constants.rb +5 -2
- data/lib/ib/errors.rb +3 -1
- data/lib/ib/messages/incoming/alert.rb +4 -4
- data/lib/ib/messages/incoming/ticks.rb +1 -1
- data/lib/ib/messages/outgoing/bar_requests.rb +2 -2
- data/lib/ib/messages/outgoing/place_order.rb +3 -3
- data/lib/ib/messages/outgoing/request_marketdata.rb +1 -1
- data/lib/ib/raw_message.rb +85 -0
- data/lib/ib/socket.rb +2 -2
- data/lib/logging.rb +9 -8
- data/lib/models/ib/contract.rb +64 -5
- data/lib/models/ib/index.rb +1 -1
- data/lib/models/ib/option_detail.rb +13 -0
- data/lib/models/ib/order.rb +23 -0
- data/lib/models/ib/portfolio_value.rb +34 -12
- data/lib/models/ib/spread.rb +33 -18
- data/lib/requires.rb +2 -1
- metadata +32 -4
- data/lib/ib/logger.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25eeaf6f08e2fd29800c3ed6d1ec94adfa5a61fecd2c9a37bfdc9a692f6cbaf9
|
4
|
+
data.tar.gz: aac0683bb11a8d7326a95a69b9e728321a70d70be072ee6d133d09dce6724251
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b28db7e5ee4aa73942e724caf8c65e07df46516eca725868fc7279f31238124d7fee05da3fe8a43737a820b43079790f3f1a77f0ff662600d89fdfcbf0c9734
|
7
|
+
data.tar.gz: ec8e9b32fd01c212249c3fb4da3c7d86b503d0d1cc6cf3854c25a03b98933e0b8a26981c56c45e1cd1799ce352053f3601ea0bef68c3297c41eb15e7c5847048
|
data/Gemfile
CHANGED
@@ -5,8 +5,8 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
|
5
5
|
# Specify your gem's dependencies in api.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem 'value_semantics' # models
|
9
|
-
|
8
|
+
# gem 'value_semantics' # models, future plans
|
9
|
+
|
10
10
|
|
11
11
|
|
12
12
|
gem 'rspec'
|
data/Gemfile.lock
CHANGED
@@ -1,39 +1,34 @@
|
|
1
|
-
GIT
|
2
|
-
remote: https://github.com/ohler55/ox.git
|
3
|
-
revision: 59c4234fe01fb5de08d49b39ecf5fc7338c1ffdc
|
4
|
-
specs:
|
5
|
-
ox (2.14.4)
|
6
|
-
|
7
1
|
PATH
|
8
2
|
remote: .
|
9
3
|
specs:
|
10
|
-
ib-api (972.
|
4
|
+
ib-api (972.5.2)
|
11
5
|
activemodel
|
12
6
|
activesupport (>= 6.0)
|
7
|
+
ox
|
8
|
+
terminal-table
|
13
9
|
|
14
10
|
GEM
|
15
11
|
remote: https://rubygems.org/
|
16
12
|
specs:
|
17
|
-
activemodel (
|
18
|
-
activesupport (=
|
19
|
-
activesupport (
|
13
|
+
activemodel (7.0.4.2)
|
14
|
+
activesupport (= 7.0.4.2)
|
15
|
+
activesupport (7.0.4.2)
|
20
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
21
17
|
i18n (>= 1.6, < 2)
|
22
18
|
minitest (>= 5.1)
|
23
19
|
tzinfo (~> 2.0)
|
24
|
-
zeitwerk (~> 2.3)
|
25
20
|
coderay (1.1.3)
|
26
|
-
concurrent-ruby (1.
|
27
|
-
diff-lcs (1.
|
28
|
-
ffi (1.15.
|
29
|
-
formatador (
|
30
|
-
guard (2.
|
21
|
+
concurrent-ruby (1.2.2)
|
22
|
+
diff-lcs (1.5.0)
|
23
|
+
ffi (1.15.5)
|
24
|
+
formatador (1.1.0)
|
25
|
+
guard (2.18.0)
|
31
26
|
formatador (>= 0.2.4)
|
32
27
|
listen (>= 2.7, < 4.0)
|
33
28
|
lumberjack (>= 1.0.12, < 2.0)
|
34
29
|
nenv (~> 0.1)
|
35
30
|
notiffany (~> 0.0)
|
36
|
-
pry (>= 0.
|
31
|
+
pry (>= 0.13.0)
|
37
32
|
shellany (~> 0.0)
|
38
33
|
thor (>= 0.18.1)
|
39
34
|
guard-compat (1.2.1)
|
@@ -41,49 +36,51 @@ GEM
|
|
41
36
|
guard (~> 2.1)
|
42
37
|
guard-compat (~> 1.1)
|
43
38
|
rspec (>= 2.99.0, < 4.0)
|
44
|
-
i18n (1.
|
39
|
+
i18n (1.12.0)
|
45
40
|
concurrent-ruby (~> 1.0)
|
46
|
-
listen (3.
|
41
|
+
listen (3.8.0)
|
47
42
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
48
43
|
rb-inotify (~> 0.9, >= 0.9.10)
|
49
44
|
lumberjack (1.2.8)
|
50
45
|
method_source (1.0.0)
|
51
|
-
minitest (5.
|
46
|
+
minitest (5.17.0)
|
52
47
|
nenv (0.3.0)
|
53
48
|
notiffany (0.1.3)
|
54
49
|
nenv (~> 0.1)
|
55
50
|
shellany (~> 0.0)
|
56
|
-
|
51
|
+
ox (2.14.14)
|
52
|
+
pry (0.14.2)
|
57
53
|
coderay (~> 1.1)
|
58
54
|
method_source (~> 1.0)
|
59
|
-
rake (13.0.
|
60
|
-
rb-fsevent (0.11.
|
55
|
+
rake (13.0.6)
|
56
|
+
rb-fsevent (0.11.2)
|
61
57
|
rb-inotify (0.10.1)
|
62
58
|
ffi (~> 1.0)
|
63
|
-
rspec (3.
|
64
|
-
rspec-core (~> 3.
|
65
|
-
rspec-expectations (~> 3.
|
66
|
-
rspec-mocks (~> 3.
|
59
|
+
rspec (3.12.0)
|
60
|
+
rspec-core (~> 3.12.0)
|
61
|
+
rspec-expectations (~> 3.12.0)
|
62
|
+
rspec-mocks (~> 3.12.0)
|
67
63
|
rspec-collection_matchers (1.2.0)
|
68
64
|
rspec-expectations (>= 2.99.0.beta1)
|
69
|
-
rspec-core (3.
|
70
|
-
rspec-support (~> 3.
|
71
|
-
rspec-expectations (3.
|
65
|
+
rspec-core (3.12.1)
|
66
|
+
rspec-support (~> 3.12.0)
|
67
|
+
rspec-expectations (3.12.2)
|
72
68
|
diff-lcs (>= 1.2.0, < 2.0)
|
73
|
-
rspec-support (~> 3.
|
69
|
+
rspec-support (~> 3.12.0)
|
74
70
|
rspec-its (1.3.0)
|
75
71
|
rspec-core (>= 3.0.0)
|
76
72
|
rspec-expectations (>= 3.0.0)
|
77
|
-
rspec-mocks (3.
|
73
|
+
rspec-mocks (3.12.3)
|
78
74
|
diff-lcs (>= 1.2.0, < 2.0)
|
79
|
-
rspec-support (~> 3.
|
80
|
-
rspec-support (3.
|
75
|
+
rspec-support (~> 3.12.0)
|
76
|
+
rspec-support (3.12.0)
|
81
77
|
shellany (0.0.1)
|
82
|
-
|
83
|
-
|
78
|
+
terminal-table (3.0.2)
|
79
|
+
unicode-display_width (>= 1.1.1, < 3)
|
80
|
+
thor (1.2.1)
|
81
|
+
tzinfo (2.0.6)
|
84
82
|
concurrent-ruby (~> 1.0)
|
85
|
-
|
86
|
-
zeitwerk (2.4.2)
|
83
|
+
unicode-display_width (2.4.2)
|
87
84
|
|
88
85
|
PLATFORMS
|
89
86
|
x86_64-linux
|
@@ -93,12 +90,10 @@ DEPENDENCIES
|
|
93
90
|
guard
|
94
91
|
guard-rspec
|
95
92
|
ib-api!
|
96
|
-
ox!
|
97
93
|
rake (~> 13.0)
|
98
94
|
rspec
|
99
95
|
rspec-collection_matchers
|
100
96
|
rspec-its
|
101
|
-
value_semantics
|
102
97
|
|
103
98
|
BUNDLED WITH
|
104
|
-
2.
|
99
|
+
2.3.22
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@ Ruby interface to Interactive Brokers' TWS API
|
|
3
3
|
|
4
4
|
Reimplementation of the basic functions of ib-ruby
|
5
5
|
|
6
|
+
|
6
7
|
__Documentation: [https://ib-ruby.github.io/ib-doc/](https://ib-ruby.github.io/ib-doc/)__ (_work in progress_)
|
7
8
|
|
8
9
|
----
|
@@ -20,7 +21,7 @@ $ gem install ib-api
|
|
20
21
|
|
21
22
|
In its plain vanilla usage, it just exchanges messages with the TWS. Any response is stored in the `recieved-Array`.
|
22
23
|
|
23
|
-
|
24
|
+
It needs just a few lines of code to place an order
|
24
25
|
|
25
26
|
```ruby
|
26
27
|
require 'ib-api'
|
@@ -64,29 +65,36 @@ or occationally
|
|
64
65
|
|
65
66
|
```ruby
|
66
67
|
# first define actions
|
67
|
-
|
68
|
+
q = Queue.new # Initialize as Queue
|
69
|
+
request_id = nil # declare variable
|
70
|
+
a = ib.subscribe(:Alert, :ContractData, :ContractDataEnd ) do |msg|
|
68
71
|
case msg
|
69
72
|
when Messages::Incoming::Alert
|
70
|
-
if msg.code == 200 # No security found
|
71
|
-
# do someting
|
72
|
-
end
|
73
|
+
q.close if msg.code == 200 # No security found
|
73
74
|
when Messages::Incoming::ContractData # security returned
|
74
|
-
|
75
|
-
|
75
|
+
q.push msg.contract if msg.request_id == request_id
|
76
|
+
when Messages::Incoming::ContractDataEnd
|
77
|
+
q.close if msg.request_id == request_id
|
76
78
|
end # case
|
77
79
|
end
|
78
80
|
# perform request
|
79
|
-
ib.send_message :RequestContractData, :contract =>
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
request_id = ib.send_message :RequestContractData, :contract => Stock.new(symbol: 'T')
|
82
|
+
|
83
|
+
while contract = q.pop
|
84
|
+
puts contract.as_table
|
85
|
+
end
|
86
|
+
┌───────┬────────┬──────────┬──────────┬────────┬────────────┬───────────────┬───────┬────────┬──────────┐
|
87
|
+
│ │ symbol │ con_id │ exchange │ expiry │ multiplier │ trading-class │ right │ strike │ currency │
|
88
|
+
╞═══════╪════════╪══════════╪══════════╪════════╪════════════╪═══════════════╪═══════╪════════╪══════════╡
|
89
|
+
│ Stock │ T │ 37018770 │ SMART │ │ │ T │ │ │ USD │
|
90
|
+
└───────┴────────┴──────────┴──────────┴────────┴────────────┴───────────────┴───────┴────────┴──────────┘
|
91
|
+
|
84
92
|
ib.unsubscribe a # release subscriptions
|
85
93
|
|
86
94
|
```
|
87
95
|
## Minimal TWS-Version
|
88
96
|
|
89
|
-
`ib-api` is tested via the _stable IB-Gateway_ (Version
|
97
|
+
`ib-api` is tested via the _stable IB-Gateway_ (Version 10.12) and should work with any current tws-installation.
|
90
98
|
|
91
99
|
## Tests
|
92
100
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
972.5
|
1
|
+
972.5.2
|
data/api.gemspec
CHANGED
data/bin/console
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
### loads the active-orient environment
|
3
|
-
### and starts an interactive shell
|
4
2
|
###
|
5
3
|
### Parameter: t)ws | g)ateway (or number of port ) Default: Gateway ,
|
6
4
|
### client_id , Default 2000
|
@@ -17,10 +15,10 @@ class Array
|
|
17
15
|
# i.e
|
18
16
|
#
|
19
17
|
# 2.5.0 :006 > C.received[:OpenOrder].local_id
|
20
|
-
# => [16, 17, 21, 20, 19, 8, 7]
|
18
|
+
# => [16, 17, 21, 20, 19, 8, 7]
|
21
19
|
# 2.5.0 :007 > C.received[:OpenOrder].contract.to_human
|
22
|
-
# => ["<Bag: IECombo SMART USD legs: >", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: WFC USD>", "<Stock: WFC USD>"]
|
23
|
-
|
20
|
+
# => ["<Bag: IECombo SMART USD legs: >", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: WFC USD>", "<Stock: WFC USD>"]
|
21
|
+
|
24
22
|
# its included only in the console, for inspection purposes
|
25
23
|
|
26
24
|
def method_missing(method, *key)
|
@@ -32,16 +30,16 @@ class Array
|
|
32
30
|
end # Array
|
33
31
|
|
34
32
|
|
35
|
-
# read items from console.yml
|
33
|
+
# read items from console.yml
|
36
34
|
read_yml = -> (key) do
|
37
35
|
YAML::load_file( File.expand_path('../console.yml',__FILE__))[key]
|
38
36
|
end
|
39
37
|
|
40
38
|
|
41
|
-
puts
|
42
|
-
puts ">> IB-Core Interactive Console <<"
|
39
|
+
puts
|
40
|
+
puts ">> IB-Core Interactive Console <<"
|
43
41
|
puts '-'* 45
|
44
|
-
puts
|
42
|
+
puts
|
45
43
|
puts "Namespace is IB ! "
|
46
44
|
puts
|
47
45
|
puts '-'* 45
|
@@ -59,24 +57,24 @@ read_yml = -> (key) do
|
|
59
57
|
end
|
60
58
|
|
61
59
|
ARGV.clear
|
62
|
-
|
60
|
+
|
63
61
|
## The Block takes instructions which are executed after initializing all instance-variables
|
64
62
|
## and prior to the connection-process
|
65
|
-
## Here we just subscribe to some events
|
66
|
-
C = Connection.new
|
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|
|
67
65
|
|
68
66
|
c.subscribe( :ContractData, :BondContractData) { |msg| c.logger.info { msg.contract.to_human } }
|
69
67
|
c.subscribe( :Alert, :ContractDataEnd, :ManagedAccounts, :OrderStatus ) {| m| c.logger.info { m.to_human } }
|
70
68
|
c.subscribe( :PortfolioValue, :AccountValue, :OrderStatus, :OpenOrderEnd, :ExecutionData ) {| m| c.logger.info { m.to_human }}
|
71
69
|
# c.subscribe :ManagedAccounts do |msg|
|
72
|
-
# puts "
|
73
|
-
# puts "Detected Accounts: #{msg.
|
70
|
+
# puts "------------------------------ Managed Accounts ----------------------------------"
|
71
|
+
# puts "Detected Accounts: #{msg.acounts.account.join(' -- ')} "
|
74
72
|
# puts
|
75
73
|
# end
|
76
74
|
|
77
|
-
c.subscribe( :OpenOrder){ |msg| "Open Order detected and stored: C.received[:OpenOrders] " }
|
78
|
-
end
|
79
|
-
C.logger.level = Logger::
|
75
|
+
c.subscribe( :OpenOrder){ |msg| puts "Open Order detected and stored: C.received[:OpenOrders] " }
|
76
|
+
end
|
77
|
+
#C.logger.level = Logger::FATAL
|
80
78
|
unless C.received[:OpenOrder].blank?
|
81
79
|
puts "------------------------------- OpenOrders ----------------------------------"
|
82
80
|
puts C.received[:OpenOrder].to_human.join "\n"
|
data/bin/console.yml
CHANGED
@@ -5,10 +5,19 @@ module CoreExtensions
|
|
5
5
|
self.each_with_object(Hash.new(0)) { |element, counter| counter[element] += 1 }.sort_by{|k,v| -v}.to_h
|
6
6
|
end
|
7
7
|
end
|
8
|
+
|
9
|
+
module TablePresenter
|
10
|
+
def as_table(&b)
|
11
|
+
the_table_header = first.table_header(&b)
|
12
|
+
the_table_rows = map &:table_row
|
13
|
+
Terminal::Table.new headings: the_table_header, rows: the_table_rows , style: { border: :unicode }
|
14
|
+
end
|
15
|
+
end
|
8
16
|
end
|
9
17
|
end
|
10
18
|
|
11
19
|
Array.include CoreExtensions::Array::DuplicatesCounter
|
20
|
+
Array.include CoreExtensions::Array::TablePresenter
|
12
21
|
|
13
22
|
|
14
23
|
|
data/lib/ib/base_properties.rb
CHANGED
@@ -17,12 +17,33 @@ module IB
|
|
17
17
|
end.compact.sort.join(' ') + ">"
|
18
18
|
end
|
19
19
|
|
20
|
+
def table_header
|
21
|
+
[ self.class.to_s.demodulize ] + content_attributes.keys
|
22
|
+
end
|
23
|
+
def table_row
|
24
|
+
[ self.class.to_s.demodulize ] + content_attributes.values
|
25
|
+
end
|
26
|
+
# the optional block specifies a title
|
27
|
+
# i.e.
|
28
|
+
#s = Symbols::Spreads.stoxx_dez
|
29
|
+
# puts s.portfolio_value( U).as_table{ s.description[1..-2] }
|
30
|
+
#┌───────────┬─────────────────────────────────────────────┬─────┬────────┬─────────┬──────────┬────────────┬──────────┐
|
31
|
+
#│ │ Straddle ESTX50(4200.0)[Dec 2021] │ pos │ entry │ market │ value │ unrealized │ realized │
|
32
|
+
#╞═══════════╪═════════════════════════════════════════════╪═════╪════════╪═════════╪══════════╪════════════╪══════════╡
|
33
|
+
#│ U7274612 │ Option: ESTX50 20211217 put 4200.0 DTB EUR │ -4 │ 179.85 │ 169.831 │ -6793.22 │ 400.78 │ │
|
34
|
+
#│ U7274612 │ Option: ESTX50 20211217 call 4200.0 DTB EUR │ -4 │ 97.85 │ 131.438 │ -5257.51 │ -1343.51 │ │
|
35
|
+
#└───────────┴─────────────────────────────────────────────┴─────┴────────┴─────────┴──────────┴────────────┴──────────┘
|
36
|
+
##
|
37
|
+
def as_table &b
|
38
|
+
Terminal::Table.new headings: table_header(&b), rows: [table_row ], style: { border: :unicode }
|
39
|
+
end
|
40
|
+
|
20
41
|
# Comparison support
|
21
42
|
def content_attributes
|
22
43
|
#NoMethodError if a Hash is assigned to an attribute
|
23
44
|
Hash[attributes.reject do |(attr, _)|
|
24
45
|
attr.to_s =~ /(_count)\z/ ||
|
25
|
-
[:created_at, :type,
|
46
|
+
[:created_at, :type, :updated_at,
|
26
47
|
:id, :order_id, :contract_id].include?(attr.to_sym)
|
27
48
|
end]
|
28
49
|
end
|