ib-api 972.1 → 972.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9119cbc06f3b5e5e32b73fbe0d706b06d94c55ff2ce2ca4357e4f349f49f43f
4
- data.tar.gz: b977e09dee0df176e673679839b738425871dbf25ca8cad4e8f497323647ecc6
3
+ metadata.gz: 0beb8b8f1edf85049336ec063de7fcaa5c0c0e1dae3e6f813131f997718892ad
4
+ data.tar.gz: c2178ec4cdff3a6d90c7ef0c1cd68dab1620ce57ab2feba811873a113d1a6536
5
5
  SHA512:
6
- metadata.gz: '02538d6ab965ee0024cef798aebbcdff42859025a848108c5ca7af1e305cae019b1db3f9489300497fde388f5b0e659064d305ec316695d4154d20abc05277f1'
7
- data.tar.gz: 3245c0fda19a98f6ab5b29827b246b91d31c91a5daac10bcd8bbe114d699edc117922bae11503b3219f7bd18d8b654b6be6e19365c346bad3f4201829ce6f97b
6
+ metadata.gz: e1b6919bbc9adf1044b602bb64da8b67f0bfe2ec54c354a6a6465e2bf7dfa49355315029c0bba3ae682b2226dea3002d74a0e3ba7b02834de7217d22ec2f2461
7
+ data.tar.gz: 8e3bc0babb443933c0b843884a2ec76ceb2fb0df7ea89aad1912c68b672c217dd56b4a8ea90ed350b83660f838895853f3aadc9e1fb2c5baf2ddc029c5e7fc22
data/Gemfile.lock CHANGED
@@ -1,31 +1,31 @@
1
1
  GIT
2
2
  remote: https://github.com/ohler55/ox.git
3
- revision: 67ce6ecb45a0d1354e1f8ed9a155826ba986e21e
3
+ revision: 59c4234fe01fb5de08d49b39ecf5fc7338c1ffdc
4
4
  specs:
5
- ox (2.13.4)
5
+ ox (2.14.4)
6
6
 
7
7
  PATH
8
8
  remote: .
9
9
  specs:
10
- ib-api (972.1)
10
+ ib-api (972.3.1)
11
11
  activemodel
12
12
  activesupport (>= 6.0)
13
13
 
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- activemodel (6.1.0)
18
- activesupport (= 6.1.0)
19
- activesupport (6.1.0)
17
+ activemodel (6.1.3.2)
18
+ activesupport (= 6.1.3.2)
19
+ activesupport (6.1.3.2)
20
20
  concurrent-ruby (~> 1.0, >= 1.0.2)
21
21
  i18n (>= 1.6, < 2)
22
22
  minitest (>= 5.1)
23
23
  tzinfo (~> 2.0)
24
24
  zeitwerk (~> 2.3)
25
25
  coderay (1.1.3)
26
- concurrent-ruby (1.1.7)
26
+ concurrent-ruby (1.1.8)
27
27
  diff-lcs (1.4.4)
28
- ffi (1.13.1)
28
+ ffi (1.15.0)
29
29
  formatador (0.2.5)
30
30
  guard (2.16.2)
31
31
  formatador (>= 0.2.4)
@@ -41,55 +41,55 @@ GEM
41
41
  guard (~> 2.1)
42
42
  guard-compat (~> 1.1)
43
43
  rspec (>= 2.99.0, < 4.0)
44
- i18n (1.8.5)
44
+ i18n (1.8.10)
45
45
  concurrent-ruby (~> 1.0)
46
- listen (3.2.1)
46
+ listen (3.5.1)
47
47
  rb-fsevent (~> 0.10, >= 0.10.3)
48
48
  rb-inotify (~> 0.9, >= 0.9.10)
49
49
  lumberjack (1.2.8)
50
50
  method_source (1.0.0)
51
- minitest (5.14.2)
51
+ minitest (5.14.4)
52
52
  nenv (0.3.0)
53
53
  notiffany (0.1.3)
54
54
  nenv (~> 0.1)
55
55
  shellany (~> 0.0)
56
- pry (0.13.1)
56
+ pry (0.14.1)
57
57
  coderay (~> 1.1)
58
58
  method_source (~> 1.0)
59
- rake (13.0.1)
60
- rb-fsevent (0.10.4)
59
+ rake (13.0.3)
60
+ rb-fsevent (0.11.0)
61
61
  rb-inotify (0.10.1)
62
62
  ffi (~> 1.0)
63
- rspec (3.9.0)
64
- rspec-core (~> 3.9.0)
65
- rspec-expectations (~> 3.9.0)
66
- rspec-mocks (~> 3.9.0)
63
+ rspec (3.10.0)
64
+ rspec-core (~> 3.10.0)
65
+ rspec-expectations (~> 3.10.0)
66
+ rspec-mocks (~> 3.10.0)
67
67
  rspec-collection_matchers (1.2.0)
68
68
  rspec-expectations (>= 2.99.0.beta1)
69
- rspec-core (3.9.3)
70
- rspec-support (~> 3.9.3)
71
- rspec-expectations (3.9.2)
69
+ rspec-core (3.10.1)
70
+ rspec-support (~> 3.10.0)
71
+ rspec-expectations (3.10.1)
72
72
  diff-lcs (>= 1.2.0, < 2.0)
73
- rspec-support (~> 3.9.0)
73
+ rspec-support (~> 3.10.0)
74
74
  rspec-its (1.3.0)
75
75
  rspec-core (>= 3.0.0)
76
76
  rspec-expectations (>= 3.0.0)
77
- rspec-mocks (3.9.1)
77
+ rspec-mocks (3.10.2)
78
78
  diff-lcs (>= 1.2.0, < 2.0)
79
- rspec-support (~> 3.9.0)
80
- rspec-support (3.9.3)
79
+ rspec-support (~> 3.10.0)
80
+ rspec-support (3.10.2)
81
81
  shellany (0.0.1)
82
- thor (1.0.1)
82
+ thor (1.1.0)
83
83
  tzinfo (2.0.4)
84
84
  concurrent-ruby (~> 1.0)
85
85
  value_semantics (3.6.0)
86
86
  zeitwerk (2.4.2)
87
87
 
88
88
  PLATFORMS
89
- ruby
89
+ x86_64-linux
90
90
 
91
91
  DEPENDENCIES
92
- bundler (~> 1.17)
92
+ bundler
93
93
  guard
94
94
  guard-rspec
95
95
  ib-api!
@@ -101,4 +101,4 @@ DEPENDENCIES
101
101
  value_semantics
102
102
 
103
103
  BUNDLED WITH
104
- 1.17.3
104
+ 2.2.3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 972.1
1
+ 972.5
data/api.gemspec CHANGED
@@ -35,7 +35,7 @@ Gem::Specification.new do |spec|
35
35
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
36
  spec.require_paths = ["lib"]
37
37
 
38
- spec.add_development_dependency "bundler", "~> 1.17"
38
+ spec.add_development_dependency "bundler"
39
39
  spec.add_development_dependency "rake", "~> 13.0"
40
40
  spec.add_development_dependency "rspec", "~> 3.0"
41
41
  spec.add_dependency 'activesupport', '>= 6.0'
data/bin/console CHANGED
@@ -10,8 +10,6 @@
10
10
  require 'bundler/setup'
11
11
  require 'yaml'
12
12
 
13
- require 'logger'
14
-
15
13
  require 'ib-api'
16
14
 
17
15
  class Array
@@ -47,7 +45,6 @@ read_yml = -> (key) do
47
45
  puts "Namespace is IB ! "
48
46
  puts
49
47
  puts '-'* 45
50
- include LogDev
51
48
  include IB
52
49
  require 'irb'
53
50
  client_id = ARGV[1] || read_yml[:client_id]
@@ -62,16 +59,15 @@ read_yml = -> (key) do
62
59
  end
63
60
 
64
61
  ARGV.clear
65
- logger = default_logger # Logger.new STDOUT
66
62
 
67
63
  ## The Block takes instructions which are executed after initializing all instance-variables
68
64
  ## and prior to the connection-process
69
65
  ## Here we just subscribe to some events
70
66
  C = Connection.new client_id: client_id, port: port do |c| # future use__ , optional_capacities: "+PACEAPI" do |c|
71
67
 
72
- c.subscribe( :ContractData, :BondContractData) { |msg| logger.info { msg.contract.to_human } }
73
- c.subscribe( :Alert, :ContractDataEnd, :ManagedAccounts, :OrderStatus ) {| m| logger.info { m.to_human } }
74
- c.subscribe( :PortfolioValue, :AccountValue, :OrderStatus, :OpenOrderEnd, :ExecutionData ) {| m| logger.info { m.to_human }}
68
+ c.subscribe( :ContractData, :BondContractData) { |msg| c.logger.info { msg.contract.to_human } }
69
+ c.subscribe( :Alert, :ContractDataEnd, :ManagedAccounts, :OrderStatus ) {| m| c.logger.info { m.to_human } }
70
+ c.subscribe( :PortfolioValue, :AccountValue, :OrderStatus, :OpenOrderEnd, :ExecutionData ) {| m| c.logger.info { m.to_human }}
75
71
  # c.subscribe :ManagedAccounts do |msg|
76
72
  # puts "------------------------------- Managed Accounts ----------------------------------"
77
73
  # puts "Detected Accounts: #{msg.accounts.account.join(' -- ')} "
@@ -79,8 +75,8 @@ read_yml = -> (key) do
79
75
  # end
80
76
 
81
77
  c.subscribe( :OpenOrder){ |msg| "Open Order detected and stored: C.received[:OpenOrders] " }
82
- c.logger.level = Logger::INFO
83
78
  end
79
+ C.logger.level = Logger::INFO
84
80
  unless C.received[:OpenOrder].blank?
85
81
  puts "------------------------------- OpenOrders ----------------------------------"
86
82
  puts C.received[:OpenOrder].to_human.join "\n"
data/changelog.md CHANGED
@@ -15,4 +15,5 @@ Changelog
15
15
  | 1.12.2020 | creating a dummy Contract#verify to guaranty safe operation of spreads |
16
16
 
17
17
  | | Preparation of a Gem-Release |
18
-
18
+ | 23.2.2021 | Fixed retrieving of ContractDetail requests of Options with strikes < 1
19
+ | | Gem Release |
data/lib/ib/connection.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require 'thread'
2
2
  #require 'active_support'
3
3
  require 'ib/socket'
4
- require 'ib/logger'
4
+ require 'logger'
5
+ require 'logging'
5
6
  require 'ib/messages'
6
7
 
7
8
  module IB
@@ -18,10 +19,9 @@ module IB
18
19
  ## public data-queue: received, received?, wait_for, clear_received
19
20
  ## misc: reader_running?
20
21
 
21
- include LogDev # provides default_logger
22
+ include Support::Logging # provides default_logger
22
23
 
23
24
  mattr_accessor :current
24
- mattr_accessor :logger ## borrowed from active_support
25
25
  # Please note, we are realizing only the most current TWS protocol versions,
26
26
  # thus improving performance at the expense of backwards compatibility.
27
27
  # Older protocol versions support can be found in older gem versions.
@@ -40,7 +40,7 @@ module IB
40
40
  connect: true, # Connect at initialization
41
41
  received: true, # Keep all received messages in a @received Hash
42
42
  # redis: false, # future plans
43
- logger: default_logger,
43
+ logger: nil,
44
44
  client_id: rand( 1001 .. 9999 ) ,
45
45
  client_version: IB::Messages::CLIENT_VERSION, # lib/ib/server_versions.rb
46
46
  optional_capacities: "", # TWS-Version 974: "+PACEAPI"
@@ -49,17 +49,13 @@ module IB
49
49
  # V 974 release motes
50
50
  # API messages sent at a higher rate than 50/second can now be paced by TWS at the 50/second rate instead of potentially causing a disconnection. This is now done automatically by the RTD Server API and can be done with other API technologies by invoking SetConnectOptions("+PACEAPI") prior to eConnect.
51
51
 
52
-
52
+ self.class.configure_logger logger
53
53
  # convert parameters into instance-variables and assign them
54
- method(__method__).parameters.each do |type, k|
55
- next unless type == :key
56
- case k
57
- when :logger
58
- self.logger = logger
59
- else
54
+ method(__method__).parameters.each do |type, k|
55
+ next unless type == :key ## available: key , keyrest
56
+ next if k.to_s == 'logger'
60
57
  v = eval(k.to_s)
61
58
  instance_variable_set("@#{k}", v) unless v.nil?
62
- end
63
59
  end
64
60
 
65
61
  # A couple of locks to avoid race conditions in JRuby
@@ -79,9 +75,9 @@ module IB
79
75
  yield self if block_given?
80
76
 
81
77
  self.subscribe(:NextValidId) do |msg|
82
- logger.progname = "Connection#connect"
78
+ self.logger.progname = "Connection#connect"
83
79
  self.next_local_id = msg.local_id
84
- logger.info { "Got next valid order id: #{next_local_id}." }
80
+ self.logger.info { "Got next valid order id: #{next_local_id}." }
85
81
  end
86
82
 
87
83
  # Ensure the transmission of NextValidId.
@@ -100,7 +96,7 @@ module IB
100
96
  def update_next_order_id
101
97
  i,finish = 0, false
102
98
  sub = self.subscribe(:NextValidID) { finish = true }
103
- connected? ? self.send_message( :RequestIds ) : open()
99
+ connected? ? self.send_message( :RequestIds ) : open()
104
100
  Timeout::timeout(1, IB::TransmissionError,"Could not get NextValidId" ) do
105
101
  loop { sleep 0.1; break if finish }
106
102
  end
@@ -186,7 +182,13 @@ module IB
186
182
  when what.is_a?(Class) && what < Messages::Incoming::AbstractMessage
187
183
  [what]
188
184
  when what.is_a?(Symbol)
189
- [Messages::Incoming.const_get(what)]
185
+ if Messages::Incoming.const_defined?(what)
186
+ [Messages::Incoming.const_get(what)]
187
+ elsif TechnicalAnalysis::Signals.const_defined?(what)
188
+ [TechnicalAnalysis::Signals.const_get?(what)]
189
+ else
190
+ error "#{what} is no IB::Messages or TechnicalAnalyis::Signals class"
191
+ end
190
192
  when what.is_a?(Regexp)
191
193
  Messages::Incoming::Classes.values.find_all { |klass| klass.to_s =~ what }
192
194
  else
@@ -416,7 +418,7 @@ module IB
416
418
  @subscribe_lock.synchronize do
417
419
  subscribers[msg.class].each { |_, subscriber| subscriber.call(msg) }
418
420
  end
419
- logger.warn { "No subscribers for message #{msg.class}!" } if subscribers[msg.class].empty?
421
+ logger.info { "No subscribers for message #{msg.class}!" } if subscribers[msg.class].empty?
420
422
 
421
423
  # Collect all received messages into a @received Hash
422
424
  if @received
data/lib/ib/logger.rb CHANGED
@@ -18,7 +18,7 @@ module LogDev
18
18
  end
19
19
 
20
20
  # Add universally accessible log method/accessor into Object
21
- def log *args
21
+ def logger *args
22
22
  default_logger.tap do |logger|
23
23
  logger.fatal *args unless args.empty?
24
24
  end
@@ -30,12 +30,12 @@ module IB
30
30
  @created_at = Time.now
31
31
  if source.is_a?(Hash) # Source is a @data Hash
32
32
  @data = source
33
- @buffer =[] # initialize empty buffer, indicates a successfull initializing
33
+ @buffer =[] # initialize empty buffer, indicates a successful initializing
34
34
  else
35
35
  @buffer = source
36
36
  ### DEBUG DEBUG DEBUG RAW STREAM ###############
37
37
  # if uncommented, the raw-input from the tws is included in the logging
38
- # puts "BUFFER :> #{buffer.inspect} "
38
+ ## puts "BUFFER :> #{buffer.inspect} "
39
39
  ### DEBUG DEBUG DEBUG RAW STREAM ###############
40
40
  @data = Hash.new
41
41
  self.load
@@ -43,11 +43,11 @@ module IB
43
43
  end
44
44
 
45
45
  def valid?
46
- @buffer.empty?
46
+ @buffer.empty?
47
47
  end
48
48
 
49
49
  ## more recent messages omit the transmission of a version
50
- ## thus just load the parameter-map
50
+ ## thus just load the parameter-map
51
51
  def simple_load
52
52
  load_map *self.class.data_map
53
53
  rescue IB::Error => e
@@ -87,7 +87,7 @@ module IB
87
87
 
88
88
  when Symbol # Normal map
89
89
  group, name, type, block =
90
- if instruction[2].nil? || instruction[2].is_a?(Proc) # lambda's are Proc's
90
+ if instruction[2].nil? || instruction[2].is_a?(Proc) # lambda's are Proc's
91
91
  [nil] + instruction # No group, [ :name, :type, (:block) ]
92
92
  else
93
93
  instruction # [ :group, :name, :type, (:block)]
@@ -95,14 +95,14 @@ module IB
95
95
  begin
96
96
  data = @buffer.__send__("read_#{type}", &block)
97
97
  rescue IB::LoadError, NoMethodError => e
98
- error "Reading #{self.class}: #{e.class}: #{e.message} --> Instruction: #{name}" , :reader, false
98
+ error "Reading #{self.class}: #{e.class}: #{e.message} --> Instruction: #{name}" , :reader, false
99
99
  end
100
100
  # debug puts data.inspect
101
101
  if group
102
102
  @data[group] ||= {}
103
103
  @data[group][name] = data
104
104
  else
105
- @data[name] = data
105
+ @data[name] = data
106
106
  end
107
107
  else
108
108
  error "Unrecognized instruction #{instruction}"
@@ -26,7 +26,11 @@ module IB
26
26
 
27
27
  class ReceiveFA
28
28
  def accounts
29
- xml[:ListOfAccountAliases][:AccountAlias].map{|x| Account.new x }
29
+ if( a= xml[:ListOfAccountAliases][:AccountAlias]).is_a? Array
30
+ a.map{|x| Account.new x }
31
+ elsif a.is_a? Hash ## only one account (soley financial advisor)
32
+ [ Account.new( a ) ]
33
+ end
30
34
  end
31
35
 
32
36
  def to_human
@@ -41,12 +41,12 @@ module IB
41
41
  IB::Bar.new :time => buffer.read_int_date, # conversion of epoche-time-integer to Dateime
42
42
  # requires format_date in request to be "2"
43
43
  # (outgoing/bar_requests # RequestHistoricalData#Encoding)
44
- :open => buffer.read_decimal,
45
- :high => buffer.read_decimal,
46
- :low => buffer.read_decimal,
47
- :close => buffer.read_decimal,
44
+ :open => buffer.read_float,
45
+ :high => buffer.read_float,
46
+ :low => buffer.read_float,
47
+ :close => buffer.read_float,
48
48
  :volume => buffer.read_int,
49
- :wap => buffer.read_decimal,
49
+ :wap => buffer.read_float,
50
50
  # :has_gaps => buffer.read_string, # only in ServerVersion < 124
51
51
  :trades => buffer.read_int
52
52
  end
@@ -79,6 +79,26 @@ module IB
79
79
  end
80
80
  end
81
81
 
82
+ HistoricalDataUpdate = def_message [90, 0] ,
83
+ [:request_id, :int] ,
84
+ [:count, :int],
85
+ [:bar, :bar] # defined in support.rb
86
+
87
+ class HistoricalDataUpdate
88
+ attr_accessor :results
89
+ using IBSupport # extended Array-Class from abstract_message
90
+
91
+ def bar
92
+ @bar = IB::Bar.new @data[:bar]
93
+ end
94
+
95
+ def to_human
96
+ "<HistDataUpdate #{request_id} #{bar}>"
97
+ end
98
+ end
99
+
100
+
101
+
82
102
  end # module Incoming
83
103
  end # module Messages
84
104
  end # module IB
@@ -25,9 +25,9 @@ module IB
25
25
  #
26
26
  def send_to socket
27
27
  ### debugging of outgoing Messages
28
- # puts "------sendto ---------(debugging output in outgoing/abstract_message)"
29
- # puts socket.prepare_message( self.preprocess).inspect.split('\x00')[3..-1].inspect
30
- # puts "------sendto ---------"
28
+ # puts "------sendto ---------(debugging output in outgoing/abstract_message)"
29
+ # puts socket.prepare_message( self.preprocess).inspect.split('\x00')[3..-1].inspect
30
+ # puts "------sendto ---------"
31
31
  socket.send_messages self.preprocess #.each {|data| socket.write_data data}
32
32
  end
33
33
 
@@ -18,11 +18,10 @@ module IB
18
18
  # unless BAR_SIZES.keys.include?(bar_size)
19
19
  # error ":bar_size must be one of #{BAR_SIZES.inspect}", :args
20
20
  # end
21
-
22
- contract = data[:contract].is_a?(IB::Contract) ?
23
- data[:contract] : IB::Contract.from_ib_ruby(data[:contract])
24
-
25
- [data_type, nil, contract]
21
+ unless data[:contract].is_a? IB::Contract
22
+ error "contract must be a valid IB::Contract" , :args
23
+ end
24
+ [data_type, nil, data[:contract]]
26
25
  end
27
26
  end
28
27