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.
@@ -1,66 +1,59 @@
1
1
  require 'model_helper'
2
2
 
3
- describe IB::Models::Option do # AKA IB::Option
4
-
5
- let(:props) do
6
- {:symbol => 'AAPL',
7
- :expiry => '201301',
8
- :strike => 600.5,
9
- :right => :put,
10
- }
11
- end
3
+ describe IB::Models::Option,
4
+ :human => "<Option: AAPL 201301 put 600.5 SMART >",
12
5
 
13
- let(:human) do
14
- "<Option: AAPL 201301 put 600.5 SMART >"
15
- end
6
+ :errors => {:right => ["should be put or call"],
7
+ :strike => ["must be greater than 0"],
8
+ },
16
9
 
17
- let(:errors) do
18
- {:right => ["should be put or call"],
19
- :strike => ["must be greater than 0"],
20
- }
21
- end
10
+ :props => {:symbol => 'AAPL',
11
+ :expiry => '201301',
12
+ :strike => 600.5,
13
+ :right => :put,
14
+ },
22
15
 
23
- let(:assigns) do
24
- {:expiry =>
25
- {[200609, '200609'] => '200609',
26
- [20060913, '20060913'] => '20060913',
27
- [:foo, 2006, 42, 'bar'] => /should be YYYYMM or YYYYMMDD/},
16
+ :assigns => {
17
+ :local_symbol =>
18
+ {['AAPL 130119C00500000',
19
+ :'AAPL 130119C00500000'] => 'AAPL 130119C00500000',
20
+ 'BAR'=> /invalid OSI code/},
28
21
 
29
- :sec_type =>
30
- {['OPT', :option] => :option,
31
- IB::CODES[:sec_type].reject { |k, _| k == :option }.to_a =>
32
- /should be an option/},
22
+ :expiry =>
23
+ {[200609, '200609'] => '200609',
24
+ [20060913, '20060913'] => '20060913',
25
+ [:foo, 2006, 42, 'bar'] => /should be YYYYMM or YYYYMMDD/},
33
26
 
34
- :right =>
35
- {["PUT", "put", "P", "p", :put] => :put,
36
- ["CALL", "call", "C", "c", :call] => :call,
37
- ['', '0', '?', :none, :foo, 'BAR', 42] => /should be put or call/},
27
+ :sec_type =>
28
+ {['OPT', :option] => :option,
29
+ IB::CODES[:sec_type].reject { |k, _| k == :option }.to_a =>
30
+ /should be an option/},
38
31
 
39
- :exchange => string_upcase_assigns.merge(
40
- [:smart, 'SMART', 'smArt'] => 'SMART'),
32
+ :right =>
33
+ {["PUT", "put", "P", "p", :put] => :put,
34
+ ["CALL", "call", "C", "c", :call] => :call,
35
+ ['', '0', '?', :none, :foo, 'BAR', 42] => /should be put or call/},
41
36
 
42
- :primary_exchange =>string_upcase_assigns.merge(
43
- [:SMART, 'SMART'] => /should not be SMART/),
37
+ :exchange => string_upcase_assigns.merge(
38
+ [:smart, 'SMART', 'smArt'] => 'SMART'),
44
39
 
45
- :multiplier => to_i_assigns,
40
+ :primary_exchange =>string_upcase_assigns.merge(
41
+ [:SMART, 'SMART'] => /should not be SMART/),
46
42
 
47
- :symbol => string_assigns,
43
+ :multiplier => to_i_assigns,
48
44
 
49
- :local_symbol =>
50
- {['AAPL 130119C00500000', :'AAPL 130119C00500000'] => 'AAPL 130119C00500000',
51
- 'BAR'=> /invalid OSI code/},
52
-
53
- :strike => {[0, -30.0] => /must be greater than 0/},
54
- }
55
- end
45
+ :symbol => string_assigns,
56
46
 
57
- context 'using shortest class name without properties' do
58
- subject { IB::Option.new }
59
- it_behaves_like 'Model instantiated empty'
60
- end
47
+ :strike => {[0, -30.0] => /must be greater than 0/},
48
+ } do # AKA IB::Option
61
49
 
62
- it_behaves_like 'Model'
63
50
  it_behaves_like 'Self-equal Model'
51
+ it_behaves_like 'Model with invalid defaults'
52
+
53
+ it 'has class name shortcut' do
54
+ IB::Option.should == IB::Models::Option
55
+ IB::Option.new.should == IB::Models::Option.new
56
+ end
64
57
 
65
58
  context 'properly initiated' do
66
59
  subject { IB::Option.new props }
@@ -86,6 +79,13 @@ describe IB::Models::Option do # AKA IB::Option
86
79
  end
87
80
  end
88
81
 
82
+ it 'correctly validates OSI symbol' do
83
+ o = IB::Option.new props
84
+ o.should be_valid
85
+ o.local_symbol = "AAPL 130119C00500000"
86
+ o.should be_valid
87
+ end
88
+
89
89
  context '.from_osi class builder' do
90
90
  subject { IB::Option.from_osi 'AAPL130119C00500000' }
91
91
 
@@ -1,98 +1,96 @@
1
1
  require 'model_helper'
2
2
 
3
- describe IB::Models::Order do
4
-
5
- let(:props) do
6
- {:local_id => 23,
7
- :order_ref => 'Test',
8
- :client_id => 1111,
9
- :perm_id => 173276893,
10
- :parent_id => 0,
11
- :side => :buy,
12
- :order_type => :market_if_touched,
13
- :limit_price => 0.1,
14
- :quantity => 100,
15
- :tif => :good_till_cancelled,
16
- :open_close => :close,
17
- :oca_group => '',
18
- :oca_type => :reduce_no_block,
19
- :origin => :firm,
20
- :designated_location => "WHATEVER",
21
- :exempt_code => 123,
22
- :delta_neutral_order_type => :market,
23
- :transmit => false,
24
- :outside_rth => true,
25
- :what_if => true,
26
- :not_held => true}
27
- end
28
-
29
- # TODO: :presents => { Object => "Formatted"}
30
- let(:human) do
31
- "<Order: Test MIT GTC buy 100 New 0.1 #23/173276893 from 1111>"
32
- end
33
-
34
- let(:errors) do
35
- {:side =>["should be buy/sell/short"]}
36
- end
37
-
38
- let(:assigns) do
39
- {[:order_type, :delta_neutral_order_type] => codes_and_values_for(:order_type),
40
-
41
- :open_close =>
42
- {[42, nil, 'Foo', :bar] => /should be same.open.close.unknown/,
43
- ['SAME', 'same', 'S', 's', :same, 0, '0'] => :same,
44
- ['OPEN', 'open', 'O', 'o', :open, 1, '1'] => :open,
45
- ['CLOSE', 'close', 'C', 'c', :close, 2, '2'] => :close,
46
- ['UNKNOWN', 'unknown', 'U', 'u', :unknown, 3, '3'] => :unknown,
47
- },
3
+ describe IB::Models::Order,
4
+ :props =>
5
+ {:local_id => 23,
6
+ :order_ref => 'Test',
7
+ :client_id => 1111,
8
+ :perm_id => 173276893,
9
+ :parent_id => 0,
10
+ :side => :buy,
11
+ :order_type => :market_if_touched,
12
+ :limit_price => 0.1,
13
+ :quantity => 100,
14
+ :tif => :good_till_cancelled,
15
+ :open_close => :close,
16
+ :oca_group => '',
17
+ :oca_type => :reduce_no_block,
18
+ :origin => :firm,
19
+ :designated_location => "WHATEVER",
20
+ :exempt_code => 123,
21
+ :delta_neutral_order_type => :market,
22
+ :transmit => false,
23
+ :outside_rth => true,
24
+ :what_if => true,
25
+ :not_held => true},
26
+
27
+ # TODO: :presents => { Object => "Formatted"}
28
+ :human => "<Order: Test MIT GTC buy 100 New 0.1 #23/173276893 from 1111>",
29
+
30
+ :errors => {:side =>["should be buy/sell/short"]},
31
+
32
+ :assigns =>
33
+ {[:order_type, :delta_neutral_order_type] => codes_and_values_for(:order_type),
34
+
35
+ :open_close =>
36
+ {[42, nil, 'Foo', :bar] => /should be same.open.close.unknown/,
37
+ ['SAME', 'same', 'S', 's', :same, 0, '0'] => :same,
38
+ ['OPEN', 'open', 'O', 'o', :open, 1, '1'] => :open,
39
+ ['CLOSE', 'close', 'C', 'c', :close, 2, '2'] => :close,
40
+ ['UNKNOWN', 'unknown', 'U', 'u', :unknown, 3, '3'] => :unknown,
41
+ },
42
+
43
+ [:what_if, :not_held, :outside_rth, :hidden, :transmit, :block_order,
44
+ :sweep_to_fill, :override_percentage_constraints, :all_or_none,
45
+ :etrade_only, :firm_quote_only, :opt_out_smart_routing, :scale_auto_reset,
46
+ :scale_random_percent] => boolean_assigns,
47
+
48
+ [:local_id, :perm_id, :parent_id] => numeric_or_nil_assigns,
49
+ },
50
+
51
+ :aliases =>
52
+ {[:side, :action] => buy_sell_short_assigns,
53
+ [:quantity, :total_quantity] => numeric_or_nil_assigns,
54
+ },
55
+
56
+ :collections =>
57
+ {:order_states =>[{:status => :Foo},
58
+ {:status => 'Bar'},],
59
+
60
+ :executions =>
61
+ [{:local_id => 23,
62
+ :client_id => 1111,
63
+ :perm_id => 173276893,
64
+ :exchange => "IDEALPRO",
65
+ :exec_id => "0001f4e8.4f5d48f1.01.01",
66
+ :price => 0.1,
67
+ :average_price => 0.1,
68
+ :shares => 40,
69
+ :cumulative_quantity => 40,
70
+ :side => :buy,
71
+ :time => "20120312 15:41:09"},
72
+
73
+ {:local_id => 23,
74
+ :client_id => 1111,
75
+ :perm_id => 173276893,
76
+ :exchange => "IDEALPRO",
77
+ :exec_id => "0001f4e8.4f5d48f1.01.02",
78
+ :price => 0.1,
79
+ :average_price => 0.1,
80
+ :shares => 60,
81
+ :cumulative_quantity => 100,
82
+ :side => :buy,
83
+ :time => "20120312 15:41:10"}]
84
+ } do
48
85
 
49
- [:what_if, :not_held, :outside_rth, :hidden, :transmit, :block_order,
50
- :sweep_to_fill, :override_percentage_constraints, :all_or_none,
51
- :etrade_only, :firm_quote_only, :opt_out_smart_routing, :scale_auto_reset,
52
- :scale_random_percent] => boolean_assigns,
53
-
54
- [:local_id, :perm_id, :parent_id] => numeric_or_nil_assigns,
55
- }
56
- end
57
-
58
- let(:aliases) do
59
- {[:side, :action] => buy_sell_short_assigns,
60
- [:quantity, :total_quantity] => numeric_or_nil_assigns,
61
- }
62
- end
86
+ it_behaves_like 'Self-equal Model'
87
+ it_behaves_like 'Model with invalid defaults'
63
88
 
64
- let(:collections) do
65
- {:order_states => [IB::OrderState.new(:status => :Foo),
66
- IB::OrderState.new(:status => 'Bar'),],
67
-
68
- :executions => [IB::Execution.new(:local_id => 23,
69
- :client_id => 1111,
70
- :perm_id => 173276893,
71
- :exchange => "IDEALPRO",
72
- :exec_id => "0001f4e8.4f5d48f1.01.01",
73
- :price => 0.1,
74
- :average_price => 0.1,
75
- :shares => 40,
76
- :cumulative_quantity => 40,
77
- :side => :buy,
78
- :time => "20120312 15:41:09"),
79
- IB::Execution.new(:local_id => 23,
80
- :client_id => 1111,
81
- :perm_id => 173276893,
82
- :exchange => "IDEALPRO",
83
- :exec_id => "0001f4e8.4f5d48f1.01.02",
84
- :price => 0.1,
85
- :average_price => 0.1,
86
- :shares => 60,
87
- :cumulative_quantity => 100,
88
- :side => :buy,
89
- :time => "20120312 15:41:10")]
90
- }
89
+ it 'has class name shortcut' do
90
+ IB::Order.should == IB::Models::Order
91
+ IB::Order.new.should == IB::Models::Order.new
91
92
  end
92
93
 
93
- it_behaves_like 'Model'
94
- it_behaves_like 'Self-equal Model'
95
-
96
94
  context 'Order associations' do
97
95
  after(:all) { DatabaseCleaner.clean }
98
96
 
@@ -129,12 +127,12 @@ describe IB::Models::Order do
129
127
  subject.maint_margin.should be_nil
130
128
  subject.equity_with_loan.should be_nil
131
129
  # Properties arriving via OrderStatus message
132
- subject.filled.should == 0
133
- subject.remaining.should == 0
134
- subject.price.should == 0
135
- subject.last_fill_price.should == 0
136
- subject.average_price.should == 0
137
- subject.average_fill_price.should == 0
130
+ subject.filled.should == 0
131
+ subject.remaining.should == 0
132
+ subject.price.should == 0
133
+ subject.last_fill_price.should == 0
134
+ subject.average_price.should == 0
135
+ subject.average_fill_price.should == 0
138
136
  subject.why_held.should be_nil
139
137
  # Testing Order state
140
138
  subject.should be_new
@@ -1,77 +1,64 @@
1
1
  require 'model_helper'
2
2
 
3
- describe IB::Models::OrderState do
3
+ describe IB::Models::OrderState,
4
+ :props =>
5
+ {:local_id => 23,
6
+ :perm_id => 173276893,
7
+ :client_id => 1111,
8
+ :parent_id => 0,
9
+ :filled => 3,
10
+ :remaining => 2,
11
+ :last_fill_price => 0.5,
12
+ :average_fill_price => 0.55,
13
+ :why_held => 'child',
14
+
15
+ :init_margin => 500.0,
16
+ :maint_margin => 500.0,
17
+ :equity_with_loan => 750.0,
18
+ :commission_currency => 'USD',
19
+ :commission => 1.2,
20
+ :min_commission => 1,
21
+ :max_commission => 1.5,
22
+ :status => 'PreSubmitted',
23
+ :warning_text => 'Oh noes!',
24
+ },
25
+ :human =>
26
+ "<OrderState: PreSubmitted #23/173276893 from 1111 filled 3/2 at 0.5/0.55 margin 500.0/500.0 equity 750.0 fee 1.2 why_held child warning Oh noes!>",
27
+ :errors =>
28
+ {:status => ["must not be empty"],
29
+ },
30
+ :assigns =>
31
+ {[:status] =>
32
+ {[nil, ''] => /must not be empty/,
33
+ ['Zorro', :Zorro] => 'Zorro'},
34
+
35
+ :local_id => numeric_or_nil_assigns,
36
+ },
37
+ :aliases =>
38
+ {[:price, :last_fill_price] => float_or_nil_assigns,
39
+ [:average_price, :average_fill_price] => float_or_nil_assigns,
40
+ } do
4
41
 
5
- let(:props) do
6
- {:local_id => 23,
7
- :perm_id => 173276893,
8
- :client_id => 1111,
9
- :parent_id => 0,
10
- :filled => 3,
11
- :remaining => 2,
12
- :last_fill_price => 0.5,
13
- :average_fill_price => 0.55,
14
- :why_held => 'child',
15
-
16
- :init_margin => 500.0,
17
- :maint_margin => 500.0,
18
- :equity_with_loan => 750.0,
19
- :commission_currency => 'USD',
20
- :commission => 1.2,
21
- :min_commission => 1,
22
- :max_commission => 1.5,
23
- :status => 'PreSubmitted',
24
- :warning_text => 'Oh noes!',
25
- }
26
- end
27
-
28
- # TODO: :presents => { Object => "Formatted"}
29
- let(:human) do
30
- "<OrderState: PreSubmitted #23/173276893 from 1111 filled 3/2 at 0.5/0.55 margin 500.0/500.0 equity 750.0 fee 1.2 why_held child warning Oh noes!>"
31
- end
32
-
33
- let(:errors) do
34
- {:status => ["must not be empty"],
35
- }
36
- end
37
-
38
- let(:assigns) do
39
- {[:status] =>
40
- {[nil, ''] => /must not be empty/,
41
- ['Zorro', :Zorro] => 'Zorro'},
42
-
43
- :local_id => numeric_or_nil_assigns,
44
- }
45
- end
42
+ it_behaves_like 'Self-equal Model'
43
+ it_behaves_like 'Model with invalid defaults'
46
44
 
47
- let(:aliases) do
48
- {[:price, :last_fill_price] => float_or_nil_assigns,
49
- [:average_price, :average_fill_price] => float_or_nil_assigns,
50
- }
45
+ it 'has class name shortcut' do
46
+ IB::OrderState.should == IB::Models::OrderState
47
+ IB::OrderState.new.should == IB::Models::OrderState.new
51
48
  end
52
49
 
53
- it_behaves_like 'Model'
54
- it_behaves_like 'Self-equal Model'
55
-
56
50
  context '#update_missing' do
57
51
  let(:nil_state) { IB::OrderState.new(:filled => nil, :remaining => nil,
58
52
  :price => nil, :average_price => nil) }
59
53
  context 'updating with Hash' do
60
-
61
54
  subject { nil_state.update_missing(props) }
62
-
63
55
  it_behaves_like 'Model instantiated with properties'
64
-
65
56
  end
66
57
 
67
58
  context 'updating with Model' do
68
-
69
59
  subject { nil_state.update_missing(IB::OrderState.new(props)) }
70
-
71
60
  it_behaves_like 'Model instantiated with properties'
72
-
73
61
  end
74
-
75
62
  end
76
63
 
77
64
  it 'has extra test methods' do
@@ -1,36 +1,29 @@
1
1
  require 'model_helper'
2
2
 
3
- describe IB::Models::Underlying do # AKA IB::Underlying
3
+ describe IB::Models::Underlying,
4
+ :props =>
5
+ {:con_id => 234567,
6
+ :delta => 0.55,
7
+ :price => 20.5,
8
+ },
4
9
 
5
- let(:props) do
6
- {:con_id => 234567,
7
- :delta => 0.55,
8
- :price => 20.5,
9
- }
10
- end
10
+ :human => /<Underlying: con_id: 234567 .*delta: 0.55 price: 20.5.*>/,
11
11
 
12
- let(:human) do
13
- /<Underlying: con_id: 234567 .*delta: 0.55 price: 20.5.*>/
14
- end
12
+ :errors =>
13
+ {:delta => ['is not a number'],
14
+ :price => ['is not a number'],
15
+ },
15
16
 
16
- let(:errors) do
17
- {:delta => ['is not a number'],
18
- :price => ['is not a number'],
19
- }
20
- end
17
+ :assigns =>
18
+ {[:con_id, :delta, :price] => numeric_assigns,
21
19
 
22
- let(:assigns) do
23
- {[:con_id, :delta, :price] => numeric_assigns,
24
- }
25
- end
20
+ } do # AKA IB::Underlying
26
21
 
27
- it_behaves_like 'Model'
28
22
  it_behaves_like 'Self-equal Model'
23
+ it_behaves_like 'Model with invalid defaults'
29
24
 
30
- context 'using shortest class name without properties' do
31
- subject { IB::Underlying.new }
32
- it_behaves_like 'Model instantiated empty'
33
- it_behaves_like 'Self-equal Model'
25
+ it 'has class name shortcut' do
26
+ IB::Underlying.should == IB::Models::Underlying
27
+ IB::Underlying.new.should == IB::Models::Underlying.new
34
28
  end
35
-
36
29
  end # describe IB::Contract
@@ -29,6 +29,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
29
29
  msg = @ib.received[:ContractData].first
30
30
  msg.request_id.should == 111
31
31
  msg.contract.should == @contract
32
+ msg.contract.should be_valid
32
33
  end
33
34
 
34
35
  it 'receives Contract Data with extended fields' do
@@ -79,6 +80,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
79
80
  it 'receives Contract Data for requested contract' do
80
81
  subject.request_id.should == 123
81
82
  subject.contract.should == @contract
83
+ subject.contract.should be_valid
82
84
  end
83
85
 
84
86
  it 'receives Contract Data with extended fields' do
@@ -127,6 +129,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
127
129
  it 'receives Contract Data for requested contract' do
128
130
  subject.request_id.should == 135
129
131
  subject.contract.should == @contract
132
+ subject.contract.should be_valid
130
133
  end
131
134
 
132
135
  it 'receives Contract Data with extended fields' do
@@ -172,6 +175,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
172
175
  it 'receives Contract Data for requested contract' do
173
176
  subject.request_id.should == 147
174
177
  subject.contract.should == @contract
178
+ subject.contract.should be_valid
175
179
  end
176
180
 
177
181
  it 'receives Contract Data with extended fields' do