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.
data/lib/ib/support.rb CHANGED
@@ -28,13 +28,13 @@ module IBSupport
28
28
 
29
29
  ## Values -1 and below indicate: Not computed (TickOptionComputation)
30
30
  def read_decimal_limit_1
31
- i= read_decimal
31
+ i= read_float
32
32
  i <= -1 ? nil : i
33
33
  end
34
34
 
35
35
  ## Values -2 and below indicate: Not computed (TickOptionComputation)
36
36
  def read_decimal_limit_2
37
- i= read_decimal
37
+ i= read_float
38
38
  i <= -2 ? nil : i
39
39
  end
40
40
 
@@ -62,7 +62,7 @@ module IBSupport
62
62
 
63
63
  def read_int_date
64
64
  t= read_int
65
- s= Time.at(t)
65
+ s= Time.at(t.to_i)
66
66
  # s.year == 1970 --> data is most likely a date-string
67
67
  s.year == 1970 ? Date.parse(t.to_s) : s
68
68
  end
@@ -139,20 +139,37 @@ module IBSupport
139
139
  end
140
140
  #
141
141
 
142
- def read_contract # read a standard contract and return als hash
143
- { con_id: read_int,
144
- symbol: read_string,
145
- sec_type: read_string,
146
- expiry: read_string,
147
- strike: read_decimal,
148
- right: read_string,
149
- multiplier: read_int,
150
- exchange: read_string,
151
- currency: read_string,
152
- local_symbol: read_string,
153
- trading_class: read_string } # new Version 8
154
-
155
- end
142
+ def read_contract # read a standard contract and return als hash
143
+ { con_id: read_int,
144
+ symbol: read_string,
145
+ sec_type: read_string,
146
+ expiry: read_string,
147
+ strike: read_decimal,
148
+ right: read_string,
149
+ multiplier: read_int,
150
+ exchange: read_string,
151
+ currency: read_string,
152
+ local_symbol: read_string,
153
+ trading_class: read_string } # new Version 8
154
+ end
155
+
156
+
157
+ def read_bar # read a Historical data bar
158
+ # ** historicalDataUpdate: time open close high low ** covered hier
159
+ # historicalData time open high low close <- covered in messages/incomming
160
+ { :time => read_int_date, # conversion of epoche-time-integer to Dateime
161
+ # requires format_date in request to be "2"
162
+ # (outgoing/bar_requests # RequestHistoricalData#Encoding)
163
+ :open => read_float,
164
+ :close => read_float,
165
+ :high => read_float,
166
+ :low => read_float,
167
+ :wap => read_float,
168
+ :volume => read_int,
169
+ # :has_gaps => read_string, # only in ServerVersion < 124
170
+ :trades => read_int }
171
+
172
+ end
156
173
 
157
174
 
158
175
  alias read_bool read_boolean
data/lib/logging.rb ADDED
@@ -0,0 +1,45 @@
1
+ #module Kernel
2
+ # private
3
+ # def this_method_name
4
+ # caller[0] =~ /`([^']*)'/ and $1
5
+ # end
6
+ # see also __method__ and __callee__
7
+ #end
8
+
9
+
10
+
11
+ module Support
12
+ module Logging
13
+ def self.included(base)
14
+ base.extend ClassMethods
15
+ base.send :define_method, :logger do
16
+ base.logger
17
+ end
18
+ end
19
+
20
+ module ClassMethods
21
+ def logger
22
+ @logger
23
+ end
24
+
25
+ def logger=(logger)
26
+ @logger = logger
27
+ end
28
+
29
+ def configure_logger(log=nil)
30
+ if log
31
+ @logger = log
32
+ else
33
+ @logger = Logger.new(STDOUT)
34
+ @logger.level = Logger::INFO
35
+ @logger.formatter = proc do |severity, datetime, progname, msg|
36
+ # "#{datetime.strftime("%d.%m.(%X)")}#{"%5s" % severity}->#{msg}\n"
37
+ "#{"%5s" % severity}::#{msg}\n"
38
+ end
39
+ @logger.debug "------------------------------ start logging ----------------------------"
40
+ end # branch
41
+ end # def
42
+ end # module ClassMethods
43
+ end # module Logging
44
+ end # module Support
45
+
data/lib/models/ib/bag.rb CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  module IB
4
4
 
5
+ if defined?(Bag)
6
+ puts "Bag already a #{defined?(Bag)}"
7
+
8
+ # puts Bag.ancestors
9
+ IB.send(:remove_const, 'Bag')
10
+ end
5
11
  # "BAG" is not really a contract, but a combination (combo) of securities.
6
12
  # AKA basket or bag of securities. Individual securities in combo are represented
7
13
  # by ComboLeg objects.
data/lib/models/ib/bar.rb CHANGED
@@ -22,7 +22,7 @@ module IB
22
22
  validates_numericality_of :open, :high, :low, :close, :volume
23
23
 
24
24
  def to_human
25
- "<Bar: #{time} wap #{wap} OHLC #{open} #{high} #{low} #{close} " +
25
+ "<Bar: #{time.strftime("(%d.%m.%y)%X")} wap #{wap.round(3)} OHLC #{open} #{high} #{low} #{close} " +
26
26
  (trades ? "trades #{trades}" : "") + " vol #{volume}>"
27
27
  end
28
28
 
@@ -83,6 +83,28 @@ module IB
83
83
  ].flatten
84
84
  end
85
85
 
86
+
87
+ # fields are generated by serialize(:extended)
88
+ # i.e.
89
+ # z= Strangle.build from: Symbols::Index.stoxx, p: 3700, c: 4000, expiry: 202106
90
+ # zc= z.combo_legs.serialize :extended
91
+ # => [[321584786, 1, "BUY", "DTB", 0, 0, "", -1], [321584637, 1, "BUY", "DTB", 0, 0, "", -1]]
92
+ # nz = zc.map{|o| ComboLeg.build *o }
93
+ # zc.map{|o| ComboLeg.build o } => # is equivalent
94
+ # => [#<IB::ComboLeg:0x0000000001c36bc0 @attributes={:con_id=>321584786, :ratio=>1, :side=>"B", :exchange=>"DTB", ...
95
+ # nz.first == z.combo_legs.first => true
96
+ #
97
+ def self.build *fields
98
+ self.new Hash[[:con_id,
99
+ :ratio,
100
+ :side, # reverse to_sup?
101
+ :exchange,
102
+ :open_close,
103
+ :short_sale_slot,
104
+ :designated_location,
105
+ :exempt_code].zip fields]
106
+ end
107
+
86
108
  def to_human
87
109
  "<ComboLeg: #{side} #{ratio} con_id #{con_id} at #{exchange}>"
88
110
  end
@@ -6,7 +6,8 @@ require 'models/ib/underlying'
6
6
  module IB
7
7
 
8
8
  if defined?(Contract)
9
- puts "Contract already a #{defined?(Contract)}"
9
+ #Connection.current.logger.warn "Contract already a #{defined?(Contract)}"
10
+
10
11
  # puts Contract.ancestors
11
12
  # IB.send(:remove_const, 'Contract')
12
13
  end
@@ -119,7 +120,7 @@ module IB
119
120
 
120
121
  def default_attributes # :nodoc:
121
122
  super.merge :con_id => 0,
122
- :strike => 0.0,
123
+ :strike => "",
123
124
  :right => :none, # Not an option
124
125
  # :exchange => 'SMART',
125
126
  :include_expired => false
@@ -136,13 +137,13 @@ module IB
136
137
 
137
138
  def serialize *fields # :nodoc:
138
139
  print_default = ->(field, default="") { field.blank? ? default : field }
139
- print_not_zero = ->(field, default="") { field.to_i.zero? ? default : field }
140
140
  [(con_id.present? && !con_id.is_a?(Symbol) && con_id.to_i > 0 ? con_id : ""),
141
141
  print_default[symbol],
142
142
  print_default[self[:sec_type]],
143
143
  ( fields.include?(:option) ?
144
144
  [ print_default[expiry],
145
- print_not_zero[strike],
145
+ ## a Zero-Strike-Option has to be defined with «strike: -1 »
146
+ strike.present? && ( strike.is_a?(Numeric) && !strike.zero? && strike > 0 ) ? strike : strike<0 ? 0 : "",
146
147
  print_default[self[:right]],
147
148
  print_default[multiplier]] : nil ),
148
149
  print_default[exchange],
@@ -217,20 +218,18 @@ module IB
217
218
  # the link to contract-details is __not__ maintained.
218
219
  def essential
219
220
 
220
- self_attributes = [ :sec_type]
221
- the_attributes = [ :symbol , :con_id, :exchange, :right,
221
+ the_attributes = [ :sec_type, :symbol , :con_id, :exchange, :right,
222
222
  :currency, :expiry, :strike, :local_symbol, :last_trading_day,
223
- :multiplier, :primary_exchange, :trading_class ]
224
- the_hash= the_attributes.map{|x| y= self.send(x); [x,y] if y.present? }.compact.to_h
225
- the_hash[:description] =
226
- if @description.present?
227
- @description
228
- elsif contract_detail.present?
229
- contract_detail.long_name
230
- else
231
- ""
232
- end
233
- self.class.new the_hash.merge( self_attributes.map{|x| y = self.send(x); [x,y] unless y == :none }.compact.to_h )
223
+ :multiplier, :primary_exchange, :trading_class, :description ]
224
+ new_contract= self.class.new invariant_attributes.select{|k,_| the_attributes.include? k }.compact
225
+ new_contract[:description] = if @description.present?
226
+ @description
227
+ elsif contract_detail.present?
228
+ contract_detail.long_name
229
+ else
230
+ ""
231
+ end
232
+ new_contract # return contract
234
233
  end
235
234
 
236
235
 
@@ -381,6 +380,7 @@ In places where these terms are used to indicate a concept, we have left them as
381
380
 
382
381
 
383
382
  ### Now let's deal with Contract subclasses
383
+ begin
384
384
 
385
385
  require_relative 'option'
386
386
  require 'models/ib/bag'
@@ -388,14 +388,25 @@ In places where these terms are used to indicate a concept, we have left them as
388
388
  require 'models/ib/future'
389
389
  require 'models/ib/stock'
390
390
  require 'models/ib/index'
391
+ ### walkaraound to enable spreads with orientdb
392
+ if IB::const_defined? :Spread
393
+ IB::send(:remove_const, :Spread)
394
+ #puts "Spread already defined"
395
+ #puts "erasing"
396
+ end
397
+ require 'models/ib/spread.rb'
398
+ end
399
+
400
+
391
401
 
392
402
  class Contract
393
403
  # Contract subclasses representing specialized security types.
404
+ using IBSupport
394
405
 
395
406
  Subclasses = Hash.new(Contract)
396
407
  Subclasses[:bag] = IB::Bag
397
408
  Subclasses[:option] = IB::Option
398
- Subclasses[:future_option] = IB::FutureOption
409
+ Subclasses[:futures_option] = IB::FutureOption
399
410
  Subclasses[:future] = IB::Future
400
411
  Subclasses[:stock] = IB::Stock
401
412
  Subclasses[:forex] = IB::Forex
@@ -403,31 +414,14 @@ In places where these terms are used to indicate a concept, we have left them as
403
414
 
404
415
 
405
416
  # This builds an appropriate Contract subclass based on its type
406
- #
407
- # the method is also used to copy Contract.values to new instances
417
+ #
418
+ # the method is also used to copy Contract.values to new instances
408
419
  def self.build opts = {}
409
420
  subclass =( VALUES[:sec_type][opts[:sec_type]] || opts['sec_type'] || opts[:sec_type]).to_sym
410
421
  Contract::Subclasses[subclass].new opts
411
422
  end
412
423
 
413
- # This returns a Contract initialized from the serialize_ib_ruby format string.
414
- def self.from_ib_ruby
415
- keys = [:con_id, :symbol, :sec_type, :expiry, :strike, :right, :multiplier,
416
- :exchange, :primary_exchange, :currency, :local_symbol]
417
- props = Hash[keys.zip(string.split(":"))]
418
- props.delete_if { |k, v| v.nil? || v.empty? }
419
- Contract.build props
420
- end
424
+
421
425
  end # class Contract
422
426
  end # module IB
423
427
 
424
- class String
425
- def to_contract
426
- keys = [:con_id, :symbol, :sec_type, :expiry, :strike, :right, :multiplier,
427
- :exchange, :primary_exchange, :currency, :local_symbol]
428
- props = Hash[keys.zip(split(":"))]
429
- props.delete_if { |k, v| v.nil? || v.empty? }
430
- IB::Contract.build props
431
-
432
- end
433
- end
@@ -77,6 +77,8 @@ module IB
77
77
  end # class Option
78
78
 
79
79
  class FutureOption < Option
80
-
80
+ def default_attributes
81
+ super.merge :sec_type => :futures_option
82
+ end
81
83
  end
82
84
  end # module IB
@@ -514,6 +514,11 @@ Format of serialisation
514
514
  (account ? "/#{account}" : '') +
515
515
  (commission ? " fee #{commission}" : '') + ">"
516
516
  end
517
+ def serialize_rabbit
518
+ { 'Contract' => contract.present? ? contract.serialize( :option, :trading_class ): '' ,
519
+ 'Order' => self,
520
+ 'OrderState' => order_state}
521
+ end
517
522
 
518
523
  end # class Order
519
524
  end # module IB
@@ -1,6 +1,12 @@
1
- #require 'ib/verify'
1
+ # require 'ib/verify'
2
2
  module IB
3
- class Spread < Bag
3
+ if defined?(Spread)
4
+ puts "Bag already a #{defined?(Spread)}"
5
+
6
+ # puts Spread.ancestors
7
+ IB.send(:remove_const, 'Spread')
8
+ end
9
+ class Spread < Bag
4
10
  has_many :legs
5
11
 
6
12
  using IBSupport
@@ -63,14 +69,6 @@ Adds (or substracts) relative (back) measures to the front month, just passes ab
63
69
  end
64
70
 
65
71
 
66
-
67
- def serialize_rabbit
68
- { "Spread" => serialize( :option, :trading_class ),
69
- 'legs' => legs.map{ |y| y.serialize :option, :trading_class }, 'combo_legs' => combo_legs.map(&:serialize),
70
- 'misc' => [description]
71
- }
72
- end
73
-
74
72
  # adds a leg to any spread
75
73
  #
76
74
  # Parameter:
@@ -90,7 +88,7 @@ Adds (or substracts) relative (back) measures to the front month, just passes ab
90
88
  the_leg= ComboLeg.new( nc.attributes.slice( :con_id, :exchange )
91
89
  .merge( leg_params ))
92
90
  self.combo_legs << the_leg
93
- self.description = description + " added #{nc.to_human}" rescue "Spread: #{nc.to_human}"
91
+ self.description = "#{description.nil? ? "": description} added #{nc.to_human}" rescue "Spread: #{nc.to_human}"
94
92
  self.legs << nc
95
93
  end
96
94
  self # return value to enable chaining
@@ -109,18 +107,28 @@ Adds (or substracts) relative (back) measures to the front month, just passes ab
109
107
  self
110
108
  end
111
109
 
112
-
110
+ # essentail
111
+ # effectivley clones the object
112
+ #
113
113
  def essential
114
- legs.each{ |x| x.essential }
115
- self
114
+ the_es = self.class.new invariant_attributes
115
+ the_es.legs = legs.map{|y| IB::Contract.build y.invariant_attributes}
116
+ the_es.combo_legs = combo_legs.map{|y| IB::ComboLeg.new y.invariant_attributes }
117
+ the_es.description = description
118
+ the_es # return
116
119
  end
120
+
117
121
  def multiplier
118
122
  (legs.map(&:multiplier).sum/legs.size).to_i
119
123
  end
120
124
 
121
- # provide a negative con_id
125
+ # provide a negative con_id
122
126
  def con_id
123
- -legs.map(&:con_id).sum
127
+ if attributes[:con_id].present? && attributes[] < 0
128
+ attributes[:con_id]
129
+ else
130
+ -legs.map{ |x| x.is_a?(String) ? x.expand.con_id : x.con_id}.sum
131
+ end
124
132
  end
125
133
 
126
134
 
@@ -146,13 +154,14 @@ Adds (or substracts) relative (back) measures to the front month, just passes ab
146
154
  :exchange => a.read_string
147
155
 
148
156
  end
149
- object= self.new container['Spread'].read_contract
150
- object.legs = container['legs'].map{|x| IB::Contract.build x.read_contract}
151
- object.combo_legs = container['combo_legs'].map{ |x| read_leg[ x ] }
152
- object.description = container['misc'].read_string
157
+ object= self.new container['Spread'].clone.read_contract
158
+ object.legs = container['legs'].map{|x| IB::Contract.build x.clone.read_contract}
159
+ object.combo_legs = container['combo_legs'].map{ |x| read_leg[ x.clone ] }
160
+ object.description = container['misc'].clone.read_string
153
161
  object
154
162
 
155
163
  end
164
+
156
165
  end
157
166
 
158
167
 
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ib-api
3
3
  version: !ruby/object:Gem::Version
4
- version: '972.1'
4
+ version: '972.5'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hartmut Bischoff
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-22 00:00:00.000000000 Z
11
+ date: 2021-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -103,19 +103,6 @@ files:
103
103
  - bin/console.yml
104
104
  - bin/setup
105
105
  - changelog.md
106
- - example/README.md
107
- - example/account_info
108
- - example/account_positions
109
- - example/account_summary
110
- - example/cancel_orders
111
- - example/fa_accounts
112
- - example/fundamental_data
113
- - example/historic_data_cli
114
- - example/list_orders
115
- - example/portfolio_csv
116
- - example/scanner_data
117
- - example/template
118
- - example/tick_data
119
106
  - lib/extensions/class-extensions.rb
120
107
  - lib/ib-api.rb
121
108
  - lib/ib/base.rb
@@ -155,6 +142,7 @@ files:
155
142
  - lib/ib/socket.rb
156
143
  - lib/ib/support.rb
157
144
  - lib/ib/version.rb
145
+ - lib/logging.rb
158
146
  - lib/models/ib/account.rb
159
147
  - lib/models/ib/account_value.rb
160
148
  - lib/models/ib/bag.rb
@@ -197,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
185
  - !ruby/object:Gem::Version
198
186
  version: '0'
199
187
  requirements: []
200
- rubygems_version: 3.0.4
188
+ rubygems_version: 3.2.3
201
189
  signing_key:
202
190
  specification_version: 4
203
191
  summary: Ruby Implementation of the Interactive Brokers TWS API