ib-ruby 0.7.0 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY CHANGED
@@ -137,3 +137,11 @@
137
137
  == 0.7.0 / 2012-03-22
138
138
 
139
139
  * Support for API v.967
140
+
141
+ == 0.7.1 / 2012-03-22
142
+
143
+ * Starting preparation for ActiveModel compatibility
144
+
145
+ == 0.7.2 / 2012-03-23
146
+
147
+ * Better spec documentation
data/README.md CHANGED
@@ -24,10 +24,10 @@ the same machine as TWS.
24
24
  As a rule of thumb, most recent version of ib-ruby gem only supports latest versions
25
25
  of TWS/Gateway API. Older versions of API are supported by previous gem versions:
26
26
 
27
- ib-ruby gem TWS version API version
28
- 0.5.21 918-920 965
29
- 0.6.1 921-923 966
30
- 0.7.1 924+ 967
27
+ ib-ruby gem TWS version API version
28
+ 0.5.21 918-920 965
29
+ 0.6.1 921-923 966
30
+ 0.7.1 924+ 967
31
31
 
32
32
  ## INSTALLATION:
33
33
 
@@ -92,6 +92,26 @@ The sample scripts in `bin` directory provide examples of how common tasks
92
92
  can be achieved using ib-ruby. You may also want to look into `spec/integration`
93
93
  directory for more scenarios and examples of handling IB messages.
94
94
 
95
+ ## RUNNING TESTS:
96
+
97
+ The gem comes with a spec suit that may be used to test ib-ruby compatibility
98
+ with your specific TWS/Gateway installation. The test suit should be run ONLY
99
+ against your IB paper trading account. Running it against live account may result
100
+ in financial losses.
101
+
102
+ In order to run tests, you should set up your IB paper trading connection parameters
103
+ in 'spec/spec_helper' file. Modify account_name, host and port under section
104
+ 'Your IB PAPER ACCOUNT'. Do not change the client_id.
105
+
106
+ Before running tests, you need to start your TWS/Gateway and allow API connection.
107
+ You should not have any open/pending orders on your IB paper trading account prior
108
+ to running tests, otherwise some tests will fail. Use 'bin/cancel_orders' script for
109
+ bulk cancelling of open orders before running tests as needed.
110
+
111
+ You can easily create your own tests following the guide in 'spec/README'.
112
+ Help the development! See 'spec/TODO' for the list of use cases/scenarios
113
+ that still need to be tested.
114
+
95
115
  ## LICENSE:
96
116
 
97
117
  This software is available under the LGPL.
data/TODO CHANGED
@@ -12,15 +12,9 @@ http://finance.groups.yahoo.com/group/TWSAPI/message/25413
12
12
 
13
13
  5. IB Connection reconnects gracefully in case if TWS disconnects/reconnects
14
14
 
15
- 6. Compatibility check for new TWS v.966
15
+ 6. @received_at timestamp in messages
16
16
 
17
- 7. @received_at timestamp in messages
18
-
19
- 8. Collect all messages in Connection#received_messages
20
-
21
- 9. Flow handlers: Connection#wait_for / Connection#received?
22
-
23
- 10. Create integration tests for more use cases (spec/README)
17
+ 7. Create integration tests for more use cases (spec/README)
24
18
 
25
19
 
26
20
  Done:
@@ -29,6 +23,12 @@ Done:
29
23
 
30
24
  2. IB#subscribe should accept regexes.
31
25
 
26
+ 3. Compatibility with for API v.966, 967
27
+
28
+ 4. Collect all received messages in Connection#received[:type] by default
29
+
30
+ 5. Flow handlers: Connection#wait_for / Connection#received?
31
+
32
32
  Ideas for future:
33
33
 
34
34
  1. Decouple Broker-specific Adapter from universal high-level messaging layer
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.0
1
+ 0.7.2
data/bin/account_info CHANGED
@@ -12,7 +12,7 @@ require 'bundler/setup'
12
12
  require 'ib-ruby'
13
13
 
14
14
  # First, connect to IB TWS.
15
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
15
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
16
16
 
17
17
  # Set log level
18
18
  log.level = Logger::FATAL
data/bin/cancel_orders CHANGED
@@ -13,7 +13,7 @@ require 'bundler/setup'
13
13
  require 'ib-ruby'
14
14
 
15
15
  # First, connect to IB TWS.
16
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
16
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
17
17
 
18
18
  # Subscribe to TWS alerts/errors and order-related messages
19
19
  ib.subscribe(:Alert, :OpenOrder, :OrderStatus, :OpenOrderEnd) { |msg| puts msg.to_human }
data/bin/contract_details CHANGED
@@ -18,7 +18,7 @@ require 'ib-ruby'
18
18
  144 => IB::Symbols::Stocks[:wrong]}
19
19
 
20
20
  # Connect to IB TWS.
21
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
21
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
22
22
 
23
23
  # Subscribe to TWS alerts/errors
24
24
  ib.subscribe(IB::Messages::Incoming::Alert) { |msg| puts msg.to_human }
data/bin/depth_of_market CHANGED
@@ -20,7 +20,7 @@ require 'ib-ruby'
20
20
  }
21
21
 
22
22
  # First, connect to IB TWS.
23
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
23
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
24
24
 
25
25
  # Subscribe to TWS alerts/errors
26
26
  ib.subscribe(:Alert) { |msg| puts msg.to_human }
data/bin/historic_data CHANGED
@@ -19,7 +19,7 @@ require 'ib-ruby'
19
19
  }
20
20
 
21
21
  # Connect to IB TWS.
22
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
22
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
23
23
 
24
24
  # Subscribe to TWS alerts/errors
25
25
  ib.subscribe(:Alert) { |msg| puts msg.to_human }
@@ -133,7 +133,7 @@ DATE_FORMAT = (opt["dateformat"] && opt["dateformat"].to_i) || 1
133
133
  PORT = (opt["port"] && opt["port"]) || '4001'
134
134
 
135
135
  # First, connect to IB TWS.
136
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
136
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
137
137
 
138
138
  # Subscribe to TWS alerts/errors
139
139
  ib.subscribe(:Alert) { |msg| puts msg.to_human }
data/bin/list_orders CHANGED
@@ -9,10 +9,11 @@ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
9
9
 
10
10
  require 'rubygems'
11
11
  require 'bundler/setup'
12
+ require 'pp'
12
13
  require 'ib-ruby'
13
14
 
14
- # First, connect to IB TWS.
15
- ib = IB::Connection.new :client_id => 0 # All Orders, including TWS-generated ones
15
+ # Connect to IB as 0 (TWS) to retrieve all Orders, including TWS-generated ones
16
+ ib = IB::Connection.new :client_id => 0 #, :port => 7496 # TWS
16
17
 
17
18
  # Subscribe to TWS alerts/errors and order-related messages
18
19
  @counter = 0
@@ -22,9 +23,11 @@ ib.subscribe(:Alert, :OrderStatus, :OpenOrderEnd) { |msg| puts msg.to_human }
22
23
  ib.subscribe(:OpenOrder) do |msg|
23
24
  @counter += 1
24
25
  puts "#{@counter}: #{msg.to_human}"
26
+ pp msg.order
25
27
  end
26
28
 
27
29
  ib.send_message :RequestAllOpenOrders
28
30
 
29
31
  # Wait for IB to respond to our request
30
32
  ib.wait_for :OpenOrderEnd
33
+ sleep 1 # Let printer do the job
data/bin/market_data CHANGED
@@ -18,7 +18,7 @@ require 'ib-ruby'
18
18
  789 => IB::Symbols::Forex[:usdcad]}
19
19
 
20
20
  # First, connect to IB TWS.
21
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
21
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
22
22
 
23
23
  ## Subscribe to TWS alerts/errors
24
24
  ib.subscribe(:Alert) { |msg| puts msg.to_human }
data/bin/option_data CHANGED
@@ -18,8 +18,8 @@ require 'ib-ruby'
18
18
  17 => IB::Symbols::Options[:spy75],
19
19
  19 => IB::Symbols::Options[:spy100]}
20
20
 
21
- # First, connect to IB TWS.
22
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
21
+ # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
22
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
23
23
 
24
24
  ## Subscribe to TWS alerts/errors
25
25
  ib.subscribe(:Alert) { |msg| puts msg.to_human }
@@ -39,12 +39,12 @@ def butterfly symbol, expiry, right, *strikes
39
39
  end
40
40
 
41
41
 
42
- # First, connect to IB TWS.
43
- @ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
44
- @ib.wait_for :NextValidId
42
+ # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
43
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
45
44
 
46
45
  # Subscribe to TWS alerts/errors and order-related messages
47
46
  @ib.subscribe(:Alert, :OpenOrder, :OrderStatus) { |msg| puts msg.to_human }
47
+ @ib.wait_for :NextValidId
48
48
 
49
49
  # Create multi-legged option Combo using utility method above
50
50
  combo = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
data/bin/place_order CHANGED
@@ -11,8 +11,8 @@ require 'rubygems'
11
11
  require 'bundler/setup'
12
12
  require 'ib-ruby'
13
13
 
14
- # First, connect to IB TWS.
15
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
14
+ # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
15
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
16
16
 
17
17
  # Subscribe to TWS alerts/errors and order-related messages
18
18
  ib.subscribe(:Alert, :OpenOrder, :OrderStatus) { |msg| puts msg.to_human }
data/bin/template CHANGED
@@ -10,8 +10,8 @@ require 'rubygems'
10
10
  require 'bundler/setup'
11
11
  require 'ib-ruby'
12
12
 
13
- # Connect to IB TWS.
14
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
13
+ # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
14
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
15
15
 
16
16
  # Subscribe to TWS alerts/errors
17
17
  ib.subscribe(:Alert) { |msg| puts msg.to_human }
data/bin/tick_data CHANGED
@@ -16,7 +16,8 @@ contract = IB::Models::Contract.new :symbol=> 'AAPL',
16
16
  :sec_type=> IB::SECURITY_TYPES[:stock],
17
17
  :description=> "Some stock"
18
18
 
19
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
19
+ # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
20
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
20
21
 
21
22
  ib.subscribe(:Alert) { |msg| puts msg.to_human }
22
23
  ib.subscribe(:TickGeneric, :TickString, :TickPrice, :TickSize) { |msg| puts msg.inspect }
data/bin/time_and_sales CHANGED
@@ -20,14 +20,12 @@ require 'ib-ruby'
20
20
  # To determine when the timeout has passed.
21
21
  @last_msg_time = Time.now.to_i + 2
22
22
 
23
- # Connect to IB TWS.
24
- ib = IB::Connection.new :client_id => 1112 # Arbitrary id to identify your script
23
+ # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
24
+ ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
25
25
 
26
26
  # Subscribe to TWS alerts/errors
27
27
  ib.subscribe(:Alert) { |msg| puts msg.to_human }
28
28
 
29
- MIN_SIZE = 0
30
-
31
29
  # This method filters out non-:last type events, and filters out any sale < MIN_SIZE.
32
30
  # Note that we have to look the ticker id of each incoming message
33
31
  # up in local memory to figure out what it's for.
@@ -73,6 +73,15 @@ module IB
73
73
 
74
74
  class OpenOrder
75
75
 
76
+ # Accessors to make OpenOrder API-compatible with OrderStatus message
77
+ def order_id
78
+ order && order.order_id
79
+ end
80
+
81
+ def status
82
+ order && order.status
83
+ end
84
+
76
85
  def load
77
86
  super
78
87
 
@@ -475,7 +475,6 @@ module IB
475
475
  aux_price == other.aux_price &&
476
476
  outside_rth == other.outside_rth &&
477
477
  origin == other.origin &&
478
- transmit == other.transmit &&
479
478
  designated_location == other.designated_location &&
480
479
  exempt_code == other.exempt_code &&
481
480
  what_if == other.what_if &&
data/spec/README.md CHANGED
@@ -2,33 +2,41 @@
2
2
 
3
3
  Pattern for writing integration specs is like this:
4
4
 
5
- 1. You define your user scenario (such as: subscribe for FOREX market data).
5
+ 1. You define your user scenario (such as: subscribe for FUTURES market data).
6
6
 
7
7
  2. You find out experimentally, what messages should be sent to IB to accomplish it,
8
8
  and what messages are sent by IB in return.
9
9
 
10
- 3. You start writing spec, requiring 'integration_helper'.
10
+ 3. You start writing spec, requiring 'integration_helper'. Don't forget to
11
+ 'verify_account'! Running tests against live IB account can be pretty painful.
11
12
 
12
- 4. Indicate your interest in incoming message types by calling 'connect_and_receive'
13
- in a top-level before(:all) block. All messages of given types will be caught
14
- and placed into @received Hash, keyed by message type.
13
+ 4. Establish connection in a top-level before(:all) block. Wait for IB to deliver
14
+ initial messages/data, for example using '@ib.wait_for :NextValidId' idiom.
15
15
 
16
- 5. All log entries produced by ib-ruby will be caught and placed into log_entries Array.
16
+ 5. Now, you set up your context and send appropriate request messages to IB. Once
17
+ messages are sent, you need to give the server time to respond. The proper way
18
+ to do it is by '@ib.wait_for' specific message type that indicates that your
19
+ request was answered. For example, if you send :RequestOpenOrders, then received
20
+ :OpenOrdersEnd will be a sign that your request was processed. Usually, you
21
+ wait_for in a context before(:all) block.
17
22
 
18
- 6. You send request messages to IB and then wait for specific conditions (or timeout)
19
- by calling 'wait_for' (usually, in a context before(:all) block).
23
+ 6. It is now time to examine what responses you've got from IB and see if they meet
24
+ your expectations. All messages received frem IB are caught and placed into
25
+ @ib.received Hash, keyed by message type. The Hash has following structure:
26
+ {:MessageType1 => [msg1, msg2, msg3...], :MessageType2 => [msg1, msg2, msg3...] }.
20
27
 
21
- 7. Once the conditions are satisfied, your examples can test the content of @received
22
- Hash to see what messages were received, or log_entries Array to see what was logged
28
+ 7. If you created @ib Connection with mock_logger, all log entries produced by IB
29
+ will be also caught and placed into log_entries Array.
23
30
 
24
- 8. When done, you call 'close_connection' in a top-level after(:all) block.
31
+ 8. Your examples can thus test the content of @ib.received Hash to see what messages
32
+ were received, or log_entries Array to see what was logged.
25
33
 
26
- TODO: Add more scenarios:
27
- 1. RealTimeBars
28
- 2. BondContractData
29
- 3. RequestScannerParameters + RequestScannerSubscription
30
- 4. RequestFundamentalData
31
- 5. ExerciseOptions
32
- 6. RequestMarketData + special tick list
33
- 7. RequestNewsBulletins
34
- 8. RequestImpliedVolatility / RequestOptionPrice
34
+ 9. When done with this context, you call 'close_connection' helper in a top-level
35
+ after(:all) block to get rid of your active connection.
36
+
37
+ 10. If you reuse the connection between contexts and requests, it is recommended to
38
+ call 'clean_connection' in after block to remove old content from @ib.received Hash,
39
+ or otherwise manually clean it to remove old/not needed messages from it.
40
+
41
+ Help the development!
42
+ See 'spec/TODO' file for list of scenarios that still need to be tested.
data/spec/TODO ADDED
@@ -0,0 +1,10 @@
1
+ TODO: Add more scenarios:
2
+
3
+ 1. RealTimeBars
4
+ 2. BondContractData
5
+ 3. RequestScannerParameters + RequestScannerSubscription
6
+ 4. RequestFundamentalData
7
+ 5. ExerciseOptions
8
+ 6. RequestMarketData + special tick list
9
+ 7. RequestNewsBulletins
10
+ 8. RequestImpliedVolatility / RequestOptionPrice
@@ -7,7 +7,7 @@ shared_examples_for 'Alert message' do
7
7
  its(:message_type) { should == :Alert }
8
8
  its(:message_id) { should == 4 }
9
9
  its(:version) { should == 2 }
10
- its(:data) { should == {:version=>2, :error_id=>-1, :code=>2104, :message=>"Market data farm connection is OK:cashfarm"} }
10
+ its(:data) { should_not be_empty }
11
11
  its(:error_id) { should == -1 }
12
12
  its(:code) { should == 2104 }
13
13
  its(:message) { should =~ /Market data farm connection is OK/ }
@@ -28,7 +28,7 @@ def butterfly symbol, expiry, right, *strikes
28
28
  :legs => legs
29
29
  end
30
30
 
31
- describe "Combo Order", :connected => true, :integration => true do
31
+ describe "Combo Order", :connected => true, :integration => true, :slow => true do
32
32
 
33
33
  before(:all) { verify_account }
34
34
 
@@ -38,14 +38,60 @@ describe "Combo Order", :connected => true, :integration => true do
38
38
  @ib.wait_for :NextValidId
39
39
  @ib.clear_received # to avoid conflict with pre-existing Orders
40
40
 
41
- @combo = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
41
+ @contract = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
42
42
 
43
- place_order @combo, :limit_price => 0.01 #, :what_if => true
44
- @ib.wait_for [:OpenOrder, 3], [:OrderStatus, 2], 5
43
+ place_order @contract, :limit_price => 0.01 #, :what_if => true
44
+ @ib.wait_for :OpenOrder, :OrderStatus, 5
45
45
  end
46
46
 
47
47
  after(:all) { close_connection }
48
48
 
49
49
  it_behaves_like 'Placed Order'
50
50
  end # Limit
51
+
52
+ context "Limit with attached takeprofit" do
53
+ before(:all) do
54
+ @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
55
+ @ib.wait_for :NextValidId
56
+ @ib.clear_received # to avoid conflict with pre-existing Orders
57
+
58
+ @contract = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
59
+
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 }
65
+
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
69
+ end
70
+
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, :OrderStatus, 5
82
+ end
83
+
84
+ it_behaves_like 'Placed Order'
85
+ end
86
+
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
51
96
  end # Combo Orders
97
+
@@ -50,7 +50,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
50
50
  it { @ib.received[:ExecutionDataEnd].should be_empty }
51
51
 
52
52
  it 'receives filled OpenOrder' do
53
- order_should_be 'Filled', -1
53
+ order_should_be 'Filled'
54
54
  msg = @ib.received[:OpenOrder].last
55
55
  msg.order.commission.should == 2.5
56
56
  end
@@ -60,7 +60,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
60
60
  end
61
61
 
62
62
  it 'receives OrderStatus with fill details' do
63
- status_should_be 'Filled', -1
63
+ status_should_be 'Filled'
64
64
  end
65
65
  end # Placing BUY
66
66
 
@@ -92,7 +92,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
92
92
  it { @ib.received[:ExecutionData].should have_exactly(1).execution_data }
93
93
 
94
94
  it 'receives filled OpenOrder' do
95
- order_should_be 'Filled', -1
95
+ order_should_be 'Filled'
96
96
  msg = @ib.received[:OpenOrder].last
97
97
  msg.order.commission.should == 2.5
98
98
  end
@@ -102,7 +102,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
102
102
  end
103
103
 
104
104
  it 'receives OrderStatus with fill details' do
105
- status_should_be 'Filled', -1
105
+ status_should_be 'Filled'
106
106
  end
107
107
  end # Placing SELL
108
108
 
@@ -77,3 +77,22 @@ This is just a dump file to compare received order messages:
77
77
  :why_held=>""},
78
78
  @socket=nil>]
79
79
 
80
+ Original Combo: Attached Auto Combo Limit:
81
+
82
+ <Order: LMT DAY BUY 100 PreSubmitted 0.01 2: <Order: LMT DAY SELL 100 PreSubmitted 1.01
83
+ id: 3/173276893 from: 1111/DU118180>> id: 0/173276895 from: 0/DU118180>>
84
+ #<IB::Models::Order:0xfa0 #<IB::Models::Order:0x102c
85
+ @action="BUY", @action="SELL",
86
+ @client_id=1111, @client_id=0, # Attached via TWS
87
+ @created_at=Fri Mar 23 09:09:16 +0400 2012, @created_at=Fri Mar 23 09:09:16 +0400 2012,
88
+ @limit_price=0.01, @limit_price=1.01,
89
+ @oca_group="", @oca_group="173276893",
90
+ @oca_type=3, @oca_type=3,
91
+ @order_id=3, @order_id=0,
92
+ @order_type="LMT", @order_type="LMT",
93
+ @parent_id=0, @parent_id=3,
94
+ @perm_id=173276893, @perm_id=173276895,
95
+ @status="PreSubmitted", @status="PreSubmitted",
96
+ @tif="DAY", @tif="DAY",
97
+ @total_quantity=100, @total_quantity=100,
98
+ @what_if=false> @what_if=false>
data/spec/order_helper.rb CHANGED
@@ -6,7 +6,7 @@ shared_examples_for 'Placed Order' do
6
6
 
7
7
  it 'changes client`s next_order_id' do
8
8
  @order_id_placed.should == @order_id_before
9
- @ib.next_order_id.should == @order_id_before + 1
9
+ @ib.next_order_id.should be >= @order_id_before
10
10
  end
11
11
 
12
12
  it { @ib.received[:OpenOrder].should have_at_least(1).order_message }
@@ -30,10 +30,11 @@ shared_examples_for 'Placed Order' do
30
30
  @ib.next_order_id.should == @order_id_after
31
31
  end
32
32
 
33
- it { @ib.received[:OpenOrder].should have_exactly(1).order_message }
34
- it { @ib.received[:OrderStatus].should have_exactly(1).status_message }
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
35
  it { @ib.received[:OpenOrderEnd].should have_exactly(1).order_end_message }
36
- it { @ib.received[:Alert].should have_exactly(0).alert_messages }
36
+
37
+ #it { @ib.received[:Alert].should have_exactly(0).alert_messages }
37
38
 
38
39
  it 'receives OpenOrder and OrderStatus for placed order' do
39
40
  order_should_be /Submitted/
@@ -44,7 +45,7 @@ shared_examples_for 'Placed Order' do
44
45
  context "Cancelling placed order" do
45
46
  before(:all) do
46
47
  @ib.cancel_order @order_id_placed
47
- @ib.wait_for :OrderStatus, :Alert
48
+ @ib.wait_for [:OrderStatus, 2], :Alert
48
49
  end
49
50
 
50
51
  after(:all) { clean_connection } # Clear logs and message collector
@@ -57,8 +58,8 @@ shared_examples_for 'Placed Order' do
57
58
  @ib.received?(:OpenOrder).should be_false
58
59
  end
59
60
 
60
- it { @ib.received[:OrderStatus].should have_exactly(1).status_message }
61
- it { @ib.received[:Alert].should have_exactly(1).alert_message }
61
+ it { @ib.received[:OrderStatus].should have_at_least(1).status_message }
62
+ it { @ib.received[:Alert].should have_at_least(1).alert_message }
62
63
 
63
64
  it 'receives cancellation Order Status' do
64
65
  status_should_be /Cancel/ # Cancelled / PendingCancel
@@ -86,24 +87,18 @@ def place_order contract, opts
86
87
  @order_id_after = @ib.next_order_id
87
88
  end
88
89
 
89
- def check_status item, status
90
- case status
91
- when Regexp
92
- item.status.should =~ status
93
- when String
94
- item.status.should == status
90
+ def status_should_be status
91
+ msg = @ib.received[:OrderStatus].find do |msg|
92
+ msg.order_id == @order_id_placed &&
93
+ status.is_a?(Regexp) ? msg.status =~ status : msg.status == status
95
94
  end
96
- end
97
-
98
- def status_should_be status, index=0
99
- msg = @ib.received[:OrderStatus][index]
95
+ msg.should_not be_nil
100
96
  msg.should be_an IB::Messages::Incoming::OrderStatus
101
97
  msg.order_id.should == @order_id_placed
102
98
  msg.perm_id.should be_an Integer
103
99
  msg.client_id.should == OPTS[:connection][:client_id]
104
100
  msg.parent_id.should == 0
105
101
  msg.why_held.should == ''
106
- check_status msg, status
107
102
 
108
103
  if @contract == IB::Symbols::Forex[:eurusd]
109
104
  msg.filled.should == 20000
@@ -119,13 +114,16 @@ def status_should_be status, index=0
119
114
  end
120
115
  end
121
116
 
122
- def order_should_be status, index=0
123
- msg = @ib.received[:OpenOrder][index]
117
+ def order_should_be status
118
+ msg = @ib.received[:OpenOrder].find do |msg|
119
+ msg.order_id == @order_id_placed &&
120
+ status.is_a?(Regexp) ? msg.status =~ status : msg.status == status
121
+ end
122
+ msg.should_not be_nil
124
123
  msg.should be_an IB::Messages::Incoming::OpenOrder
125
124
  msg.order.should == @order
126
125
  msg.contract.should == @contract
127
126
  msg.order.order_id.should == @order_id_placed
128
- check_status msg.order, status
129
127
  end
130
128
 
131
129
  def execution_should_be side, opts={}
data/spec/spec_helper.rb CHANGED
@@ -41,6 +41,6 @@ else
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
43
  :host => '10.211.55.2', # Where your TWS/gateway is located, likely 'localhost'
44
- :port=> 4001 # 4001 for Gateway, 7496 for TWS GUI
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.0
5
+ version: 0.7.2
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-22 00:00:00 Z
14
+ date: 2012-03-23 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -119,6 +119,7 @@ files:
119
119
  - spec/order_helper.rb
120
120
  - spec/README.md
121
121
  - spec/spec_helper.rb
122
+ - spec/TODO
122
123
  - spec/ib-ruby/connection_spec.rb
123
124
  - spec/ib-ruby/messages/incoming_spec.rb
124
125
  - spec/ib-ruby/messages/outgoing_spec.rb
@@ -184,6 +185,7 @@ test_files:
184
185
  - spec/order_helper.rb
185
186
  - spec/README.md
186
187
  - spec/spec_helper.rb
188
+ - spec/TODO
187
189
  - spec/ib-ruby/connection_spec.rb
188
190
  - spec/ib-ruby/messages/incoming_spec.rb
189
191
  - spec/ib-ruby/messages/outgoing_spec.rb