ib-api 972.1 → 972.5

Sign up to get free protection for your applications and to get access to all the features.
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