ib-ruby 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/HISTORY +4 -0
  2. data/README.md +60 -30
  3. data/TODO +1 -0
  4. data/VERSION +1 -1
  5. data/bin/account_info +1 -4
  6. data/bin/cancel_orders +0 -3
  7. data/bin/contract_details +2 -5
  8. data/bin/depth_of_market +1 -4
  9. data/bin/fa_accounts +22 -0
  10. data/bin/historic_data +1 -4
  11. data/bin/historic_data_cli +0 -4
  12. data/bin/list_orders +2 -6
  13. data/bin/market_data +1 -4
  14. data/bin/option_data +2 -5
  15. data/bin/place_combo_order +17 -22
  16. data/bin/place_order +6 -10
  17. data/bin/tick_data +6 -9
  18. data/bin/time_and_sales +2 -5
  19. data/lib/ib-ruby/connection.rb +10 -5
  20. data/lib/ib-ruby/messages/incoming/open_order.rb +15 -13
  21. data/lib/ib-ruby/messages/incoming/ticks.rb +1 -1
  22. data/lib/ib-ruby/messages/incoming.rb +18 -18
  23. data/lib/ib-ruby/messages/outgoing.rb +2 -2
  24. data/lib/ib-ruby/messages.rb +3 -7
  25. data/lib/ib-ruby/models/{contract → contracts}/bag.rb +5 -8
  26. data/lib/ib-ruby/models/contracts/contract.rb +296 -0
  27. data/lib/ib-ruby/models/{contract → contracts}/option.rb +2 -4
  28. data/lib/ib-ruby/models/contracts.rb +27 -0
  29. data/lib/ib-ruby/models/execution.rb +1 -1
  30. data/lib/ib-ruby/models/order.rb +6 -17
  31. data/lib/ib-ruby/models.rb +9 -7
  32. data/lib/ib-ruby/symbols/forex.rb +50 -50
  33. data/lib/ib-ruby/symbols/futures.rb +47 -47
  34. data/lib/ib-ruby/symbols/options.rb +23 -23
  35. data/lib/ib-ruby/symbols/stocks.rb +14 -14
  36. data/lib/ib-ruby.rb +17 -9
  37. data/spec/README.md +6 -0
  38. data/spec/account_helper.rb +1 -1
  39. data/spec/combo_helper.rb +31 -0
  40. data/spec/ib-ruby/models/combo_leg_spec.rb +4 -4
  41. data/spec/ib-ruby/models/contract_spec.rb +37 -26
  42. data/spec/ib-ruby/models/execution_spec.rb +5 -5
  43. data/spec/ib-ruby/models/order_spec.rb +16 -16
  44. data/spec/integration/contract_info_spec.rb +8 -10
  45. data/spec/integration/historic_data_spec.rb +1 -1
  46. data/spec/integration/market_data_spec.rb +5 -5
  47. data/spec/integration/orders/attached_spec.rb +87 -0
  48. data/spec/integration/orders/combo_spec.rb +52 -65
  49. data/spec/integration/orders/placement_spec.rb +8 -8
  50. data/spec/order_helper.rb +97 -28
  51. data/spec/spec_helper.rb +2 -2
  52. metadata +12 -5
  53. data/lib/ib-ruby/models/contract.rb +0 -308
@@ -1,308 +0,0 @@
1
- require 'ib-ruby/models/model'
2
-
3
- module IB
4
- module Models
5
- class Contract < Model
6
-
7
- # Specialized Contract subclasses representing different security types
8
- TYPES = {}
9
- #BAG_SEC_TYPE = "BAG"
10
-
11
- # This returns a Contract initialized from the serialize_ib_ruby format string.
12
- def self.build opts = {}
13
- type = opts[:sec_type]
14
- if TYPES[type]
15
- TYPES[type].new opts
16
- else
17
- Contract.new opts
18
- end
19
- end
20
-
21
- # This returns a Contract initialized from the serialize_ib_ruby format string.
22
- def self.from_ib_ruby string
23
- keys = [:symbol, :sec_type, :expiry, :strike, :right, :multiplier,
24
- :exchange, :primary_exchange, :currency, :local_symbol]
25
- props = Hash[keys.zip(string.split(":"))]
26
- props.delete_if { |k, v| v.nil? || v.empty? }
27
- Contract.new props
28
- end
29
-
30
- # Fields are Strings unless noted otherwise
31
- prop :con_id, # int: The unique contract identifier.
32
- :symbol, # This is the symbol of the underlying asset.
33
- :sec_type, # Security type. Valid values are: SECURITY_TYPES
34
- :strike, # double: The strike price.
35
- :exchange, # The order destination, such as Smart.
36
- :currency, # Only needed if there is an ambiguity, e.g. when SMART exchange
37
- # and IBM is being requested (IBM can trade in GBP or USD).
38
-
39
- :local_symbol, # Local exchange symbol of the underlying asset
40
- :include_expired, # When true, contract details requests and historical
41
- # data queries can be performed pertaining to expired contracts.
42
- # Note: Historical data queries on expired contracts are
43
- # limited to the last year of the contracts life, and are
44
- # only supported for expired futures contracts.
45
- # This field can NOT be set to true for orders.
46
-
47
- :sec_id_type, # Security identifier, when querying contract details or
48
- # when placing orders. Supported identifiers are:
49
- # - ISIN (Example: Apple: US0378331005)
50
- # - CUSIP (Example: Apple: 037833100)
51
- # - SEDOL (6-AN + check digit. Example: BAE: 0263494)
52
- # - RIC (exchange-independent RIC Root and exchange-
53
- # identifying suffix. Ex: AAPL.O for Apple on NASDAQ.)
54
- :sec_id, # Unique identifier of the given secIdType.
55
-
56
- # COMBOS
57
- :legs_description, # received in OpenOrder for all combos
58
-
59
- :multiplier => :i,
60
- # Future/option contract multiplier (only needed when multiple possibilities exist)
61
-
62
- :primary_exchange =>
63
- # non-aggregate (ie not the SMART) exchange that the contract trades on.
64
- proc { |val|
65
- val.upcase! if val.is_a?(String)
66
- error "Don't set primary_exchange to smart", :args if val == 'SMART'
67
- self[:primary_exchange] = val
68
- },
69
-
70
- :right => # Specifies a Put or Call. Valid input values are: P, PUT, C, CALL
71
- proc { |val|
72
- self[:right] =
73
- case val.to_s.upcase
74
- when '', '0', '?'
75
- nil
76
- when 'PUT', 'P'
77
- 'PUT'
78
- when 'CALL', 'C'
79
- 'CALL'
80
- else
81
- error "Right must be one of PUT, CALL, P, C - not '#{val}'", :args
82
- end
83
- },
84
-
85
- :expiry => # The expiration date. Use the format YYYYMM.
86
- proc { |val|
87
- self[:expiry] =
88
- case val.to_s
89
- when /\d{6,8}/
90
- val.to_s
91
- when nil, ''
92
- nil
93
- else
94
- error "Invalid expiry '#{val}' (must be in format YYYYMM or YYYYMMDD)", :args
95
- end
96
- },
97
-
98
- :sec_type => # Security type. Valid values are: SECURITY_TYPES
99
- proc { |val|
100
- val = nil if !val.nil? && val.empty?
101
- unless val.nil? || SECURITY_TYPES.values.include?(val)
102
- error "Invalid security type '#{val}' (must be one of #{SECURITY_TYPES.values}", :args
103
- end
104
- self[:sec_type] = val
105
- }
106
-
107
- # ContractDetails fields are bundled into Contract proper, as it should be
108
- # All fields Strings, unless specified otherwise:
109
- prop :market_name, # The market name for this contract.
110
- :trading_class, # The trading class name for this contract.
111
- :min_tick, # double: The minimum price tick.
112
- :price_magnifier, # int: Allows execution and strike prices to be
113
- # reported consistently with market data, historical data and the
114
- # order price: Z on LIFFE is reported in index points, not GBP.
115
-
116
- :order_types, # The list of valid order types for this contract.
117
- :valid_exchanges, # The list of exchanges this contract is traded on.
118
- :under_con_id, # int: The underlying contract ID.
119
- :long_name, # Descriptive name of the asset.
120
- :contract_month, # The contract month of the underlying for a futures contract.
121
-
122
- # The industry classification of the underlying/product:
123
- :industry, # Wide industry. For example, Financial.
124
- :category, # Industry category. For example, InvestmentSvc.
125
- :subcategory, # Subcategory. For example, Brokerage.
126
- :time_zone, # Time zone for the trading hours of the product. For example, EST.
127
- :trading_hours, # The trading hours of the product. For example:
128
- # 20090507:0700-1830,1830-2330;20090508:CLOSED.
129
- :liquid_hours, # The liquid trading hours of the product. For example,
130
- # 20090507:0930-1600;20090508:CLOSED.
131
-
132
- # Bond values:
133
- :cusip, # The nine-character bond CUSIP or the 12-character SEDOL.
134
- :ratings, # Credit rating of the issuer. Higher rating is less risky investment.
135
- # Bond ratings are from Moody's and S&P respectively.
136
- :desc_append, # Additional descriptive information about the bond.
137
- :bond_type, # The type of bond, such as "CORP."
138
- :coupon_type, # The type of bond coupon.
139
- :callable, # bool: Can be called by the issuer under certain conditions.
140
- :puttable, # bool: Can be sold back to the issuer under certain conditions
141
- :coupon, # double: The interest rate used to calculate the amount you
142
- # will receive in interest payments over the year. default 0
143
- :convertible, # bool: Can be converted to stock under certain conditions.
144
- :maturity, # The date on which the issuer must repay bond face value
145
- :issue_date, # The date the bond was issued.
146
- :next_option_date, # only if bond has embedded options.
147
- :next_option_type, # only if bond has embedded options.
148
- :next_option_partial, # bool: # only if bond has embedded options.
149
- :notes # Additional notes, if populated for the bond in IB's database
150
-
151
- # Used for Delta-Neutral Combo contracts only!
152
- # UnderComp fields are bundled into Contract proper, as it should be.
153
- prop :under_comp, # if not nil, attributes below are sent to server
154
- #:under_con_id is is already defined in ContractDetails section
155
- :under_delta, # double: The underlying stock or future delta.
156
- :under_price # double: The price of the underlying.
157
-
158
- # Legs arriving via OpenOrder message, need to define them here
159
- attr_accessor :legs # leg definitions for this contract.
160
- alias combo_legs legs
161
- alias combo_legs= legs=
162
- alias combo_legs_description legs_description
163
- alias combo_legs_description= legs_description=
164
-
165
- attr_accessor :description # NB: local to ib-ruby, not part of TWS.
166
-
167
- DEFAULT_PROPS = {:con_id => 0,
168
- :strike => 0,
169
- :exchange => 'SMART',
170
- :include_expired => false,
171
-
172
- # These properties are from ContractDetails
173
- :under_con_id => 0,
174
- :min_tick => 0,
175
- :callable => false,
176
- :puttable => false,
177
- :coupon => 0,
178
- :convertible => false,
179
- :next_option_partial => false, }
180
-
181
- # NB: ContractDetails reference - to self!
182
- def summary
183
- self
184
- end
185
-
186
- # This returns an Array of data from the given contract.
187
- # Different messages serialize contracts differently. Go figure.
188
- # Note that it does NOT include the combo legs.
189
- def serialize *fields
190
- [(fields.include?(:con_id) ? [con_id] : []),
191
- symbol,
192
- sec_type,
193
- (fields.include?(:option) ? [expiry, strike, right, multiplier] : []),
194
- exchange,
195
- (fields.include?(:primary_exchange) ? [primary_exchange] : []),
196
- currency,
197
- local_symbol,
198
- (fields.include?(:sec_id) ? [sec_id_type, sec_id] : []),
199
- (fields.include?(:include_expired) ? [include_expired] : []),
200
- ].flatten
201
- end
202
-
203
- def serialize_long *fields
204
- serialize :option, :primary_exchange, *fields
205
- end
206
-
207
- def serialize_short *fields
208
- serialize :option, *fields
209
- end
210
-
211
- # Serialize under_comp parameters
212
- def serialize_under_comp *args
213
- # EClientSocket.java, line 471:
214
- if under_comp
215
- [true,
216
- under_con_id,
217
- under_delta,
218
- under_price]
219
- else
220
- [false]
221
- end
222
- end
223
-
224
- # Redefined in BAG subclass
225
- def serialize_legs *fields
226
- []
227
- end
228
-
229
- # This produces a string uniquely identifying this contract, in the format used
230
- # for command line arguments in the IB-Ruby examples. The format is:
231
- #
232
- # symbol:security_type:expiry:strike:right:multiplier:exchange:primary_exchange:currency:local_symbol
233
- #
234
- # Fields not needed for a particular security should be left blank
235
- # (e.g. strike and right are only relevant for options.)
236
- #
237
- # For example, to query the British pound futures contract trading on Globex
238
- # expiring in September, 2008, the string is:
239
- #
240
- # GBP:FUT:200809:::62500:GLOBEX::USD:
241
- def serialize_ib_ruby
242
- serialize_long.join(":")
243
- end
244
-
245
- # Contract comparison
246
- def == other
247
- return false unless other.is_a?(self.class)
248
-
249
- # Different sec_id_type
250
- return false if sec_id_type && other.sec_id_type && sec_id_type != other.sec_id_type
251
-
252
- # Different sec_id
253
- return false if sec_id && other.sec_id && sec_id != other.sec_id
254
-
255
- # Different under_comp
256
- return false if under_comp && other.under_comp && under_comp != other.under_comp
257
-
258
- # Different symbols
259
- return false if symbol && other.symbol && symbol != other.symbol
260
-
261
- # Different currency
262
- return false if currency && other.currency && currency != other.currency
263
-
264
- # Same con_id for all Bags, but unknown for new Contracts...
265
- # 0 or nil con_id matches any
266
- return false if con_id != 0 && other.con_id != 0 &&
267
- con_id && other.con_id && con_id != other.con_id
268
-
269
- # SMART or nil exchange matches any
270
- return false if exchange != 'SMART' && other.exchange != 'SMART' &&
271
- exchange && other.exchange && exchange != other.exchange
272
-
273
- # Comparison for Bonds and Options
274
- if sec_type == SECURITY_TYPES[:bond] || sec_type == SECURITY_TYPES[:option]
275
- return false if right != other.right || strike != other.strike
276
- return false if multiplier && other.multiplier && multiplier != other.multiplier
277
- return false if expiry[0..5] != other.expiry[0..5]
278
- return false unless expiry[6..7] == other.expiry[6..7] ||
279
- expiry[6..7].empty? || other.expiry[6..7].empty?
280
- end
281
-
282
- # All else being equal...
283
- sec_type == other.sec_type
284
- end
285
-
286
- def to_s
287
- "<Contract: " + instance_variables.map do |key|
288
- value = send(key[1..-1])
289
- " #{key}=#{value}" unless value.nil? || value == '' || value == 0
290
- end.compact.join(',') + " >"
291
- end
292
-
293
- def to_human
294
- "<Contract: " + [symbol, sec_type, expiry, strike, right, exchange, currency].join("-") + ">"
295
- end
296
-
297
- def to_short
298
- "#{symbol}#{expiry}#{strike}#{right}#{exchange}#{currency}"
299
- end
300
-
301
- end # class Contract
302
- end # module Models
303
- end # module IB
304
-
305
- # TODO Where should we require this?
306
- require 'ib-ruby/models/contract/option'
307
- require 'ib-ruby/models/contract/bag'
308
-