ib-ruby 0.7.6 → 0.7.8

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.
Files changed (61) hide show
  1. data/HISTORY +8 -0
  2. data/Rakefile +8 -0
  3. data/VERSION +1 -1
  4. data/bin/fundamental_data +6 -9
  5. data/lib/ib-ruby/connection.rb +16 -19
  6. data/lib/ib-ruby/constants.rb +3 -1
  7. data/lib/ib-ruby/extensions.rb +5 -0
  8. data/lib/ib-ruby/messages/incoming/contract_data.rb +46 -45
  9. data/lib/ib-ruby/messages/incoming/delta_neutral_validation.rb +8 -5
  10. data/lib/ib-ruby/messages/incoming/execution_data.rb +2 -2
  11. data/lib/ib-ruby/messages/incoming/next_valid_id.rb +18 -0
  12. data/lib/ib-ruby/messages/incoming/open_order.rb +23 -16
  13. data/lib/ib-ruby/messages/incoming/order_status.rb +5 -3
  14. data/lib/ib-ruby/messages/incoming/scanner_data.rb +15 -11
  15. data/lib/ib-ruby/messages/incoming.rb +1 -5
  16. data/lib/ib-ruby/messages/outgoing/abstract_message.rb +2 -1
  17. data/lib/ib-ruby/messages/outgoing/place_order.rb +1 -1
  18. data/lib/ib-ruby/messages/outgoing.rb +1 -1
  19. data/lib/ib-ruby/models/bag.rb +59 -0
  20. data/lib/ib-ruby/models/combo_leg.rb +10 -6
  21. data/lib/ib-ruby/models/contract.rb +278 -0
  22. data/lib/ib-ruby/models/contract_detail.rb +70 -0
  23. data/lib/ib-ruby/models/execution.rb +22 -16
  24. data/lib/ib-ruby/models/model.rb +75 -17
  25. data/lib/ib-ruby/models/model_properties.rb +40 -26
  26. data/lib/ib-ruby/models/option.rb +62 -0
  27. data/lib/ib-ruby/models/order.rb +122 -86
  28. data/lib/ib-ruby/models/order_state.rb +11 -12
  29. data/lib/ib-ruby/models/underlying.rb +36 -0
  30. data/lib/ib-ruby/models.rb +1 -4
  31. data/spec/account_helper.rb +2 -1
  32. data/spec/db.rb +1 -1
  33. data/spec/db_helper.rb +105 -0
  34. data/spec/ib-ruby/connection_spec.rb +3 -3
  35. data/spec/ib-ruby/messages/incoming/open_order_spec.rb +5 -5
  36. data/spec/ib-ruby/messages/incoming/order_status_spec.rb +3 -3
  37. data/spec/ib-ruby/models/bag_spec.rb +15 -23
  38. data/spec/ib-ruby/models/bar_spec.rb +0 -5
  39. data/spec/ib-ruby/models/combo_leg_spec.rb +18 -25
  40. data/spec/ib-ruby/models/contract_detail_spec.rb +54 -0
  41. data/spec/ib-ruby/models/contract_spec.rb +25 -37
  42. data/spec/ib-ruby/models/execution_spec.rb +64 -19
  43. data/spec/ib-ruby/models/option_spec.rb +12 -34
  44. data/spec/ib-ruby/models/order_spec.rb +107 -45
  45. data/spec/ib-ruby/models/order_state_spec.rb +12 -12
  46. data/spec/ib-ruby/models/underlying_spec.rb +36 -0
  47. data/spec/integration/contract_info_spec.rb +65 -55
  48. data/spec/integration/fundamental_data_spec.rb +2 -2
  49. data/spec/integration/orders/attached_spec.rb +3 -3
  50. data/spec/integration/orders/combo_spec.rb +3 -3
  51. data/spec/integration/orders/placement_spec.rb +8 -8
  52. data/spec/integration/orders/{execution_spec.rb → trades_spec.rb} +8 -12
  53. data/spec/integration/orders/valid_ids_spec.rb +3 -3
  54. data/spec/message_helper.rb +1 -1
  55. data/spec/model_helper.rb +150 -85
  56. data/spec/order_helper.rb +35 -18
  57. metadata +18 -10
  58. data/lib/ib-ruby/models/contracts/bag.rb +0 -62
  59. data/lib/ib-ruby/models/contracts/contract.rb +0 -320
  60. data/lib/ib-ruby/models/contracts/option.rb +0 -66
  61. data/lib/ib-ruby/models/contracts.rb +0 -27
@@ -6,7 +6,7 @@ shared_examples_for 'OpenOrder message' do
6
6
  its(:message_id) { should == 5 }
7
7
  its(:version) { should == 28 }
8
8
  its(:data) { should_not be_empty }
9
- its(:order_id) { should be_an Integer }
9
+ its(:local_id) { should be_an Integer }
10
10
  its(:status) { should =~ /Submit/ }
11
11
  its(:to_human) { should =~
12
12
  /<OpenOrder: <Contract: WFC stock NYSE USD> <Order: LMT DAY buy 100 .*Submit.* 9.13 #\d+\/\d+ from 1111/ }
@@ -23,7 +23,7 @@ shared_examples_for 'OpenOrder message' do
23
23
  o.should be_an IB::Order
24
24
  o.client_id.should == 1111
25
25
  o.parent_id.should == 0
26
- o.order_id.should be_an Integer
26
+ o.local_id.should be_an Integer
27
27
  o.perm_id.should be_an Integer
28
28
  o.order_type.should == :limit
29
29
  o.tif.should == :day
@@ -32,7 +32,7 @@ shared_examples_for 'OpenOrder message' do
32
32
 
33
33
  it 'has proper order_state accessor' do
34
34
  os = subject.order_state
35
- os.order_id.should be_an Integer
35
+ os.local_id.should be_an Integer
36
36
  os.perm_id.should be_an Integer
37
37
  os.client_id.should == 1111
38
38
  os.parent_id.should == 0
@@ -53,7 +53,7 @@ describe IB::Messages::Incoming::OpenOrder do
53
53
  subject do
54
54
  IB::Messages::Incoming::OpenOrder.new :version => 28,
55
55
  :order =>
56
- {:order_id => 1313,
56
+ {:local_id => 1313,
57
57
  :perm_id => 172323928,
58
58
  :client_id => 1111,
59
59
  :parent_id => 0,
@@ -63,7 +63,7 @@ describe IB::Messages::Incoming::OpenOrder do
63
63
  :total_quantity => 100,
64
64
  },
65
65
  :order_state =>
66
- {:order_id => 1313,
66
+ {:local_id => 1313,
67
67
  :perm_id => 172323928,
68
68
  :client_id => 1111,
69
69
  :parent_id => 0,
@@ -6,14 +6,14 @@ shared_examples_for 'OrderStatus message' do
6
6
  its(:message_id) { should == 3 }
7
7
  its(:version) { should == 6 }
8
8
  its(:data) { should_not be_empty }
9
- its(:order_id) { should be_an Integer }
9
+ its(:local_id) { should be_an Integer }
10
10
  its(:status) { should =~ /Submit/ }
11
11
  its(:to_human) { should =~
12
12
  /<OrderStatus: <OrderState: .*Submit.* #\d+\/\d+ from 1111 filled 0\/100/ }
13
13
 
14
14
  it 'has proper order_state accessor' do
15
15
  os = subject.order_state
16
- os.order_id.should be_an Integer
16
+ os.local_id.should be_an Integer
17
17
  os.perm_id.should be_an Integer
18
18
  os.client_id.should == 1111
19
19
  os.parent_id.should == 0
@@ -39,7 +39,7 @@ describe IB::Messages::Incoming::OrderStatus do
39
39
  subject do
40
40
  IB::Messages::Incoming::OrderStatus.new :version => 6,
41
41
  :order_state =>
42
- {:order_id => 1313,
42
+ {:local_id => 1313,
43
43
  :perm_id => 172323928,
44
44
  :client_id => 1111,
45
45
  :parent_id => 0,
@@ -1,6 +1,6 @@
1
1
  require 'model_helper'
2
2
 
3
- describe IB::Models::Contracts::Bag do # AKA IB::Bag
3
+ describe IB::Models::Bag do # AKA IB::Bag
4
4
 
5
5
  let(:props) do
6
6
  {:symbol => 'GOOG',
@@ -16,16 +16,6 @@ describe IB::Models::Contracts::Bag do # AKA IB::Bag
16
16
  "<Bag: GOOG SMART USD legs: 81032967|1,81032968|-2,81032973|1 >"
17
17
  end
18
18
 
19
- let(:defaults) do
20
- {:sec_type => :bag,
21
- :con_id => 0,
22
- :strike => 0,
23
- :min_tick => 0,
24
- :include_expired => false,
25
- :created_at => Time,
26
- }
27
- end
28
-
29
19
  let(:errors) do
30
20
  {:legs => ["legs cannot be empty"],
31
21
  }
@@ -39,7 +29,7 @@ describe IB::Models::Contracts::Bag do # AKA IB::Bag
39
29
 
40
30
  :sec_type =>
41
31
  {['BAG', :bag] => :bag,
42
- IB::CODES[:sec_type].reject { |k, v,| k == :bag }.to_a =>
32
+ IB::CODES[:sec_type].reject { |k, _| k == :bag }.to_a =>
43
33
  /should be a bag/},
44
34
 
45
35
  :right =>
@@ -47,23 +37,25 @@ describe IB::Models::Contracts::Bag do # AKA IB::Bag
47
37
  ["PUT", :put, "CALL", "C", :call, :foo, 'BAR', 42] =>
48
38
  /should be none/},
49
39
 
50
- :exchange =>
51
- {[:cboe, 'cboE', 'CBOE'] => 'CBOE',
52
- [:smart, 'SMART', 'smArt'] => 'SMART'},
40
+ :exchange => string_upcase_assigns.merge(
41
+ [:smart, 'SMART', 'smArt'] => 'SMART'),
53
42
 
54
- :primary_exchange =>
55
- {[:cboe, 'cboE', 'CBOE'] => 'CBOE',
56
- [:SMART, 'SMART'] => /should not be SMART/},
43
+ :primary_exchange =>string_upcase_assigns.merge(
44
+ [:SMART, 'SMART'] => /should not be SMART/),
57
45
 
58
- [:symbol, :local_symbol] =>
59
- {['AAPL', :AAPL] => 'AAPL'},
46
+ [:symbol, :local_symbol] => string_assigns,
60
47
 
61
- :multiplier => {['123', 123] => 123},
62
-
63
- [:under_con_id, :min_tick, :coupon] => {123 => 123}
48
+ :multiplier => to_i_assigns,
64
49
  }
65
50
  end
66
51
 
52
+ it 'does not allow empty legs' do
53
+ bag = IB::Bag.new props
54
+ bag.legs = []
55
+ bag.should be_invalid
56
+ bag.errors.messages[:legs].should include "legs cannot be empty"
57
+ end
58
+
67
59
  context 'using shortest class name without properties' do
68
60
  subject { IB::Bag.new }
69
61
  it_behaves_like 'Model instantiated empty'
@@ -15,11 +15,6 @@ describe IB::Models::Bar do # AKA IB::Bar
15
15
  }
16
16
  end
17
17
 
18
- let(:defaults) do
19
- {:created_at => Time,
20
- }
21
- end
22
-
23
18
  let(:errors) do
24
19
  {:close => ["is not a number"],
25
20
  :high => ["is not a number"],
@@ -5,7 +5,7 @@ describe IB::Models::ComboLeg do
5
5
  let(:props) do
6
6
  {:con_id => 81032967,
7
7
  :ratio => 2,
8
- :action => :buy,
8
+ :side => :buy,
9
9
  :exchange => 'CBOE',
10
10
  :open_close => :open,
11
11
  :short_sale_slot => :broker,
@@ -17,41 +17,34 @@ describe IB::Models::ComboLeg do
17
17
  "<ComboLeg: buy 2 con_id 81032967 at CBOE>"
18
18
  end
19
19
 
20
- let(:defaults) do
21
- {:con_id => 0,
22
- :open_close => :same,
23
- :designated_location => '',
24
- :exempt_code => -1,
25
- :exchange => 'SMART', # Unless SMART, Order modification fails
26
- :created_at => Time,
27
- }
28
- end
29
-
30
20
  let(:errors) do
31
21
  {:ratio => ["is not a number"],
32
22
  :side => ["should be buy/sell/short"]}
33
23
  end
34
24
 
35
25
  let(:assigns) do
36
- {:open_close =>
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, nil, 'Foo', :bar] => /should be same.open.close.unknown/},
42
-
43
- :side =>
44
- {['BOT', 'BUY', 'Buy', 'buy', :BUY, :BOT, :Buy, :buy, 'B', :b] => :buy,
45
- ['SELL', 'SLD', 'Sel', 'sell', :SELL, :SLD, :Sell, :sell, 'S', :S] => :sell,
46
- ['SSHORT', 'Short', 'short', :SHORT, :short, 'T', :T] => :short,
47
- ['SSHORTX', 'Shortextemt', 'shortx', :short_exempt, 'X', :X] => :short_exempt,
48
- [42, nil, 'ASK', :foo] => /should be buy.sell.short/},
49
-
26
+ {:open_close => open_close_assigns,
27
+ :side => buy_sell_short_assigns,
50
28
  :designated_location =>
51
29
  {[42, 'FOO', :bar] => /should be blank or orders will be rejected/},
52
30
  }
53
31
  end
54
32
 
33
+ let(:aliases) do
34
+ {[:side, :action] => buy_sell_short_assigns,
35
+ }
36
+ end
37
+
38
+ it 'has combined weight accessor' do
39
+ leg = IB::ComboLeg.new props
40
+ leg.weight = -3
41
+ leg.side.should == :sell
42
+ leg.ratio.should == 3
43
+ leg.weight = 5
44
+ leg.side.should == :buy
45
+ leg.ratio.should == 5
46
+ end
47
+
55
48
  it_behaves_like 'Model'
56
49
  it_behaves_like 'Self-equal Model'
57
50
 
@@ -0,0 +1,54 @@
1
+ require 'model_helper'
2
+
3
+ describe IB::Models::ContractDetail do # AKA IB::ContractDetail
4
+
5
+ let(:props) do
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
+ end
23
+
24
+ let(:human) do
25
+ /<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>/
26
+ end
27
+
28
+ let(:errors) do
29
+ {:time_zone => ['should be XXX'],
30
+ }
31
+ end
32
+
33
+ let(:assigns) do
34
+ {[:under_con_id, :min_tick, :coupon] => {123 => 123},
35
+
36
+ [:callable, :puttable, :convertible, :next_option_partial] => boolean_assigns,
37
+ }
38
+ end
39
+
40
+ let(:aliases) do
41
+ {[:contract, :summary] => {IB::Contract.new => IB::Contract.new}
42
+ }
43
+ end
44
+
45
+ it_behaves_like 'Model'
46
+ it_behaves_like 'Self-equal Model'
47
+
48
+ context 'using shortest class name without properties' do
49
+ subject { IB::ContractDetail.new }
50
+ it_behaves_like 'Model instantiated empty'
51
+ it_behaves_like 'Self-equal Model'
52
+ end
53
+
54
+ end # describe IB::Contract
@@ -1,13 +1,13 @@
1
1
  require 'model_helper'
2
2
  require 'combo_helper'
3
3
 
4
- describe IB::Models::Contracts::Contract do # AKA IB::Contract
4
+ describe IB::Models::Contract do # AKA IB::Contract
5
5
 
6
6
  let(:props) do
7
7
  {:symbol => 'AAPL',
8
8
  :sec_type => :option,
9
9
  :expiry => '201301',
10
- :strike => 600,
10
+ :strike => 600.5,
11
11
  :right => :put,
12
12
  :multiplier => 10,
13
13
  :exchange => 'SMART',
@@ -16,21 +16,7 @@ describe IB::Models::Contracts::Contract do # AKA IB::Contract
16
16
  end
17
17
 
18
18
  let(:human) do
19
- "<Contract: AAPL option 201301 put 600 SMART USD>"
20
- end
21
-
22
- let(:defaults) do
23
- {:con_id => 0,
24
- :strike => 0,
25
- :min_tick => 0,
26
- :coupon => 0,
27
- :callable => false,
28
- :puttable => false,
29
- :convertible => false,
30
- :next_option_partial => false,
31
- :include_expired => false,
32
- :created_at => Time,
33
- }
19
+ "<Contract: AAPL option 201301 put 600.5 SMART USD>"
34
20
  end
35
21
 
36
22
  let(:errors) do
@@ -47,26 +33,31 @@ describe IB::Models::Contracts::Contract do # AKA IB::Contract
47
33
  :sec_type => codes_and_values_for(:sec_type).
48
34
  merge([:foo, 'BAR', 42] => /should be valid security type/),
49
35
 
36
+ :sec_id_type =>
37
+ {[:isin, 'ISIN', 'iSin'] => 'ISIN',
38
+ [:sedol, :SEDOL, 'sEDoL', 'SEDOL'] => 'SEDOL',
39
+ [:cusip, :CUSIP, 'Cusip', 'CUSIP'] => 'CUSIP',
40
+ [:ric, :RIC, 'rIC', 'RIC'] => 'RIC',
41
+ [nil, ''] => '',
42
+ [:foo, 'BAR', 'baz'] => /should be valid security identifier/},
43
+
50
44
  :right =>
51
45
  {["PUT", "put", "P", "p", :put] => :put,
52
46
  ["CALL", "call", "C", "c", :call] => :call,
53
47
  ['', '0', '?', :none] => :none,
54
48
  [:foo, 'BAR', 42] => /should be put, call or none/},
55
49
 
56
- :exchange =>
57
- {[:cboe, 'cboE', 'CBOE'] => 'CBOE',
58
- [:smart, 'SMART', 'smArt'] => 'SMART'},
50
+ :exchange => string_upcase_assigns.merge(
51
+ [:smart, 'SMART', 'smArt'] => 'SMART'),
59
52
 
60
- :primary_exchange =>
61
- {[:cboe, 'cboE', 'CBOE'] => 'CBOE',
62
- [:SMART, 'SMART'] => /should not be SMART/},
53
+ :primary_exchange =>string_upcase_assigns.merge(
54
+ [:SMART, 'SMART'] => /should not be SMART/),
63
55
 
64
- :multiplier => {['123', 123] => 123},
56
+ :multiplier => to_i_assigns,
65
57
 
66
- [:under_con_id, :min_tick, :coupon] => {123 => 123},
58
+ :strike => to_f_assigns,
67
59
 
68
- [:callable, :puttable, :convertible, :next_option_partial] =>
69
- {[1, true] => true, [0, false] => false},
60
+ :include_expired => boolean_assigns,
70
61
  }
71
62
  end
72
63
 
@@ -123,13 +114,6 @@ describe IB::Models::Contracts::Contract do # AKA IB::Contract
123
114
 
124
115
  end
125
116
 
126
- context 'using shorter class name without properties' do
127
- subject { IB::Models::Contract.new }
128
- it_behaves_like 'Model instantiated empty'
129
- it_behaves_like 'Self-equal Model'
130
- it_behaves_like 'Contract'
131
- end
132
-
133
117
  context 'using shortest class name without properties' do
134
118
  subject { IB::Contract.new }
135
119
  it_behaves_like 'Model instantiated empty'
@@ -149,17 +133,17 @@ describe IB::Models::Contracts::Contract do # AKA IB::Contract
149
133
 
150
134
  it "serializes long" do
151
135
  subject.serialize_long.should ==
152
- ["AAPL", "OPT", "201301", 600, "P", 10, "SMART", nil, "USD", "AAPL 130119C00500000"]
136
+ ["AAPL", "OPT", "201301", 600.5, "P", 10, "SMART", "", "USD", "AAPL 130119C00500000"]
153
137
  end
154
138
 
155
139
  it "serializes short" do
156
140
  subject.serialize_short.should ==
157
- ["AAPL", "OPT", "201301", 600, "P", 10, "SMART", "USD", "AAPL 130119C00500000"]
141
+ ["AAPL", "OPT", "201301", 600.5, "P", 10, "SMART", "USD", "AAPL 130119C00500000"]
158
142
  end
159
143
 
160
144
  it "serializes combo (BAG) contracts for Order placement" do
161
145
  @combo.serialize_long(:con_id, :sec_id).should ==
162
- [0, "GOOG", "BAG", nil, 0.0, "", nil, "SMART", nil, "USD", nil, nil, nil]
146
+ [0, "GOOG", "BAG", "", 0.0, "", nil, "SMART", "", "USD", "", "", nil]
163
147
  end
164
148
 
165
149
  it 'also serializes attached combo legs' do
@@ -178,3 +162,7 @@ describe IB::Models::Contracts::Contract do # AKA IB::Contract
178
162
 
179
163
 
180
164
  end # describe IB::Contract
165
+
166
+ __END__
167
+ IB::Models::ContractDetail id: nil, contract_id: nil, market_name: "AAPL", trading_class: "AAPL", min_tick: 0.01, price_magnifier: 1, order_types: "ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKE...", valid_exchanges: "SMART,AMEX,BATS,BOX,CBOE,CBOE2,IBSX,ISE,MIBSX,NASDA...", under_con_id: 265598, long_name: "APPLE INC", contract_month: "201301", industry: "Technology", category: "Computers", subcategory: "Computers", time_zone: "EST", trading_hours: "20120422:0930-1600;20120423:0930-1600", liquid_hours: "20120422:0930-1600;20120423:0930-1600", cusip: nil, ratings: nil, desc_append: nil, bond_type: nil, coupon_type: nil, coupon: 0.0, maturity: nil, issue_date: nil, next_option_date: nil, next_option_type: nil, notes: nil, callable: false, puttable: false, convertible: false, next_option_partial: false, created_at: "2012-04-23 13:58:05", updated_at: "2012-04-23 13:58:05"
168
+ IB::Models::ContractDetail id: nil, contract_id: nil, market_name: "AAPL", trading_class: "AAPL", min_tick: 0.01, price_magnifier: 1, order_types: "ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKE...", valid_exchanges: "SMART,AMEX,BATS,BOX,CBOE,CBOE2,IBSX,ISE,MIBSX,NASDA...", under_con_id: 265598, long_name: "APPLE INC", contract_month: "201301", industry: "Technology", category: "Computers", subcategory: "Computers", time_zone: "EST", trading_hours: "20120422:0930-1600;20120423:0930-1600", liquid_hours: "20120422:0930-1600;20120423:0930-1600", cusip: nil, ratings: nil, desc_append: nil, bond_type: nil, coupon_type: nil, coupon: 0.0, maturity: nil, issue_date: nil, next_option_date: nil, next_option_type: nil, notes: nil, callable: false, puttable: false, convertible: false, next_option_partial: false, created_at: "2012-04-23 13:58:04", updated_at: "2012-04-23 13:58:04">
@@ -8,14 +8,14 @@ describe IB::Models::Execution do # AKA IB::Execution
8
8
  :exchange => "IDEALPRO",
9
9
  :exec_id => "0001f4e8.4f5d48f1.01.01",
10
10
  :liquidation => true,
11
- :order_id => 373,
11
+ :local_id => 373,
12
12
  :perm_id => 1695693619,
13
13
  :price => 1.31075,
14
14
  :average_price => 1.31075,
15
15
  :shares => 20000,
16
16
  :cumulative_quantity => 20000,
17
17
  :side => :buy,
18
- :time => "20120312 15:41:09"
18
+ :time => "20120312 15:41:09",
19
19
  }
20
20
  end
21
21
 
@@ -24,17 +24,6 @@ describe IB::Models::Execution do # AKA IB::Execution
24
24
  "cumulative 20000 at 1.31075, ids 373/1695693619/0001f4e8.4f5d48f1.01.01>"
25
25
  end
26
26
 
27
- let(:defaults) do
28
- {:order_id => 0,
29
- :client_id => 0,
30
- :perm_id => 0,
31
- :shares=> 0,
32
- :price => 0,
33
- :liquidation => false,
34
- :created_at => Time,
35
- }
36
- end
37
-
38
27
  let(:errors) do
39
28
  {:side=>["should be buy/sell/short"],
40
29
  :cumulative_quantity=>["is not a number"],
@@ -42,17 +31,73 @@ describe IB::Models::Execution do # AKA IB::Execution
42
31
  end
43
32
 
44
33
  let(:assigns) do
45
- {:side =>
46
- {['BOT', 'BUY', 'Buy', 'buy', :BUY, :BOT, :Buy, :buy, 'B', :b] => :buy,
47
- ['SELL', 'SLD', 'Sel', 'sell', :SELL, :SLD, :Sell, :sell, 'S', :S] => :sell},
34
+ {[:perm_id, :client_id, :cumulative_quantity, :price, :average_price] => numeric_assigns,
35
+ :liquidation => boolean_assigns,
36
+ }
37
+ end
48
38
 
49
- [:shares, :cumulative_quantity, :price, :average_price] =>
50
- {[:foo, 'BAR', nil] => /is not a number/},
39
+ let(:aliases) do
40
+ {[:side, :action] => buy_sell_assigns,
41
+ [:local_id, :order_id] => numeric_assigns,
42
+ [:quantity, :shares] => numeric_assigns,
43
+ [:account_name, :account_number]=> string_assigns,
44
+ }
45
+ end
51
46
 
52
- :liquidation => {[1, true] => true, [0, false] => false},
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
+ :order_type => :market)
53
54
  }
54
55
  end
55
56
 
56
57
  it_behaves_like 'Model'
57
58
 
59
+ ## TODO: Playing with associations!
60
+ context 'associations' do
61
+ subject { IB::Execution.new props }
62
+
63
+ before(:all) { DatabaseCleaner.clean if IB::DB }
64
+
65
+ it 'saves associated order' do
66
+ order = associations[:order]
67
+
68
+ #p order.save
69
+
70
+ subject.order = order
71
+
72
+ p subject.save
73
+ p subject.errors.messages
74
+
75
+
76
+ p subject.order
77
+ p subject.order.executions
78
+ p subject.to_xml
79
+ p subject.serializable_hash
80
+ p subject.to_json
81
+ p subject.as_json
82
+
83
+ p IB::Execution.new.from_json subject.to_json # TODO: Strings for keys!
84
+
85
+ pending 'Still need to test associations properly'
86
+ end
87
+
88
+ it 'loads associated execution' do
89
+ pending 'Still need to test associations properly'
90
+
91
+ #s1 = IB::Execution.first
92
+ #p s1
93
+ #p s1.order.executions
94
+
95
+ #p o1 = IB::Order.find(:first)
96
+ #p o1.execution
97
+ #
98
+ #p o1.execution.order_id
99
+ end
100
+
101
+ end
102
+
58
103
  end # describe IB::Models::Contract
@@ -1,27 +1,17 @@
1
1
  require 'model_helper'
2
2
 
3
- describe IB::Models::Contracts::Option do # AKA IB::Option
3
+ describe IB::Models::Option do # AKA IB::Option
4
4
 
5
5
  let(:props) do
6
6
  {:symbol => 'AAPL',
7
7
  :expiry => '201301',
8
- :strike => 600,
8
+ :strike => 600.5,
9
9
  :right => :put,
10
10
  }
11
11
  end
12
12
 
13
13
  let(:human) do
14
- "<Option: AAPL 201301 put 600 SMART >"
15
- end
16
-
17
- let(:defaults) do
18
- {:sec_type => :option,
19
- :con_id => 0,
20
- :strike => 0,
21
- :min_tick => 0,
22
- :include_expired => false,
23
- :created_at => Time,
24
- }
14
+ "<Option: AAPL 201301 put 600.5 SMART >"
25
15
  end
26
16
 
27
17
  let(:errors) do
@@ -38,7 +28,7 @@ describe IB::Models::Contracts::Option do # AKA IB::Option
38
28
 
39
29
  :sec_type =>
40
30
  {['OPT', :option] => :option,
41
- IB::CODES[:sec_type].reject { |k, v,| k == :option }.to_a =>
31
+ IB::CODES[:sec_type].reject { |k, _| k == :option }.to_a =>
42
32
  /should be an option/},
43
33
 
44
34
  :right =>
@@ -46,36 +36,24 @@ describe IB::Models::Contracts::Option do # AKA IB::Option
46
36
  ["CALL", "call", "C", "c", :call] => :call,
47
37
  ['', '0', '?', :none, :foo, 'BAR', 42] => /should be put or call/},
48
38
 
49
- :exchange =>
50
- {[:cboe, 'cboE', 'CBOE'] => 'CBOE',
51
- [:smart, 'SMART', 'smArt'] => 'SMART'},
39
+ :exchange => string_upcase_assigns.merge(
40
+ [:smart, 'SMART', 'smArt'] => 'SMART'),
52
41
 
53
- :primary_exchange =>
54
- {[:cboe, 'cboE', 'CBOE'] => 'CBOE',
55
- [:SMART, 'SMART'] => /should not be SMART/},
42
+ :primary_exchange =>string_upcase_assigns.merge(
43
+ [:SMART, 'SMART'] => /should not be SMART/),
56
44
 
57
- :symbol =>
58
- {['AAPL', :AAPL] => 'AAPL'},
45
+ :multiplier => to_i_assigns,
46
+
47
+ :symbol => string_assigns,
59
48
 
60
49
  :local_symbol =>
61
- {['AAPL 130119C00500000', :'AAPL 130119C00500000'] =>
62
- 'AAPL 130119C00500000',
50
+ {['AAPL 130119C00500000', :'AAPL 130119C00500000'] => 'AAPL 130119C00500000',
63
51
  'BAR'=> /invalid OSI code/},
64
52
 
65
53
  :strike => {[0, -30.0] => /must be greater than 0/},
66
-
67
- :multiplier => {['123', 123] => 123},
68
-
69
- [:under_con_id, :min_tick, :coupon] => {123 => 123}
70
-
71
54
  }
72
55
  end
73
56
 
74
- context 'using shorter class name without properties' do
75
- subject { IB::Models::Option.new }
76
- it_behaves_like 'Model instantiated empty'
77
- end
78
-
79
57
  context 'using shortest class name without properties' do
80
58
  subject { IB::Option.new }
81
59
  it_behaves_like 'Model instantiated empty'