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.
- data/HISTORY +4 -0
- data/README.md +60 -30
- data/TODO +1 -0
- data/VERSION +1 -1
- data/bin/account_info +1 -4
- data/bin/cancel_orders +0 -3
- data/bin/contract_details +2 -5
- data/bin/depth_of_market +1 -4
- data/bin/fa_accounts +22 -0
- data/bin/historic_data +1 -4
- data/bin/historic_data_cli +0 -4
- data/bin/list_orders +2 -6
- data/bin/market_data +1 -4
- data/bin/option_data +2 -5
- data/bin/place_combo_order +17 -22
- data/bin/place_order +6 -10
- data/bin/tick_data +6 -9
- data/bin/time_and_sales +2 -5
- data/lib/ib-ruby/connection.rb +10 -5
- data/lib/ib-ruby/messages/incoming/open_order.rb +15 -13
- data/lib/ib-ruby/messages/incoming/ticks.rb +1 -1
- data/lib/ib-ruby/messages/incoming.rb +18 -18
- data/lib/ib-ruby/messages/outgoing.rb +2 -2
- data/lib/ib-ruby/messages.rb +3 -7
- data/lib/ib-ruby/models/{contract → contracts}/bag.rb +5 -8
- data/lib/ib-ruby/models/contracts/contract.rb +296 -0
- data/lib/ib-ruby/models/{contract → contracts}/option.rb +2 -4
- data/lib/ib-ruby/models/contracts.rb +27 -0
- data/lib/ib-ruby/models/execution.rb +1 -1
- data/lib/ib-ruby/models/order.rb +6 -17
- data/lib/ib-ruby/models.rb +9 -7
- data/lib/ib-ruby/symbols/forex.rb +50 -50
- data/lib/ib-ruby/symbols/futures.rb +47 -47
- data/lib/ib-ruby/symbols/options.rb +23 -23
- data/lib/ib-ruby/symbols/stocks.rb +14 -14
- data/lib/ib-ruby.rb +17 -9
- data/spec/README.md +6 -0
- data/spec/account_helper.rb +1 -1
- data/spec/combo_helper.rb +31 -0
- data/spec/ib-ruby/models/combo_leg_spec.rb +4 -4
- data/spec/ib-ruby/models/contract_spec.rb +37 -26
- data/spec/ib-ruby/models/execution_spec.rb +5 -5
- data/spec/ib-ruby/models/order_spec.rb +16 -16
- data/spec/integration/contract_info_spec.rb +8 -10
- data/spec/integration/historic_data_spec.rb +1 -1
- data/spec/integration/market_data_spec.rb +5 -5
- data/spec/integration/orders/attached_spec.rb +87 -0
- data/spec/integration/orders/combo_spec.rb +52 -65
- data/spec/integration/orders/placement_spec.rb +8 -8
- data/spec/order_helper.rb +97 -28
- data/spec/spec_helper.rb +2 -2
- metadata +12 -5
- 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::
|
17
|
-
|
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::
|
65
|
-
|
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::
|
111
|
-
|
112
|
-
|
113
|
-
|
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::
|
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::
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
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,
|
44
|
-
|
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
|
-
|
50
|
-
|
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
|
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,
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
after(:all) { close_connection }
|
72
|
+
place_order @contract,
|
73
|
+
:limit_price => 0.01,
|
74
|
+
:total_quantity => 10
|
65
75
|
|
66
|
-
|
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
|
-
|
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
|
-
|
88
|
-
|
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 '
|
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
|
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
|
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
|
-
|
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
|
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
|
13
|
-
|
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 /
|
17
|
-
status_should_be /
|
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
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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,
|
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 '
|
58
|
-
@ib.received?
|
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
|
62
|
-
|
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::
|
82
|
-
|
83
|
-
|
84
|
-
|
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 ==
|
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 ==
|
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 ==
|
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 ==
|
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', #
|
44
|
-
:port => 4001 #
|
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.
|
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-
|
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/
|
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/
|
111
|
-
- lib/ib-ruby/models/contract
|
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
|