ib-ruby 0.5.21 → 0.6.1
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 +8 -0
- data/README.md +46 -27
- data/TODO +13 -2
- data/VERSION +1 -1
- data/bin/generic_data.rb +26 -0
- data/bin/place_order +1 -1
- data/lib/ib-ruby/connection.rb +126 -65
- data/lib/ib-ruby/messages/incoming.rb +3 -3
- data/lib/ib-ruby/models/bar.rb +11 -11
- data/lib/ib-ruby/models/combo_leg.rb +23 -29
- data/lib/ib-ruby/models/contract/bag.rb +34 -2
- data/lib/ib-ruby/models/contract/option.rb +2 -2
- data/lib/ib-ruby/models/contract.rb +151 -197
- data/lib/ib-ruby/models/execution.rb +27 -45
- data/lib/ib-ruby/models/model.rb +10 -4
- data/lib/ib-ruby/models/model_properties.rb +63 -0
- data/lib/ib-ruby/models/order.rb +274 -320
- data/lib/ib-ruby/symbols/stocks.rb +11 -5
- data/spec/account_helper.rb +80 -0
- data/spec/ib-ruby/connection_spec.rb +195 -52
- data/spec/ib-ruby/messages/incoming_spec.rb +4 -4
- data/spec/ib-ruby/models/combo_leg_spec.rb +1 -0
- data/spec/ib-ruby/models/contract_spec.rb +1 -1
- data/spec/ib-ruby/models/execution_spec.rb +73 -0
- data/spec/integration/account_info_spec.rb +12 -59
- data/spec/integration/contract_info_spec.rb +23 -37
- data/spec/integration/depth_data_spec.rb +4 -4
- data/spec/integration/historic_data_spec.rb +15 -27
- data/spec/integration/market_data_spec.rb +74 -61
- data/spec/integration/option_data_spec.rb +5 -48
- data/spec/integration/orders/execution_spec.rb +26 -31
- data/spec/integration/orders/open_order +2 -0
- data/spec/integration/orders/placement_spec.rb +28 -28
- data/spec/integration/orders/valid_ids_spec.rb +11 -11
- data/spec/integration_helper.rb +46 -32
- data/spec/message_helper.rb +4 -38
- data/spec/spec_helper.rb +2 -3
- metadata +9 -2
@@ -4,8 +4,8 @@ describe "Request Contract Info", :connected => true, :integration => true do
|
|
4
4
|
|
5
5
|
before(:all) do
|
6
6
|
verify_account
|
7
|
-
|
8
|
-
wait_for
|
7
|
+
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
8
|
+
@ib.wait_for :NextValidId
|
9
9
|
end
|
10
10
|
|
11
11
|
after(:all) { close_connection }
|
@@ -15,20 +15,17 @@ describe "Request Contract Info", :connected => true, :integration => true do
|
|
15
15
|
before(:all) do
|
16
16
|
@contract = IB::Models::Contract.new :symbol => 'AAPL',
|
17
17
|
:sec_type => IB::SECURITY_TYPES[:stock]
|
18
|
-
@ib.send_message :RequestContractData,
|
19
|
-
|
20
|
-
:contract => @contract
|
21
|
-
|
22
|
-
wait_for(3) { received? :ContractDataEnd }
|
18
|
+
@ib.send_message :RequestContractData, :id => 111, :contract => @contract
|
19
|
+
@ib.wait_for 3, :ContractDataEnd
|
23
20
|
end
|
24
21
|
|
25
22
|
after(:all) { clean_connection } # Clear logs and message collector
|
26
23
|
|
27
|
-
it { @received[:ContractData].should have_exactly(2).contract_data }
|
28
|
-
it { @received[:ContractDataEnd].should have_exactly(1).contract_data_end }
|
24
|
+
it { @ib.received[:ContractData].should have_exactly(2).contract_data }
|
25
|
+
it { @ib.received[:ContractDataEnd].should have_exactly(1).contract_data_end }
|
29
26
|
|
30
27
|
it 'receives Contract Data for requested contract' do
|
31
|
-
msg = @received[:ContractData].first
|
28
|
+
msg = @ib.received[:ContractData].first
|
32
29
|
msg.request_id.should == 111
|
33
30
|
msg.contract.should == @contract
|
34
31
|
end
|
@@ -36,7 +33,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
|
|
36
33
|
it 'receives Contract Data with extended fields' do
|
37
34
|
# Returns 2 contracts, one for NASDAQ and one for IBIS - internal crossing?
|
38
35
|
|
39
|
-
@received[:ContractData].each do |msg|
|
36
|
+
@ib.received[:ContractData].each do |msg|
|
40
37
|
contract = msg.contract
|
41
38
|
contract.symbol.should == 'AAPL'
|
42
39
|
|
@@ -68,19 +65,16 @@ describe "Request Contract Info", :connected => true, :integration => true do
|
|
68
65
|
:expiry => "201301",
|
69
66
|
:right => "CALL",
|
70
67
|
:strike => 500
|
71
|
-
@ib.send_message :RequestContractData,
|
72
|
-
|
73
|
-
:contract => @contract
|
74
|
-
|
75
|
-
wait_for(3) { received? :ContractDataEnd }
|
68
|
+
@ib.send_message :RequestContractData, :id => 123, :contract => @contract
|
69
|
+
@ib.wait_for 3, :ContractDataEnd
|
76
70
|
end
|
77
71
|
|
78
72
|
after(:all) { clean_connection } # Clear logs and message collector
|
79
73
|
|
80
|
-
subject { @received[:ContractData].first }
|
74
|
+
subject { @ib.received[:ContractData].first }
|
81
75
|
|
82
|
-
it { @received[:ContractData].should have_exactly(1).contract_data }
|
83
|
-
it { @received[:ContractDataEnd].should have_exactly(1).contract_data_end }
|
76
|
+
it { @ib.received[:ContractData].should have_exactly(1).contract_data }
|
77
|
+
it { @ib.received[:ContractDataEnd].should have_exactly(1).contract_data_end }
|
84
78
|
|
85
79
|
it 'receives Contract Data for requested contract' do
|
86
80
|
subject.request_id.should == 123
|
@@ -117,20 +111,16 @@ describe "Request Contract Info", :connected => true, :integration => true do
|
|
117
111
|
:currency => "USD",
|
118
112
|
:exchange => "IDEALPRO",
|
119
113
|
:sec_type => IB::SECURITY_TYPES[:forex]
|
120
|
-
|
121
|
-
@ib.
|
122
|
-
:id => 135,
|
123
|
-
:contract => @contract
|
124
|
-
|
125
|
-
wait_for(3) { received? :ContractDataEnd }
|
114
|
+
@ib.send_message :RequestContractData, :id => 135, :contract => @contract
|
115
|
+
@ib.wait_for 3, :ContractDataEnd
|
126
116
|
end
|
127
117
|
|
128
118
|
after(:all) { clean_connection } # Clear logs and message collector
|
129
119
|
|
130
|
-
subject { @received[:ContractData].first }
|
120
|
+
subject { @ib.received[:ContractData].first }
|
131
121
|
|
132
|
-
it { @received[:ContractData].should have_exactly(1).contract_data }
|
133
|
-
it { @received[:ContractDataEnd].should have_exactly(1).contract_data_end }
|
122
|
+
it { @ib.received[:ContractData].should have_exactly(1).contract_data }
|
123
|
+
it { @ib.received[:ContractDataEnd].should have_exactly(1).contract_data_end }
|
134
124
|
|
135
125
|
it 'receives Contract Data for requested contract' do
|
136
126
|
subject.request_id.should == 135
|
@@ -164,20 +154,16 @@ describe "Request Contract Info", :connected => true, :integration => true do
|
|
164
154
|
|
165
155
|
before(:all) do
|
166
156
|
@contract = IB::Symbols::Futures[:ym] # Mini Dow Jones Industrial
|
167
|
-
|
168
|
-
@ib.
|
169
|
-
:id => 147,
|
170
|
-
:contract => @contract
|
171
|
-
|
172
|
-
wait_for(3) { received? :ContractDataEnd }
|
157
|
+
@ib.send_message :RequestContractData, :id => 147, :contract => @contract
|
158
|
+
@ib.wait_for 3, :ContractDataEnd
|
173
159
|
end
|
174
160
|
|
175
161
|
after(:all) { clean_connection } # Clear logs and message collector
|
176
162
|
|
177
|
-
subject { @received[:ContractData].first }
|
163
|
+
subject { @ib.received[:ContractData].first }
|
178
164
|
|
179
|
-
it { @received[:ContractData].should have_exactly(1).contract_data }
|
180
|
-
it { @received[:ContractDataEnd].should have_exactly(1).contract_data_end }
|
165
|
+
it { @ib.received[:ContractData].should have_exactly(1).contract_data }
|
166
|
+
it { @ib.received[:ContractDataEnd].should have_exactly(1).contract_data_end }
|
181
167
|
|
182
168
|
it 'receives Contract Data for requested contract' do
|
183
169
|
subject.request_id.should == 147
|
@@ -5,12 +5,12 @@ describe 'Request Depth of Market Data', :connected => true,
|
|
5
5
|
|
6
6
|
before(:all) do
|
7
7
|
verify_account
|
8
|
-
|
8
|
+
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
9
9
|
|
10
10
|
@ib.send_message :RequestMarketDepth, :id => 456, :num_rows => 3,
|
11
11
|
:contract => IB::Symbols::Forex[:eurusd]
|
12
12
|
|
13
|
-
wait_for
|
13
|
+
@ib.wait_for 10, [:MarketDepth, 8]
|
14
14
|
end
|
15
15
|
|
16
16
|
after(:all) do
|
@@ -18,9 +18,9 @@ describe 'Request Depth of Market Data', :connected => true,
|
|
18
18
|
close_connection
|
19
19
|
end
|
20
20
|
|
21
|
-
subject { @received[:MarketDepth].last }
|
21
|
+
subject { @ib.received[:MarketDepth].last }
|
22
22
|
|
23
|
-
it { @received[:MarketDepth].should have_at_least(8).depth_data }
|
23
|
+
it { @ib.received[:MarketDepth].should have_at_least(8).depth_data }
|
24
24
|
|
25
25
|
it { should be_an IB::Messages::Incoming::MarketDepth }
|
26
26
|
its(:request_id) { should == 456 }
|
@@ -2,38 +2,33 @@ require 'integration_helper'
|
|
2
2
|
|
3
3
|
describe 'Request Historic Data', :connected => true, :integration => true do
|
4
4
|
|
5
|
+
CORRECT_OPTS = {:id => 456,
|
6
|
+
:contract => IB::Symbols::Stocks[:wfc],
|
7
|
+
:end_date_time => Time.now.to_ib,
|
8
|
+
:duration => '1 D',
|
9
|
+
:bar_size => '15 mins',
|
10
|
+
:what_to_show => :trades,
|
11
|
+
:format_date => 1}
|
5
12
|
before(:all) do
|
6
13
|
verify_account
|
7
|
-
|
14
|
+
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
8
15
|
end
|
9
16
|
|
10
17
|
after(:all) do
|
11
|
-
|
18
|
+
#@ib.send_message :CancelHistoricalData, :id => 456
|
12
19
|
close_connection
|
13
20
|
end
|
14
21
|
|
15
22
|
context 'Wrong Requests' do
|
16
23
|
it 'raises if incorrect bar size' do
|
17
24
|
expect do
|
18
|
-
@ib.send_message :RequestHistoricalData, :
|
19
|
-
:contract => IB::Symbols::Stocks[:wfc],
|
20
|
-
:end_date_time => Time.now.to_ib,
|
21
|
-
:duration => '1 D',
|
22
|
-
:bar_size => '11 min',
|
23
|
-
:what_to_show => :trades,
|
24
|
-
:format_date => 1
|
25
|
+
@ib.send_message :RequestHistoricalData, CORRECT_OPTS.merge(:bar_size => '11 min')
|
25
26
|
end.to raise_error /bar_size must be one of/
|
26
27
|
end
|
27
28
|
|
28
29
|
it 'raises if incorrect what_to_show' do
|
29
30
|
expect do
|
30
|
-
@ib.send_message :RequestHistoricalData, :
|
31
|
-
:contract => IB::Symbols::Stocks[:wfc],
|
32
|
-
:end_date_time => Time.now.to_ib,
|
33
|
-
:duration => '1 D',
|
34
|
-
:bar_size => '15 mins',
|
35
|
-
:what_to_show => :nonsense,
|
36
|
-
:format_date => 1
|
31
|
+
@ib.send_message :RequestHistoricalData, CORRECT_OPTS.merge(:what_to_show => :nonsense)
|
37
32
|
end.to raise_error /:what_to_show must be one of/
|
38
33
|
end
|
39
34
|
end
|
@@ -41,20 +36,13 @@ describe 'Request Historic Data', :connected => true, :integration => true do
|
|
41
36
|
context 'Correct Request' do
|
42
37
|
before(:all) do
|
43
38
|
# No historical data for GBP/CASH@IDEALPRO
|
44
|
-
@ib.send_message :RequestHistoricalData,
|
45
|
-
|
46
|
-
:end_date_time => Time.now.to_ib,
|
47
|
-
:duration => '1 D',
|
48
|
-
:bar_size => '15 mins',
|
49
|
-
:what_to_show => :trades,
|
50
|
-
:format_date => 1
|
51
|
-
|
52
|
-
wait_for(3) { received? :HistoricalData }
|
39
|
+
@ib.send_message :RequestHistoricalData, CORRECT_OPTS
|
40
|
+
@ib.wait_for 5, :HistoricalData
|
53
41
|
end
|
54
42
|
|
55
|
-
subject { @received[:HistoricalData].last }
|
43
|
+
subject { @ib.received[:HistoricalData].last }
|
56
44
|
|
57
|
-
it { @received[:HistoricalData].should have_at_least(1).historic_data }
|
45
|
+
it { @ib.received[:HistoricalData].should have_at_least(1).historic_data }
|
58
46
|
|
59
47
|
it { should be_an IB::Messages::Incoming::HistoricalData }
|
60
48
|
its(:request_id) { should == 456 }
|
@@ -1,17 +1,25 @@
|
|
1
1
|
require 'integration_helper'
|
2
|
+
#!/usr/bin/env ruby
|
2
3
|
|
4
|
+
require 'ib-ruby'
|
5
|
+
|
6
|
+
#OPTS[:silent] = false
|
3
7
|
describe 'Request Market Data', :connected => true, :integration => true do
|
4
8
|
|
5
|
-
|
9
|
+
require 'ib-ruby'
|
10
|
+
before(:all) { verify_account }
|
6
11
|
|
12
|
+
context 'US Stocks market', :if => :us_trading_hours do
|
7
13
|
before(:all) do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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"
|
20
|
+
)
|
21
|
+
@ib.send_message :RequestMarketData, :id => 456, :contract => @contract
|
22
|
+
@ib.wait_for 5, :TickSize, :TickString
|
15
23
|
end
|
16
24
|
|
17
25
|
after(:all) do
|
@@ -19,79 +27,84 @@ describe 'Request Market Data', :connected => true, :integration => true do
|
|
19
27
|
close_connection
|
20
28
|
end
|
21
29
|
|
22
|
-
|
23
|
-
subject { @received[:Alert].first }
|
30
|
+
it_behaves_like 'Received Market Data'
|
24
31
|
|
25
|
-
|
26
|
-
|
27
|
-
it { should_not be_error }
|
28
|
-
its(:code) { should be_an Integer }
|
29
|
-
its(:message) { should =~ /Market data farm connection is OK/ }
|
30
|
-
its(:to_human) { should =~ /TWS Warning/ }
|
31
|
-
end
|
32
|
+
context "received :TickString message" do
|
33
|
+
subject { @ib.received[:TickString].first }
|
32
34
|
|
33
|
-
|
34
|
-
subject { @received[:TickPrice].first }
|
35
|
-
|
36
|
-
it { should be_an IB::Messages::Incoming::TickPrice }
|
35
|
+
it { should be_an IB::Messages::Incoming::TickString }
|
37
36
|
its(:tick_type) { should be_an Integer }
|
38
37
|
its(:type) { should be_a Symbol }
|
39
|
-
its(:
|
40
|
-
its(:size) { should be_an Integer }
|
38
|
+
its(:value) { should be_a String }
|
41
39
|
its(:data) { should be_a Hash }
|
42
40
|
its(:ticker_id) { should == 456 } # ticker_id
|
43
|
-
its(:to_human) { should =~ /
|
41
|
+
its(:to_human) { should =~ /TickString/ }
|
44
42
|
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'FOREX market' do
|
46
|
+
context 'when subscribed to :Tick... messages' do
|
45
47
|
|
46
|
-
context "received :TickSize message", :if => :forex_trading_hours do
|
47
48
|
before(:all) do
|
48
|
-
|
49
|
+
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
50
|
+
|
51
|
+
##TODO consider a follow the sun market lookup for windening the types tested
|
52
|
+
@ib.subscribe(:Alert, :TickPrice, :TickSize) {}
|
53
|
+
@ib.send_message :RequestMarketData, :id => 456,
|
54
|
+
:contract => IB::Symbols::Forex[:eurusd]
|
55
|
+
|
56
|
+
@ib.wait_for 3, :TickPrice, :TickSize
|
49
57
|
end
|
50
58
|
|
51
|
-
|
59
|
+
after(:all) do
|
60
|
+
@ib.send_message :CancelMarketData, :id => 456
|
61
|
+
close_connection
|
62
|
+
end
|
52
63
|
|
53
|
-
|
54
|
-
its(:type) { should_not be_nil }
|
55
|
-
its(:data) { should be_a Hash }
|
56
|
-
its(:tick_type) { should be_an Integer }
|
57
|
-
its(:type) { should be_a Symbol }
|
58
|
-
its(:size) { should be_an Integer }
|
59
|
-
its(:ticker_id) { should == 456 }
|
60
|
-
its(:to_human) { should =~ /TickSize/ }
|
61
|
-
end
|
62
|
-
end # when subscribed to :Tick... messages
|
64
|
+
it_behaves_like 'Received Market Data'
|
63
65
|
|
64
|
-
|
66
|
+
it 'logs no warning about unhandled :Alert message' do
|
67
|
+
should_not_log /No subscribers for message .*:Alert/
|
68
|
+
end
|
65
69
|
|
66
|
-
|
67
|
-
|
70
|
+
it 'logs no warning about unhandled :Tick... messages' do
|
71
|
+
should_not_log /No subscribers for message .*:TickPrice/
|
72
|
+
end
|
68
73
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
74
|
+
it 'logs no warning about unhandled :Tick... messages', :if => :forex_trading_hours do
|
75
|
+
should_not_log /No subscribers for message .*:TickSize/
|
76
|
+
end
|
73
77
|
|
74
|
-
|
75
|
-
@ib.send_message :CancelMarketData, :id => 456
|
76
|
-
close_connection
|
77
|
-
end
|
78
|
+
end # when subscribed to :Tick... messages
|
78
79
|
|
79
|
-
|
80
|
-
should_log /No subscribers for message .*:OpenOrderEnd/
|
81
|
-
end
|
80
|
+
context 'when NOT subscribed to :Tick... messages', :slow => true do
|
82
81
|
|
83
|
-
|
84
|
-
|
85
|
-
end
|
82
|
+
before(:all) do
|
83
|
+
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
86
84
|
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
@ib.send_message :RequestMarketData, :id => 456,
|
86
|
+
:contract => IB::Symbols::Forex[:eurusd]
|
87
|
+
@ib.wait_for 3, :TickPrice, :TickSize
|
88
|
+
end
|
90
89
|
|
91
|
-
|
92
|
-
|
93
|
-
|
90
|
+
after(:all) do
|
91
|
+
@ib.send_message :CancelMarketData, :id => 456
|
92
|
+
close_connection
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'logs warning about unhandled :Alert message' do
|
96
|
+
should_log /No subscribers for message .*:Alert/
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'logs warning about unhandled :Tick... messages' do
|
100
|
+
should_log /No subscribers for message .*:TickPrice/
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'logs warning about unhandled :Tick... messages', :if => :forex_trading_hours do
|
104
|
+
should_log /No subscribers for message .*:TickSize/
|
105
|
+
end
|
94
106
|
|
95
|
-
|
107
|
+
end # NOT subscribed to :Tick... messages
|
108
|
+
end
|
96
109
|
|
97
110
|
end # Request Market Data
|
@@ -1,22 +1,15 @@
|
|
1
1
|
require 'integration_helper'
|
2
2
|
|
3
|
-
def wait_for_all_ticks
|
4
|
-
wait_for(5) do
|
5
|
-
received?(:TickPrice) && received?(:TickSize) &&
|
6
|
-
received?(:TickOption) && received?(:TickString)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
3
|
describe 'Request Market Data for Options', :if => :us_trading_hours,
|
11
4
|
:connected => true, :integration => true do
|
12
5
|
|
13
6
|
before(:all) do
|
14
7
|
verify_account
|
15
|
-
|
8
|
+
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
16
9
|
|
17
10
|
@ib.send_message :RequestMarketData, :id => 456,
|
18
11
|
:contract => IB::Symbols::Options[:aapl500]
|
19
|
-
|
12
|
+
@ib.wait_for 5, :TickPrice, :TickSize, :TickString, :TickOption
|
20
13
|
end
|
21
14
|
|
22
15
|
after(:all) do
|
@@ -24,46 +17,10 @@ describe 'Request Market Data for Options', :if => :us_trading_hours,
|
|
24
17
|
close_connection
|
25
18
|
end
|
26
19
|
|
27
|
-
|
28
|
-
subject { @received[:Alert].first }
|
29
|
-
|
30
|
-
it { should be_an IB::Messages::Incoming::Alert }
|
31
|
-
it { should be_warning }
|
32
|
-
it { should_not be_error }
|
33
|
-
its(:code) { should be_an Integer }
|
34
|
-
its(:message) { should =~ /Market data farm connection is OK/ }
|
35
|
-
its(:to_human) { should =~ /TWS Warning/ }
|
36
|
-
end
|
37
|
-
|
38
|
-
context "received :TickPrice message" do
|
39
|
-
subject { @received[:TickPrice].first }
|
40
|
-
|
41
|
-
it { should be_an IB::Messages::Incoming::TickPrice }
|
42
|
-
its(:tick_type) { should be_an Integer }
|
43
|
-
its(:type) { should be_a Symbol }
|
44
|
-
its(:price) { should be_a Float }
|
45
|
-
its(:size) { should be_an Integer }
|
46
|
-
its(:can_auto_execute) { should be_an Integer }
|
47
|
-
its(:data) { should be_a Hash }
|
48
|
-
its(:ticker_id) { should == 456 } # ticker_id
|
49
|
-
its(:to_human) { should =~ /TickPrice/ }
|
50
|
-
end
|
51
|
-
|
52
|
-
context "received :TickSize message" do
|
53
|
-
subject { @received[:TickSize].first }
|
54
|
-
|
55
|
-
it { should be_an IB::Messages::Incoming::TickSize }
|
56
|
-
its(:type) { should_not be_nil }
|
57
|
-
its(:data) { should be_a Hash }
|
58
|
-
its(:tick_type) { should be_an Integer }
|
59
|
-
its(:type) { should be_a Symbol }
|
60
|
-
its(:size) { should be_an Integer }
|
61
|
-
its(:ticker_id) { should == 456 }
|
62
|
-
its(:to_human) { should =~ /TickSize/ }
|
63
|
-
end
|
20
|
+
it_behaves_like 'Received Market Data'
|
64
21
|
|
65
22
|
context "received :TickOption message" do
|
66
|
-
subject { @received[:TickOption].first }
|
23
|
+
subject { @ib.received[:TickOption].first }
|
67
24
|
|
68
25
|
it { should be_an IB::Messages::Incoming::TickOption }
|
69
26
|
its(:type) { should_not be_nil }
|
@@ -82,7 +39,7 @@ describe 'Request Market Data for Options', :if => :us_trading_hours,
|
|
82
39
|
end
|
83
40
|
|
84
41
|
context "received :TickString message" do
|
85
|
-
subject { @received[:TickString].first }
|
42
|
+
subject { @ib.received[:TickString].first }
|
86
43
|
|
87
44
|
it { should be_an IB::Messages::Incoming::TickString }
|
88
45
|
its(:type) { should_not be_nil }
|
@@ -1,14 +1,5 @@
|
|
1
1
|
require 'integration_helper'
|
2
2
|
|
3
|
-
# TODO: RequestExecutions (with filters?)
|
4
|
-
|
5
|
-
def wait_for_execution_and_commission
|
6
|
-
wait_for(5) do
|
7
|
-
received?(:ExecutionData) && received?(:OpenOrder) &&
|
8
|
-
@received[:OpenOrder].last.order.commission
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
3
|
describe "Trades", :connected => true, :integration => true, :slow => true do
|
13
4
|
|
14
5
|
before(:all) { verify_account }
|
@@ -17,9 +8,8 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
|
|
17
8
|
|
18
9
|
before(:all) do
|
19
10
|
@contract = IB::Symbols::Forex[:eurusd]
|
20
|
-
|
21
|
-
|
22
|
-
wait_for { received? :NextValidID }
|
11
|
+
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
12
|
+
@ib.wait_for :NextValidId
|
23
13
|
end
|
24
14
|
|
25
15
|
after(:all) { close_connection }
|
@@ -32,7 +22,9 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
|
|
32
22
|
:limit_price => 2,
|
33
23
|
:action => 'BUY'
|
34
24
|
|
35
|
-
|
25
|
+
@ib.wait_for(5, :ExecutionData, :OpenOrder) do
|
26
|
+
@ib.received[:OpenOrder].last.order.commission
|
27
|
+
end
|
36
28
|
end
|
37
29
|
|
38
30
|
after(:all) do
|
@@ -45,19 +37,19 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
|
|
45
37
|
@ib.next_order_id.should == @order_id_before + 1
|
46
38
|
end
|
47
39
|
|
48
|
-
it { @received[:OpenOrder].should have_at_least(1).open_order_message }
|
49
|
-
it { @received[:OrderStatus].should have_at_least(1).status_message }
|
50
|
-
it { @received[:ExecutionData].should have_exactly(1).execution_data }
|
51
|
-
it { @received[:ExecutionDataEnd].should be_empty }
|
40
|
+
it { @ib.received[:OpenOrder].should have_at_least(1).open_order_message }
|
41
|
+
it { @ib.received[:OrderStatus].should have_at_least(1).status_message }
|
42
|
+
it { @ib.received[:ExecutionData].should have_exactly(1).execution_data }
|
43
|
+
it { @ib.received[:ExecutionDataEnd].should be_empty }
|
52
44
|
|
53
45
|
it 'receives filled OpenOrder' do
|
54
46
|
open_order_should_be 'Filled', -1
|
55
|
-
msg = @received[:OpenOrder].last
|
47
|
+
msg = @ib.received[:OpenOrder].last
|
56
48
|
msg.order.commission.should == 2.5
|
57
49
|
end
|
58
50
|
|
59
51
|
it 'receives Execution Data' do
|
60
|
-
execution_should_be
|
52
|
+
execution_should_be :buy
|
61
53
|
end
|
62
54
|
|
63
55
|
it 'receives OrderStatus with fill details' do
|
@@ -73,7 +65,9 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
|
|
73
65
|
:limit_price => 1,
|
74
66
|
:action => 'SELL'
|
75
67
|
|
76
|
-
|
68
|
+
@ib.wait_for(5, :ExecutionData, :OpenOrder) do
|
69
|
+
@ib.received[:OpenOrder].last.order.commission
|
70
|
+
end
|
77
71
|
end
|
78
72
|
|
79
73
|
after(:all) do
|
@@ -86,18 +80,18 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
|
|
86
80
|
@ib.next_order_id.should == @order_id_before + 1
|
87
81
|
end
|
88
82
|
|
89
|
-
it { @received[:OpenOrder].should have_at_least(1).open_order_message }
|
90
|
-
it { @received[:OrderStatus].should have_at_least(1).status_message }
|
91
|
-
it { @received[:ExecutionData].should have_exactly(1).execution_data }
|
83
|
+
it { @ib.received[:OpenOrder].should have_at_least(1).open_order_message }
|
84
|
+
it { @ib.received[:OrderStatus].should have_at_least(1).status_message }
|
85
|
+
it { @ib.received[:ExecutionData].should have_exactly(1).execution_data }
|
92
86
|
|
93
87
|
it 'receives filled OpenOrder' do
|
94
88
|
open_order_should_be 'Filled', -1
|
95
|
-
msg = @received[:OpenOrder].last
|
89
|
+
msg = @ib.received[:OpenOrder].last
|
96
90
|
msg.order.commission.should == 2.5
|
97
91
|
end
|
98
92
|
|
99
93
|
it 'receives Execution Data' do
|
100
|
-
execution_should_be
|
94
|
+
execution_should_be :sell
|
101
95
|
end
|
102
96
|
|
103
97
|
it 'receives OrderStatus with fill details' do
|
@@ -106,28 +100,29 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
|
|
106
100
|
end # Placing SELL
|
107
101
|
|
108
102
|
context "Request executions" do
|
103
|
+
# TODO: RequestExecutions with filters?
|
109
104
|
|
110
105
|
before(:all) do
|
111
106
|
@ib.send_message :RequestExecutions,
|
112
107
|
:request_id => 456,
|
113
108
|
:client_id => OPTS[:connection][:client_id],
|
114
|
-
:time => (Time.now-10).to_ib
|
115
|
-
wait_for
|
109
|
+
:time => (Time.now-10).to_ib # Time zone problems possible
|
110
|
+
@ib.wait_for 3, :ExecutionData
|
116
111
|
end
|
117
112
|
|
118
113
|
#after(:all) { clean_connection }
|
119
114
|
|
120
115
|
it 'does not receive Order-related messages' do
|
121
|
-
@received[:OpenOrder].should be_empty
|
122
|
-
@received[:OrderStatus].should be_empty
|
116
|
+
@ib.received[:OpenOrder].should be_empty
|
117
|
+
@ib.received[:OrderStatus].should be_empty
|
123
118
|
end
|
124
119
|
|
125
120
|
it 'receives ExecutionData messages' do
|
126
|
-
@received[:ExecutionData].should have_at_least(1).execution_data
|
121
|
+
@ib.received[:ExecutionData].should have_at_least(1).execution_data
|
127
122
|
end
|
128
123
|
|
129
124
|
it 'receives Execution Data' do
|
130
|
-
execution_should_be
|
125
|
+
execution_should_be :sell, :request_id => 456
|
131
126
|
end
|
132
127
|
end # Request executions
|
133
128
|
end # Forex order
|
@@ -1,3 +1,5 @@
|
|
1
|
+
This is just a dump file to compare received order messages:
|
2
|
+
|
1
3
|
[#<IB::Messages::Incoming::OpenOrder:0xfdc #<IB::Messages::Incoming::OpenOrder:0x10b8 #<IB::Messages::Incoming::OpenOrder:0x1198
|
2
4
|
@contract= @contract= @contract=
|
3
5
|
#<IB::Models::Contract:0xfe0 #<IB::Models::Contract:0x10bc #<IB::Models::Contract:0x119c
|