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.
@@ -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