ib-ruby 0.6.1 → 0.7.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.
Files changed (50) hide show
  1. data/HISTORY +4 -0
  2. data/README.md +25 -17
  3. data/VERSION +1 -1
  4. data/bin/account_info +1 -1
  5. data/bin/cancel_orders +2 -1
  6. data/bin/contract_details +3 -2
  7. data/bin/depth_of_market +1 -1
  8. data/bin/historic_data +1 -1
  9. data/bin/historic_data_cli +57 -104
  10. data/bin/list_orders +4 -3
  11. data/bin/market_data +1 -1
  12. data/bin/option_data +1 -1
  13. data/bin/place_combo_order +63 -0
  14. data/bin/place_order +2 -4
  15. data/bin/template +1 -1
  16. data/bin/{generic_data.rb → tick_data} +3 -1
  17. data/bin/time_and_sales +1 -1
  18. data/lib/ib-ruby.rb +1 -0
  19. data/lib/ib-ruby/connection.rb +68 -68
  20. data/lib/ib-ruby/errors.rb +28 -0
  21. data/lib/ib-ruby/extensions.rb +7 -0
  22. data/lib/ib-ruby/messages.rb +1 -0
  23. data/lib/ib-ruby/messages/abstract_message.rb +16 -11
  24. data/lib/ib-ruby/messages/incoming.rb +125 -329
  25. data/lib/ib-ruby/messages/incoming/open_order.rb +193 -0
  26. data/lib/ib-ruby/messages/incoming/ticks.rb +131 -0
  27. data/lib/ib-ruby/messages/outgoing.rb +44 -45
  28. data/lib/ib-ruby/models/combo_leg.rb +16 -1
  29. data/lib/ib-ruby/models/contract.rb +18 -10
  30. data/lib/ib-ruby/models/contract/bag.rb +1 -7
  31. data/lib/ib-ruby/models/execution.rb +2 -1
  32. data/lib/ib-ruby/models/model.rb +1 -1
  33. data/lib/ib-ruby/models/order.rb +116 -56
  34. data/lib/ib-ruby/socket.rb +24 -3
  35. data/spec/account_helper.rb +2 -1
  36. data/spec/ib-ruby/messages/outgoing_spec.rb +1 -1
  37. data/spec/ib-ruby/models/combo_leg_spec.rb +0 -1
  38. data/spec/integration/account_info_spec.rb +2 -2
  39. data/spec/integration/contract_info_spec.rb +4 -4
  40. data/spec/integration/depth_data_spec.rb +3 -3
  41. data/spec/integration/historic_data_spec.rb +1 -1
  42. data/spec/integration/market_data_spec.rb +4 -4
  43. data/spec/integration/option_data_spec.rb +1 -1
  44. data/spec/integration/orders/combo_spec.rb +51 -0
  45. data/spec/integration/orders/execution_spec.rb +15 -8
  46. data/spec/integration/orders/placement_spec.rb +46 -72
  47. data/spec/integration/orders/valid_ids_spec.rb +6 -6
  48. data/spec/integration_helper.rb +0 -79
  49. data/spec/order_helper.rb +153 -0
  50. metadata +13 -4
@@ -1,5 +1,6 @@
1
- require 'integration_helper'
1
+ require 'order_helper'
2
2
 
3
+ #OPTS[:silent] = false
3
4
  shared_examples_for 'Received single id' do
4
5
  subject { @ib.received[:NextValidId].first }
5
6
 
@@ -41,7 +42,7 @@ describe 'Ids valid for Order placement', :connected => true, :integration => tr
41
42
  before(:all) do
42
43
  verify_account
43
44
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
44
- @ib.wait_for 3, :OpenOrderEnd, :NextValidId
45
+ @ib.wait_for :NextValidId, 3 # , :OpenOrderEnd
45
46
  @id = {} # Moving id between contexts. Feels dirty.
46
47
  end
47
48
 
@@ -51,14 +52,13 @@ describe 'Ids valid for Order placement', :connected => true, :integration => tr
51
52
 
52
53
  it_behaves_like 'Received single id'
53
54
 
54
- it { @ib.received[:OpenOrderEnd].should have_exactly(1).message }
55
-
56
- it 'receives also :OpenOrderEnd message' do
55
+ it 'receives also :OpenOrderEnd message', :pending => 'not in GW 924.2e' do
56
+ @ib.received[:OpenOrderEnd].should have_exactly(1).message
57
57
  @ib.received[:OpenOrderEnd].first.should be_an IB::Messages::Incoming::OpenOrderEnd
58
58
  end
59
59
 
60
60
  it 'logs connection notification' do
61
- should_log /Connected to server, version: 53, connection time/
61
+ should_log /Connected to server, version: .., connection time/
62
62
  end
63
63
  end # at connect
64
64
 
@@ -43,82 +43,3 @@ shared_examples_for 'Received Market Data' do
43
43
  its(:to_human) { should =~ /TickSize/ }
44
44
  end
45
45
  end
46
-
47
- ### Helpers for placing and verifying orders
48
-
49
- def place_order contract, opts
50
- @contract = contract
51
- @order = IB::Models::Order.new({:total_quantity => 100,
52
- :limit_price => 9.13,
53
- :action => 'BUY',
54
- :order_type => 'LMT'}.merge(opts))
55
- @order_id_before = @ib.next_order_id
56
- @order_id_placed = @ib.place_order @order, @contract
57
- @order_id_after = @ib.next_order_id
58
- end
59
-
60
- def check_status item, status
61
- case status
62
- when Regexp
63
- item.status.should =~ status
64
- when String
65
- item.status.should == status
66
- end
67
- end
68
-
69
- def order_status_should_be status, index=0
70
- msg = @ib.received[:OrderStatus][index]
71
- msg.should be_an IB::Messages::Incoming::OrderStatus
72
- msg.order_id.should == @order_id_placed
73
- msg.perm_id.should be_an Integer
74
- msg.client_id.should == OPTS[:connection][:client_id]
75
- msg.parent_id.should == 0
76
- msg.why_held.should == ''
77
- check_status msg, status
78
-
79
- if @contract == IB::Symbols::Forex[:eurusd]
80
- msg.filled.should == 20000
81
- msg.remaining.should == 0
82
- msg.average_fill_price.should be > 1
83
- msg.average_fill_price.should be < 2
84
- msg.last_fill_price.should == msg.average_fill_price
85
- else
86
- msg.filled.should == 0
87
- msg.remaining.should == @order.total_quantity
88
- msg.average_fill_price.should == 0
89
- msg.last_fill_price.should == 0
90
- end
91
- end
92
-
93
- def open_order_should_be status, index=0
94
- msg = @ib.received[:OpenOrder][index]
95
- msg.should be_an IB::Messages::Incoming::OpenOrder
96
- msg.order.should == @order
97
- msg.contract.should == @contract
98
- msg.order.order_id.should == @order_id_placed
99
- check_status msg.order, status
100
- end
101
-
102
- def execution_should_be side, opts={}
103
- msg = @ib.received[:ExecutionData][opts[:index] || -1]
104
- msg.request_id.should == (opts[:request_id] || -1)
105
- msg.contract.should == @contract
106
-
107
- exec = msg.execution
108
- exec.perm_id.should be_an Integer
109
- exec.perm_id.should == @ib.received[:OpenOrder].last.order.perm_id if @ib.received?(:OpenOrder)
110
- exec.client_id.should == OPTS[:connection][:client_id]
111
- exec.order_id.should be_an Integer
112
- exec.order_id.should == @order.order_id if @order
113
- exec.exec_id.should be_a String
114
- exec.time.should =~ /\d\d:\d\d:\d\d/
115
- exec.account_name.should == OPTS[:connection][:account_name]
116
- exec.exchange.should == 'IDEALPRO'
117
- exec.side.should == side
118
- exec.shares.should == 20000
119
- exec.cumulative_quantity.should == 20000
120
- exec.price.should be > 1
121
- exec.price.should be < 2
122
- exec.price.should == exec.average_price
123
- exec.liquidation.should == 0
124
- end
@@ -0,0 +1,153 @@
1
+ require 'integration_helper'
2
+
3
+ shared_examples_for 'Placed Order' do
4
+ context "Placing" do
5
+ after(:all) { clean_connection } # Clear logs and message collector
6
+
7
+ it 'changes client`s next_order_id' do
8
+ @order_id_placed.should == @order_id_before
9
+ @ib.next_order_id.should == @order_id_before + 1
10
+ end
11
+
12
+ it { @ib.received[:OpenOrder].should have_at_least(1).order_message }
13
+ it { @ib.received[:OrderStatus].should have_at_least(1).status_message }
14
+
15
+ it 'receives confirmation of Order submission' do
16
+ order_should_be /Submitted/ # ()Pre)Submitted
17
+ status_should_be /Submitted/
18
+ end
19
+ end # Placing
20
+
21
+ context "Retrieving placed" do
22
+ before(:all) do
23
+ @ib.send_message :RequestOpenOrders
24
+ @ib.wait_for :OpenOrderEnd
25
+ end
26
+
27
+ after(:all) { clean_connection } # Clear logs and message collector
28
+
29
+ it 'does not increase client`s next_order_id further' do
30
+ @ib.next_order_id.should == @order_id_after
31
+ end
32
+
33
+ it { @ib.received[:OpenOrder].should have_exactly(1).order_message }
34
+ it { @ib.received[:OrderStatus].should have_exactly(1).status_message }
35
+ it { @ib.received[:OpenOrderEnd].should have_exactly(1).order_end_message }
36
+ it { @ib.received[:Alert].should have_exactly(0).alert_messages }
37
+
38
+ it 'receives OpenOrder and OrderStatus for placed order' do
39
+ order_should_be /Submitted/
40
+ status_should_be /Submitted/
41
+ end
42
+ end # Retrieving
43
+
44
+ context "Cancelling placed order" do
45
+ before(:all) do
46
+ @ib.cancel_order @order_id_placed
47
+ @ib.wait_for :OrderStatus, :Alert
48
+ end
49
+
50
+ after(:all) { clean_connection } # Clear logs and message collector
51
+
52
+ it 'does not increase client`s next_order_id further' do
53
+ @ib.next_order_id.should == @order_id_after
54
+ end
55
+
56
+ it 'does not receive OpenOrder message' do
57
+ @ib.received?(:OpenOrder).should be_false
58
+ end
59
+
60
+ it { @ib.received[:OrderStatus].should have_exactly(1).status_message }
61
+ it { @ib.received[:Alert].should have_exactly(1).alert_message }
62
+
63
+ it 'receives cancellation Order Status' do
64
+ status_should_be /Cancel/ # Cancelled / PendingCancel
65
+ end
66
+
67
+ it 'receives Order cancelled Alert' do
68
+ alert = @ib.received[:Alert].first
69
+ alert.should be_an IB::Messages::Incoming::Alert
70
+ alert.message.should =~ /Order Canceled - reason:/
71
+ end
72
+ end # Cancelling
73
+ end
74
+
75
+
76
+ ### Helpers for placing and verifying orders
77
+
78
+ def place_order contract, opts
79
+ @contract = contract
80
+ @order = IB::Models::Order.new({:total_quantity => 100,
81
+ :limit_price => 9.13,
82
+ :action => 'BUY',
83
+ :order_type => 'LMT'}.merge(opts))
84
+ @order_id_before = @ib.next_order_id
85
+ @order_id_placed = @ib.place_order @order, @contract
86
+ @order_id_after = @ib.next_order_id
87
+ end
88
+
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
95
+ end
96
+ end
97
+
98
+ def status_should_be status, index=0
99
+ msg = @ib.received[:OrderStatus][index]
100
+ msg.should be_an IB::Messages::Incoming::OrderStatus
101
+ msg.order_id.should == @order_id_placed
102
+ msg.perm_id.should be_an Integer
103
+ msg.client_id.should == OPTS[:connection][:client_id]
104
+ msg.parent_id.should == 0
105
+ msg.why_held.should == ''
106
+ check_status msg, status
107
+
108
+ if @contract == IB::Symbols::Forex[:eurusd]
109
+ msg.filled.should == 20000
110
+ msg.remaining.should == 0
111
+ msg.average_fill_price.should be > 1
112
+ msg.average_fill_price.should be < 2
113
+ msg.last_fill_price.should == msg.average_fill_price
114
+ else
115
+ msg.filled.should == 0
116
+ msg.remaining.should == @order.total_quantity
117
+ msg.average_fill_price.should == 0
118
+ msg.last_fill_price.should == 0
119
+ end
120
+ end
121
+
122
+ def order_should_be status, index=0
123
+ msg = @ib.received[:OpenOrder][index]
124
+ msg.should be_an IB::Messages::Incoming::OpenOrder
125
+ msg.order.should == @order
126
+ msg.contract.should == @contract
127
+ msg.order.order_id.should == @order_id_placed
128
+ check_status msg.order, status
129
+ end
130
+
131
+ def execution_should_be side, opts={}
132
+ msg = @ib.received[:ExecutionData][opts[:index] || -1]
133
+ msg.request_id.should == (opts[:request_id] || -1)
134
+ msg.contract.should == @contract
135
+
136
+ exec = msg.execution
137
+ exec.perm_id.should be_an Integer
138
+ exec.perm_id.should == @ib.received[:OpenOrder].last.order.perm_id if @ib.received?(:OpenOrder)
139
+ exec.client_id.should == OPTS[:connection][:client_id]
140
+ exec.order_id.should be_an Integer
141
+ exec.order_id.should == @order.order_id if @order
142
+ exec.exec_id.should be_a String
143
+ exec.time.should =~ /\d\d:\d\d:\d\d/
144
+ exec.account_name.should == OPTS[:connection][:account_name]
145
+ exec.exchange.should == 'IDEALPRO'
146
+ exec.side.should == side
147
+ exec.shares.should == 20000
148
+ exec.cumulative_quantity.should == 20000
149
+ exec.price.should be > 1
150
+ exec.price.should be < 2
151
+ exec.price.should == exec.average_price
152
+ exec.liquidation.should == 0
153
+ 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.6.1
5
+ version: 0.7.0
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-14 00:00:00 Z
14
+ date: 2012-03-22 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -55,14 +55,15 @@ executables:
55
55
  - cancel_orders
56
56
  - contract_details
57
57
  - depth_of_market
58
- - generic_data.rb
59
58
  - historic_data
60
59
  - historic_data_cli
61
60
  - list_orders
62
61
  - market_data
63
62
  - option_data
63
+ - place_combo_order
64
64
  - place_order
65
65
  - template
66
+ - tick_data
66
67
  - time_and_sales
67
68
  extensions: []
68
69
 
@@ -73,18 +74,20 @@ files:
73
74
  - bin/cancel_orders
74
75
  - bin/contract_details
75
76
  - bin/depth_of_market
76
- - bin/generic_data.rb
77
77
  - bin/historic_data
78
78
  - bin/historic_data_cli
79
79
  - bin/list_orders
80
80
  - bin/market_data
81
81
  - bin/option_data
82
+ - bin/place_combo_order
82
83
  - bin/place_order
83
84
  - bin/template
85
+ - bin/tick_data
84
86
  - bin/time_and_sales
85
87
  - lib/ib-ruby.rb
86
88
  - lib/ib-ruby/connection.rb
87
89
  - lib/ib-ruby/constants.rb
90
+ - lib/ib-ruby/errors.rb
88
91
  - lib/ib-ruby/extensions.rb
89
92
  - lib/ib-ruby/logger.rb
90
93
  - lib/ib-ruby/messages.rb
@@ -95,6 +98,8 @@ files:
95
98
  - lib/ib-ruby/messages/abstract_message.rb
96
99
  - lib/ib-ruby/messages/incoming.rb
97
100
  - lib/ib-ruby/messages/outgoing.rb
101
+ - lib/ib-ruby/messages/incoming/open_order.rb
102
+ - lib/ib-ruby/messages/incoming/ticks.rb
98
103
  - lib/ib-ruby/models/bar.rb
99
104
  - lib/ib-ruby/models/combo_leg.rb
100
105
  - lib/ib-ruby/models/contract.rb
@@ -111,6 +116,7 @@ files:
111
116
  - spec/account_helper.rb
112
117
  - spec/integration_helper.rb
113
118
  - spec/message_helper.rb
119
+ - spec/order_helper.rb
114
120
  - spec/README.md
115
121
  - spec/spec_helper.rb
116
122
  - spec/ib-ruby/connection_spec.rb
@@ -126,6 +132,7 @@ files:
126
132
  - spec/integration/historic_data_spec.rb
127
133
  - spec/integration/market_data_spec.rb
128
134
  - spec/integration/option_data_spec.rb
135
+ - spec/integration/orders/combo_spec.rb
129
136
  - spec/integration/orders/execution_spec.rb
130
137
  - spec/integration/orders/open_order
131
138
  - spec/integration/orders/placement_spec.rb
@@ -174,6 +181,7 @@ test_files:
174
181
  - spec/account_helper.rb
175
182
  - spec/integration_helper.rb
176
183
  - spec/message_helper.rb
184
+ - spec/order_helper.rb
177
185
  - spec/README.md
178
186
  - spec/spec_helper.rb
179
187
  - spec/ib-ruby/connection_spec.rb
@@ -189,6 +197,7 @@ test_files:
189
197
  - spec/integration/historic_data_spec.rb
190
198
  - spec/integration/market_data_spec.rb
191
199
  - spec/integration/option_data_spec.rb
200
+ - spec/integration/orders/combo_spec.rb
192
201
  - spec/integration/orders/execution_spec.rb
193
202
  - spec/integration/orders/open_order
194
203
  - spec/integration/orders/placement_spec.rb