ib-ruby 0.7.11 → 0.7.12
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.
- 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
|