ib-extensions 1.1 → 1.3

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.
@@ -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.