ib-ruby 0.5.18 → 0.5.19
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +4 -0
- data/TODO +21 -20
- data/VERSION +1 -1
- data/bin/cancel_orders +1 -1
- data/bin/list_orders +1 -2
- data/lib/ib-ruby/connection.rb +25 -8
- data/lib/ib-ruby/constants.rb +1 -0
- data/lib/ib-ruby/messages/incoming.rb +5 -5
- data/lib/ib-ruby/messages/outgoing.rb +21 -21
- data/lib/ib-ruby/models/contract.rb +52 -2
- data/lib/ib-ruby/models/model.rb +10 -0
- data/lib/ib-ruby/models/order.rb +34 -2
- data/lib/ib-ruby/socket.rb +1 -1
- data/spec/ib-ruby/connection_spec.rb +24 -17
- data/spec/ib-ruby/messages/account_info_spec.rb +5 -5
- data/spec/ib-ruby/messages/just_connect_spec.rb +3 -1
- data/spec/ib-ruby/messages/market_data_spec.rb +3 -3
- data/spec/ib-ruby/messages/open_order +273 -0
- data/spec/ib-ruby/messages/orders_spec.rb +219 -0
- data/spec/ib-ruby/models/contract_spec.rb +65 -69
- data/spec/ib-ruby/models/order_spec.rb +34 -12
- data/spec/message_helper.rb +16 -2
- data/spec/spec_helper.rb +16 -1
- metadata +7 -3
@@ -0,0 +1,273 @@
|
|
1
|
+
[#<IB::Messages::Incoming::OpenOrder:0xfdc #<IB::Messages::Incoming::OpenOrder:0x10b8 #<IB::Messages::Incoming::OpenOrder:0x1198
|
2
|
+
@contract= @contract= @contract=
|
3
|
+
#<IB::Models::Contract:0xfe0 #<IB::Models::Contract:0x10bc #<IB::Models::Contract:0x119c
|
4
|
+
@con_id="12087792", @con_id="12087792", @con_id="12087792",
|
5
|
+
@exchange="IDEALPRO", @exchange="IDEALPRO", @exchange="IDEALPRO",
|
6
|
+
@local_symbol="EUR.USD", @local_symbol="EUR.USD", @local_symbol="EUR.USD",
|
7
|
+
@sec_type="CASH", @sec_type="CASH", @sec_type="CASH",
|
8
|
+
@created_at=Thu Feb 23 12:17:48 +0400 2012, @created_at=Thu Feb 23 12:17:48 +0400 2012, @created_at=Thu Feb 23 12:17:48 +0400 2012,
|
9
|
+
@order= @order= @order=
|
10
|
+
#<IB::Models::Order:0x1018 #<IB::Models::Order:0x10f4 #<IB::Models::Order:0x11d4
|
11
|
+
@client_id=1111, @client_id=1111, @client_id=1111,
|
12
|
+
@commission=nil, @commission=2.5, @commission=2.5,
|
13
|
+
@commission_currency="USD", @commission_currency="USD", @commission_currency="USD",
|
14
|
+
@id=38, @id=38, @id=38,
|
15
|
+
@limit_price=1.4, @limit_price=1.4, @limit_price=1.4,
|
16
|
+
@perm_id=300145671, @perm_id=300145671, @perm_id=300145671,
|
17
|
+
@status="Filled", @status="Filled", @status="Filled",
|
18
|
+
@total_quantity=20000, @total_quantity=20000, @total_quantity=20000,
|
19
|
+
@socket=nil>, @socket=nil>, @socket=nil>]
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
[#<IB::Messages::Incoming::OrderStatus:0x127c
|
229
|
+
@created_at=Thu Feb 23 12:17:48 +0400 2012,
|
230
|
+
@data=
|
231
|
+
{:version=>6,
|
232
|
+
:id=>38,
|
233
|
+
:status=>"Filled",
|
234
|
+
:filled=>20000,
|
235
|
+
:remaining=>0,
|
236
|
+
:average_fill_price=>1.3292,
|
237
|
+
:perm_id=>300145671,
|
238
|
+
:parent_id=>0,
|
239
|
+
:last_fill_price=>1.3292,
|
240
|
+
:client_id=>1111,
|
241
|
+
:why_held=>""},
|
242
|
+
@socket=nil>,
|
243
|
+
#<IB::Messages::Incoming::OrderStatus:0x12bc
|
244
|
+
@created_at=Thu Feb 23 12:17:48 +0400 2012,
|
245
|
+
@data=
|
246
|
+
{:version=>6,
|
247
|
+
:id=>38,
|
248
|
+
:status=>"Filled",
|
249
|
+
:filled=>20000,
|
250
|
+
:remaining=>0,
|
251
|
+
:average_fill_price=>1.3292,
|
252
|
+
:perm_id=>300145671,
|
253
|
+
:parent_id=>0,
|
254
|
+
:last_fill_price=>1.3292,
|
255
|
+
:client_id=>1111,
|
256
|
+
:why_held=>""},
|
257
|
+
@socket=nil>,
|
258
|
+
#<IB::Messages::Incoming::OrderStatus:0x12d8
|
259
|
+
@created_at=Thu Feb 23 12:17:48 +0400 2012,
|
260
|
+
@data=
|
261
|
+
{:version=>6,
|
262
|
+
:id=>38,
|
263
|
+
:status=>"Filled",
|
264
|
+
:filled=>20000,
|
265
|
+
:remaining=>0,
|
266
|
+
:average_fill_price=>1.3292,
|
267
|
+
:perm_id=>300145671,
|
268
|
+
:parent_id=>0,
|
269
|
+
:last_fill_price=>1.3292,
|
270
|
+
:client_id=>1111,
|
271
|
+
:why_held=>""},
|
272
|
+
@socket=nil>]
|
273
|
+
|
@@ -0,0 +1,219 @@
|
|
1
|
+
require 'message_helper'
|
2
|
+
|
3
|
+
describe IB::Messages do
|
4
|
+
|
5
|
+
context "Orders", :connected => true do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@eur = IB::Symbols::Forex[:eurusd]
|
9
|
+
@eur_order = IB::Models::Order.new :total_quantity => 20000,
|
10
|
+
:limit_price => 1,
|
11
|
+
:action => 'SELL',
|
12
|
+
:order_type => 'LMT'
|
13
|
+
@wfc = IB::Symbols::Stocks[:wfc]
|
14
|
+
@wfc_order = IB::Models::Order.new :total_quantity => 100,
|
15
|
+
:action => 'BUY',
|
16
|
+
:order_type => 'LMT'
|
17
|
+
end
|
18
|
+
|
19
|
+
context "Placing wrong order" do
|
20
|
+
|
21
|
+
before(:all) do
|
22
|
+
connect_and_receive :NextValidID, :Alert, :OpenOrder, :OrderStatus
|
23
|
+
wait_for { received? :NextValidID }
|
24
|
+
|
25
|
+
@wfc_order.limit_price = 9.131313 # Set weird non-acceptable price
|
26
|
+
@order_id_before = @ib.next_order_id
|
27
|
+
@order_id_placed = @ib.place_order @wfc_order, @wfc
|
28
|
+
|
29
|
+
wait_for 2
|
30
|
+
end
|
31
|
+
|
32
|
+
after(:all) do
|
33
|
+
@ib.cancel_order @order_id_placed # Just in case...
|
34
|
+
close_connection
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does not place new Order' do
|
38
|
+
@received[:OpenOrder].should be_empty
|
39
|
+
@received[:OrderStatus].should be_empty
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'still changes client`s next_order_id' do
|
43
|
+
@order_id_placed = @order_id_before
|
44
|
+
@ib.next_order_id.should == @order_id_before + 1
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'received :Alert message' do
|
48
|
+
subject { @received[:Alert].last }
|
49
|
+
|
50
|
+
it { should be_an IB::Messages::Incoming::Alert }
|
51
|
+
it { should be_error }
|
52
|
+
its(:code) { should be_a Integer }
|
53
|
+
its(:message) { should =~ /The price does not conform to the minimum price variation for this contract/ }
|
54
|
+
end
|
55
|
+
|
56
|
+
end # Placing wrong order
|
57
|
+
|
58
|
+
context "Off-market order" do
|
59
|
+
before(:all) do
|
60
|
+
connect_and_receive :NextValidID, :Alert, :OpenOrder, :OrderStatus
|
61
|
+
wait_for { received? :NextValidID }
|
62
|
+
|
63
|
+
@wfc_order.limit_price = 9.13 # Set acceptable price
|
64
|
+
@order_id_before = @ib.next_order_id
|
65
|
+
@order_id_placed = @ib.place_order @wfc_order, @wfc
|
66
|
+
|
67
|
+
wait_for(2) { @received[:OpenOrder].size > 1 && @received[:OpenOrder].size > 1 }
|
68
|
+
end
|
69
|
+
|
70
|
+
after(:all) do
|
71
|
+
#pp @received[:OpenOrder]
|
72
|
+
@ib.cancel_order @order_id_placed # Just in case...
|
73
|
+
close_connection
|
74
|
+
end
|
75
|
+
|
76
|
+
context "Placing" do
|
77
|
+
|
78
|
+
after(:all) { clean_connection } # Clear logs and message collector
|
79
|
+
|
80
|
+
it 'changes client`s next_order_id' do
|
81
|
+
@order_id_placed = @order_id_before
|
82
|
+
@ib.next_order_id.should == @order_id_before + 1
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'received :OpenOrder messages' do
|
86
|
+
subject { @received[:OpenOrder] }
|
87
|
+
|
88
|
+
it { should have_at_least(1).message }
|
89
|
+
|
90
|
+
it 'receives (optional) Order confirmation first' do
|
91
|
+
if subject.size > 1
|
92
|
+
msg = subject.first
|
93
|
+
msg.should be_an IB::Messages::Incoming::OpenOrder
|
94
|
+
msg.contract.should == @wfc
|
95
|
+
msg.order.should == @wfc_order
|
96
|
+
msg.order.order_id.should == @order_id_placed
|
97
|
+
msg.order.status.should == 'PreSubmitted'
|
98
|
+
else
|
99
|
+
puts 'Warning: Confirmation was skipped!'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'receives Order submission then' do
|
104
|
+
msg = subject.last
|
105
|
+
msg.should be_an IB::Messages::Incoming::OpenOrder
|
106
|
+
msg.contract.should == @wfc
|
107
|
+
msg.order.should == @wfc_order
|
108
|
+
msg.order.order_id.should == @order_id_placed
|
109
|
+
msg.order.status.should == 'Submitted'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'received :OrderStatus messages' do
|
114
|
+
subject { @received[:OrderStatus] }
|
115
|
+
|
116
|
+
it { should have_at_least(1).message }
|
117
|
+
|
118
|
+
it 'receives (optional) Order confirmation first' do
|
119
|
+
if subject.size > 1
|
120
|
+
msg = subject.first
|
121
|
+
msg.should be_an IB::Messages::Incoming::OrderStatus
|
122
|
+
msg.id.should == @order_id_placed
|
123
|
+
msg.perm_id.should be_an Integer
|
124
|
+
msg.client_id.should == 1111
|
125
|
+
msg.parent_id.should == 0
|
126
|
+
#msg.order_id.should == @order_id_placed
|
127
|
+
msg.status.should == 'PreSubmitted'
|
128
|
+
msg.filled.should == 0
|
129
|
+
msg.remaining.should == 100
|
130
|
+
msg.average_fill_price.should == 0
|
131
|
+
msg.last_fill_price.should == 0
|
132
|
+
msg.why_held.should == ''
|
133
|
+
else
|
134
|
+
puts 'Warning: Confirmation was skipped!'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'receives Order submission then' do
|
139
|
+
msg = subject.last
|
140
|
+
msg.should be_an IB::Messages::Incoming::OrderStatus
|
141
|
+
msg.id.should == @order_id_placed
|
142
|
+
#msg.order_id.should == @order_id_placed
|
143
|
+
msg.perm_id.should be_an Integer
|
144
|
+
msg.client_id.should == 1111
|
145
|
+
msg.parent_id.should == 0
|
146
|
+
msg.status.should == 'Submitted'
|
147
|
+
msg.filled.should == 0
|
148
|
+
msg.remaining.should == 100
|
149
|
+
msg.average_fill_price.should == 0
|
150
|
+
msg.last_fill_price.should == 0
|
151
|
+
msg.why_held.should == ''
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end # Placing
|
155
|
+
|
156
|
+
context "Cancelling placed order" do
|
157
|
+
before(:all) do
|
158
|
+
@ib.cancel_order @order_id_placed
|
159
|
+
|
160
|
+
wait_for(2) { received?(:OrderStatus) && received?(:Alert) }
|
161
|
+
end
|
162
|
+
|
163
|
+
after(:all) { clean_connection } # Clear logs and message collector
|
164
|
+
|
165
|
+
it 'does not increase client`s next_order_id further' do
|
166
|
+
@ib.next_order_id.should == @order_id_before + 1
|
167
|
+
end
|
168
|
+
|
169
|
+
it { @received[:OrderStatus].should have_exactly(1).status_message }
|
170
|
+
|
171
|
+
it { @received[:Alert].should have_exactly(1).alert_message }
|
172
|
+
|
173
|
+
it 'receives Order cancellation status' do
|
174
|
+
msg = @received[:OrderStatus].first
|
175
|
+
msg.should be_an IB::Messages::Incoming::OrderStatus
|
176
|
+
msg.id.should == @order_id_placed
|
177
|
+
#msg.order_id.should == @order_id_placed
|
178
|
+
msg.perm_id.should be_an Integer
|
179
|
+
msg.client_id.should == 1111
|
180
|
+
msg.parent_id.should == 0
|
181
|
+
msg.status.should == 'Cancelled'
|
182
|
+
msg.filled.should == 0
|
183
|
+
msg.remaining.should == 100
|
184
|
+
msg.average_fill_price.should == 0
|
185
|
+
msg.last_fill_price.should == 0
|
186
|
+
msg.why_held.should == ''
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'receives Order cancelled Alert' do
|
190
|
+
alert = @received[:Alert].first
|
191
|
+
alert.should be_an IB::Messages::Incoming::Alert
|
192
|
+
alert.message.should =~ /Order Canceled - reason:/
|
193
|
+
end
|
194
|
+
end # Cancelling
|
195
|
+
|
196
|
+
context "Cancelling wrong order" do
|
197
|
+
before(:all) do
|
198
|
+
@ib.cancel_order rand(99999999)
|
199
|
+
|
200
|
+
wait_for(2) { received?(:Alert) }
|
201
|
+
end
|
202
|
+
|
203
|
+
it { @received[:Alert].should have_exactly(1).alert_message }
|
204
|
+
|
205
|
+
it 'does not increase client`s next_order_id further' do
|
206
|
+
@ib.next_order_id.should == @order_id_before + 1
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'receives unable to find Order Alert' do
|
210
|
+
alert = @received[:Alert].first
|
211
|
+
alert.should be_an IB::Messages::Incoming::Alert
|
212
|
+
alert.message.should =~ /Can't find order with id =/
|
213
|
+
end
|
214
|
+
end # Cancelling
|
215
|
+
end # Off-market order
|
216
|
+
|
217
|
+
|
218
|
+
end # Orders
|
219
|
+
end # describe IB::Messages::Incomming
|
@@ -19,11 +19,11 @@ describe IB::Models::Contract do
|
|
19
19
|
subject { IB::Models::Contract.new }
|
20
20
|
|
21
21
|
it { should_not be_nil }
|
22
|
-
its(:con_id) {should == 0}
|
23
|
-
its(:strike) {should == 0}
|
24
|
-
its(:sec_type) {should == ''}
|
25
|
-
its(:created_at) {should be_a Time}
|
26
|
-
its(:include_expired) {should == false}
|
22
|
+
its(:con_id) { should == 0 }
|
23
|
+
its(:strike) { should == 0 }
|
24
|
+
its(:sec_type) { should == '' }
|
25
|
+
its(:created_at) { should be_a Time }
|
26
|
+
its(:include_expired) { should == false }
|
27
27
|
end
|
28
28
|
|
29
29
|
context 'with properties' do
|
@@ -36,9 +36,9 @@ describe IB::Models::Contract do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
context 'essential properties are still set, even if not given explicitely' do
|
39
|
-
its(:con_id) {should == 0}
|
40
|
-
its(:created_at) {should be_a Time}
|
41
|
-
its(:include_expired) {should == false}
|
39
|
+
its(:con_id) { should == 0 }
|
40
|
+
its(:created_at) { should be_a Time }
|
41
|
+
its(:include_expired) { should == false }
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -56,22 +56,22 @@ describe IB::Models::Contract do
|
|
56
56
|
context 'empty without properties' do
|
57
57
|
subject { IB::Models::Contract.new }
|
58
58
|
|
59
|
-
its(:summary) {should == subject}
|
60
|
-
its(:under_con_id) {should == 0}
|
61
|
-
its(:min_tick) {should == 0}
|
62
|
-
its(:callable) {should == false}
|
63
|
-
its(:puttable) {should == false}
|
64
|
-
its(:coupon) {should == 0}
|
65
|
-
its(:convertible) {should == false}
|
66
|
-
its(:next_option_partial) {should == false}
|
67
|
-
its(:created_at) {should be_a Time}
|
59
|
+
its(:summary) { should == subject }
|
60
|
+
its(:under_con_id) { should == 0 }
|
61
|
+
its(:min_tick) { should == 0 }
|
62
|
+
its(:callable) { should == false }
|
63
|
+
its(:puttable) { should == false }
|
64
|
+
its(:coupon) { should == 0 }
|
65
|
+
its(:convertible) { should == false }
|
66
|
+
its(:next_option_partial) { should == false }
|
67
|
+
its(:created_at) { should be_a Time }
|
68
68
|
end
|
69
69
|
|
70
70
|
context 'with properties' do
|
71
71
|
subject { IB::Models::Contract.new detailed_properties }
|
72
72
|
|
73
|
-
its(:summary) {should == subject}
|
74
|
-
its(:created_at) {should be_a Time}
|
73
|
+
its(:summary) { should == subject }
|
74
|
+
its(:created_at) { should be_a Time }
|
75
75
|
|
76
76
|
it 'sets properties right' do
|
77
77
|
detailed_properties.each do |name, value|
|
@@ -81,10 +81,9 @@ describe IB::Models::Contract do
|
|
81
81
|
end
|
82
82
|
end #instantiation
|
83
83
|
|
84
|
-
|
85
84
|
it 'allows setting attributes' do
|
85
|
+
x = IB::Models::Contract.new
|
86
86
|
expect {
|
87
|
-
x = IB::Models::Contract.new
|
88
87
|
x.symbol = "TEST"
|
89
88
|
x.sec_type = IB::SECURITY_TYPES[:stock]
|
90
89
|
x.expiry = 200609
|
@@ -95,11 +94,21 @@ describe IB::Models::Contract do
|
|
95
94
|
x.currency = "USD"
|
96
95
|
x.local_symbol = "baz"
|
97
96
|
}.to_not raise_error
|
97
|
+
|
98
|
+
x.symbol.should == "TEST"
|
99
|
+
x.sec_type.should == IB::SECURITY_TYPES[:stock]
|
100
|
+
x.expiry.should == '200609'
|
101
|
+
x.strike.should == 1234
|
102
|
+
x.right.should == "PUT"
|
103
|
+
x.multiplier.should == 123
|
104
|
+
x.exchange.should == "SMART"
|
105
|
+
x.currency.should == "USD"
|
106
|
+
x.local_symbol = "baz"
|
98
107
|
end
|
99
108
|
|
100
109
|
it 'allows setting ContractDetails attributes' do
|
110
|
+
x = IB::Models::Contract.new
|
101
111
|
expect {
|
102
|
-
x = IB::Models::Contract.new
|
103
112
|
x.callable = true
|
104
113
|
x.puttable = true
|
105
114
|
x.convertible = true
|
@@ -107,56 +116,41 @@ describe IB::Models::Contract do
|
|
107
116
|
x.min_tick = 123
|
108
117
|
x.next_option_partial = true
|
109
118
|
}.to_not raise_error
|
119
|
+
|
120
|
+
x.callable.should == true
|
121
|
+
x.puttable.should == true
|
122
|
+
x.convertible.should == true
|
123
|
+
x.under_con_id.should == 321
|
124
|
+
x.min_tick.should == 123
|
125
|
+
x.next_option_partial.should == true
|
110
126
|
end
|
111
127
|
|
112
128
|
it 'raises on wrong security type' do
|
113
|
-
expect {
|
114
|
-
x = IB::Models::Contract.new({:sec_type => "asdf"})
|
115
|
-
}.to raise_error ArgumentError
|
129
|
+
expect { IB::Models::Contract.new(:sec_type => "asdf") }.to raise_error ArgumentError
|
116
130
|
|
117
|
-
expect {
|
118
|
-
x = IB::Models::Contract.new
|
119
|
-
x.sec_type = "asdf"
|
120
|
-
}.to raise_error ArgumentError
|
131
|
+
expect { IB::Models::Contract.new.sec_type = "asdf" }.to raise_error ArgumentError
|
121
132
|
end
|
122
133
|
|
123
134
|
it 'accepts pre-determined security types' do
|
124
135
|
IB::SECURITY_TYPES.values.each do |type|
|
125
|
-
expect {
|
126
|
-
|
127
|
-
}.to_not raise_error
|
128
|
-
|
129
|
-
expect {
|
130
|
-
x = IB::Models::Contract.new
|
131
|
-
x.sec_type = type
|
132
|
-
}.to_not raise_error
|
136
|
+
expect { IB::Models::Contract.new(:sec_type => type) }.to_not raise_error
|
137
|
+
|
138
|
+
expect { IB::Models::Contract.new.sec_type = type }.to_not raise_error
|
133
139
|
end
|
134
140
|
end
|
135
141
|
|
136
142
|
it 'raises on wrong expiry' do
|
137
|
-
expect {
|
138
|
-
x = IB::Models::Contract.new({:expiry => "foo"})
|
139
|
-
}.to raise_error ArgumentError
|
143
|
+
expect { IB::Models::Contract.new(:expiry => "foo") }.to raise_error ArgumentError
|
140
144
|
|
141
|
-
expect {
|
142
|
-
x = IB::Models::Contract.new
|
143
|
-
x.expiry = "foo"
|
144
|
-
}.to raise_error ArgumentError
|
145
|
+
expect { IB::Models::Contract.new.expiry = "foo" }.to raise_error ArgumentError
|
145
146
|
end
|
146
147
|
|
147
148
|
it 'accepts correct expiry' do
|
148
|
-
expect {
|
149
|
-
x = IB::Models::Contract.new({:expiry => "200607"})
|
150
|
-
}.to_not raise_error
|
149
|
+
expect { IB::Models::Contract.new(:expiry => "200607") }.to_not raise_error
|
151
150
|
|
152
|
-
expect {
|
153
|
-
x = IB::Models::Contract.new
|
154
|
-
x.expiry = "200607"
|
155
|
-
}.to_not raise_error
|
151
|
+
expect { IB::Models::Contract.new.expiry = "200607" }.to_not raise_error
|
156
152
|
|
157
|
-
expect {
|
158
|
-
x = IB::Models::Contract.new({:expiry => 200607})
|
159
|
-
}.to_not raise_error
|
153
|
+
expect { IB::Models::Contract.new(:expiry => 200607) }.to_not raise_error
|
160
154
|
|
161
155
|
expect {
|
162
156
|
x = IB::Models::Contract.new
|
@@ -167,25 +161,15 @@ describe IB::Models::Contract do
|
|
167
161
|
end
|
168
162
|
|
169
163
|
it 'raises on incorrect right (option type)' do
|
170
|
-
expect {
|
171
|
-
|
172
|
-
}.to raise_error ArgumentError
|
173
|
-
expect {
|
174
|
-
x = IB::Models::Contract.new
|
175
|
-
x.right = "foo"
|
176
|
-
}.to raise_error ArgumentError
|
164
|
+
expect { IB::Models::Contract.new(:right => "foo") }.to raise_error ArgumentError
|
165
|
+
expect { IB::Models::Contract.new.right = "foo" }.to raise_error ArgumentError
|
177
166
|
end
|
178
167
|
|
179
168
|
it 'accepts all correct values for right (option type)' do
|
180
169
|
["PUT", "put", "P", "p", "CALL", "call", "C", "c"].each do |right|
|
181
|
-
expect {
|
182
|
-
|
183
|
-
}.to_not raise_error
|
184
|
-
|
185
|
-
expect {
|
186
|
-
x = IB::Models::Contract.new
|
187
|
-
x.right = right
|
188
|
-
}.to_not raise_error
|
170
|
+
expect { IB::Models::Contract.new(:right => right) }.to_not raise_error
|
171
|
+
|
172
|
+
expect { IB::Models::Contract.new.right = right }.to_not raise_error
|
189
173
|
end
|
190
174
|
end
|
191
175
|
end #instantiation
|
@@ -204,4 +188,16 @@ describe IB::Models::Contract do
|
|
204
188
|
end
|
205
189
|
end #serialization
|
206
190
|
|
191
|
+
context 'equality' do
|
192
|
+
subject { IB::Models::Contract.new properties }
|
193
|
+
|
194
|
+
it 'be self-equal ' do
|
195
|
+
should == subject
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'be equal to object with the same properties' do
|
199
|
+
should == IB::Models::Contract.new(properties)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
207
203
|
end # describe IB::Models::Contract
|