ib-ruby 0.7.0 → 0.7.2

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