ib-ruby 0.7.3 → 0.7.4

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 (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