ib-ruby 0.7.3 → 0.7.4

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