ib-ruby 0.8.4 → 0.8.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/HISTORY +3 -0
- data/README.md +29 -9
- data/VERSION +1 -1
- data/app/assets/javascripts/ib/bars.js +2 -0
- data/app/assets/javascripts/ib/executions.js +2 -0
- data/app/assets/javascripts/ib/order_states.js +2 -0
- data/app/assets/stylesheets/ib/bars.css +4 -0
- data/app/assets/stylesheets/ib/executions.css +4 -0
- data/app/assets/stylesheets/ib/order_states.css +4 -0
- data/app/controllers/ib/bars_controller.rb +87 -0
- data/app/controllers/ib/combo_legs_controller.rb +87 -0
- data/app/controllers/ib/contract_details_controller.rb +87 -0
- data/app/controllers/ib/contracts_controller.rb +87 -0
- data/app/controllers/ib/executions_controller.rb +87 -0
- data/app/controllers/ib/order_states_controller.rb +87 -0
- data/app/controllers/ib/orders_controller.rb +87 -0
- data/app/helpers/ib/bars_helper.rb +4 -0
- data/app/helpers/ib/combo_legs_helper.rb +4 -0
- data/app/helpers/ib/contract_details_helper.rb +4 -0
- data/app/helpers/ib/contracts_helper.rb +4 -0
- data/app/helpers/ib/executions_helper.rb +4 -0
- data/app/helpers/ib/order_states_helper.rb +4 -0
- data/app/helpers/ib/orders_helper.rb +4 -0
- data/app/views/ib/bars/_form.html.erb +57 -0
- data/app/views/ib/bars/edit.html.erb +6 -0
- data/app/views/ib/bars/index.html.erb +41 -0
- data/app/views/ib/bars/new.html.erb +5 -0
- data/app/views/ib/bars/show.html.erb +55 -0
- data/app/views/ib/combo_legs/_form.html.erb +53 -0
- data/app/views/ib/combo_legs/edit.html.erb +6 -0
- data/app/views/ib/combo_legs/index.html.erb +39 -0
- data/app/views/ib/combo_legs/new.html.erb +5 -0
- data/app/views/ib/combo_legs/show.html.erb +55 -0
- data/app/views/ib/contract_details/_form.html.erb +141 -0
- data/app/views/ib/contract_details/edit.html.erb +6 -0
- data/app/views/ib/contract_details/index.html.erb +83 -0
- data/app/views/ib/contract_details/new.html.erb +5 -0
- data/app/views/ib/contract_details/show.html.erb +160 -0
- data/app/views/ib/contracts/_form.html.erb +77 -0
- data/app/views/ib/contracts/edit.html.erb +6 -0
- data/app/views/ib/contracts/index.html.erb +53 -0
- data/app/views/ib/contracts/new.html.erb +5 -0
- data/app/views/ib/contracts/show.html.erb +85 -0
- data/app/views/ib/executions/_form.html.erb +77 -0
- data/app/views/ib/executions/edit.html.erb +6 -0
- data/app/views/ib/executions/index.html.erb +51 -0
- data/app/views/ib/executions/new.html.erb +5 -0
- data/app/views/ib/executions/show.html.erb +80 -0
- data/app/views/ib/order_states/_form.html.erb +93 -0
- data/app/views/ib/order_states/edit.html.erb +6 -0
- data/app/views/ib/order_states/index.html.erb +59 -0
- data/app/views/ib/order_states/new.html.erb +5 -0
- data/app/views/ib/order_states/show.html.erb +100 -0
- data/app/views/ib/orders/_form.html.erb +353 -0
- data/app/views/ib/orders/edit.html.erb +6 -0
- data/app/views/ib/orders/index.html.erb +193 -0
- data/app/views/ib/orders/new.html.erb +5 -0
- data/app/views/ib/orders/show.html.erb +435 -0
- data/bin/scaffold.rb +29 -0
- data/config/routes.rb +8 -1
- data/db/config.yml +5 -0
- data/db/migrate/101_add_ib_executions.rb +3 -0
- data/db/migrate/111_add_ib_bars.rb +6 -0
- data/db/migrate/121_add_ib_order_states.rb +8 -0
- data/db/migrate/131_add_ib_orders.rb +24 -0
- data/db/migrate/141_add_ib_combo_legs.rb +6 -0
- data/db/migrate/151_add_ib_underlyings.rb +3 -0
- data/db/migrate/161_add_ib_contract_details.rb +11 -0
- data/db/migrate/171_add_ib_contracts.rb +8 -1
- data/db/schema.rb +6 -5
- data/lib/ib/base.rb +3 -1
- data/lib/ib/base_properties.rb +26 -15
- data/lib/ib/connection.rb +3 -2
- data/lib/ib/errors.rb +16 -9
- data/lib/ib/extensions.rb +6 -4
- data/lib/ib/symbols.rb +10 -3
- data/lib/ib/symbols/forex.rb +49 -64
- data/lib/ib/symbols/futures.rb +2 -3
- data/lib/ib/symbols/options.rb +2 -1
- data/lib/ib/symbols/stocks.rb +2 -1
- data/lib/models/ib/bar.rb +6 -2
- data/lib/models/ib/combo_leg.rb +4 -3
- data/lib/models/ib/contract.rb +9 -5
- data/lib/models/ib/contract_detail.rb +1 -1
- data/lib/models/ib/execution.rb +3 -1
- data/lib/models/ib/order.rb +22 -20
- data/lib/models/ib/order_state.rb +4 -2
- data/lib/models/ib/underlying.rb +3 -4
- data/spec/README.md +12 -10
- data/spec/ib/symbols/symbols_spec.rb +10 -0
- data/spec/integration_helper.rb +1 -1
- data/spec/model_helper.rb +9 -8
- data/spec/models/ib/combo_leg_spec.rb +29 -28
- data/spec/models/ib/contract_detail_spec.rb +4 -1
- data/spec/models/ib/contract_spec.rb +66 -58
- data/spec/models/ib/execution_spec.rb +50 -44
- data/spec/models/ib/order_spec.rb +2 -2
- data/spec/order_helper.rb +5 -4
- data/spec/spec_helper.rb +3 -3
- metadata +59 -35
- data/app/models/ib/underlying.rb +0 -5
- data/bin/account_info +0 -29
- data/bin/cancel_orders +0 -27
- data/bin/contract_details +0 -35
- data/bin/depth_of_market +0 -43
- data/bin/fa_accounts +0 -22
- data/bin/fundamental_data +0 -39
- data/bin/historic_data +0 -51
- data/bin/historic_data_cli +0 -182
- data/bin/list_orders +0 -28
- data/bin/market_data +0 -41
- data/bin/option_data +0 -44
- data/bin/place_combo_order +0 -58
- data/bin/place_order +0 -27
- data/bin/template +0 -18
- data/bin/tick_data +0 -26
- data/bin/time_and_sales +0 -53
data/lib/ib/symbols/futures.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# The Futures module tries to guess the front month
|
2
|
-
#
|
1
|
+
# The Futures module tries to guess the front month future using a crude algorithm that
|
2
|
+
# does not take into account expiry/rollover day. This will be valid most of the time,
|
3
3
|
# but near/after expiry day the next quarter's contract takes over as the volume leader.
|
4
4
|
|
5
5
|
module IB
|
@@ -8,7 +8,6 @@ module IB
|
|
8
8
|
extend Symbols
|
9
9
|
|
10
10
|
# Find the next front month of quarterly futures.
|
11
|
-
#
|
12
11
|
# N.B. This will not work as expected during the front month before expiration, as
|
13
12
|
# it will point to the next quarter even though the current month is still valid!
|
14
13
|
def self.next_quarter_month time=Time.now
|
data/lib/ib/symbols/options.rb
CHANGED
data/lib/ib/symbols/stocks.rb
CHANGED
data/lib/models/ib/bar.rb
CHANGED
@@ -4,6 +4,8 @@ module IB
|
|
4
4
|
class Bar < IB::Model
|
5
5
|
include BaseProperties
|
6
6
|
|
7
|
+
has_one :contract # The bar represents timeseries info for this Contract
|
8
|
+
|
7
9
|
prop :open, # The bar opening price.
|
8
10
|
:high, # The high price during the time covered by the bar.
|
9
11
|
:low, # The low price during the time covered by the bar.
|
@@ -17,11 +19,13 @@ module IB
|
|
17
19
|
# determined by the reqHistoricalData() formatDate parameter.
|
18
20
|
:has_gaps => :bool # Whether or not there are gaps in the data.
|
19
21
|
|
20
|
-
|
22
|
+
validates_numericality_of :open, :high, :low, :close, :volume
|
21
23
|
|
22
24
|
# Order comparison
|
23
25
|
def == other
|
24
|
-
|
26
|
+
super(other) ||
|
27
|
+
other.is_a?(self.class) &&
|
28
|
+
time == other.time &&
|
25
29
|
open == other.open &&
|
26
30
|
high == other.high &&
|
27
31
|
low == other.low &&
|
data/lib/models/ib/combo_leg.rb
CHANGED
@@ -87,11 +87,12 @@ module IB
|
|
87
87
|
|
88
88
|
# Order comparison
|
89
89
|
def == other
|
90
|
-
other
|
90
|
+
super(other) ||
|
91
|
+
other.is_a?(self.class) &&
|
91
92
|
con_id == other.con_id &&
|
92
93
|
ratio == other.ratio &&
|
93
|
-
open_close == other.open_close &&
|
94
|
-
short_sale_slot == other.short_sale_slot&&
|
94
|
+
open_close == other.open_close &&
|
95
|
+
short_sale_slot == other.short_sale_slot &&
|
95
96
|
exempt_code == other.exempt_code &&
|
96
97
|
side == other.side &&
|
97
98
|
exchange == other.exchange &&
|
data/lib/models/ib/contract.rb
CHANGED
@@ -14,7 +14,7 @@ module IB
|
|
14
14
|
|
15
15
|
:sec_type, # Security type. Valid values are: SECURITY_TYPES
|
16
16
|
|
17
|
-
:sec_id, # Unique identifier of the given secIdType.
|
17
|
+
:sec_id => :sup, # Unique identifier of the given secIdType.
|
18
18
|
|
19
19
|
:sec_id_type => :sup, # Security identifier, when querying contract details or
|
20
20
|
# when placing orders. Supported identifiers are:
|
@@ -68,6 +68,8 @@ module IB
|
|
68
68
|
|
69
69
|
has_many :orders # Placed for this Contract
|
70
70
|
|
71
|
+
has_many :bars # Possibly representing trading history for this Contract
|
72
|
+
|
71
73
|
has_one :contract_detail # Volatile info about this Contract
|
72
74
|
|
73
75
|
# For Contracts that are part of BAG
|
@@ -80,17 +82,17 @@ module IB
|
|
80
82
|
alias legs combo_legs
|
81
83
|
alias legs= combo_legs=
|
82
84
|
|
83
|
-
|
85
|
+
alias combo_legs_description legs_description
|
84
86
|
alias combo_legs_description= legs_description=
|
85
87
|
|
86
|
-
|
87
|
-
|
88
|
+
# for Delta-Neutral Combo Contracts
|
89
|
+
has_one :underlying
|
88
90
|
alias under_comp underlying
|
89
91
|
alias under_comp= underlying=
|
90
92
|
|
91
93
|
|
92
94
|
### Extra validations
|
93
|
-
|
95
|
+
validates_inclusion_of :sec_type, :in => CODES[:sec_type].keys,
|
94
96
|
:message => "should be valid security type"
|
95
97
|
|
96
98
|
validates_format_of :expiry, :with => /^\d{6}$|^\d{8}$|^$/,
|
@@ -177,6 +179,8 @@ module IB
|
|
177
179
|
|
178
180
|
# Contract comparison
|
179
181
|
def == other
|
182
|
+
return true if super(other)
|
183
|
+
|
180
184
|
return false unless other.is_a?(self.class)
|
181
185
|
|
182
186
|
# Different sec_id_type
|
@@ -48,7 +48,7 @@ module IB
|
|
48
48
|
:next_option_partial => :bool # # only if bond has embedded options.
|
49
49
|
|
50
50
|
# Extra validations
|
51
|
-
|
51
|
+
validates_format_of :time_zone, :with => /^\w{3}$/, :message => 'should be XXX'
|
52
52
|
|
53
53
|
belongs_to :contract
|
54
54
|
alias summary contract
|
data/lib/models/ib/execution.rb
CHANGED
@@ -39,7 +39,9 @@ module IB
|
|
39
39
|
|
40
40
|
# Comparison
|
41
41
|
def == other
|
42
|
-
|
42
|
+
super(other) ||
|
43
|
+
other.is_a?(self.class) &&
|
44
|
+
perm_id == other.perm_id &&
|
43
45
|
local_id == other.local_id && # ((p __LINE__)||true) &&
|
44
46
|
client_id == other.client_id &&
|
45
47
|
exec_id == other.exec_id &&
|
data/lib/models/ib/order.rb
CHANGED
@@ -348,26 +348,28 @@ module IB
|
|
348
348
|
|
349
349
|
# Order comparison
|
350
350
|
def == other
|
351
|
-
|
352
|
-
|
353
|
-
(
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
351
|
+
super(other) ||
|
352
|
+
other.is_a?(self.class) &&
|
353
|
+
(perm_id && other.perm_id && perm_id == other.perm_id ||
|
354
|
+
local_id == other.local_id && # ((p __LINE__)||true) &&
|
355
|
+
(client_id == other.client_id || client_id == 0 || other.client_id == 0) &&
|
356
|
+
parent_id == other.parent_id &&
|
357
|
+
tif == other.tif &&
|
358
|
+
action == other.action &&
|
359
|
+
order_type == other.order_type &&
|
360
|
+
quantity == other.quantity &&
|
361
|
+
(limit_price == other.limit_price || # TODO Floats should be Decimals!
|
362
|
+
(limit_price - other.limit_price).abs < 0.00001) &&
|
363
|
+
aux_price == other.aux_price &&
|
364
|
+
origin == other.origin &&
|
365
|
+
designated_location == other.designated_location &&
|
366
|
+
exempt_code == other.exempt_code &&
|
367
|
+
what_if == other.what_if &&
|
368
|
+
algo_strategy == other.algo_strategy &&
|
369
|
+
algo_params == other.algo_params)
|
370
|
+
|
371
|
+
# TODO: compare more attributes!
|
372
|
+
end
|
371
373
|
|
372
374
|
def to_s #human
|
373
375
|
"<Order:" + instance_variables.map do |key|
|
@@ -57,7 +57,7 @@ module IB
|
|
57
57
|
# (simulated orders) or an exchange (native orders) but that currently
|
58
58
|
# the order is inactive due to system, exchange or other issues.
|
59
59
|
|
60
|
-
|
60
|
+
validates_format_of :status, :without => /^$/, :message => 'must not be empty'
|
61
61
|
validates_numericality_of :price, :average_price, :allow_nil => true
|
62
62
|
validates_numericality_of :local_id, :perm_id, :client_id, :parent_id, :filled,
|
63
63
|
:remaining, :only_integer => true, :allow_nil => true
|
@@ -94,7 +94,9 @@ module IB
|
|
94
94
|
|
95
95
|
# Comparison
|
96
96
|
def == other
|
97
|
-
|
97
|
+
|
98
|
+
super(other) ||
|
99
|
+
other.is_a?(self.class) &&
|
98
100
|
status == other.status &&
|
99
101
|
local_id == other.local_id &&
|
100
102
|
perm_id == other.perm_id &&
|
data/lib/models/ib/underlying.rb
CHANGED
@@ -4,9 +4,6 @@ module IB
|
|
4
4
|
class Underlying < IB::Model
|
5
5
|
include BaseProperties
|
6
6
|
|
7
|
-
attr_accessible :created_at, :updated_at
|
8
|
-
attr_protected :id
|
9
|
-
|
10
7
|
has_one :contract
|
11
8
|
|
12
9
|
prop :con_id, # Id of the Underlying Contract
|
@@ -26,7 +23,9 @@ module IB
|
|
26
23
|
|
27
24
|
# Comparison
|
28
25
|
def == other
|
29
|
-
|
26
|
+
super(other) ||
|
27
|
+
other.is_a?(self.class) &&
|
28
|
+
con_id == other.con_id && delta == other.delta && price == other.price
|
30
29
|
end
|
31
30
|
|
32
31
|
end # class Underlying
|
data/spec/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
## RUNNING TEST SUITE:
|
2
2
|
|
3
|
-
The gem comes with a spec
|
4
|
-
with your specific TWS/Gateway installation. The test
|
3
|
+
The gem comes with a spec suite that may be used to test ib-ruby compatibility
|
4
|
+
with your specific TWS/Gateway installation. The test suite should be run ONLY
|
5
5
|
against your IB paper trading account. Running it against live account may result
|
6
6
|
in financial losses.
|
7
7
|
|
@@ -15,7 +15,7 @@ to running tests, otherwise some tests will fail. Use 'bin/cancel_orders' script
|
|
15
15
|
bulk cancelling of open orders before running tests as needed.
|
16
16
|
|
17
17
|
By default, specs suppress logging output that is normally produced by IB::Connection.
|
18
|
-
This may make it difficult to debug a failing spec.
|
18
|
+
This may make it difficult to debug a failing spec. The following option will switch on verbose
|
19
19
|
output (both logger output and content of all received IB messages is dumped). Do not use
|
20
20
|
this mode to run a whole spec - you will be swamped! Use it to debug specific failing specs
|
21
21
|
only:
|
@@ -53,22 +53,24 @@ To run specs with Dummy Rails application, use:
|
|
53
53
|
$ rspec -rdummy rails_spec
|
54
54
|
$ rspec -rdummy [spec/specific_spec.rb]
|
55
55
|
|
56
|
-
Other
|
56
|
+
Other suite switches described in previous section should work with Rails as well.
|
57
57
|
|
58
58
|
## PROBLEMS WHILE RUNNING THE SPECS:
|
59
59
|
|
60
|
-
Some of the specs may randomly fail from time to time when you are running the spec
|
60
|
+
Some of the specs may randomly fail from time to time when you are running the spec suite
|
61
61
|
against your IB paper account. This happens because these specs depend on live connection
|
62
62
|
to IB, which is inherently non-deterministic. Anything happening along the way - network
|
63
63
|
delay, problems with IB data farms, even high CPU load on your machine - may delay the
|
64
|
-
expected
|
64
|
+
expected response, so that the spec times out or does not find expected data. For example,
|
65
65
|
IB historical data farm is known to disappear from time to time, so any specs related to
|
66
66
|
historical data will fail while this outage lasts.
|
67
67
|
|
68
68
|
If you experience such intermittent spec failures, it is recommended that you run the
|
69
|
-
failing specs several times, possibly with a delay of 10-20 minutes.
|
70
|
-
|
71
|
-
|
69
|
+
failing specs several times, possibly with a delay of 10-20 minutes. Sometimes it helps
|
70
|
+
to restart your TWS or Gateway, as it may be stuck in inconsistent state, preventing
|
71
|
+
test suite from running properly. Start debugging the specs only if they are failing
|
72
|
+
regularly. Otherwise, you may just waste time chasing an artifact of unreliable IB
|
73
|
+
connection, rather than some real problem with the specs.
|
72
74
|
|
73
75
|
# WRITING YOUR OWN INTEGRATION SPECS
|
74
76
|
|
@@ -112,7 +114,7 @@ You can easily create your own integration specs. Pattern for writing specs is l
|
|
112
114
|
messages from and log entries. If your do not do this, your examples become coupled.
|
113
115
|
|
114
116
|
11. If you want to see exactly what's going on inside ib-ruby while your examples are
|
115
|
-
running, run your specs with '-rv' option to switch on verbose
|
117
|
+
running, run your specs with '-rv' option to switch on verbose output mode.
|
116
118
|
Now you will see all the messages received and log entries made as as result of
|
117
119
|
your examples running. Be warned, output is very verbose, so don't run big chunk of
|
118
120
|
specs with -rv option or you will be swamped!.
|
@@ -45,5 +45,15 @@ describe IB::Symbols do
|
|
45
45
|
fx.description.should == "British Pounds"
|
46
46
|
end
|
47
47
|
|
48
|
+
it 'raises an error if requested contract symbol is not defined' do
|
49
|
+
expect {stk = IB::Symbols::Stocks[:xyz]}.
|
50
|
+
to raise_error "Unknown symbol :xyz, please pre-define it in lib/ib/symbols/stocks.rb"
|
51
|
+
expect {opt = IB::Symbols::Options[:xyz20]}.
|
52
|
+
to raise_error "Unknown symbol :xyz20, please pre-define it in lib/ib/symbols/options.rb"
|
53
|
+
expect {fx = IB::Symbols::Forex[:abcdef]}.
|
54
|
+
to raise_error "Unknown symbol :abcdef, please pre-define it in lib/ib/symbols/forex.rb"
|
55
|
+
expect {fut = IB::Symbols::Futures[:abc]}.
|
56
|
+
to raise_error "Unknown symbol :abc, please pre-define it in lib/ib/symbols/futures.rb"
|
57
|
+
end
|
48
58
|
|
49
59
|
end # describe IB::Symbols
|
data/spec/integration_helper.rb
CHANGED
@@ -9,7 +9,7 @@ shared_examples_for 'Received Market Data' do
|
|
9
9
|
it { should be_warning }
|
10
10
|
it { should_not be_error }
|
11
11
|
its(:code) { should be_an Integer }
|
12
|
-
its(:message) { should =~ /
|
12
|
+
its(:message) { should =~ /data farm connection is OK/ }
|
13
13
|
its(:to_human) { should =~ /TWS Warning/ }
|
14
14
|
end
|
15
15
|
|
data/spec/model_helper.rb
CHANGED
@@ -71,14 +71,14 @@ def buy_sell_assigns
|
|
71
71
|
{['BOT', 'BUY', 'Buy', 'buy', :BUY, :BOT, :Buy, :buy, 'B', :b] => :buy,
|
72
72
|
['SELL', 'SLD', 'Sel', 'sell', :SELL, :SLD, :Sell, :sell, 'S', :S] => :sell,
|
73
73
|
[1, nil, 'ASK', :foo] => /should be buy.sell/
|
74
|
-
|
74
|
+
}
|
75
75
|
end
|
76
76
|
|
77
77
|
def buy_sell_short_assigns
|
78
78
|
buy_sell_assigns.merge(
|
79
|
-
|
80
|
-
|
81
|
-
|
79
|
+
['SSHORT', 'Short', 'short', :SHORT, :short, 'T', :T] => :short,
|
80
|
+
['SSHORTX', 'Shortextemt', 'shortx', :short_exempt, 'X', :X] => :short_exempt,
|
81
|
+
[1, nil, 'ASK', :foo] => /should be buy.sell.short/)
|
82
82
|
end
|
83
83
|
|
84
84
|
def test_assigns cases, prop, name
|
@@ -96,7 +96,7 @@ def test_assigns cases, prop, name
|
|
96
96
|
|
97
97
|
it "#{prop} = #{value.inspect} #=> raises #{result}" do
|
98
98
|
expect { subject.send "#{prop}=", value }.
|
99
|
-
|
99
|
+
to raise_error result
|
100
100
|
end
|
101
101
|
|
102
102
|
when Regexp # ... Non-exceptional error, making model invalid
|
@@ -106,7 +106,7 @@ def test_assigns cases, prop, name
|
|
106
106
|
expect { subject.send "#{prop}=", value }.to_not raise_error
|
107
107
|
|
108
108
|
subject.valid? # just triggers validation
|
109
|
-
|
109
|
+
#pp subject.errors.messages
|
110
110
|
|
111
111
|
subject.errors.messages.should have_key name
|
112
112
|
subject.should be_invalid
|
@@ -198,7 +198,7 @@ shared_examples_for 'Model instantiated empty' do
|
|
198
198
|
|
199
199
|
it 'sets all properties to defaults' do
|
200
200
|
subject.default_attributes.each do |name, value|
|
201
|
-
#p name, value
|
201
|
+
# p name, subject.send(name), value
|
202
202
|
case value
|
203
203
|
when Time
|
204
204
|
subject.send(name).should be_a Time
|
@@ -216,8 +216,9 @@ shared_examples_for 'Model instantiated with properties' do
|
|
216
216
|
let(:init_with_props?) { true }
|
217
217
|
|
218
218
|
it 'auto-assigns all properties given to initializer' do
|
219
|
+
# p subject
|
219
220
|
props.each do |name, value|
|
220
|
-
#p
|
221
|
+
# p name, subject.send(name), value
|
221
222
|
subject.send(name).should == value
|
222
223
|
end
|
223
224
|
end
|
@@ -1,31 +1,32 @@
|
|
1
1
|
require 'model_helper'
|
2
2
|
|
3
3
|
describe IB::ComboLeg,
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
4
|
+
:props =>
|
5
|
+
{:con_id => 81032967,
|
6
|
+
:ratio => 2,
|
7
|
+
:side => :buy,
|
8
|
+
:exchange => 'CBOE',
|
9
|
+
:open_close => :open,
|
10
|
+
:short_sale_slot => :broker,
|
11
|
+
:designated_location => '',
|
12
|
+
:exempt_code => -1},
|
13
|
+
|
14
|
+
:human => "<ComboLeg: buy 2 con_id 81032967 at CBOE>",
|
15
|
+
|
16
|
+
:errors => {:ratio => ["is not a number"],
|
17
|
+
:side => ["should be buy/sell/short"]},
|
18
|
+
|
19
|
+
:assigns =>
|
20
|
+
{:open_close => open_close_assigns,
|
21
|
+
:side => buy_sell_short_assigns,
|
22
|
+
:short_sale_slot => codes_and_values_for(:short_sale_slot),
|
23
|
+
:designated_location =>
|
24
|
+
{[42, 'FOO', :bar] => /should be blank or orders will be rejected/},
|
25
|
+
},
|
26
|
+
|
27
|
+
:aliases =>
|
28
|
+
{[:side, :action] => buy_sell_short_assigns,
|
29
|
+
} do
|
29
30
|
|
30
31
|
it 'has combined weight accessor' do
|
31
32
|
leg = IB::ComboLeg.new props
|
@@ -49,7 +50,7 @@ describe IB::ComboLeg,
|
|
49
50
|
|
50
51
|
it "serializes extended" do
|
51
52
|
subject.serialize(:extended).should ==
|
52
|
-
|
53
|
+
[81032967, 2, "BUY", "CBOE", 1, 1, '', -1]
|
53
54
|
end
|
54
55
|
end #serialization
|
55
56
|
|
@@ -115,8 +116,8 @@ describe IB::ComboLeg,
|
|
115
116
|
|
116
117
|
@combo.leg_contracts << @google
|
117
118
|
@combo.leg_contracts.should include @google
|
118
|
-
|
119
|
-
|
119
|
+
@combo.valid?.should be_true
|
120
|
+
@combo.save.should be_true
|
120
121
|
|
121
122
|
#combo.legs.should_not be_empty
|
122
123
|
@combo.leg_contracts.should include @google
|