ib-ruby 0.7.12 → 0.8.0

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.
@@ -203,3 +203,9 @@ describe "Request Contract Info", :connected => true, :integration => true do
203
203
  end
204
204
  end # Request Forex data
205
205
  end # Contract Data
206
+
207
+
208
+ __END__
209
+ ContractData messages v.6 and 8 identical:
210
+ 10-8-500-GOOG-OPT-20130118-500-C-SMART-USD-GOOG 130119C00500000-GOOG-GOOG-81032967-0.05-100-ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKET,COND,CONDORDER,DAY,DEACT,DEACTDIS,DEACTEOD,FOK,GAT,GTC,GTD,GTT,HID,ICE,IOC,LIT,LMT,MIT,MKT,MTL,NONALGO,OCA,PAON,POSTONLY,RELSTK,SCALE,SCALERST,SMARTSTG,STP,STPLMT,TRAIL,TRAILLIT,TRAILLMT,TRAILMIT,VOLAT,WHATIF,-SMART,AMEX,BATS,BOX,CBOE,CBOE2,IBSX,ISE,MIBSX,NASDAQOM,PHLX,PSE-1-30351181-GOOGLE INC-CL A--201301-Communications-Internet-Web Portals/ISP-EST-20120428:CLOSED;20120430:0930-1600-20120428:CLOSED;20120430:0930-1600-
211
+ 10-6-500-GOOG-OPT-20130118-500-C-SMART-USD-GOOG 130119C00500000-GOOG-GOOG-81032967-0.01-100-ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKET,COND,CONDORDER,DAY,DEACT,DEACTDIS,DEACTEOD,FOK,GAT,GTC,GTD,GTT,HID,ICE,IOC,LIT,LMT,MIT,MKT,MTL,NONALGO,OCA,PAON,POSTONLY,RELSTK,SCALE,SCALERST,SMARTSTG,STP,STPLMT,TRAIL,TRAILLIT,TRAILLMT,TRAILMIT,VOLAT,WHATIF,-SMART,AMEX,BATS,BOX,CBOE,CBOE2,IBSX,ISE,MIBSX,NASDAQOM,PHLX,PSE-1-30351181-GOOGLE INC-CL A--201301-Communications-Internet-Web Portals/ISP-EST-20120428:CLOSED;20120430:0930-1600-20120428:CLOSED;20120430:0930-1600-
@@ -4,8 +4,8 @@ require 'combo_helper'
4
4
  def define_contracts
5
5
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
6
6
  @contracts = {
7
- :stock => IB::Symbols::Stocks[:wfc],
8
- :butterfly => butterfly('GOOG', '201301', 'CALL', 500, 510, 520)
7
+ :stock => IB::Symbols::Stocks[:wfc],
8
+ :butterfly => butterfly('GOOG', '201301', 'CALL', 500, 510, 520)
9
9
  }
10
10
  close_connection
11
11
  end
@@ -19,13 +19,12 @@ describe 'Attached Orders', :connected => true, :integration => true do
19
19
 
20
20
  # Testing different combinations of Parent + Attached Orders:
21
21
  [
22
- [:stock, 100, 'DAY', 'LMT', 9.13, 20.0], # Parent + takeprofit target
23
- #[:stock, 100, 'DAY', 'STP', 9.13, 0.0, 8.0], # Parent + stoploss
24
- #[:stock, 100, 'GTC', 'LMT', 9.13, 20.0], # GTC Parent + target
25
- [:butterfly, 10, 'DAY', 'LMT', 0.05, 1.0], # Combo Parent + target
26
- #[:butterfly, 10, 'GTC', 'LMT', 0.05, 1.0], # GTC Combo Parent + target
27
- #[:butterfly, 100, 'GTC', 'STPLMT', 0.05, 0.05, 1.0], # GTC Combo Parent + stoplimit target
28
-
22
+ [:stock, 100, 'DAY', 'LMT', 9.13, 20.0], # Parent + takeprofit target
23
+ #[:stock, 100, 'DAY', 'STP', 9.13, 0.0, 8.0], # Parent + stoploss
24
+ #[:stock, 100, 'GTC', 'LMT', 9.13, 20.0], # GTC Parent + target
25
+ [:butterfly, 10, 'DAY', 'LMT', 0.05, 1.0], # Combo Parent + target
26
+ #[:butterfly, 10, 'GTC', 'LMT', 0.05, 1.0], # GTC Combo Parent + target
27
+ #[:butterfly, 100, 'GTC', 'STPLMT', 0.05, 0.05, 1.0], # GTC Combo Parent + stoplimit target
29
28
  ].each do |(contract, qty, tif, attach_type, limit_price, attach_price, aux_price)|
30
29
  context "#{tif} BUY (#{contract}) limit order with attached #{attach_type} SELL" do
31
30
  let(:contract_type) { contract }
@@ -38,10 +37,10 @@ describe 'Attached Orders', :connected => true, :integration => true do
38
37
  #p [contract, qty, tif, attach_type, limit_price, attach_price, aux_price]
39
38
  @contract = @contracts[contract]
40
39
  place_order @contract,
41
- :total_quantity => qty,
42
- :limit_price => limit_price,
43
- :tif => tif,
44
- :transmit => false
40
+ :total_quantity => qty,
41
+ :limit_price => limit_price,
42
+ :tif => tif,
43
+ :transmit => false
45
44
 
46
45
  @ib.wait_for :OpenOrder, :OrderStatus, 2
47
46
  end
@@ -56,12 +55,12 @@ describe 'Attached Orders', :connected => true, :integration => true do
56
55
  context "Attaching #{attach_type} order" do
57
56
  before(:all) do
58
57
  @attached_order = IB::Order.new :limit_price => attach_price,
59
- :aux_price => aux_price || 0,
60
- :total_quantity => qty,
61
- :side => :sell,
62
- :tif => tif,
63
- :order_type => attach_type,
64
- :parent_id => @local_id_placed
58
+ :aux_price => aux_price || 0,
59
+ :total_quantity => qty,
60
+ :side => :sell,
61
+ :tif => tif,
62
+ :order_type => attach_type,
63
+ :parent_id => @local_id_placed
65
64
 
66
65
  @local_id_attached = @ib.place_order @attached_order, @contract
67
66
  @local_id_after = @ib.next_local_id
@@ -82,3 +82,4 @@ describe "Combo Order", :connected => true, :integration => true, :slow => true
82
82
  end # Limit
83
83
  end # Combo Orders
84
84
 
85
+ __END__
@@ -1,5 +1,48 @@
1
1
  require 'order_helper'
2
2
 
3
+ def commission_report_should_be status=:with_pnl, exec=@ib.received[:ExecutionData].last.execution
4
+ msg = @ib.received[:CommissionReport].find { |msg| msg.exec_id == exec.exec_id }
5
+ msg.should_not be_nil
6
+ msg.should be_an IB::Messages::Incoming::CommissionReport
7
+
8
+ msg.exec_id.should == exec.exec_id
9
+ msg.commission.should == 2.5 # Fixed commission for Forex
10
+ msg.currency.should == 'USD'
11
+ msg.yield.should be_nil
12
+ msg.yield_redemption_date.should == 0 # no date, YYYYMMDD format for bonds
13
+
14
+ if status == :with_pnl
15
+ msg.realized_pnl.should be_a Float
16
+ msg.realized_pnl.should be < 10000 # Not Double.MAX_VALUE
17
+ else
18
+ msg.realized_pnl.should be_nil
19
+ end
20
+ end
21
+
22
+ def execution_should_be side, opts={}
23
+ msg = @ib.received[:ExecutionData][opts[:index] || -1]
24
+ msg.request_id.should == (opts[:request_id] || -1)
25
+ msg.contract.should == @contract
26
+
27
+ exec = msg.execution
28
+ exec.perm_id.should be_an Integer
29
+ exec.perm_id.should == @ib.received[:OpenOrder].last.order.perm_id if @ib.received?(:OpenOrder)
30
+ exec.client_id.should == OPTS[:connection][:client_id]
31
+ exec.local_id.should be_an Integer
32
+ exec.local_id.should == @order.local_id if @order
33
+ exec.exec_id.should be_a String
34
+ exec.time.should =~ /\d\d:\d\d:\d\d/
35
+ exec.account_name.should == OPTS[:connection][:account_name]
36
+ exec.exchange.should == 'IDEALPRO'
37
+ exec.side.should == side
38
+ exec.shares.should == 20000
39
+ exec.cumulative_quantity.should == 20000
40
+ exec.price.should be > 1
41
+ exec.price.should be < 2
42
+ exec.price.should == exec.average_price
43
+ exec.liquidation.should == false
44
+ end
45
+
3
46
  describe "Trades", :connected => true, :integration => true, :slow => true do
4
47
 
5
48
  before(:all) { verify_account }
@@ -21,7 +64,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
21
64
  :total_quantity => 20000,
22
65
  :limit_price => 2,
23
66
  :action => 'BUY'
24
- #:what_if => true
67
+ #:what_if => true
25
68
 
26
69
  @ib.wait_for(5, :ExecutionData, :OpenOrder) do
27
70
  @ib.received[:OpenOrder].last &&
@@ -57,6 +100,12 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
57
100
  it 'receives OrderStatus with fill details' do
58
101
  status_should_be 'Filled'
59
102
  end
103
+
104
+ it 'also receives Commission Reports' do
105
+ @ib.received[:CommissionReport].should have_exactly(1).report
106
+
107
+ commission_report_should_be :no_pnl, @ib.received[:ExecutionData].last.execution
108
+ end
60
109
  end # Placing BUY
61
110
 
62
111
  context "Placing SELL order" do
@@ -99,6 +148,12 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
99
148
  it 'receives OrderStatus with fill details' do
100
149
  status_should_be 'Filled'
101
150
  end
151
+
152
+ it 'also receives Commission Reports' do
153
+ @ib.received[:CommissionReport].should have_exactly(1).report
154
+
155
+ commission_report_should_be :with_pnl, @ib.received[:ExecutionData].last.execution
156
+ end
102
157
  end # Placing SELL
103
158
 
104
159
  context "Request executions" do
@@ -124,9 +179,34 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
124
179
  end
125
180
 
126
181
  it 'receives Execution Data' do
182
+ execution_should_be :buy, :index => 0, :request_id => 456
127
183
  execution_should_be :sell, :request_id => 456
128
184
  end
185
+
186
+ it 'also receives Commission Reports' do
187
+ @ib.received[:CommissionReport].should have_exactly(2).reports
188
+
189
+ commission_report_should_be :no_pnl, @ib.received[:ExecutionData].first.execution
190
+ commission_report_should_be :with_pnl, @ib.received[:ExecutionData].last.execution
191
+ end
192
+
129
193
  end # Request executions
130
194
  end # Forex order
131
195
 
132
196
  end # Trades
197
+
198
+ __END__
199
+
200
+ Actual message exchange for "Request executions" (TWS 925):
201
+ 10:57:41:348 <- 7-3-456-1111--20120430 10:57:31-----
202
+ 10:57:41:349 -> 11-9-456-1-12087792-EUR-CASH--0.0--IDEALPRO-USD-EUR.USD-0001f4e8.4f9dbb0b.01.01-20120430 10:57:36-DU118180-IDEALPRO-BOT-20000-1.32540-474073463-1111-0-20000-1.32540--
203
+ 10:57:41:350 -> 11-9-456-2-12087792-EUR-CASH--0.0--IDEALPRO-USD-EUR.USD-0001f4e8.4f9dbb0c.01.01-20120430 10:57:36-DU118180-IDEALPRO-SLD-20000-1.32540-474073464-1111-0-20000-1.32540--
204
+ 10:57:41:350 -> 59-1-0001f4e8.4f9dbb0b.01.01-2.5-USD-1.7976931348623157E308-1.7976931348623157E308--
205
+ 10:57:41:350 -> 59-1-0001f4e8.4f9dbb0c.01.01-2.5-USD-27.7984-1.7976931348623157E308--
206
+ 10:57:41:351 -> 55-1-456-
207
+
208
+ Actual message exchange for "Request executions" (TWS 923):
209
+ 11:11:45:436 <- 7-3-456-1111--20120430 11:11:36-----
210
+ 11:11:45:439 -> 11-8-456-1-12087792-EUR-CASH--0.0--IDEALPRO-USD-EUR.USD-0001f4e8.4f9dbc96.01.01-20120430 11:11:43-DU118180-IDEALPRO-BOT-20000-1.32485-308397342-1111-0-20000-1.32485--
211
+ 11:11:45:439 -> 11-8-456-2-12087792-EUR-CASH--0.0--IDEALPRO-USD-EUR.USD-0001f4e8.4f9dbc9a.01.01-20120430 11:11:45-DU118180-IDEALPRO-SLD-20000-1.32480-308397343-1111-0-20000-1.32480--
212
+ 11:11:45:439 -> 55-1-456-
data/spec/order_helper.rb CHANGED
@@ -219,26 +219,3 @@ def order_should_be status, order=@order
219
219
  msg.contract.should == @contract
220
220
  end
221
221
 
222
- def execution_should_be side, opts={}
223
- msg = @ib.received[:ExecutionData][opts[:index] || -1]
224
- msg.request_id.should == (opts[:request_id] || -1)
225
- msg.contract.should == @contract
226
-
227
- exec = msg.execution
228
- exec.perm_id.should be_an Integer
229
- exec.perm_id.should == @ib.received[:OpenOrder].last.order.perm_id if @ib.received?(:OpenOrder)
230
- exec.client_id.should == OPTS[:connection][:client_id]
231
- exec.local_id.should be_an Integer
232
- exec.local_id.should == @order.local_id if @order
233
- exec.exec_id.should be_a String
234
- exec.time.should =~ /\d\d:\d\d:\d\d/
235
- exec.account_name.should == OPTS[:connection][:account_name]
236
- exec.exchange.should == 'IDEALPRO'
237
- exec.side.should == side
238
- exec.shares.should == 20000
239
- exec.cumulative_quantity.should == 20000
240
- exec.price.should be > 1
241
- exec.price.should be < 2
242
- exec.price.should == exec.average_price
243
- exec.liquidation.should == false
244
- end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'rspec'
2
2
  require 'ib-ruby'
3
3
 
4
- # Top level metadata for test suite level hacking
4
+ PORT ||= 4001 # 4001 for Gateway, 7496 for TWS GUI
5
+
6
+ # Top (test suite) level metadata
5
7
  OPTS ||= {
6
8
  :verbose => false, #true, # Verbosity of test outputs
7
9
  :brokertron => false, # Use mock (Brokertron) instead of paper account
@@ -20,7 +22,7 @@ else
20
22
  {:account_name => 'DU118180', # Your IB PAPER ACCOUNT, tests will only run against it
21
23
  :client_id => 1111, # Just an arbitrary id
22
24
  :host => '10.211.55.2', # Where your TWS/gateway is located, likely '127.0.0.1'
23
- :port => 4001, # 4001 for Gateway, 7496 for TWS GUI
25
+ :port => PORT,
24
26
  :reuters => true # Subscription to Reuters data enabled ?
25
27
  }
26
28
  end
data/spec/tws.rb ADDED
@@ -0,0 +1,4 @@
1
+ puts 'To run specs against TWS (not default Gateway) port, use:'
2
+ puts '$ rspec -rtws spec'
3
+
4
+ PORT = 7496