ib-ruby 0.7.11 → 0.7.12
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +4 -0
- data/VERSION +1 -1
- data/db/migrate/121_add_order_states.rb +6 -6
- data/db/migrate/141_add_combo_legs.rb +7 -6
- data/lib/ib-ruby/models/bag.rb +2 -7
- data/lib/ib-ruby/models/combo_leg.rb +8 -4
- data/lib/ib-ruby/models/contract.rb +23 -16
- data/lib/ib-ruby/models/model.rb +3 -3
- data/lib/ib-ruby/models/model_properties.rb +50 -50
- data/lib/ib-ruby/models/option.rb +1 -1
- data/spec/db_helper.rb +57 -54
- data/spec/ib-ruby/models/bag_spec.rb +38 -51
- data/spec/ib-ruby/models/bar_spec.rb +36 -35
- data/spec/ib-ruby/models/combo_leg_spec.rb +108 -31
- data/spec/ib-ruby/models/contract_detail_spec.rb +39 -47
- data/spec/ib-ruby/models/contract_spec.rb +57 -67
- data/spec/ib-ruby/models/execution_spec.rb +53 -56
- data/spec/ib-ruby/models/option_spec.rb +48 -48
- data/spec/ib-ruby/models/order_spec.rb +93 -95
- data/spec/ib-ruby/models/order_state_spec.rb +43 -56
- data/spec/ib-ruby/models/underlying_spec.rb +18 -25
- data/spec/integration/contract_info_spec.rb +4 -0
- data/spec/model_helper.rb +77 -32
- data/spec/test.rb +61 -0
- metadata +14 -34
@@ -1,40 +1,41 @@
|
|
1
1
|
require 'model_helper'
|
2
2
|
|
3
|
-
describe IB::Models::Bar
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
describe IB::Models::Bar,
|
4
|
+
:props =>
|
5
|
+
{:open => 1.31,
|
6
|
+
:high => 1.35,
|
7
|
+
:low => 1.30,
|
8
|
+
:close => 1.33,
|
9
|
+
:wap => 1.32,
|
10
|
+
:volume => 20000,
|
11
|
+
:has_gaps => true,
|
12
|
+
:trades => 50,
|
13
|
+
:time => "20120312 15:41:09",
|
14
|
+
},
|
15
|
+
|
16
|
+
:human =>
|
17
|
+
"<Bar: 20120312 15:41:09 wap 1.32 OHLC 1.31 1.35 1.3 1.33 trades 50 vol 20000 gaps true>",
|
18
|
+
|
19
|
+
:errors =>
|
20
|
+
{:close => ["is not a number"],
|
21
|
+
:high => ["is not a number"],
|
22
|
+
:low => ["is not a number"],
|
23
|
+
:open => ["is not a number"],
|
24
|
+
:volume => ["is not a number"]},
|
25
|
+
|
26
|
+
:assigns =>
|
27
|
+
{:has_gaps => {[1, true] => true, [0, false] => false},
|
28
|
+
|
29
|
+
[:open, :high, :low, :close, :volume] =>
|
30
|
+
{[:foo, 'BAR', nil] => /is not a number/}
|
31
|
+
} do # AKA IB::Bar
|
32
|
+
|
33
|
+
it_behaves_like 'Model with invalid defaults'
|
34
|
+
it_behaves_like 'Self-equal Model'
|
35
|
+
|
36
|
+
it 'has class name shortcut' do
|
37
|
+
IB::Bar.should == IB::Models::Bar
|
38
|
+
IB::Bar.new.should == IB::Models::Bar.new
|
16
39
|
end
|
17
40
|
|
18
|
-
let(:errors) do
|
19
|
-
{:close => ["is not a number"],
|
20
|
-
:high => ["is not a number"],
|
21
|
-
:low => ["is not a number"],
|
22
|
-
:open => ["is not a number"],
|
23
|
-
:volume => ["is not a number"]}
|
24
|
-
end
|
25
|
-
|
26
|
-
let(:assigns) do
|
27
|
-
{:has_gaps => {[1, true] => true, [0, false] => false},
|
28
|
-
|
29
|
-
[:open, :high, :low, :close, :volume] =>
|
30
|
-
{[:foo, 'BAR', nil] => /is not a number/}
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
let(:human) do
|
35
|
-
"<Bar: 20120312 15:41:09 wap 1.32 OHLC 1.31 1.35 1.3 1.33 trades 50 vol 20000 gaps true>"
|
36
|
-
end
|
37
|
-
|
38
|
-
it_behaves_like 'Model'
|
39
|
-
|
40
41
|
end # describe IB::Bar
|
@@ -1,39 +1,31 @@
|
|
1
1
|
require 'model_helper'
|
2
2
|
|
3
|
-
describe IB::Models::ComboLeg
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:exempt_code => -1}
|
14
|
-
end
|
3
|
+
describe IB::Models::ComboLeg,
|
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 => nil,
|
12
|
+
:exempt_code => -1},
|
15
13
|
|
16
|
-
|
17
|
-
"<ComboLeg: buy 2 con_id 81032967 at CBOE>"
|
18
|
-
end
|
14
|
+
:human => "<ComboLeg: buy 2 con_id 81032967 at CBOE>",
|
19
15
|
|
20
|
-
|
21
|
-
|
22
|
-
:side => ["should be buy/sell/short"]}
|
23
|
-
end
|
16
|
+
:errors => {:ratio => ["is not a number"],
|
17
|
+
:side => ["should be buy/sell/short"]},
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
19
|
+
:assigns =>
|
20
|
+
{:open_close => open_close_assigns,
|
21
|
+
:side => buy_sell_short_assigns,
|
22
|
+
:designated_location =>
|
23
|
+
{[42, 'FOO', :bar] => /should be blank or orders will be rejected/},
|
24
|
+
},
|
32
25
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
26
|
+
:aliases =>
|
27
|
+
{[:side, :action] => buy_sell_short_assigns,
|
28
|
+
} do
|
37
29
|
|
38
30
|
it 'has combined weight accessor' do
|
39
31
|
leg = IB::ComboLeg.new props
|
@@ -45,9 +37,15 @@ describe IB::Models::ComboLeg do
|
|
45
37
|
leg.ratio.should == 5
|
46
38
|
end
|
47
39
|
|
48
|
-
it_behaves_like 'Model'
|
40
|
+
it_behaves_like 'Model with valid defaults'
|
49
41
|
it_behaves_like 'Self-equal Model'
|
50
42
|
|
43
|
+
it 'has class name shortcut' do
|
44
|
+
IB::ComboLeg.should == IB::Models::ComboLeg
|
45
|
+
IB::ComboLeg.new.should == IB::Models::ComboLeg.new
|
46
|
+
end
|
47
|
+
|
48
|
+
|
51
49
|
context "serialization" do
|
52
50
|
subject { IB::ComboLeg.new props }
|
53
51
|
|
@@ -61,4 +59,83 @@ describe IB::Models::ComboLeg do
|
|
61
59
|
end
|
62
60
|
end #serialization
|
63
61
|
|
62
|
+
context 'DB backed associations', :db => true do
|
63
|
+
before(:all) { DatabaseCleaner.clean }
|
64
|
+
|
65
|
+
#before(:all) do
|
66
|
+
# @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
67
|
+
# @ib.wait_for :ManagedAccounts
|
68
|
+
# @butterfly = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
|
69
|
+
# close_connection
|
70
|
+
#end
|
71
|
+
|
72
|
+
before(:each) do
|
73
|
+
@combo = IB::Bag.new
|
74
|
+
|
75
|
+
@google = IB::Option.new(:symbol => 'GOOG',
|
76
|
+
:expiry => 201301,
|
77
|
+
:right => :call,
|
78
|
+
:strike => 500)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'saves associated BAG and leg Contract' do
|
82
|
+
|
83
|
+
combo_leg = IB::ComboLeg.new :con_id => 454, :weight => 3
|
84
|
+
combo_leg.should be_valid
|
85
|
+
|
86
|
+
# Assigning both associations for a join model
|
87
|
+
combo_leg.combo = @combo
|
88
|
+
combo_leg.leg_contract = @google
|
89
|
+
|
90
|
+
combo_leg.save.should == true
|
91
|
+
@combo.should_not be_new_record
|
92
|
+
@google.should_not be_new_record
|
93
|
+
|
94
|
+
combo_leg.combo.should == @combo
|
95
|
+
combo_leg.leg_contract.should == @google
|
96
|
+
@combo.legs.should include combo_leg
|
97
|
+
@combo.leg_contracts.should include @google
|
98
|
+
@google.leg.should == combo_leg
|
99
|
+
@google.combo.should == @combo
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'loads ComboLeg together with associated BAG and leg Contract' do
|
104
|
+
|
105
|
+
combo_leg = IB::ComboLeg.where(:con_id => 454).first
|
106
|
+
combo_leg.should be_valid
|
107
|
+
|
108
|
+
#p combo_leg.combo.attributes
|
109
|
+
#p combo_leg.combo.strike
|
110
|
+
#p combo_leg.combo.include_expired
|
111
|
+
|
112
|
+
combo = combo_leg.combo
|
113
|
+
google = combo_leg.leg_contract
|
114
|
+
#combo.should == @combo # NOT equal, different legs
|
115
|
+
google.should == @google
|
116
|
+
|
117
|
+
combo.legs.should include combo_leg
|
118
|
+
combo.leg_contracts.should include google
|
119
|
+
google.leg.should == combo_leg
|
120
|
+
google.combo.should == combo
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
it 'creates ComboLeg indirectly through associated BAG and leg Contract' do
|
125
|
+
|
126
|
+
@combo.leg_contracts << @google
|
127
|
+
@combo.leg_contracts.should include @google
|
128
|
+
p @combo.valid?
|
129
|
+
p @combo.save
|
130
|
+
|
131
|
+
#combo.legs.should_not be_empty
|
132
|
+
@combo.leg_contracts.should include @google
|
133
|
+
@google.combo.should == @combo
|
134
|
+
|
135
|
+
leg = @combo.legs.first
|
136
|
+
@google.leg.should == leg
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
64
141
|
end # describe IB::Models::Contract::ComboLeg
|
@@ -1,54 +1,46 @@
|
|
1
1
|
require 'model_helper'
|
2
2
|
|
3
|
-
describe IB::Models::ContractDetail
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
let(:aliases) do
|
41
|
-
{[:contract, :summary] => {IB::Contract.new => IB::Contract.new}
|
42
|
-
}
|
43
|
-
end
|
44
|
-
|
45
|
-
it_behaves_like 'Model'
|
3
|
+
describe IB::Models::ContractDetail,
|
4
|
+
|
5
|
+
:props =>
|
6
|
+
{:market_name => 'AAPL',
|
7
|
+
:trading_class => 'AAPL',
|
8
|
+
:min_tick => 0.01,
|
9
|
+
:price_magnifier => 1,
|
10
|
+
:order_types => 'ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKET,COND,CONDORDER,DAY,DEACT,DEACTDIS,DEACTEOD,FOK,GAT,GTC,GTD,GTT,HID,ICE,IOC,LIT,LMT,MIT,MKT,MTL,NONALGO,OCA,PAON,POSTONLY,RELSTK,SCALE,SCALERST,SMARTSTG,STP,STPLMT,TRAIL,TRAILLIT,TRAILLMT,TRAILMIT,VOLAT,WHATIF,',
|
11
|
+
:valid_exchanges => 'SMART,AMEX,BATS,BOX,CBOE,CBOE2,IBSX,ISE,MIBSX,NASDAQOM,PHLX,PSE', # The list of exchanges this contract is traded on.
|
12
|
+
:under_con_id => 265598,
|
13
|
+
:long_name => 'APPLE INC',
|
14
|
+
:contract_month => '201301',
|
15
|
+
:industry => 'Technology',
|
16
|
+
:category => 'Computers',
|
17
|
+
:subcategory => 'Computers',
|
18
|
+
:time_zone => 'EST',
|
19
|
+
:trading_hours => '20120422:0930-1600;20120423:0930-1600',
|
20
|
+
:liquid_hours => '20120422:0930-1600;20120423:0930-1600',
|
21
|
+
},
|
22
|
+
|
23
|
+
:human =>/<ContractDetail: callable: false category: Computers contract_month: 201301 convertible: false coupon: 0.0 .*industry: Technology liquid_hours: 20120422:0930-1600;20120423:0930-1600 long_name: APPLE INC market_name: AAPL min_tick: 0.01 next_option_partial: false order_types: ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKET,COND,CONDORDER,DAY,DEACT,DEACTDIS,DEACTEOD,FOK,GAT,GTC,GTD,GTT,HID,ICE,IOC,LIT,LMT,MIT,MKT,MTL,NONALGO,OCA,PAON,POSTONLY,RELSTK,SCALE,SCALERST,SMARTSTG,STP,STPLMT,TRAIL,TRAILLIT,TRAILLMT,TRAILMIT,VOLAT,WHATIF, price_magnifier: 1 puttable: false subcategory: Computers time_zone: EST trading_class: AAPL trading_hours: 20120422:0930-1600;20120423:0930-1600 under_con_id: 265598 .*valid_exchanges: SMART,AMEX,BATS,BOX,CBOE,CBOE2,IBSX,ISE,MIBSX,NASDAQOM,PHLX,PSE>/,
|
24
|
+
|
25
|
+
:errors =>
|
26
|
+
{:time_zone => ['should be XXX'],
|
27
|
+
},
|
28
|
+
|
29
|
+
:assigns =>
|
30
|
+
{[:under_con_id, :min_tick, :coupon] => {123 => 123},
|
31
|
+
[:callable, :puttable, :convertible, :next_option_partial] => boolean_assigns,
|
32
|
+
},
|
33
|
+
|
34
|
+
:aliases =>
|
35
|
+
{[:contract, :summary] => {IB::Contract.new => IB::Contract.new}
|
36
|
+
} do # AKA IB::ContractDetail
|
37
|
+
|
38
|
+
it_behaves_like 'Model with invalid defaults'
|
46
39
|
it_behaves_like 'Self-equal Model'
|
47
40
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
it_behaves_like 'Self-equal Model'
|
41
|
+
it 'has class name shortcut' do
|
42
|
+
IB::ContractDetail.should == IB::Models::ContractDetail
|
43
|
+
IB::ContractDetail.new.should == IB::Models::ContractDetail.new
|
52
44
|
end
|
53
45
|
|
54
46
|
end # describe IB::Contract
|
@@ -1,69 +1,66 @@
|
|
1
1
|
require 'model_helper'
|
2
2
|
require 'combo_helper'
|
3
3
|
|
4
|
-
describe IB::Models::Contract
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
:strike => to_f_assigns,
|
4
|
+
describe IB::Models::Contract,
|
5
|
+
:props =>
|
6
|
+
{:symbol => 'AAPL',
|
7
|
+
:sec_type => :option,
|
8
|
+
:expiry => '201301',
|
9
|
+
:strike => 600.5,
|
10
|
+
:right => :put,
|
11
|
+
:multiplier => 10,
|
12
|
+
:exchange => 'SMART',
|
13
|
+
:currency => 'USD',
|
14
|
+
:local_symbol => 'AAPL 130119C00500000'},
|
15
|
+
|
16
|
+
:human => "<Contract: AAPL option 201301 put 600.5 SMART USD>",
|
17
|
+
|
18
|
+
:errors => {:sec_type => ["should be valid security type"] },
|
19
|
+
|
20
|
+
:assigns =>
|
21
|
+
{:expiry =>
|
22
|
+
{[200609, '200609'] => '200609',
|
23
|
+
[20060913, '20060913'] => '20060913',
|
24
|
+
[:foo, 2006, 42, 'bar'] => /should be YYYYMM or YYYYMMDD/},
|
25
|
+
|
26
|
+
:sec_type => codes_and_values_for(:sec_type).
|
27
|
+
merge([:foo, 'BAR', 42] => /should be valid security type/),
|
28
|
+
|
29
|
+
:sec_id_type =>
|
30
|
+
{[:isin, 'ISIN', 'iSin'] => 'ISIN',
|
31
|
+
[:sedol, :SEDOL, 'sEDoL', 'SEDOL'] => 'SEDOL',
|
32
|
+
[:cusip, :CUSIP, 'Cusip', 'CUSIP'] => 'CUSIP',
|
33
|
+
[:ric, :RIC, 'rIC', 'RIC'] => 'RIC',
|
34
|
+
[nil, ''] => '',
|
35
|
+
[:foo, 'BAR', 'baz'] => /should be valid security identifier/},
|
36
|
+
|
37
|
+
:right =>
|
38
|
+
{["PUT", "put", "P", "p", :put] => :put,
|
39
|
+
["CALL", "call", "C", "c", :call] => :call,
|
40
|
+
['', '0', '?', :none] => :none,
|
41
|
+
[:foo, 'BAR', 42] => /should be put, call or none/},
|
42
|
+
|
43
|
+
:exchange => string_upcase_assigns.merge(
|
44
|
+
[:smart, 'SMART', 'smArt'] => 'SMART'),
|
45
|
+
|
46
|
+
:primary_exchange =>string_upcase_assigns.merge(
|
47
|
+
[:SMART, 'SMART'] => /should not be SMART/),
|
48
|
+
|
49
|
+
:multiplier => to_i_assigns,
|
50
|
+
|
51
|
+
:strike => to_f_assigns,
|
52
|
+
|
53
|
+
:include_expired => boolean_assigns,
|
54
|
+
} do # AKA IB::Contract
|
55
|
+
|
56
|
+
it_behaves_like 'Model with invalid defaults'
|
57
|
+
it_behaves_like 'Self-equal Model'
|
59
58
|
|
60
|
-
|
61
|
-
|
59
|
+
it 'has class name shortcut' do
|
60
|
+
IB::Contract.should == IB::Models::Contract
|
61
|
+
IB::Contract.new.should == IB::Models::Contract.new
|
62
62
|
end
|
63
63
|
|
64
|
-
it_behaves_like 'Model'
|
65
|
-
it_behaves_like 'Self-equal Model'
|
66
|
-
|
67
64
|
context 'testing for Contract type (sec_type)' do
|
68
65
|
|
69
66
|
it 'correctly defines Contract type (sec_type) for Option contract' do
|
@@ -114,13 +111,6 @@ describe IB::Models::Contract do # AKA IB::Contract
|
|
114
111
|
|
115
112
|
end
|
116
113
|
|
117
|
-
context 'using shortest class name without properties' do
|
118
|
-
subject { IB::Contract.new }
|
119
|
-
it_behaves_like 'Model instantiated empty'
|
120
|
-
it_behaves_like 'Self-equal Model'
|
121
|
-
it_behaves_like 'Contract'
|
122
|
-
end
|
123
|
-
|
124
114
|
context "serialization" do
|
125
115
|
before(:all) do
|
126
116
|
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
@@ -1,69 +1,66 @@
|
|
1
1
|
require 'model_helper'
|
2
2
|
|
3
|
-
describe IB::Models::Execution
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
3
|
+
describe IB::Models::Execution,
|
4
|
+
:props =>
|
5
|
+
{:account_name => "DU111110",
|
6
|
+
:client_id => 1111,
|
7
|
+
:exchange => "IDEALPRO",
|
8
|
+
:exec_id => "0001f4e8.4f5d48f1.01.01",
|
9
|
+
:liquidation => true,
|
10
|
+
:local_id => 373,
|
11
|
+
:perm_id => 1695693619,
|
12
|
+
:price => 1.31075,
|
13
|
+
:average_price => 1.31075,
|
14
|
+
:shares => 20000,
|
15
|
+
:cumulative_quantity => 20000,
|
16
|
+
:side => :buy,
|
17
|
+
:time => "20120312 15:41:09",
|
18
|
+
},
|
19
|
+
:human =>
|
20
|
+
"<Execution: 20120312 15:41:09 buy 20000 at 1.31075 on IDEALPRO, " +
|
21
|
+
"cumulative 20000 at 1.31075, ids 373/1695693619/0001f4e8.4f5d48f1.01.01>",
|
22
|
+
:errors =>
|
23
|
+
{:side=>["should be buy/sell/short"],
|
24
|
+
:cumulative_quantity=>["is not a number"],
|
25
|
+
:average_price=>["is not a number"]},
|
26
|
+
|
27
|
+
:assigns =>
|
28
|
+
{[:local_id, :perm_id, :client_id, :cumulative_quantity, :price, :average_price] =>
|
29
|
+
numeric_assigns,
|
30
|
+
:liquidation => boolean_assigns,
|
31
|
+
},
|
32
|
+
|
33
|
+
:aliases =>
|
34
|
+
{[:side, :action] => buy_sell_assigns,
|
35
|
+
[:quantity, :shares] => numeric_assigns,
|
36
|
+
[:account_name, :account_number]=> string_assigns,
|
37
|
+
},
|
38
|
+
|
39
|
+
:associations =>
|
40
|
+
{:order => {:local_id => 23,
|
41
|
+
:perm_id => 173276893,
|
42
|
+
:client_id => 1111,
|
43
|
+
:parent_id => 0,
|
44
|
+
:quantity => 100,
|
45
|
+
:side => :buy,
|
46
|
+
:order_type => :market}
|
47
|
+
} do # AKA IB::Execution
|
48
|
+
|
49
|
+
it_behaves_like 'Model with invalid defaults'
|
50
|
+
it_behaves_like 'Self-equal Model'
|
51
|
+
|
52
|
+
it 'has class name shortcut' do
|
53
|
+
IB::Execution.should == IB::Models::Execution
|
54
|
+
IB::Execution.new.should == IB::Models::Execution.new
|
20
55
|
end
|
21
56
|
|
22
|
-
let(:human) do
|
23
|
-
"<Execution: 20120312 15:41:09 buy 20000 at 1.31075 on IDEALPRO, " +
|
24
|
-
"cumulative 20000 at 1.31075, ids 373/1695693619/0001f4e8.4f5d48f1.01.01>"
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:errors) do
|
28
|
-
{:side=>["should be buy/sell/short"],
|
29
|
-
:cumulative_quantity=>["is not a number"],
|
30
|
-
:average_price=>["is not a number"]}
|
31
|
-
end
|
32
|
-
|
33
|
-
let(:assigns) do
|
34
|
-
{[:local_id, :perm_id, :client_id, :cumulative_quantity, :price, :average_price] =>
|
35
|
-
numeric_assigns,
|
36
|
-
:liquidation => boolean_assigns,
|
37
|
-
}
|
38
|
-
end
|
39
|
-
|
40
|
-
let(:aliases) do
|
41
|
-
{[:side, :action] => buy_sell_assigns,
|
42
|
-
[:quantity, :shares] => numeric_assigns,
|
43
|
-
[:account_name, :account_number]=> string_assigns,
|
44
|
-
}
|
45
|
-
end
|
46
|
-
|
47
|
-
let(:associations) do
|
48
|
-
{:order => IB::Order.new(:local_id => 23,
|
49
|
-
:perm_id => 173276893,
|
50
|
-
:client_id => 1111,
|
51
|
-
:parent_id => 0,
|
52
|
-
:quantity => 100,
|
53
|
-
:side => :buy,
|
54
|
-
:order_type => :market)
|
55
|
-
}
|
56
|
-
end
|
57
|
-
|
58
|
-
it_behaves_like 'Model'
|
59
|
-
|
60
57
|
context 'DB backed associations', :db => true do
|
61
58
|
subject { IB::Execution.new props }
|
62
59
|
|
63
60
|
before(:all) { DatabaseCleaner.clean }
|
64
61
|
|
65
62
|
it 'saves associated order' do
|
66
|
-
order = associations[:order]
|
63
|
+
order = IB::Order.new associations[:order]
|
67
64
|
subject.order = order
|
68
65
|
subject.order.should == order
|
69
66
|
subject.order.should be_new_record
|