ib-ruby 0.8.1 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/HISTORY +5 -0
- data/README.md +47 -53
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/app/assets/javascripts/ib/application.js +15 -0
- data/app/assets/javascripts/ib/underlyings.js +2 -0
- data/app/assets/stylesheets/ib/application.css +13 -0
- data/app/assets/stylesheets/ib/underlyings.css +4 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/controllers/ib/application_controller.rb +5 -0
- data/app/controllers/ib/underlyings_controller.rb +87 -0
- data/app/helpers/ib/application_helper.rb +4 -0
- data/app/helpers/ib/underlyings_helper.rb +4 -0
- data/app/models/ib/underlying.rb +5 -0
- data/app/views/ib/underlyings/_form.html.erb +33 -0
- data/app/views/ib/underlyings/edit.html.erb +6 -0
- data/app/views/ib/underlyings/index.html.erb +29 -0
- data/app/views/ib/underlyings/new.html.erb +5 -0
- data/app/views/ib/underlyings/show.html.erb +25 -0
- data/app/views/layouts/ib/application.html.erb +14 -0
- data/config/routes.rb +6 -0
- data/db/config.yml +19 -0
- data/db/migrate/{101_add_executions.rb → 101_add_ib_executions.rb} +2 -2
- data/db/migrate/{111_add_bars.rb → 111_add_ib_bars.rb} +2 -2
- data/db/migrate/{121_add_order_states.rb → 121_add_ib_order_states.rb} +2 -2
- data/db/migrate/{131_add_orders.rb → 131_add_ib_orders.rb} +2 -2
- data/db/migrate/{141_add_combo_legs.rb → 141_add_ib_combo_legs.rb} +2 -2
- data/db/migrate/{151_add_underlyings.rb → 151_add_ib_underlyings.rb} +2 -2
- data/db/migrate/{161_add_contract_details.rb → 161_add_ib_contract_details.rb} +2 -2
- data/db/migrate/{171_add_contracts.rb → 171_add_ib_contracts.rb} +2 -2
- data/db/schema.rb +245 -0
- data/lib/ib/base.rb +97 -0
- data/lib/ib/base_properties.rb +140 -0
- data/lib/{ib-ruby → ib}/connection.rb +2 -2
- data/lib/{ib-ruby → ib}/constants.rb +0 -0
- data/lib/{ib-ruby → ib}/db.rb +9 -5
- data/lib/ib/engine.rb +35 -0
- data/lib/{ib-ruby → ib}/errors.rb +0 -0
- data/lib/{ib-ruby → ib}/extensions.rb +2 -2
- data/lib/{ib-ruby → ib}/logger.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/abstract_message.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/abstract_message.rb +1 -1
- data/lib/{ib-ruby → ib}/messages/incoming/alert.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/contract_data.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/delta_neutral_validation.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/execution_data.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/historical_data.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/market_depths.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/next_valid_id.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/open_order.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/order_status.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/portfolio_value.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/real_time_bar.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/scanner_data.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/ticks.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming.rb +14 -14
- data/lib/{ib-ruby → ib}/messages/outgoing/abstract_message.rb +1 -1
- data/lib/{ib-ruby → ib}/messages/outgoing/bar_requests.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/outgoing/place_order.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/outgoing.rb +5 -5
- data/lib/ib/messages.rb +8 -0
- data/lib/ib/model.rb +8 -0
- data/lib/ib/models.rb +10 -0
- data/lib/ib/requires.rb +9 -0
- data/lib/{ib-ruby → ib}/socket.rb +0 -0
- data/lib/{ib-ruby → ib}/symbols/forex.rb +1 -1
- data/lib/{ib-ruby → ib}/symbols/futures.rb +2 -2
- data/lib/{ib-ruby → ib}/symbols/options.rb +1 -1
- data/lib/{ib-ruby → ib}/symbols/stocks.rb +1 -1
- data/lib/ib/symbols.rb +9 -0
- data/lib/{ib-ruby → ib}/version.rb +0 -0
- data/lib/ib-ruby.rb +2 -24
- data/lib/ib.rb +23 -0
- data/lib/models/ib/bag.rb +51 -0
- data/lib/models/ib/bar.rb +41 -0
- data/lib/models/ib/combo_leg.rb +102 -0
- data/lib/models/ib/contract.rb +287 -0
- data/lib/models/ib/contract_detail.rb +68 -0
- data/lib/models/ib/execution.rb +62 -0
- data/lib/models/ib/option.rb +60 -0
- data/lib/models/ib/order.rb +389 -0
- data/lib/models/ib/order_state.rb +126 -0
- data/lib/models/ib/underlying.rb +35 -0
- data/spec/README.md +34 -2
- data/spec/TODO +5 -1
- data/spec/comb.rb +13 -0
- data/spec/db.rb +1 -1
- data/spec/db_helper.rb +3 -3
- data/spec/dummy.rb +13 -0
- data/spec/gw.rb +4 -0
- data/spec/{ib-ruby → ib}/connection_spec.rb +0 -0
- data/spec/{ib-ruby → ib}/messages/incoming/alert_spec.rb +0 -0
- data/spec/{ib-ruby → ib}/messages/incoming/open_order_spec.rb +0 -0
- data/spec/{ib-ruby → ib}/messages/incoming/order_status_spec.rb +16 -17
- data/spec/{ib-ruby → ib}/messages/outgoing/account_data_spec.rb +0 -0
- data/spec/{ib-ruby → ib}/messages/outgoing/market_data_type_spec.rb +0 -0
- data/spec/integration/historic_data_spec.rb +3 -3
- data/spec/integration/orders/trades_spec.rb +1 -1
- data/spec/{ib-ruby/models → models/ib}/bag_spec.rb +2 -7
- data/spec/{ib-ruby/models → models/ib}/bar_spec.rb +1 -6
- data/spec/{ib-ruby/models → models/ib}/combo_leg_spec.rb +2 -12
- data/spec/{ib-ruby/models → models/ib}/contract_detail_spec.rb +3 -8
- data/spec/{ib-ruby/models → models/ib}/contract_spec.rb +4 -12
- data/spec/{ib-ruby/models → models/ib}/execution_spec.rb +2 -7
- data/spec/{ib-ruby/models → models/ib}/option_spec.rb +1 -6
- data/spec/{ib-ruby/models → models/ib}/order_spec.rb +5 -10
- data/spec/{ib-ruby/models → models/ib}/order_state_spec.rb +2 -7
- data/spec/{ib-ruby/models → models/ib}/underlying_spec.rb +3 -7
- data/spec/my.rb +5 -0
- data/spec/spec_helper.rb +62 -36
- metadata +417 -544
- data/lib/ib-ruby/messages.rb +0 -8
- data/lib/ib-ruby/models/bag.rb +0 -54
- data/lib/ib-ruby/models/bar.rb +0 -43
- data/lib/ib-ruby/models/combo_leg.rb +0 -104
- data/lib/ib-ruby/models/contract.rb +0 -287
- data/lib/ib-ruby/models/contract_detail.rb +0 -70
- data/lib/ib-ruby/models/execution.rb +0 -64
- data/lib/ib-ruby/models/model.rb +0 -105
- data/lib/ib-ruby/models/model_properties.rb +0 -146
- data/lib/ib-ruby/models/option.rb +0 -62
- data/lib/ib-ruby/models/order.rb +0 -389
- data/lib/ib-ruby/models/order_state.rb +0 -128
- data/lib/ib-ruby/models/underlying.rb +0 -36
- data/lib/ib-ruby/models.rb +0 -15
- data/lib/ib-ruby/symbols.rb +0 -9
- data/spec/test.rb +0 -61
data/lib/ib-ruby/models/order.rb
DELETED
@@ -1,389 +0,0 @@
|
|
1
|
-
module IB
|
2
|
-
module Models
|
3
|
-
class Order < Model.for(:order)
|
4
|
-
include ModelProperties
|
5
|
-
|
6
|
-
# General Notes:
|
7
|
-
# 1. Placing Orders by con_id - When you place an order by con_id, you must
|
8
|
-
# provide the con_id AND the exchange. If you provide extra fields when placing
|
9
|
-
# an order by conid, the order may not work.
|
10
|
-
|
11
|
-
# 2. Order IDs - Each order you place must have a unique Order ID. Increment
|
12
|
-
# your own Order IDs to avoid conflicts between orders placed from your API application.
|
13
|
-
|
14
|
-
# Main order fields
|
15
|
-
prop :local_id, # int: Order id associated with client (volatile).
|
16
|
-
:client_id, # int: The id of the client that placed this order.
|
17
|
-
:perm_id, # int: TWS permanent id, remains the same over TWS sessions.
|
18
|
-
[:quantity, :total_quantity], # int: The order quantity.
|
19
|
-
|
20
|
-
:order_type, # String: Order type.
|
21
|
-
# Limit Risk: MTL / MKT PRT / QUOTE / STP / STP LMT / TRAIL / TRAIL LIMIT / TRAIL LIT / TRAIL MIT
|
22
|
-
# Speed of Execution: MKT / MIT / MOC / MOO / PEG MKT / REL
|
23
|
-
# Price Improvement: BOX TOP / LOC / LOO / LIT / PEG MID / VWAP
|
24
|
-
# Advanced Trading: OCA / VOL / SCALE
|
25
|
-
# Other (no abbreviation): Bracket, Auction, Discretionary, Sweep-to-Fill,
|
26
|
-
# Price Improvement Auction, Block, Hidden, Iceberg/Reserve, All-or-None, Fill-or-Kill
|
27
|
-
# See 'ib-ruby/constants.rb' ORDER_TYPES for a complete list of valid values.
|
28
|
-
|
29
|
-
:limit_price, # double: LIMIT price, used for limit, stop-limit and relative
|
30
|
-
# orders. In all other cases specify zero. For relative
|
31
|
-
# orders with no limit price, also specify zero.
|
32
|
-
|
33
|
-
:aux_price, # double: STOP price for stop-limit orders, and the OFFSET amount
|
34
|
-
# for relative orders. In all other cases, specify zero.
|
35
|
-
|
36
|
-
:oca_group, # String: Identifies a member of a one-cancels-all group.
|
37
|
-
:oca_type, # int: Tells how to handle remaining orders in an OCA group
|
38
|
-
# when one order or part of an order executes. Valid values:
|
39
|
-
# - 1 = Cancel all remaining orders with block
|
40
|
-
# - 2 = Remaining orders are reduced in size with block
|
41
|
-
# - 3 = Remaining orders are reduced in size with no block
|
42
|
-
# If you use a value "with block" your order has
|
43
|
-
# overfill protection. This means that only one order in
|
44
|
-
# the group will be routed at a time to remove the
|
45
|
-
# possibility of an overfill.
|
46
|
-
:parent_id, # int: The order ID of the parent (original) order, used
|
47
|
-
# for bracket (STP) and auto trailing stop (TRAIL) orders.
|
48
|
-
:display_size, # int: publicly disclosed order size for Iceberg orders.
|
49
|
-
|
50
|
-
:trigger_method, # Specifies how Simulated Stop, Stop-Limit and Trailing
|
51
|
-
# Stop orders are triggered. Valid values are:
|
52
|
-
# 0 - Default, "double bid/ask" for OTC/US options, "last" otherswise.
|
53
|
-
# 1 - "double bid/ask" method, stop orders are triggered based on
|
54
|
-
# two consecutive bid or ask prices.
|
55
|
-
# 2 - "last" method, stops are triggered based on the last price.
|
56
|
-
# 3 - double last method.
|
57
|
-
# 4 - bid/ask method. For a buy order, a single occurrence of the
|
58
|
-
# bid price must be at or above the trigger price. For a sell
|
59
|
-
# order, a single occurrence of the ask price must be at or
|
60
|
-
# below the trigger price.
|
61
|
-
# 7 - last or bid/ask method. For a buy order, a single bid price
|
62
|
-
# or the last price must be at or above the trigger price.
|
63
|
-
# For a sell order, a single ask price or the last price
|
64
|
-
# must be at or below the trigger price.
|
65
|
-
# 8 - mid-point method, where the midpoint must be at or above
|
66
|
-
# (for a buy) or at or below (for a sell) the trigger price,
|
67
|
-
# and the spread between the bid and ask must be less than
|
68
|
-
# 0.1% of the midpoint
|
69
|
-
|
70
|
-
:good_after_time, # Indicates that the trade should be submitted after the
|
71
|
-
# time and date set, format YYYYMMDD HH:MM:SS (seconds are optional).
|
72
|
-
:good_till_date, # Indicates that the trade should remain working until the
|
73
|
-
# time and date set, format YYYYMMDD HH:MM:SS (seconds are optional).
|
74
|
-
# You must set the :tif to GTD when using this string.
|
75
|
-
# Use an empty String if not applicable.
|
76
|
-
|
77
|
-
:rule_80a, # Individual = 'I', Agency = 'A', AgentOtherMember = 'W',
|
78
|
-
# IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M',
|
79
|
-
# IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N'
|
80
|
-
:min_quantity, # int: Identifies a minimum quantity order type.
|
81
|
-
:percent_offset, # double: percent offset amount for relative (REL)orders only
|
82
|
-
:trail_stop_price, # double: for TRAILLIMIT orders only
|
83
|
-
# As of client v.56, we receive trailing_percent in openOrder
|
84
|
-
:trailing_percent,
|
85
|
-
|
86
|
-
# Financial advisors only - use an empty String if not applicable.
|
87
|
-
:fa_group, :fa_profile, :fa_method, :fa_percentage,
|
88
|
-
|
89
|
-
# Institutional orders only!
|
90
|
-
:origin, # 0=Customer, 1=Firm
|
91
|
-
:order_ref, # String: Order reference. Customer defined order ID tag.
|
92
|
-
:short_sale_slot, # 1 - you hold the shares,
|
93
|
-
# 2 - they will be delivered from elsewhere.
|
94
|
-
# Only for Action="SSHORT
|
95
|
-
:designated_location, # String: set when slot==2 only
|
96
|
-
:exempt_code, # int
|
97
|
-
|
98
|
-
# Clearing info
|
99
|
-
:account, # String: The account. For institutional customers only.
|
100
|
-
:settling_firm, # String: Institutional only
|
101
|
-
:clearing_account, # String: For IBExecution customers: Specifies the
|
102
|
-
# true beneficiary of the order. This value is required
|
103
|
-
# for FUT/FOP orders for reporting to the exchange.
|
104
|
-
:clearing_intent, # IBExecution customers: "", IB, Away, PTA (post trade allocation).
|
105
|
-
|
106
|
-
# SMART routing only
|
107
|
-
:discretionary_amount, # double: The amount off the limit price
|
108
|
-
# allowed for discretionary orders.
|
109
|
-
:nbbo_price_cap, # double: Maximum Smart order distance from the NBBO.
|
110
|
-
|
111
|
-
# BOX or VOL ORDERS ONLY
|
112
|
-
:auction_strategy, # For BOX exchange only. Valid values:
|
113
|
-
# 1=AUCTION_MATCH, 2=AUCTION_IMPROVEMENT, 3=AUCTION_TRANSPARENT
|
114
|
-
:starting_price, # double: Starting price. Valid on BOX orders only.
|
115
|
-
:stock_ref_price, # double: The stock reference price, used for VOL
|
116
|
-
# orders to compute the limit price sent to an exchange (whether or not
|
117
|
-
# Continuous Update is selected), and for price range monitoring.
|
118
|
-
:delta, # double: Stock delta. Valid on BOX orders only.
|
119
|
-
|
120
|
-
# Pegged to stock or VOL orders. For price improvement option orders
|
121
|
-
# on BOX and VOL orders with dynamic management:
|
122
|
-
:stock_range_lower, # double: The lower value for the acceptable
|
123
|
-
# underlying stock price range.
|
124
|
-
:stock_range_upper, # double The upper value for the acceptable
|
125
|
-
# underlying stock price range.
|
126
|
-
|
127
|
-
# VOLATILITY ORDERS ONLY:
|
128
|
-
# http://www.interactivebrokers.com/en/general/education/pdfnotes/PDF-VolTrader.php
|
129
|
-
:volatility, # double: What the price is, computed via TWSs Options
|
130
|
-
# Analytics. For VOL orders, the limit price sent to an
|
131
|
-
# exchange is not editable, as it is the output of a
|
132
|
-
# function. Volatility is expressed as a percentage.
|
133
|
-
:volatility_type, # int: How the volatility is calculated: 1=daily, 2=annual
|
134
|
-
:reference_price_type, # int: For dynamic management of volatility orders:
|
135
|
-
# - 1 = Average of National Best Bid or Ask,
|
136
|
-
# - 2 = National Best Bid when buying a call or selling a put;
|
137
|
-
# and National Best Ask when selling a call or buying a put.
|
138
|
-
:continuous_update, # int: Used for dynamic management of volatility orders.
|
139
|
-
# Determines whether TWS is supposed to update the order price as the underlying
|
140
|
-
# moves. If selected, the limit price sent to an exchange is modified by TWS
|
141
|
-
# if the computed price of the option changes enough to warrant doing so. This
|
142
|
-
# is helpful in keeping the limit price up to date as the underlying price changes.
|
143
|
-
:delta_neutral_order_type, # String: Enter an order type to instruct TWS
|
144
|
-
# to submit a delta neutral trade on full or partial execution of the
|
145
|
-
# VOL order. For no hedge delta order to be sent, specify NONE.
|
146
|
-
# Valid values - LMT, MKT, MTL, REL, MOC
|
147
|
-
:delta_neutral_aux_price, # double: Use this field to enter a value if
|
148
|
-
# the value in the deltaNeutralOrderType field is an order
|
149
|
-
# type that requires an Aux price, such as a REL order.
|
150
|
-
|
151
|
-
# As of client v.52, we also receive delta... params in openOrder
|
152
|
-
:delta_neutral_con_id,
|
153
|
-
:delta_neutral_settling_firm,
|
154
|
-
:delta_neutral_clearing_account,
|
155
|
-
:delta_neutral_clearing_intent,
|
156
|
-
|
157
|
-
# HEDGE ORDERS ONLY:
|
158
|
-
# As of client v.49/50, we can now add hedge orders using the API.
|
159
|
-
# Hedge orders are child orders that take additional fields. There are four
|
160
|
-
# types of hedging orders supported by the API: Delta, Beta, FX, Pair.
|
161
|
-
# All hedge orders must have a parent order submitted first. The hedge order
|
162
|
-
# should set its :parent_id. If the hedgeType is Beta, the beta sent in the
|
163
|
-
# hedgeParm can be zero, which means it is not used. Delta is only valid
|
164
|
-
# if the parent order is an option and the child order is a stock.
|
165
|
-
|
166
|
-
:hedge_type, # String: D = Delta, B = Beta, F = FX or P = Pair
|
167
|
-
:hedge_param, # String; value depends on the hedgeType; sent from the API
|
168
|
-
# only if hedge_type is NOT null. It is required for Pair hedge order,
|
169
|
-
# optional for Beta hedge orders, and ignored for Delta and FX hedge orders.
|
170
|
-
|
171
|
-
# COMBO ORDERS ONLY:
|
172
|
-
:basis_points, # double: EFP orders only
|
173
|
-
:basis_points_type, # double: EFP orders only
|
174
|
-
|
175
|
-
# ALGO ORDERS ONLY:
|
176
|
-
:algo_strategy, # String
|
177
|
-
:algo_params, # public Vector<TagValue> m_algoParams; ?!
|
178
|
-
|
179
|
-
# SCALE ORDERS ONLY:
|
180
|
-
:scale_init_level_size, # int: Size of the first (initial) order component.
|
181
|
-
:scale_subs_level_size, # int: Order size of the subsequent scale order
|
182
|
-
# components. Used in conjunction with scaleInitLevelSize().
|
183
|
-
:scale_price_increment, # double: Price increment between scale components.
|
184
|
-
# This field is required for Scale orders.
|
185
|
-
|
186
|
-
# As of client v.54, we can receive additional scale order fields:
|
187
|
-
:scale_price_adjust_value,
|
188
|
-
:scale_price_adjust_interval,
|
189
|
-
:scale_profit_offset,
|
190
|
-
:scale_init_position,
|
191
|
-
:scale_init_fill_qty,
|
192
|
-
:scale_auto_reset => :bool,
|
193
|
-
:scale_random_percent => :bool
|
194
|
-
|
195
|
-
# Properties with complex processing logics
|
196
|
-
prop :tif, # String: Time in Force (time to market): DAY/GAT/GTD/GTC/IOC
|
197
|
-
:what_if => :bool, # Only return pre-trade commissions and margin info, do not place
|
198
|
-
:not_held => :bool, # Not Held
|
199
|
-
:outside_rth => :bool, # Order may trigger or fill outside of regular hours. (WAS: ignore_rth)
|
200
|
-
:hidden => :bool, # Order will not be visible in market depth. ISLAND only.
|
201
|
-
:transmit => :bool, # If false, order will be created but not transmitted.
|
202
|
-
:block_order => :bool, # This is an ISE Block order.
|
203
|
-
:sweep_to_fill => :bool, # This is a Sweep-to-Fill order.
|
204
|
-
:override_percentage_constraints => :bool,
|
205
|
-
# TWS Presets page constraints ensure that your price and size order values
|
206
|
-
# are reasonable. Orders sent from the API are also validated against these
|
207
|
-
# safety constraints, unless this parameter is set to True.
|
208
|
-
:all_or_none => :bool, # AON
|
209
|
-
:etrade_only => :bool, # Trade with electronic quotes.
|
210
|
-
:firm_quote_only => :bool, # Trade with firm quotes.
|
211
|
-
:opt_out_smart_routing => :bool, # Australian exchange only, default false
|
212
|
-
:open_close => PROPS[:open_close], # Originally String: O=Open, C=Close ()
|
213
|
-
# for ComboLeg compatibility: SAME = 0; OPEN = 1; CLOSE = 2; UNKNOWN = 3;
|
214
|
-
[:side, :action] => PROPS[:side] # String: Action/side: BUY/SELL/SSHORT/SSHORTX
|
215
|
-
|
216
|
-
prop :placed_at,
|
217
|
-
:modified_at,
|
218
|
-
:leg_prices,
|
219
|
-
:algo_params,
|
220
|
-
:combo_params
|
221
|
-
|
222
|
-
alias order_combo_legs leg_prices
|
223
|
-
alias smart_combo_routing_params combo_params
|
224
|
-
|
225
|
-
serialize :leg_prices
|
226
|
-
serialize :algo_params, Hash
|
227
|
-
serialize :combo_params
|
228
|
-
|
229
|
-
# Order is always placed for a contract. Here, we explicitly set this link.
|
230
|
-
belongs_to :contract
|
231
|
-
|
232
|
-
# Order has a collection of Executions if it was filled
|
233
|
-
has_many :executions
|
234
|
-
|
235
|
-
# Order has a collection of OrderStates, last one is always current
|
236
|
-
has_many :order_states
|
237
|
-
|
238
|
-
def order_state
|
239
|
-
order_states.last
|
240
|
-
end
|
241
|
-
|
242
|
-
def order_state= state
|
243
|
-
self.order_states.push case state
|
244
|
-
when IB::OrderState
|
245
|
-
state
|
246
|
-
when Symbol, String
|
247
|
-
IB::OrderState.new :status => state
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
# Some properties received from IB are separated into OrderState object,
|
252
|
-
# but they are still readable as Order properties through delegation:
|
253
|
-
# Properties arriving via OpenOrder message:
|
254
|
-
[:commission, # double: Shows the commission amount on the order.
|
255
|
-
:commission_currency, # String: Shows the currency of the commission.
|
256
|
-
:min_commission, # The possible min range of the actual order commission.
|
257
|
-
:max_commission, # The possible max range of the actual order commission.
|
258
|
-
:warning_text, # String: Displays a warning message if warranted.
|
259
|
-
:init_margin, # Float: The impact the order would have on your initial margin.
|
260
|
-
:maint_margin, # Float: The impact the order would have on your maintenance margin.
|
261
|
-
:equity_with_loan, # Float: The impact the order would have on your equity
|
262
|
-
:status, # String: Displays the order status. See OrderState for values
|
263
|
-
# Properties arriving via OrderStatus message:
|
264
|
-
:filled, # int
|
265
|
-
:remaining, # int
|
266
|
-
:price, # double
|
267
|
-
:last_fill_price, # double
|
268
|
-
:average_price, # double
|
269
|
-
:average_fill_price, # double
|
270
|
-
:why_held, # String: comma-separated list of reasons for order to be held.
|
271
|
-
# Testing Order state:
|
272
|
-
:new?,
|
273
|
-
:submitted?,
|
274
|
-
:pending?,
|
275
|
-
:active?,
|
276
|
-
:inactive?,
|
277
|
-
:complete_fill?,
|
278
|
-
].each { |property| define_method(property) { order_state.send(property) } }
|
279
|
-
|
280
|
-
# Order is not valid without correct :local_id
|
281
|
-
validates_numericality_of :local_id, :perm_id, :client_id, :parent_id,
|
282
|
-
:quantity, :min_quantity, :display_size,
|
283
|
-
:only_integer => true, :allow_nil => true
|
284
|
-
|
285
|
-
validates_numericality_of :limit_price, :aux_price, :allow_nil => true
|
286
|
-
|
287
|
-
|
288
|
-
def default_attributes
|
289
|
-
super.merge :aux_price => 0.0,
|
290
|
-
:discretionary_amount => 0.0,
|
291
|
-
:parent_id => 0,
|
292
|
-
:tif => :day,
|
293
|
-
:order_type => :limit,
|
294
|
-
:open_close => :open,
|
295
|
-
:origin => :customer,
|
296
|
-
:short_sale_slot => :default,
|
297
|
-
:trigger_method => :default,
|
298
|
-
:oca_type => :none,
|
299
|
-
:auction_strategy => :none,
|
300
|
-
:designated_location => '',
|
301
|
-
:exempt_code => -1,
|
302
|
-
:display_size => 0,
|
303
|
-
:continuous_update => 0,
|
304
|
-
:delta_neutral_con_id => 0,
|
305
|
-
:algo_strategy => '',
|
306
|
-
:transmit => true,
|
307
|
-
:what_if => false,
|
308
|
-
:leg_prices => [],
|
309
|
-
:algo_params => HashWithIndifferentAccess.new, #{},
|
310
|
-
:combo_params => HashWithIndifferentAccess.new, #{},
|
311
|
-
:order_state => IB::OrderState.new(:status => 'New',
|
312
|
-
:filled => 0,
|
313
|
-
:remaining => 0,
|
314
|
-
:price => 0,
|
315
|
-
:average_price => 0)
|
316
|
-
end
|
317
|
-
|
318
|
-
def serialize_algo
|
319
|
-
if algo_strategy.nil? || algo_strategy.empty?
|
320
|
-
''
|
321
|
-
else
|
322
|
-
[algo_strategy,
|
323
|
-
algo_params.size,
|
324
|
-
algo_params.to_a]
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
# Placement
|
329
|
-
def place contract, connection
|
330
|
-
error "Unable to place order, next_local_id not known" unless connection.next_local_id
|
331
|
-
self.client_id = connection.server[:client_id]
|
332
|
-
self.local_id = connection.next_local_id
|
333
|
-
connection.next_local_id += 1
|
334
|
-
self.placed_at = Time.now
|
335
|
-
modify contract, connection, self.placed_at
|
336
|
-
end
|
337
|
-
|
338
|
-
# Modify Order (convenience wrapper for send_message :PlaceOrder). Returns local_id.
|
339
|
-
def modify contract, connection, time=Time.now
|
340
|
-
self.modified_at = time
|
341
|
-
connection.send_message :PlaceOrder,
|
342
|
-
:order => self,
|
343
|
-
:contract => contract,
|
344
|
-
:local_id => local_id
|
345
|
-
local_id
|
346
|
-
end
|
347
|
-
|
348
|
-
# Order comparison
|
349
|
-
def == other
|
350
|
-
perm_id && other.perm_id && perm_id == other.perm_id ||
|
351
|
-
local_id == other.local_id && # ((p __LINE__)||true) &&
|
352
|
-
(client_id == other.client_id || client_id == 0 || other.client_id == 0) &&
|
353
|
-
parent_id == other.parent_id &&
|
354
|
-
tif == other.tif &&
|
355
|
-
action == other.action &&
|
356
|
-
order_type == other.order_type &&
|
357
|
-
quantity == other.quantity &&
|
358
|
-
(limit_price == other.limit_price || # TODO Floats should be Decimals!
|
359
|
-
(limit_price - other.limit_price).abs < 0.00001) &&
|
360
|
-
aux_price == other.aux_price &&
|
361
|
-
origin == other.origin &&
|
362
|
-
designated_location == other.designated_location &&
|
363
|
-
exempt_code == other.exempt_code &&
|
364
|
-
what_if == other.what_if &&
|
365
|
-
algo_strategy == other.algo_strategy &&
|
366
|
-
algo_params == other.algo_params
|
367
|
-
|
368
|
-
# TODO: || compare all attributes!
|
369
|
-
end
|
370
|
-
|
371
|
-
def to_s #human
|
372
|
-
"<Order:" + instance_variables.map do |key|
|
373
|
-
value = instance_variable_get(key)
|
374
|
-
" #{key}=#{value}" unless value.nil? || value == '' || value == 0
|
375
|
-
end.compact.join(',') + " >"
|
376
|
-
end
|
377
|
-
|
378
|
-
def to_human
|
379
|
-
"<Order: " + ((order_ref && order_ref != '') ? "#{order_ref} " : '') +
|
380
|
-
"#{self[:order_type]} #{self[:tif]} #{side} #{quantity} " +
|
381
|
-
"#{status} " + (limit_price ? "#{limit_price} " : '') +
|
382
|
-
((aux_price && aux_price != 0) ? "/#{aux_price}" : '') +
|
383
|
-
"##{local_id}/#{perm_id} from #{client_id}" +
|
384
|
-
(account ? "/#{account}" : '') +
|
385
|
-
(commission ? " fee #{commission}" : '') + ">"
|
386
|
-
end
|
387
|
-
end # class Order
|
388
|
-
end # module Models
|
389
|
-
end # module IB
|
@@ -1,128 +0,0 @@
|
|
1
|
-
module IB
|
2
|
-
module Models
|
3
|
-
|
4
|
-
# OrderState represents dynamic (changeable) info about a single Order,
|
5
|
-
# isolating these changes and making Order essentially immutable
|
6
|
-
class OrderState < Model.for(:order_state)
|
7
|
-
include ModelProperties
|
8
|
-
|
9
|
-
#p column_names
|
10
|
-
belongs_to :order
|
11
|
-
|
12
|
-
# Properties arriving via OpenOrder message
|
13
|
-
prop :init_margin, # Float: The impact the order would have on your initial margin.
|
14
|
-
:maint_margin, # Float: The impact the order would have on your maintenance margin.
|
15
|
-
:equity_with_loan, # Float: The impact the order would have on your equity
|
16
|
-
:commission, # double: Shows the commission amount on the order.
|
17
|
-
:min_commission, # The possible min range of the actual order commission.
|
18
|
-
:max_commission, # The possible max range of the actual order commission.
|
19
|
-
:commission_currency, # String: Shows the currency of the commission.
|
20
|
-
:warning_text # String: Displays a warning message if warranted.
|
21
|
-
|
22
|
-
# Properties arriving via OrderStatus message:
|
23
|
-
prop :filled, # int
|
24
|
-
:remaining, # int
|
25
|
-
[:price, :last_fill_price,], # double
|
26
|
-
[:average_price, :average_fill_price], # double
|
27
|
-
:why_held # String: comma-separated list of reasons for order to be held.
|
28
|
-
|
29
|
-
# Properties arriving in both messages:
|
30
|
-
prop :local_id, # int: Order id associated with client (volatile).
|
31
|
-
:perm_id, # int: TWS permanent id, remains the same over TWS sessions.
|
32
|
-
:client_id, # int: The id of the client that placed this order.
|
33
|
-
:parent_id, # int: The order ID of the parent (original) order, used
|
34
|
-
:status => :s # String: Displays the order status. Possible values include:
|
35
|
-
# - PendingSubmit - indicates that you have transmitted the order, but
|
36
|
-
# have not yet received confirmation that it has been accepted by the
|
37
|
-
# order destination. NOTE: This order status is NOT sent back by TWS
|
38
|
-
# and should be explicitly set by YOU when an order is submitted.
|
39
|
-
# - PendingCancel - indicates that you have sent a request to cancel
|
40
|
-
# the order but have not yet received cancel confirmation from the
|
41
|
-
# order destination. At this point, your order cancel is not confirmed.
|
42
|
-
# You may still receive an execution while your cancellation request
|
43
|
-
# is pending. NOTE: This order status is not sent back by TWS and
|
44
|
-
# should be explicitly set by YOU when an order is canceled.
|
45
|
-
# - PreSubmitted - indicates that a simulated order type has been
|
46
|
-
# accepted by the IB system and that this order has yet to be elected.
|
47
|
-
# The order is held in the IB system until the election criteria are
|
48
|
-
# met. At that time the order is transmitted to the order destination
|
49
|
-
# as specified.
|
50
|
-
# - Submitted - indicates that your order has been accepted at the order
|
51
|
-
# destination and is working.
|
52
|
-
# - Cancelled - indicates that the balance of your order has been
|
53
|
-
# confirmed canceled by the IB system. This could occur unexpectedly
|
54
|
-
# when IB or the destination has rejected your order.
|
55
|
-
# - ApiCancelled - canceled via API
|
56
|
-
# - Filled - indicates that the order has been completely filled.
|
57
|
-
# - Inactive - indicates that the order has been accepted by the system
|
58
|
-
# (simulated orders) or an exchange (native orders) but that currently
|
59
|
-
# the order is inactive due to system, exchange or other issues.
|
60
|
-
|
61
|
-
validates_format_of :status, :without => /^$/, :message => 'must not be empty'
|
62
|
-
validates_numericality_of :price, :average_price, :allow_nil => true
|
63
|
-
validates_numericality_of :local_id, :perm_id, :client_id, :parent_id, :filled,
|
64
|
-
:remaining, :only_integer => true, :allow_nil => true
|
65
|
-
|
66
|
-
## Testing Order state:
|
67
|
-
|
68
|
-
def new?
|
69
|
-
status.empty? || status == 'New'
|
70
|
-
end
|
71
|
-
|
72
|
-
# Order is in a valid, working state on TWS side
|
73
|
-
def submitted?
|
74
|
-
status == 'PreSubmitted' || status == 'Submitted'
|
75
|
-
end
|
76
|
-
|
77
|
-
# Order is in a valid, working state on TWS side
|
78
|
-
def pending?
|
79
|
-
submitted? || status == 'PendingSubmit'
|
80
|
-
end
|
81
|
-
|
82
|
-
# Order is in invalid state
|
83
|
-
def active?
|
84
|
-
new? || pending?
|
85
|
-
end
|
86
|
-
|
87
|
-
# Order is in invalid state
|
88
|
-
def inactive?
|
89
|
-
!active? # status == 'Inactive'
|
90
|
-
end
|
91
|
-
|
92
|
-
def complete_fill?
|
93
|
-
status == 'Filled' && remaining == 0 # filled >= total_quantity # Manually corrected
|
94
|
-
end
|
95
|
-
|
96
|
-
# Comparison
|
97
|
-
def == other
|
98
|
-
other && other.is_a?(OrderState) &&
|
99
|
-
status == other.status &&
|
100
|
-
local_id == other.local_id &&
|
101
|
-
perm_id == other.perm_id &&
|
102
|
-
client_id == other.client_id &&
|
103
|
-
filled == other.filled &&
|
104
|
-
remaining == other.remaining &&
|
105
|
-
last_fill_price == other.last_fill_price &&
|
106
|
-
init_margin == other.init_margin &&
|
107
|
-
maint_margin == other.maint_margin &&
|
108
|
-
equity_with_loan == other.equity_with_loan &&
|
109
|
-
why_held == other.why_held &&
|
110
|
-
warning_text == other.warning_text &&
|
111
|
-
commission == other.commission
|
112
|
-
end
|
113
|
-
|
114
|
-
def to_human
|
115
|
-
"<OrderState: #{status} ##{local_id}/#{perm_id} from #{client_id}" +
|
116
|
-
(filled ? " filled #{filled}/#{remaining}" : '') +
|
117
|
-
(last_fill_price ? " at #{last_fill_price}/#{average_fill_price}" : '') +
|
118
|
-
(init_margin ? " margin #{init_margin}/#{maint_margin}" : '') +
|
119
|
-
(equity_with_loan ? " equity #{equity_with_loan}" : '') +
|
120
|
-
(commission && commission > 0 ? " fee #{commission}" : "") +
|
121
|
-
(why_held ? " why_held #{why_held}" : '') +
|
122
|
-
((warning_text && warning_text != '') ? " warning #{warning_text}" : '') + ">"
|
123
|
-
end
|
124
|
-
|
125
|
-
alias to_s to_human
|
126
|
-
end # class Order
|
127
|
-
end # module Models
|
128
|
-
end # module IB
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'ib-ruby/models/contract_detail'
|
2
|
-
|
3
|
-
module IB
|
4
|
-
module Models
|
5
|
-
|
6
|
-
# Calculated characteristics of underlying Contract (volatile)
|
7
|
-
class Underlying < Model.for(:underlying)
|
8
|
-
include ModelProperties
|
9
|
-
|
10
|
-
has_one :contract
|
11
|
-
|
12
|
-
prop :con_id, # Id of the Underlying Contract
|
13
|
-
:delta, # double: The underlying stock or future delta.
|
14
|
-
:price # double: The price of the underlying.
|
15
|
-
|
16
|
-
validates_numericality_of :con_id, :delta, :price #, :allow_nil => true
|
17
|
-
|
18
|
-
def default_attributes
|
19
|
-
super.merge :con_id => 0
|
20
|
-
end
|
21
|
-
|
22
|
-
# Serialize under_comp parameters
|
23
|
-
def serialize
|
24
|
-
[true, con_id, delta, price]
|
25
|
-
end
|
26
|
-
|
27
|
-
# Comparison
|
28
|
-
def == other
|
29
|
-
con_id == other.con_id && delta == other.delta && price == other.price
|
30
|
-
end
|
31
|
-
|
32
|
-
end # class Contract
|
33
|
-
UnderComp = Underlying
|
34
|
-
|
35
|
-
end # module Models
|
36
|
-
end # module IB
|
data/lib/ib-ruby/models.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
module IB
|
2
|
-
module Models
|
3
|
-
|
4
|
-
require 'ib-ruby/models/model_properties'
|
5
|
-
require 'ib-ruby/models/model'
|
6
|
-
|
7
|
-
require 'ib-ruby/models/contract'
|
8
|
-
require 'ib-ruby/models/order_state'
|
9
|
-
require 'ib-ruby/models/order'
|
10
|
-
require 'ib-ruby/models/combo_leg'
|
11
|
-
require 'ib-ruby/models/execution'
|
12
|
-
require 'ib-ruby/models/bar'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
data/lib/ib-ruby/symbols.rb
DELETED
data/spec/test.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# This script retrieves list of all Orders from TWS
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
require 'bundler/setup'
|
7
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
8
|
-
|
9
|
-
require 'yaml'
|
10
|
-
require 'pathname'
|
11
|
-
require 'ib-ruby/db'
|
12
|
-
|
13
|
-
# Load DB config, determine correct environment
|
14
|
-
db_file = Pathname.new(__FILE__).realpath.dirname + '../db/config.yml'
|
15
|
-
raise "Unable to find DB config file: #{db_file}" unless db_file.exist?
|
16
|
-
|
17
|
-
env = RUBY_PLATFORM =~ /java/ ? 'test' : 'test-mri'
|
18
|
-
db_config = YAML::load_file(db_file)[env]
|
19
|
-
|
20
|
-
# Establish connection to test DB
|
21
|
-
IB::DB.connect db_config
|
22
|
-
|
23
|
-
require 'ib-ruby'
|
24
|
-
|
25
|
-
# Connect to IB as 0 (TWS) to retrieve all Orders, including TWS-generated ones
|
26
|
-
ib = IB::Connection.new :client_id => 0 #, :port => 7496 # TWS
|
27
|
-
|
28
|
-
## Subscribe to TWS alerts/errors and order-related messages
|
29
|
-
#@counter = 0
|
30
|
-
#
|
31
|
-
#ib.subscribe(:Alert, :OrderStatus, :OpenOrderEnd) { |msg| puts msg.to_human }
|
32
|
-
#
|
33
|
-
#ib.subscribe(:OpenOrder) do |msg|
|
34
|
-
# @counter += 1
|
35
|
-
# puts "#{@counter}: #{msg.to_human}"
|
36
|
-
# #pp msg.order
|
37
|
-
#end
|
38
|
-
#
|
39
|
-
#ib.send_message :RequestAllOpenOrders
|
40
|
-
#
|
41
|
-
## Wait for IB to respond to our request
|
42
|
-
#ib.wait_for :OpenOrderEnd
|
43
|
-
#sleep 1 # Let printer do the job
|
44
|
-
|
45
|
-
combo = IB::Bag.new
|
46
|
-
|
47
|
-
google = IB::Option.new(:symbol => 'GOOG',
|
48
|
-
:expiry => 201301,
|
49
|
-
:right => :call,
|
50
|
-
:strike => 500)
|
51
|
-
|
52
|
-
combo.leg_contracts << google
|
53
|
-
p combo.leg_contracts
|
54
|
-
p combo.save
|
55
|
-
|
56
|
-
#combo.legs.should_not be_empty
|
57
|
-
p combo.leg_contracts
|
58
|
-
p google.combo
|
59
|
-
|
60
|
-
leg = combo.legs.first
|
61
|
-
p google.leg
|