ib-api 972.1 → 972.5

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