ib-extensions 1.1 → 1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -60,15 +60,14 @@ module IB
60
60
  end
61
61
  kind = { :p => fields.delete(:p), :c => fields.delete(:c) }
62
62
  initialize_spread( underlying ) do | the_spread |
63
- leg_prototype = IB::Option.new underlying.attributes
64
- .slice( :currency, :symbol, :exchange)
65
- .merge(defaults)
66
- .merge( fields )
67
- .merge( local_symbol: "" )
63
+ leg_prototype = IB::Option.new from.attributes
64
+ .slice( :currency, :symbol, :exchange)
65
+ .merge(defaults)
66
+ .merge( fields )
68
67
 
69
- leg_prototype.sec_type = 'FOP' if underlying.is_a?(IB::Future)
70
- the_spread.add_leg IB::Contract.build leg_prototype.attributes.merge( right: :put, strike: kind[:p] )
71
- the_spread.add_leg IB::Contract.build leg_prototype.attributes.merge( right: :call, strike: kind[:c] )
68
+ leg_prototype.sec_type = 'FOP' if underlying.is_a?(IB::Future)
69
+ the_spread.add_leg leg_prototype.merge( right: :put, strike: kind[:p] ).verify.first
70
+ the_spread.add_leg leg_prototype.merge( right: :call, strike: kind[:c] ).verify.first
72
71
  error "Initialisation of Legs failed" if the_spread.legs.size != 2
73
72
  the_spread.description = the_description( the_spread )
74
73
  end
@@ -88,7 +87,7 @@ module IB
88
87
 
89
88
 
90
89
  def the_description spread
91
- "<Strangle #{spread.symbol}(#{spread.legs.map(&:strike).join(",")})[#{Date.parse(spread.legs.first.last_trading_day).strftime("%b %Y")}]>"
90
+ "<Strangle #{spread.symbol}(#{spread.legs.map(&:strike).join(",")})[#{Date.parse(spread.legs.first.last_trading_day).strftime("%b %Y")}]>"
92
91
  end
93
92
 
94
93
  end # class
@@ -20,8 +20,8 @@ module IB
20
20
  buy = master.strike if buy.zero?
21
21
  sell = master.strike if sell.zero?
22
22
  initialize_spread( master ) do | the_spread |
23
- the_spread.add_leg master.essential.merge(strike: sell, local_symbol: "", con_id: 0), action: :sell
24
- the_spread.add_leg master.essential.merge(strike: buy, local_symbol: "", con_id: 0), action: :buy
23
+ the_spread.add_leg master.merge(strike: sell).verify.first, action: :sell
24
+ the_spread.add_leg master.merge(strike: buy).verify.first, action: :buy
25
25
  error "Initialisation of Legs failed" if the_spread.legs.size != 2
26
26
  the_spread.description = the_description( the_spread )
27
27
  end
@@ -54,16 +54,15 @@ module IB
54
54
  from
55
55
  end
56
56
  kind = { :buy => fields.delete(:buy), :sell => fields.delete(:sell) }
57
- error "Specifiaction of :buy and :sell nessesary, got: #{kind.inspect}" if kind.values.any?(nil)
57
+ error "Specification of :buy and :sell necessary, got: #{kind.inspect}" if kind.values.any?(nil)
58
58
  initialize_spread( underlying ) do | the_spread |
59
- leg_prototype = IB::Option.new underlying.attributes
59
+ leg_prototype = Option.new underlying.attributes
60
60
  .slice( :currency, :symbol, :exchange)
61
61
  .merge(defaults)
62
62
  .merge( fields )
63
- .merge( local_symbol: "" )
64
63
  leg_prototype.sec_type = 'FOP' if underlying.is_a?(IB::Future)
65
- the_spread.add_leg leg_prototype.merge(strike: kind[:sell]), action: :sell
66
- the_spread.add_leg leg_prototype.merge(strike: kind[:buy] ), action: :buy
64
+ the_spread.add_leg leg_prototype.merge(strike: kind[:sell]).verify.first, action: :sell
65
+ the_spread.add_leg leg_prototype.merge(strike: kind[:buy] ).verify.first, action: :buy
67
66
  error "Initialisation of Legs failed" if the_spread.legs.size != 2
68
67
  the_spread.description = the_description( the_spread )
69
68
  end
data/lib/ib/verify.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  module IB
2
2
  # define a custom ErrorClass which can be fired if a verification fails
3
- # class VerifyError < StandardError
3
+ class VerifyError < StandardError
4
+
5
+ end
4
6
  # end
5
7
 
6
8
  class Contract
@@ -49,12 +51,15 @@ module IB
49
51
  # IB::Symbols::W500.map{|c| c.verify(thread: true){ |vc| do_something }}.join
50
52
 
51
53
  def verify thread: nil, &b
52
- return [self] if contract_detail.present? || sec_type == :bag
53
- _verify update: false, thread: thread, &b # returns the allocated threads
54
+ if thread
55
+ Thread.new { _verify &b }
56
+ else
57
+ _verify &b
58
+ end
54
59
  end # def
55
60
 
56
61
  # returns a hash
57
- def nessesary_attributes
62
+ def necessary_attributes
58
63
 
59
64
  v= { stock: { currency: 'USD', exchange: 'SMART', symbol: nil},
60
65
  option: { currency: 'USD', exchange: 'SMART', right: 'P', expiry: nil, strike: nil, symbol: nil},
@@ -70,8 +75,9 @@ module IB
70
75
  def verify!
71
76
  c = 0
72
77
  IB::Connection.logger.warn "Contract.verify! is depreciated. Use \"contract = contract.verify.first\" instead"
73
- _verify( update: true){| response | c+=1 } # wait for the returned thread to finish
74
- IB::Connection.logger.error { "Multible Contracts detected during verify!." } if c > 1
78
+ c= verify.first
79
+ self.attributes = c.invariant_attributes
80
+ self.contract_detail = c.contract_detail
75
81
  self
76
82
  end
77
83
 
@@ -88,47 +94,43 @@ module IB
88
94
  # if :update is true, the attributes of the Contract itself are adapted
89
95
  #
90
96
  # otherwise the Contract is untouched
91
- def _verify thread: nil , update:, &b # :nodoc:
97
+ def _verify &b # :nodoc:
92
98
  ib = Connection.current
99
+ error "No Connection" unless ib.is_a? Connection
93
100
  # we generate a Request-Message-ID on the fly
94
- message_id = nil
101
+ error "Either con_id or sec_type have to be set", :verify if con_id.to_i.zero? && sec_type.blank?
95
102
  # define local vars which are updated within the query-block
96
- recieved_contracts = []
103
+ received_contracts = []
97
104
  queue = Queue.new
98
- a = nil
105
+ message_id = nil
99
106
 
100
107
  # a tws-request is suppressed for bags and if the contract_detail-record is present
101
- tws_request_not_nessesary = bag? || contract_detail.is_a?( ContractDetail )
108
+ tws_request_not_necessary = bag? || contract_detail.is_a?( ContractDetail )
102
109
 
103
- if tws_request_not_nessesary
110
+ if tws_request_not_necessary
104
111
  yield self if block_given?
105
- return self
112
+ return [self] # return an array!
106
113
  else # subscribe to ib-messages and describe what to do
107
114
  a = ib.subscribe(:Alert, :ContractData, :ContractDataEnd) do |msg|
108
115
  case msg
109
116
  when Messages::Incoming::Alert
117
+ ## do not throw an error here, asynchronous operation!
118
+ ## just notice failure in log and return nil instead of contract-object
110
119
  if msg.code == 200 && msg.error_id == message_id
111
120
  ib.logger.error { "Not a valid Contract :: #{self.to_human} " }
112
121
  queue.close
113
122
  end
114
123
  when Messages::Incoming::ContractData
115
124
  if msg.request_id.to_i == message_id
116
- # if multiple contracts are present, all of them are assigned
117
- # Only the last contract is saved in self; 'count' is incremented
118
- ## a specified block gets the contract_object on any unique ContractData-Event
119
- recieved_contracts << if block_given?
120
- yield msg.contract
121
- else
122
- msg.contract
123
- end
124
- if update
125
- self.attributes = msg.contract.attributes
126
- self.contract_detail = msg.contract_detail unless msg.contract_detail.nil?
127
- end
125
+ c = if block_given?
126
+ yield msg.contract
127
+ else
128
+ msg.contract
129
+ end
130
+ queue.push c unless c.nil?
128
131
  end
129
132
  when Messages::Incoming::ContractDataEnd
130
- queue.push(1) if msg.request_id.to_i == message_id
131
-
133
+ queue.close if msg.request_id.to_i == message_id
132
134
  end # case
133
135
  end # subscribe
134
136
 
@@ -138,19 +140,12 @@ module IB
138
140
  # if contract_to_be_queried.present? # is nil if query_contract fails
139
141
  message_id = ib.send_message :RequestContractData, :contract => query_contract
140
142
 
141
- th = Thread.new do
142
- queue.pop
143
- # j=0; loop{ sleep(0.01); j+=1; break if queue.closed? || queue.pop || j> 100; }
144
- # ib.logger.error{ "#{to_human} --> No ContractData recieved " } if j >= 100 && !queue.closed?
145
- ib.unsubscribe a
146
- end
147
- if thread.nil?
148
- th.join # wait for the thread to finish
149
- recieved_contracts # return queue of contracts
150
- else
151
- th # return active thread
143
+ while r = queue.pop
144
+ received_contracts << r
152
145
  end
146
+ ib.unsubscribe a
153
147
  end
148
+ received_contracts # return contracts
154
149
  end
155
150
 
156
151
  # Generates an IB::Contract with the required attributes to retrieve a unique contract from the TWS
@@ -189,7 +184,7 @@ module IB
189
184
  # Contract.build item_attributehash[necessary_items].merge(:sec_type=> sec_type) # return this
190
185
  Contract.build self.invariant_attributes # return this
191
186
  else # its always possible, to retrieve a Contract if con_id and exchange or are present
192
- Contract.new con_id: con_id , :exchange => exchange.presence || item_attributehash[nessesary_attributes][:exchange].presence || 'SMART' # return this
187
+ Contract.new con_id: con_id , :exchange => exchange.presence || item_attributehash[necessary_attributes][:exchange].presence || 'SMART' # return this
193
188
  end # if
194
189
  end # def
195
190
  end
data/lib/ib-gateway.rb CHANGED
@@ -1,5 +1,17 @@
1
+ require "distribution"
2
+ require "polars"
1
3
  require 'ib-api'
2
4
  require 'ib/verify'
3
5
  require 'ib/spread-prototypes'
4
6
  require 'ib/order-prototypes'
7
+ require "ib/eod"
8
+ require "ib/market-price"
9
+ require "ib/option-chain"
10
+ require "ib/option-greeks"
11
+ require "ib/models/contract.rb"
12
+ require "ib/models/bag.rb"
13
+ require "ib/models/account.rb"
14
+ require "ib/models/option.rb"
15
+ require "ib/models/future.rb"
16
+ require "ib/probability_of_expiring"
5
17
  require 'ib/gateway'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ib-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.1'
4
+ version: '1.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hartmut Bischoff
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-16 00:00:00.000000000 Z
11
+ date: 2023-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ox
@@ -24,20 +24,62 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: prime
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: distribution
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: polars-df
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.3.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.3.1
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: ib-api
29
71
  requirement: !ruby/object:Gem::Requirement
30
72
  requirements:
31
73
  - - "~>"
32
74
  - !ruby/object:Gem::Version
33
- version: '972.4'
75
+ version: 972.5.2
34
76
  type: :runtime
35
77
  prerelease: false
36
78
  version_requirements: !ruby/object:Gem::Requirement
37
79
  requirements:
38
80
  - - "~>"
39
81
  - !ruby/object:Gem::Version
40
- version: '972.4'
82
+ version: 972.5.2
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: bundler
43
85
  requirement: !ruby/object:Gem::Requirement
@@ -158,11 +200,15 @@ files:
158
200
  - lib/ib/gateway/order-handling.rb
159
201
  - lib/ib/market-price.rb
160
202
  - lib/ib/models/account.rb
203
+ - lib/ib/models/bag.rb
204
+ - lib/ib/models/contract.rb
205
+ - lib/ib/models/future.rb
161
206
  - lib/ib/models/option.rb
162
207
  - lib/ib/option-chain.rb
163
208
  - lib/ib/option-greeks.rb
164
209
  - lib/ib/order-prototypes.rb
165
210
  - lib/ib/order_prototypes/abstract.rb
211
+ - lib/ib/order_prototypes/all-in-one.rb
166
212
  - lib/ib/order_prototypes/combo.rb
167
213
  - lib/ib/order_prototypes/forex.rb
168
214
  - lib/ib/order_prototypes/limit.rb
@@ -171,6 +217,8 @@ files:
171
217
  - lib/ib/order_prototypes/premarket.rb
172
218
  - lib/ib/order_prototypes/stop.rb
173
219
  - lib/ib/order_prototypes/volatility.rb
220
+ - lib/ib/plot-poec.rb
221
+ - lib/ib/probability_of_expiring.rb
174
222
  - lib/ib/spread-prototypes.rb
175
223
  - lib/ib/spread_prototypes/butterfly.rb
176
224
  - lib/ib/spread_prototypes/calendar.rb
@@ -200,7 +248,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
248
  - !ruby/object:Gem::Version
201
249
  version: '0'
202
250
  requirements: []
203
- rubygems_version: 3.2.3
251
+ rubygems_version: 3.3.7
204
252
  signing_key:
205
253
  specification_version: 4
206
254
  summary: Part of IB-Ruby. Tools to to access the tws-api comfortably.