ib-ruby 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/HISTORY +4 -0
  2. data/README.md +60 -30
  3. data/TODO +1 -0
  4. data/VERSION +1 -1
  5. data/bin/account_info +1 -4
  6. data/bin/cancel_orders +0 -3
  7. data/bin/contract_details +2 -5
  8. data/bin/depth_of_market +1 -4
  9. data/bin/fa_accounts +22 -0
  10. data/bin/historic_data +1 -4
  11. data/bin/historic_data_cli +0 -4
  12. data/bin/list_orders +2 -6
  13. data/bin/market_data +1 -4
  14. data/bin/option_data +2 -5
  15. data/bin/place_combo_order +17 -22
  16. data/bin/place_order +6 -10
  17. data/bin/tick_data +6 -9
  18. data/bin/time_and_sales +2 -5
  19. data/lib/ib-ruby/connection.rb +10 -5
  20. data/lib/ib-ruby/messages/incoming/open_order.rb +15 -13
  21. data/lib/ib-ruby/messages/incoming/ticks.rb +1 -1
  22. data/lib/ib-ruby/messages/incoming.rb +18 -18
  23. data/lib/ib-ruby/messages/outgoing.rb +2 -2
  24. data/lib/ib-ruby/messages.rb +3 -7
  25. data/lib/ib-ruby/models/{contract → contracts}/bag.rb +5 -8
  26. data/lib/ib-ruby/models/contracts/contract.rb +296 -0
  27. data/lib/ib-ruby/models/{contract → contracts}/option.rb +2 -4
  28. data/lib/ib-ruby/models/contracts.rb +27 -0
  29. data/lib/ib-ruby/models/execution.rb +1 -1
  30. data/lib/ib-ruby/models/order.rb +6 -17
  31. data/lib/ib-ruby/models.rb +9 -7
  32. data/lib/ib-ruby/symbols/forex.rb +50 -50
  33. data/lib/ib-ruby/symbols/futures.rb +47 -47
  34. data/lib/ib-ruby/symbols/options.rb +23 -23
  35. data/lib/ib-ruby/symbols/stocks.rb +14 -14
  36. data/lib/ib-ruby.rb +17 -9
  37. data/spec/README.md +6 -0
  38. data/spec/account_helper.rb +1 -1
  39. data/spec/combo_helper.rb +31 -0
  40. data/spec/ib-ruby/models/combo_leg_spec.rb +4 -4
  41. data/spec/ib-ruby/models/contract_spec.rb +37 -26
  42. data/spec/ib-ruby/models/execution_spec.rb +5 -5
  43. data/spec/ib-ruby/models/order_spec.rb +16 -16
  44. data/spec/integration/contract_info_spec.rb +8 -10
  45. data/spec/integration/historic_data_spec.rb +1 -1
  46. data/spec/integration/market_data_spec.rb +5 -5
  47. data/spec/integration/orders/attached_spec.rb +87 -0
  48. data/spec/integration/orders/combo_spec.rb +52 -65
  49. data/spec/integration/orders/placement_spec.rb +8 -8
  50. data/spec/order_helper.rb +97 -28
  51. data/spec/spec_helper.rb +2 -2
  52. metadata +12 -5
  53. data/lib/ib-ruby/models/contract.rb +0 -308
@@ -13,8 +13,8 @@ describe "Request Contract Info", :connected => true, :integration => true do
13
13
  context "Request Stock data" do
14
14
 
15
15
  before(:all) do
16
- @contract = IB::Models::Contract.new :symbol => 'AAPL',
17
- :sec_type => IB::SECURITY_TYPES[:stock]
16
+ @contract = IB::Contract.new :symbol => 'AAPL',
17
+ :sec_type => IB::SECURITY_TYPES[:stock]
18
18
  @ib.send_message :RequestContractData, :id => 111, :contract => @contract
19
19
  @ib.wait_for :ContractDataEnd, 3 # sec
20
20
  end
@@ -61,10 +61,8 @@ describe "Request Contract Info", :connected => true, :integration => true do
61
61
  context "Request Option contract data" do
62
62
 
63
63
  before(:all) do
64
- @contract = IB::Models::Contract::Option.new :symbol => "AAPL",
65
- :expiry => "201301",
66
- :right => "CALL",
67
- :strike => 500
64
+ @contract = IB::Option.new :symbol => "AAPL", :expiry => "201301",
65
+ :right => "CALL", :strike => 500
68
66
  @ib.send_message :RequestContractData, :id => 123, :contract => @contract
69
67
  @ib.wait_for :ContractDataEnd, 3 # sec
70
68
  end
@@ -107,10 +105,10 @@ describe "Request Contract Info", :connected => true, :integration => true do
107
105
  context "Request Forex contract data" do
108
106
 
109
107
  before(:all) do
110
- @contract = IB::Models::Contract.new :symbol => 'EUR', # EURUSD pair
111
- :currency => "USD",
112
- :exchange => "IDEALPRO",
113
- :sec_type => IB::SECURITY_TYPES[:forex]
108
+ @contract = IB::Contract.new :symbol => 'EUR', # EURUSD pair
109
+ :currency => "USD",
110
+ :exchange => "IDEALPRO",
111
+ :sec_type => IB::SECURITY_TYPES[:forex]
114
112
  @ib.send_message :RequestContractData, :id => 135, :contract => @contract
115
113
  @ib.wait_for :ContractDataEnd, 3 # sec
116
114
  end
@@ -55,7 +55,7 @@ describe 'Request Historic Data', :connected => true, :integration => true do
55
55
  subject.results.should be_an Array
56
56
  subject.results.size.should == subject.count
57
57
  subject.results.each do |bar|
58
- bar.should be_an IB::Models::Bar
58
+ bar.should be_an IB::Bar
59
59
  bar.time.should =~ /\d{8} *\d\d:\d\d:\d\d/
60
60
  bar.open.should be_a Float
61
61
  bar.high.should be_a Float
@@ -12,11 +12,11 @@ describe 'Request Market Data', :connected => true, :integration => true do
12
12
  context 'US Stocks market', :if => :us_trading_hours do
13
13
  before(:all) do
14
14
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
15
- @contract = IB::Models::Contract.new(:symbol => 'AAPL',
16
- :exchange => "Smart",
17
- :currency => "USD",
18
- :sec_type => IB::SECURITY_TYPES[:stock],
19
- :description => "Apple"
15
+ @contract = IB::Contract.new(:symbol => 'AAPL',
16
+ :exchange => "Smart",
17
+ :currency => "USD",
18
+ :sec_type => IB::SECURITY_TYPES[:stock],
19
+ :description => "Apple"
20
20
  )
21
21
  @ib.send_message :RequestMarketData, :id => 456, :contract => @contract
22
22
  @ib.wait_for :TickSize, :TickString, 3 # sec
@@ -0,0 +1,87 @@
1
+ require 'order_helper'
2
+ require 'combo_helper'
3
+
4
+ #OPTS[:silent] = false
5
+
6
+ def define_contracts
7
+ @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
8
+ @contracts = {
9
+ :stock => IB::Symbols::Stocks[:wfc],
10
+ :butterfly => butterfly('GOOG', '201301', 'CALL', 500, 510, 520)
11
+ }
12
+ close_connection
13
+ end
14
+
15
+ describe 'Attached Orders', :connected => true, :integration => true do
16
+
17
+ before(:all) do
18
+ verify_account
19
+ define_contracts
20
+ end
21
+
22
+ # Testing different combinations of Parent + Attached Orders:
23
+ [
24
+ #[:stock, 100, 'DAY', 'LMT', 9.13, 20.0], # Parent + takeprofit target
25
+ [:stock, 100, 'DAY', 'STP', 9.13, 0.0, 8.0], # Parent + stoploss
26
+ [:stock, 100, 'GTC', 'LMT', 9.13, 20.0], # GTC Parent + target
27
+ [:butterfly, 10, 'DAY', 'LMT', 0.05, 1.0], # Combo Parent + target
28
+ #[:butterfly, 10, 'GTC', 'LMT', 0.05, 1.0], # GTC Combo Parent + target
29
+ [:butterfly, 100, 'GTC', 'STPLMT', 0.05, 0.05, 1.0], # GTC Combo Parent + stoplimit target
30
+
31
+ ].each do |(contract, qty, tif, attach_type, limit_price, attach_price, aux_price)|
32
+ context "#{tif} BUY (#{contract}) limit order with attached #{attach_type} SELL" do
33
+ let(:contract_type) { contract }
34
+
35
+ before(:all) do
36
+ @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
37
+ @ib.wait_for :NextValidId
38
+ @ib.clear_received # to avoid conflict with pre-existing Orders
39
+
40
+ #p [contract, qty, tif, attach_type, limit_price, attach_price, aux_price]
41
+ @contract = @contracts[contract]
42
+ place_order @contract,
43
+ :total_quantity => qty,
44
+ :limit_price => limit_price,
45
+ :tif => tif,
46
+ :transmit => false
47
+
48
+ @ib.wait_for :OpenOrder, :OrderStatus, 2
49
+ end
50
+
51
+ after(:all) { close_connection }
52
+
53
+ it 'does not transmit original Order before attach' do
54
+ @ib.received[:OpenOrder].should have_exactly(0).order_message
55
+ @ib.received[:OrderStatus].should have_exactly(0).status_message
56
+ end
57
+
58
+ context "Attaching #{attach_type} order" do
59
+ before(:all) do
60
+ @attached_order = IB::Order.new :total_quantity => qty,
61
+ :limit_price => attach_price,
62
+ :aux_price => aux_price || 0,
63
+ :action => 'SELL',
64
+ :tif => tif,
65
+ :order_type => attach_type,
66
+ :parent_id => @order_id_placed
67
+
68
+ @order_id_attached = @ib.place_order @attached_order, @contract
69
+ @order_id_after = @ib.next_order_id
70
+ @ib.wait_for [:OpenOrder, 3], [:OrderStatus, 3], 4
71
+ end
72
+
73
+ it_behaves_like 'Placed Order'
74
+ end
75
+
76
+ context 'When original Order cancels' do
77
+ it 'attached takeprofit is cancelled implicitly' do
78
+ @ib.send_message :RequestOpenOrders
79
+ @ib.wait_for :OpenOrderEnd
80
+ @ib.received[:OpenOrder].should have_exactly(0).order_message
81
+ @ib.received[:OrderStatus].should have_exactly(0).status_message
82
+ end
83
+ end
84
+
85
+ end
86
+ end
87
+ end # Orders
@@ -1,55 +1,67 @@
1
1
  require 'order_helper'
2
+ require 'combo_helper'
2
3
 
3
4
  #OPTS[:silent] = false
4
5
 
5
- def butterfly symbol, expiry, right, *strikes
6
- raise 'No Connection!' unless @ib && @ib.connected?
7
-
8
- legs = strikes.zip([1, -2, 1]).map do |strike, weight|
9
- # Create contract
10
- contract = IB::Models::Contract::Option.new :symbol => symbol,
11
- :expiry => expiry,
12
- :right => right,
13
- :strike => strike
14
- # Find out contract's con_id
15
- @ib.clear_received :ContractData, :ContractDataEnd
16
- @ib.send_message :RequestContractData, :id => strike, :contract => contract
17
- @ib.wait_for :ContractDataEnd, 3
18
- con_id = @ib.received[:ContractData].last.contract.con_id
19
-
20
- # Create Comboleg from con_id and weight
21
- IB::Models::ComboLeg.new :con_id => con_id, :weight => weight
22
- end
23
-
24
- # Create new Combo contract
25
- IB::Models::Contract::Bag.new :symbol => symbol,
26
- :currency => "USD", # Only US options in combo Contracts
27
- :exchange => "SMART",
28
- :legs => legs
29
- end
30
-
31
6
  describe "Combo Order", :connected => true, :integration => true, :slow => true do
32
7
 
8
+ let(:contract_type) { :butterfly }
9
+
33
10
  before(:all) { verify_account }
34
11
 
35
- context "Limit" do # , :if => :us_trading_hours
12
+ context 'What-if order' do
36
13
  before(:all) do
37
14
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
38
15
  @ib.wait_for :NextValidId
39
- @ib.clear_received # to avoid conflict with pre-existing Orders
40
16
 
41
17
  @contract = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
42
18
 
43
- place_order @contract, :limit_price => 0.01 #, :what_if => true
44
- @ib.wait_for :OpenOrder, :OrderStatus, 8
19
+ place_order @contract,
20
+ :limit_price => 0.01,
21
+ :total_quantity => 10,
22
+ :what_if => true
23
+
24
+ @ib.wait_for :OpenOrder, 8
45
25
  end
46
26
 
47
27
  after(:all) { close_connection }
48
28
 
49
- it_behaves_like 'Placed Order'
50
- end # Limit
29
+ it 'changes client`s next_order_id' do
30
+ @order_id_placed.should == @order_id_before
31
+ @ib.next_order_id.should == @order_id_before + 1
32
+ end
33
+
34
+ it { @ib.received[:OpenOrder].should have_at_least(1).open_order_message }
35
+ it { @ib.received[:OrderStatus].should have_exactly(0).status_messages }
36
+
37
+ it 'responds with margin info' do
38
+ order_should_be /PreSubmitted/
39
+ order = @ib.received[:OpenOrder].first.order
40
+ order.what_if.should == true
41
+ order.equity_with_loan.should be_a Float
42
+ order.init_margin.should be_a Float
43
+ order.maint_margin.should be_a Float
44
+ order.equity_with_loan.should be > 0
45
+ order.init_margin.should be > 0
46
+ order.maint_margin.should be > 0
47
+ end
48
+
49
+ it 'responds with commission info',
50
+ :pending => 'API Bug: No commission in what_if for Combo orders' do
51
+ order = @ib.received[:OpenOrder].first.order
52
+ order.commission.should be_a Float
53
+ order.commission.should be > 1
54
+ end
55
+
56
+ it 'is not actually being placed though' do
57
+ @ib.clear_received
58
+ @ib.send_message :RequestOpenOrders
59
+ @ib.wait_for :OpenOrderEnd
60
+ @ib.received[:OpenOrder].should have_exactly(0).order_message
61
+ end
62
+ end
51
63
 
52
- context "Limit with attached takeprofit" do
64
+ context "Limit" do # , :if => :us_trading_hours
53
65
  before(:all) do
54
66
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
55
67
  @ib.wait_for :NextValidId
@@ -57,41 +69,16 @@ describe "Combo Order", :connected => true, :integration => true, :slow => true
57
69
 
58
70
  @contract = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
59
71
 
60
- place_order @contract, :limit_price => 0.01, :transmit => false
61
- @ib.wait_for :OpenOrder, :OrderStatus, 2
62
- end
63
-
64
- after(:all) { close_connection }
72
+ place_order @contract,
73
+ :limit_price => 0.01,
74
+ :total_quantity => 10
65
75
 
66
- it 'does not transmit original Order just yet' do
67
- @ib.received[:OpenOrder].should have_exactly(0).order_message
68
- @ib.received[:OrderStatus].should have_exactly(0).status_message
76
+ @ib.wait_for [:OpenOrder, 2], [:OrderStatus, 2], 6
69
77
  end
70
78
 
71
- context 'Attaching takeprofit' do
72
- before(:all) do
73
- @attached_order = IB::Models::Order.new :total_quantity => 100,
74
- :limit_price => 0.5,
75
- :action => 'SELL',
76
- :order_type => 'LMT',
77
- :parent_id => @order_id_placed
78
-
79
- @order_id_attached = @ib.place_order @attached_order, @contract
80
- @order_id_after = @ib.next_order_id
81
- @ib.wait_for [:OpenOrder, 2], [:OrderStatus, 2], 8
82
- end
83
-
84
- it_behaves_like 'Placed Order'
85
- end
79
+ after(:all) { close_connection }
86
80
 
87
- context 'When original Order cancels' do
88
- it 'attached takeprofit is cancelled implicitely' do
89
- @ib.send_message :RequestOpenOrders
90
- @ib.wait_for :OpenOrderEnd
91
- @ib.received[:OpenOrder].should have_exactly(0).order_message
92
- @ib.received[:OrderStatus].should have_exactly(0).status_message
93
- end
94
- end
95
- end # Attached
81
+ it_behaves_like 'Placed Order'
82
+ end # Limit
96
83
  end # Combo Orders
97
84
 
@@ -1,7 +1,9 @@
1
1
  require 'order_helper'
2
2
 
3
3
  #OPTS[:silent] = false
4
+
4
5
  describe 'Orders', :connected => true, :integration => true do
6
+ let(:contract_type) { :stock }
5
7
 
6
8
  before(:all) { verify_account }
7
9
 
@@ -60,7 +62,7 @@ describe 'Orders', :connected => true, :integration => true do
60
62
  it { @ib.received[:OpenOrder].should have_at_least(1).open_order_message }
61
63
  it { @ib.received[:OrderStatus].should have_exactly(0).status_messages }
62
64
 
63
- it 'returns as what-if Order with margin and commission info' do
65
+ it 'responds with margin and commission info' do
64
66
  order_should_be /PreSubmitted/
65
67
  order = @ib.received[:OpenOrder].first.order
66
68
  order.what_if.should == true
@@ -74,7 +76,7 @@ describe 'Orders', :connected => true, :integration => true do
74
76
  order.commission.should be > 1
75
77
  end
76
78
 
77
- it 'is not actually opened though' do
79
+ it 'is not actually being placed though' do
78
80
  @ib.clear_received
79
81
  @ib.send_message :RequestOpenOrders
80
82
  @ib.wait_for :OpenOrderEnd
@@ -82,14 +84,12 @@ describe 'Orders', :connected => true, :integration => true do
82
84
  end
83
85
  end
84
86
 
85
- context 'Off-market stock order' do
87
+ context 'Off-market limit' do
86
88
  before(:all) do
87
89
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
88
90
  @ib.wait_for :NextValidId
89
-
90
- place_order IB::Symbols::Stocks[:wfc],
91
- :limit_price => 9.13 # Set acceptable price
92
- @ib.wait_for [:OpenOrder, 3], [:OrderStatus, 2]
91
+ place_order IB::Symbols::Stocks[:wfc], :limit_price => 9.13 # Acceptable price
92
+ @ib.wait_for [:OpenOrder, 3], [:OrderStatus, 2], 10
93
93
  end
94
94
 
95
95
  after(:all) { close_connection }
@@ -120,5 +120,5 @@ describe 'Orders', :connected => true, :integration => true do
120
120
  alert.message.should =~ /Can't find order with id =/
121
121
  end
122
122
  end # Cancelling
123
- end # Off-market order
123
+ end # Off-market limit
124
124
  end # Orders
data/spec/order_helper.rb CHANGED
@@ -9,12 +9,14 @@ shared_examples_for 'Placed Order' do
9
9
  @ib.next_order_id.should be >= @order_id_before
10
10
  end
11
11
 
12
- it { @ib.received[:OpenOrder].should have_at_least(1).order_message }
13
- it { @ib.received[:OrderStatus].should have_at_least(1).status_message }
12
+ it 'receives all appropriate response messages' do
13
+ @ib.received[:OpenOrder].should have_at_least(1).order_message
14
+ @ib.received[:OrderStatus].should have_at_least(1).status_message
15
+ end
14
16
 
15
17
  it 'receives confirmation of Order submission' do
16
- order_should_be /Submitted/ # ()Pre)Submitted
17
- status_should_be /Submitted/
18
+ order_should_be /Submit/ # ()Pre)Submitted
19
+ status_should_be /Submit/
18
20
  end
19
21
  end # Placing
20
22
 
@@ -30,22 +32,79 @@ shared_examples_for 'Placed Order' do
30
32
  @ib.next_order_id.should == @order_id_after
31
33
  end
32
34
 
33
- it { @ib.received[:OpenOrder].should have_at_least(1).order_message }
34
- it { @ib.received[:OrderStatus].should have_at_least(1).status_message }
35
- it { @ib.received[:OpenOrderEnd].should have_exactly(1).order_end_message }
36
-
37
- #it { @ib.received[:Alert].should have_exactly(0).alert_messages }
35
+ it 'receives all appropriate response messages' do
36
+ @ib.received[:OpenOrder].should have_at_least(1).order_message
37
+ @ib.received[:OrderStatus].should have_at_least(1).status_message
38
+ @ib.received[:OpenOrderEnd].should have_exactly(1).order_end_message
39
+ end
38
40
 
39
- it 'receives OpenOrder and OrderStatus for placed order' do
41
+ it 'receives OpenOrder and OrderStatus for placed order(s)' do
40
42
  order_should_be /Submitted/
41
43
  status_should_be /Submitted/
44
+
45
+ if @attached_order
46
+ if contract_type == :butterfly && @attached_order.tif == 'GTC'
47
+ pending 'API Bug: Attached DAY orders not working for butterflies!'
48
+ else
49
+ order_should_be /Submit/, @attached_order
50
+ end
51
+ end
42
52
  end
43
53
  end # Retrieving
44
54
 
55
+ context "Modifying Order" do
56
+ before(:all) do
57
+ if defined?(contract_type) && contract_type == :butterfly
58
+ pending 'API Bug: Order modification not working for butterflies!'
59
+ else
60
+ # Modification only works for non-attached, non-combo orders
61
+ @order.total_quantity = 200
62
+ @order.limit_price += 0.05
63
+ @order.transmit = true
64
+ @ib.modify_order @order, @contract
65
+
66
+ if @attached_order
67
+ # Modify attached order, if any
68
+ @attached_order.limit_price *= 1.5
69
+ @attached_order.tif = 'GTC'
70
+ @ib.modify_order @attached_order, @contract
71
+ end
72
+ end
73
+ @ib.send_message :RequestOpenOrders
74
+ @ib.wait_for :OpenOrderEnd, 6 #sec
75
+ end
76
+
77
+ after(:all) { clean_connection } # Clear logs and message collector
78
+
79
+ it 'does not increase client`s next_order_id further' do
80
+ @ib.next_order_id.should == @order_id_after
81
+ end
82
+
83
+ it 'receives all appropriate response messages' do
84
+ @ib.received[:OpenOrder].should have_at_least(1).order_message
85
+ @ib.received[:OrderStatus].should have_at_least(1).status_message
86
+ @ib.received[:OpenOrderEnd].should have_exactly(1).order_end_message
87
+ end
88
+
89
+ it 'modifies the placed order(s)' do
90
+ @contract.should == @ib.received[:OpenOrder].first.contract
91
+ order_should_be /Submit/
92
+ status_should_be /Submit/
93
+
94
+ if @attached_order
95
+ if contract_type == :butterfly && @attached_order.tif == 'GTC'
96
+ pending 'API Bug: Attached DAY orders not working for butterflies!'
97
+ else
98
+ order_should_be /Submit/, @attached_order
99
+ end
100
+ end
101
+ end
102
+ end # Modifying
103
+
45
104
  context "Cancelling placed order" do
46
105
  before(:all) do
47
106
  @ib.cancel_order @order_id_placed
48
- @ib.wait_for [:OrderStatus, 2], :Alert
107
+ @ib.wait_for [:OrderStatus, 3], :Alert
49
108
  end
50
109
 
51
110
  after(:all) { clean_connection } # Clear logs and message collector
@@ -54,15 +113,26 @@ shared_examples_for 'Placed Order' do
54
113
  @ib.next_order_id.should == @order_id_after
55
114
  end
56
115
 
57
- it 'does not receive OpenOrder message' do
58
- @ib.received?(:OpenOrder).should be_false
116
+ it 'only receives OpenOrder message with PendingCancel' do
117
+ if @ib.received? :OpenOrder
118
+ order_should_be /PendingCancel/
119
+ end
59
120
  end
60
121
 
61
- it { @ib.received[:OrderStatus].should have_at_least(1).status_message }
62
- it { @ib.received[:Alert].should have_at_least(1).alert_message }
122
+ it 'receives all appropriate response messages' do
123
+ @ib.received[:OrderStatus].should have_at_least(1).status_message
124
+ @ib.received[:Alert].should have_at_least(1).alert_message
125
+ end
63
126
 
64
127
  it 'receives cancellation Order Status' do
65
128
  status_should_be /Cancel/ # Cancelled / PendingCancel
129
+ if @attached_order
130
+ if contract_type == :butterfly && @attached_order.tif == 'GTC'
131
+ pending 'API Bug: Attached DAY orders not working for butterflies!'
132
+ else
133
+ status_should_be /Cancel/, @attached_order
134
+ end
135
+ end
66
136
  end
67
137
 
68
138
  it 'receives Order cancelled Alert' do
@@ -73,34 +143,34 @@ shared_examples_for 'Placed Order' do
73
143
  end # Cancelling
74
144
  end
75
145
 
76
-
77
146
  ### Helpers for placing and verifying orders
78
147
 
79
148
  def place_order contract, opts
80
149
  @contract = contract
81
- @order = IB::Models::Order.new({:total_quantity => 100,
82
- :limit_price => 9.13,
83
- :action => 'BUY',
84
- :order_type => 'LMT'}.merge(opts))
150
+ @order = IB::Order.new({:total_quantity => 100,
151
+ :limit_price => 9.13,
152
+ :action => 'BUY',
153
+ :order_type => 'LMT'}.merge(opts))
85
154
  @order_id_before = @ib.next_order_id
86
155
  @order_id_placed = @ib.place_order @order, @contract
87
156
  @order_id_after = @ib.next_order_id
88
157
  end
89
158
 
90
- def status_should_be status
159
+ def status_should_be status, order=@order
91
160
  msg = @ib.received[:OrderStatus].find do |msg|
92
- msg.order_id == @order_id_placed &&
161
+ msg.order_id == order.order_id &&
93
162
  status.is_a?(Regexp) ? msg.status =~ status : msg.status == status
94
163
  end
95
164
  msg.should_not be_nil
96
165
  msg.should be_an IB::Messages::Incoming::OrderStatus
97
- msg.order_id.should == @order_id_placed
166
+ msg.order_id.should == order.order_id
98
167
  msg.perm_id.should be_an Integer
99
168
  msg.client_id.should == OPTS[:connection][:client_id]
100
- msg.parent_id.should == 0
169
+ msg.parent_id.should == 0 unless @attached_order
101
170
  msg.why_held.should == ''
102
171
 
103
172
  if @contract == IB::Symbols::Forex[:eurusd]
173
+ # We know that this order filled for sure
104
174
  msg.filled.should == 20000
105
175
  msg.remaining.should == 0
106
176
  msg.average_fill_price.should be > 1
@@ -114,16 +184,15 @@ def status_should_be status
114
184
  end
115
185
  end
116
186
 
117
- def order_should_be status
187
+ def order_should_be status, order=@order
118
188
  msg = @ib.received[:OpenOrder].find do |msg|
119
- msg.order_id == @order_id_placed &&
189
+ msg.order_id == order.order_id &&
120
190
  status.is_a?(Regexp) ? msg.status =~ status : msg.status == status
121
191
  end
122
192
  msg.should_not be_nil
123
193
  msg.should be_an IB::Messages::Incoming::OpenOrder
124
- msg.order.should == @order
194
+ msg.order.should == order
125
195
  msg.contract.should == @contract
126
- msg.order.order_id.should == @order_id_placed
127
196
  end
128
197
 
129
198
  def execution_should_be side, opts={}
data/spec/spec_helper.rb CHANGED
@@ -40,7 +40,7 @@ else
40
40
  OPTS[:connection] =
41
41
  {:account_name => 'DU118180', # Your IB PAPER ACCOUNT, tests will only run against it
42
42
  :client_id => 1111, # Just an arbitrary id
43
- :host => '10.211.55.2', # Where your TWS/gateway is located, likely 'localhost'
44
- :port => 4001 # 4001 for Gateway, 7496 for TWS GUI
43
+ :host => '10.211.55.2', # Where your TWS/gateway is located, likely '127.0.0.1'
44
+ :port => 4001 # 4001 for Gateway, 7496 for TWS GUI
45
45
  }
46
46
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: ib-ruby
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.7.3
5
+ version: 0.7.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Paul Legato
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2012-03-23 00:00:00 Z
14
+ date: 2012-04-04 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -55,6 +55,7 @@ executables:
55
55
  - cancel_orders
56
56
  - contract_details
57
57
  - depth_of_market
58
+ - fa_accounts
58
59
  - historic_data
59
60
  - historic_data_cli
60
61
  - list_orders
@@ -74,6 +75,7 @@ files:
74
75
  - bin/cancel_orders
75
76
  - bin/contract_details
76
77
  - bin/depth_of_market
78
+ - bin/fa_accounts
77
79
  - bin/historic_data
78
80
  - bin/historic_data_cli
79
81
  - bin/list_orders
@@ -102,18 +104,20 @@ files:
102
104
  - lib/ib-ruby/messages/incoming/ticks.rb
103
105
  - lib/ib-ruby/models/bar.rb
104
106
  - lib/ib-ruby/models/combo_leg.rb
105
- - lib/ib-ruby/models/contract.rb
107
+ - lib/ib-ruby/models/contracts.rb
106
108
  - lib/ib-ruby/models/execution.rb
107
109
  - lib/ib-ruby/models/model.rb
108
110
  - lib/ib-ruby/models/model_properties.rb
109
111
  - lib/ib-ruby/models/order.rb
110
- - lib/ib-ruby/models/contract/bag.rb
111
- - lib/ib-ruby/models/contract/option.rb
112
+ - lib/ib-ruby/models/contracts/bag.rb
113
+ - lib/ib-ruby/models/contracts/contract.rb
114
+ - lib/ib-ruby/models/contracts/option.rb
112
115
  - lib/ib-ruby/symbols/forex.rb
113
116
  - lib/ib-ruby/symbols/futures.rb
114
117
  - lib/ib-ruby/symbols/options.rb
115
118
  - lib/ib-ruby/symbols/stocks.rb
116
119
  - spec/account_helper.rb
120
+ - spec/combo_helper.rb
117
121
  - spec/integration_helper.rb
118
122
  - spec/message_helper.rb
119
123
  - spec/order_helper.rb
@@ -133,6 +137,7 @@ files:
133
137
  - spec/integration/historic_data_spec.rb
134
138
  - spec/integration/market_data_spec.rb
135
139
  - spec/integration/option_data_spec.rb
140
+ - spec/integration/orders/attached_spec.rb
136
141
  - spec/integration/orders/combo_spec.rb
137
142
  - spec/integration/orders/execution_spec.rb
138
143
  - spec/integration/orders/open_order
@@ -180,6 +185,7 @@ specification_version: 3
180
185
  summary: Ruby Implementation of the Interactive Brokers TWS API
181
186
  test_files:
182
187
  - spec/account_helper.rb
188
+ - spec/combo_helper.rb
183
189
  - spec/integration_helper.rb
184
190
  - spec/message_helper.rb
185
191
  - spec/order_helper.rb
@@ -199,6 +205,7 @@ test_files:
199
205
  - spec/integration/historic_data_spec.rb
200
206
  - spec/integration/market_data_spec.rb
201
207
  - spec/integration/option_data_spec.rb
208
+ - spec/integration/orders/attached_spec.rb
202
209
  - spec/integration/orders/combo_spec.rb
203
210
  - spec/integration/orders/execution_spec.rb
204
211
  - spec/integration/orders/open_order