ib-ruby 0.8.0 → 0.8.1

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
@@ -189,3 +189,7 @@
189
189
  == 0.8.0 / 2012-06-07
190
190
 
191
191
  * TWS 926 support
192
+
193
+ == 0.8.1 / 2012-06-13
194
+
195
+ * Combo routing parameters and algo parameters supported
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.8.1
@@ -83,9 +83,9 @@ class AddOrders < ActiveRecord::Migration
83
83
  t.float :basis_points_type # double: EFP orders only
84
84
  t.string :algo_strategy
85
85
 
86
- # t.string :algo_params # public Vector<TagValue> m_algoParams; ?!
87
- # t.string :leg_prices # Vector<OrderComboLeg> m_orderComboLegs
88
- # t.string :combo_params # not used yet
86
+ t.text :leg_prices # Vector<OrderComboLeg> m_orderComboLegs
87
+ t.text :algo_params # public Vector<TagValue> m_algoParams; ?!
88
+ t.text :combo_params # not used yet
89
89
 
90
90
  t.integer :scale_init_level_size # int: Size of the first (initial) order component.
91
91
  t.integer :scale_subs_level_size # int: Order size of the subsequent scale order
@@ -49,6 +49,7 @@ module IB
49
49
  end
50
50
 
51
51
  def []= key, val
52
+ # p key, val
52
53
  attributes[key.to_sym] = val
53
54
  end
54
55
 
@@ -222,9 +222,9 @@ module IB
222
222
  alias order_combo_legs leg_prices
223
223
  alias smart_combo_routing_params combo_params
224
224
 
225
- #serialize :leg_prices
226
- #serialize :algo_params
227
- #serialize :combo_params
225
+ serialize :leg_prices
226
+ serialize :algo_params, Hash
227
+ serialize :combo_params
228
228
 
229
229
  # Order is always placed for a contract. Here, we explicitly set this link.
230
230
  belongs_to :contract
@@ -306,8 +306,8 @@ module IB
306
306
  :transmit => true,
307
307
  :what_if => false,
308
308
  :leg_prices => [],
309
- :algo_params => [],
310
- :combo_params => [],
309
+ :algo_params => HashWithIndifferentAccess.new, #{},
310
+ :combo_params => HashWithIndifferentAccess.new, #{},
311
311
  :order_state => IB::OrderState.new(:status => 'New',
312
312
  :filled => 0,
313
313
  :remaining => 0,
@@ -315,13 +315,6 @@ module IB
315
315
  :average_price => 0)
316
316
  end
317
317
 
318
- #after_initialize do #opts = {}
319
- # #self.leg_prices = []
320
- # #self.algo_params = {}
321
- # #self.combo_params = {}
322
- # #self.order_state ||= IB::OrderState.new :status => 'New'
323
- #end
324
-
325
318
  def serialize_algo
326
319
  if algo_strategy.nil? || algo_strategy.empty?
327
320
  ''
@@ -103,7 +103,7 @@ describe IB::Connection do
103
103
 
104
104
  before(:all) do
105
105
  @ib.send_message :RequestAccountData
106
- @ib.wait_for :AccountDownloadEnd
106
+ @ib.wait_for :AccountDownloadEnd, 3
107
107
  end
108
108
 
109
109
  after(:all) { @ib.send_message :RequestAccountData, :subscribe => false }
@@ -1,87 +1,87 @@
1
1
  require 'model_helper'
2
2
 
3
3
  describe IB::Models::Order,
4
- :props =>
5
- {:local_id => 23,
6
- :order_ref => 'Test',
7
- :client_id => 1111,
8
- :perm_id => 173276893,
9
- :parent_id => 0,
10
- :side => :buy,
11
- :order_type => :market_if_touched,
12
- :limit_price => 0.1,
13
- :quantity => 100,
14
- :tif => :good_till_cancelled,
15
- :open_close => :close,
16
- :oca_group => '',
17
- :oca_type => :reduce_no_block,
18
- :origin => :firm,
19
- :designated_location => "WHATEVER",
20
- :exempt_code => 123,
21
- :delta_neutral_order_type => :market,
22
- :transmit => false,
23
- :outside_rth => true,
24
- :what_if => true,
25
- :not_held => true},
26
-
27
- # TODO: :presents => { Object => "Formatted"}
28
- :human => "<Order: Test MIT GTC buy 100 New 0.1 #23/173276893 from 1111>",
29
-
30
- :errors => {:side =>["should be buy/sell/short"]},
31
-
32
- :assigns =>
33
- {[:order_type, :delta_neutral_order_type] => codes_and_values_for(:order_type),
34
-
35
- :open_close =>
36
- {[42, nil, 'Foo', :bar] => /should be same.open.close.unknown/,
37
- ['SAME', 'same', 'S', 's', :same, 0, '0'] => :same,
38
- ['OPEN', 'open', 'O', 'o', :open, 1, '1'] => :open,
39
- ['CLOSE', 'close', 'C', 'c', :close, 2, '2'] => :close,
40
- ['UNKNOWN', 'unknown', 'U', 'u', :unknown, 3, '3'] => :unknown,
41
- },
42
-
43
- [:what_if, :not_held, :outside_rth, :hidden, :transmit, :block_order,
44
- :sweep_to_fill, :override_percentage_constraints, :all_or_none,
45
- :etrade_only, :firm_quote_only, :opt_out_smart_routing, :scale_auto_reset,
46
- :scale_random_percent] => boolean_assigns,
47
-
48
- [:local_id, :perm_id, :parent_id] => numeric_or_nil_assigns,
49
- },
50
-
51
- :aliases =>
52
- {[:side, :action] => buy_sell_short_assigns,
53
- [:quantity, :total_quantity] => numeric_or_nil_assigns,
54
- },
55
-
56
- :collections =>
57
- {:order_states =>[{:status => :Foo},
58
- {:status => 'Bar'},],
59
-
60
- :executions =>
61
- [{:local_id => 23,
62
- :client_id => 1111,
63
- :perm_id => 173276893,
64
- :exchange => "IDEALPRO",
65
- :exec_id => "0001f4e8.4f5d48f1.01.01",
66
- :price => 0.1,
67
- :average_price => 0.1,
68
- :shares => 40,
69
- :cumulative_quantity => 40,
70
- :side => :buy,
71
- :time => "20120312 15:41:09"},
72
-
73
- {:local_id => 23,
74
- :client_id => 1111,
75
- :perm_id => 173276893,
76
- :exchange => "IDEALPRO",
77
- :exec_id => "0001f4e8.4f5d48f1.01.02",
78
- :price => 0.1,
79
- :average_price => 0.1,
80
- :shares => 60,
81
- :cumulative_quantity => 100,
82
- :side => :buy,
83
- :time => "20120312 15:41:10"}]
84
- } do
4
+ :props =>
5
+ {:local_id => 23,
6
+ :order_ref => 'Test',
7
+ :client_id => 1111,
8
+ :perm_id => 173276893,
9
+ :parent_id => 0,
10
+ :side => :buy,
11
+ :order_type => :market_if_touched,
12
+ :limit_price => 0.1,
13
+ :quantity => 100,
14
+ :tif => :good_till_cancelled,
15
+ :open_close => :close,
16
+ :oca_group => '',
17
+ :oca_type => :reduce_no_block,
18
+ :origin => :firm,
19
+ :designated_location => "WHATEVER",
20
+ :exempt_code => 123,
21
+ :delta_neutral_order_type => :market,
22
+ :transmit => false,
23
+ :outside_rth => true,
24
+ :what_if => true,
25
+ :not_held => true},
26
+
27
+ # TODO: :presents => { Object => "Formatted"}
28
+ :human => "<Order: Test MIT GTC buy 100 New 0.1 #23/173276893 from 1111>",
29
+
30
+ :errors => {:side =>["should be buy/sell/short"]},
31
+
32
+ :assigns =>
33
+ {[:order_type, :delta_neutral_order_type] => codes_and_values_for(:order_type),
34
+
35
+ :open_close =>
36
+ {[42, nil, 'Foo', :bar] => /should be same.open.close.unknown/,
37
+ ['SAME', 'same', 'S', 's', :same, 0, '0'] => :same,
38
+ ['OPEN', 'open', 'O', 'o', :open, 1, '1'] => :open,
39
+ ['CLOSE', 'close', 'C', 'c', :close, 2, '2'] => :close,
40
+ ['UNKNOWN', 'unknown', 'U', 'u', :unknown, 3, '3'] => :unknown,
41
+ },
42
+
43
+ [:what_if, :not_held, :outside_rth, :hidden, :transmit, :block_order,
44
+ :sweep_to_fill, :override_percentage_constraints, :all_or_none,
45
+ :etrade_only, :firm_quote_only, :opt_out_smart_routing, :scale_auto_reset,
46
+ :scale_random_percent] => boolean_assigns,
47
+
48
+ [:local_id, :perm_id, :parent_id] => numeric_or_nil_assigns,
49
+ },
50
+
51
+ :aliases =>
52
+ {[:side, :action] => buy_sell_short_assigns,
53
+ [:quantity, :total_quantity] => numeric_or_nil_assigns,
54
+ },
55
+
56
+ :collections =>
57
+ {:order_states =>[{:status => :Foo},
58
+ {:status => 'Bar'},],
59
+
60
+ :executions =>
61
+ [{:local_id => 23,
62
+ :client_id => 1111,
63
+ :perm_id => 173276893,
64
+ :exchange => "IDEALPRO",
65
+ :exec_id => "0001f4e8.4f5d48f1.01.01",
66
+ :price => 0.1,
67
+ :average_price => 0.1,
68
+ :shares => 40,
69
+ :cumulative_quantity => 40,
70
+ :side => :buy,
71
+ :time => "20120312 15:41:09"},
72
+
73
+ {:local_id => 23,
74
+ :client_id => 1111,
75
+ :perm_id => 173276893,
76
+ :exchange => "IDEALPRO",
77
+ :exec_id => "0001f4e8.4f5d48f1.01.02",
78
+ :price => 0.1,
79
+ :average_price => 0.1,
80
+ :shares => 60,
81
+ :cumulative_quantity => 100,
82
+ :side => :buy,
83
+ :time => "20120312 15:41:10"}]
84
+ } do
85
85
 
86
86
  it_behaves_like 'Self-equal Model'
87
87
  it_behaves_like 'Model with invalid defaults'
@@ -173,53 +173,89 @@ describe IB::Models::Order,
173
173
 
174
174
  it 'is not equal for Orders with different limit price' do
175
175
  order1 = IB::Order.new :quantity => 100,
176
- :limit_price => 1,
177
- :action => 'BUY'
176
+ :limit_price => 1,
177
+ :action => 'BUY'
178
178
 
179
179
  order2 = IB::Order.new :total_quantity => 100,
180
- :limit_price => 2,
181
- :action => 'BUY'
180
+ :limit_price => 2,
181
+ :action => 'BUY'
182
182
  order1.should_not == order2
183
183
  order2.should_not == order1
184
184
  end
185
185
 
186
186
  it 'is not equal for Orders with different total_quantity' do
187
187
  order1 = IB::Order.new :quantity => 20000,
188
- :limit_price => 1,
189
- :action => 'BUY'
188
+ :limit_price => 1,
189
+ :action => 'BUY'
190
190
 
191
191
  order2 = IB::Order.new :total_quantity => 100,
192
- :action => 'BUY',
193
- :limit_price => 1
192
+ :action => 'BUY',
193
+ :limit_price => 1
194
194
  order1.should_not == order2
195
195
  order2.should_not == order1
196
196
  end
197
197
 
198
198
  it 'is not equal for Orders with different action/side' do
199
199
  order1 = IB::Order.new :quantity => 100,
200
- :limit_price => 1,
201
- :action => 'SELL'
200
+ :limit_price => 1,
201
+ :action => 'SELL'
202
202
 
203
203
  order2 = IB::Order.new :quantity => 100,
204
- :action => 'BUY',
205
- :limit_price => 1
204
+ :action => 'BUY',
205
+ :limit_price => 1
206
206
  order1.should_not == order2
207
207
  order2.should_not == order1
208
208
  end
209
209
 
210
210
  it 'is not equal for Orders with different order_type' do
211
211
  order1 = IB::Order.new :quantity => 100,
212
- :limit_price => 1,
213
- :action => 'BUY',
214
- :order_type => 'LMT'
212
+ :limit_price => 1,
213
+ :action => 'BUY',
214
+ :order_type => 'LMT'
215
215
 
216
216
  order2 = IB::Order.new :quantity => 100,
217
- :action => 'BUY',
218
- :limit_price => 1,
219
- :order_type => 'MKT'
217
+ :action => 'BUY',
218
+ :limit_price => 1,
219
+ :order_type => 'MKT'
220
220
  order1.should_not == order2
221
221
  order2.should_not == order1
222
222
  end
223
223
  end
224
224
 
225
+ context 'DB-backed serialization of properties', :db => true do
226
+ let(:serializable_props) do
227
+ {
228
+ :algo_strategy => "ArrivalPx",
229
+ :algo_params => { "maxPctVol" => "0.01",
230
+ "riskAversion" => "Passive",
231
+ "startTime" => "9:00:00 EST",
232
+ "endTime" => "15:00:00 EST",
233
+ "forceCompletion" => "0",
234
+ "allowPastEndTime" => "1"},
235
+ :combo_params => {"NonGuaranteed" => "1",
236
+ "LeginPrio" => "0"},
237
+ :leg_prices => [1,2,3],
238
+ }
239
+ end
240
+
241
+ subject { IB::Order.new(props.merge(serializable_props)) }
242
+
243
+ after(:all) { DatabaseCleaner.clean }
244
+
245
+ it 'is saved to DB with serializable_props' do
246
+ subject.save.should be_true
247
+ end
248
+
249
+ it 'is loaded from DB with serializable_props' do
250
+ models = described_class.find(:all)
251
+ models.should have_exactly(1).model
252
+ order = models.first
253
+ order.algo_strategy.should == serializable_props[:algo_strategy]
254
+ order.algo_params.should == serializable_props[:algo_params]
255
+ order.combo_params.should == serializable_props[:combo_params]
256
+ order.leg_prices.should == serializable_props[:leg_prices]
257
+ p order.combo_params
258
+ end
259
+ end # DB
260
+
225
261
  end # describe IB::Order
data/tasks/common.rake CHANGED
@@ -1,18 +1,5 @@
1
- #task :default => 'test:run'
2
- #task 'gem:release' => 'test:run'
1
+ task :default => 'spec:spec'
3
2
 
4
3
  task :notes do
5
4
  puts 'Output annotations (TBD)'
6
5
  end
7
-
8
- #Bundler not ready for prime time just yet
9
- #desc 'Bundle dependencies'
10
- #task :bundle do
11
- # output = `bundle check 2>&1`
12
- #
13
- # unless $?.to_i == 0
14
- # puts output
15
- # system "bundle install"
16
- # puts
17
- # end
18
- #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.8.0
5
+ version: 0.8.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Paul Legato
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-07 00:00:00.000000000 Z
13
+ date: 2012-06-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -34,13 +34,13 @@ dependencies:
34
34
  requirements:
35
35
  - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: 0.0.1
37
+ version: 3.2.0
38
38
  none: false
39
39
  requirement: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - ! '>='
42
42
  - !ruby/object:Gem::Version
43
- version: 0.0.1
43
+ version: 3.2.0
44
44
  none: false
45
45
  prerelease: false
46
46
  type: :runtime
@@ -84,13 +84,13 @@ dependencies:
84
84
  requirements:
85
85
  - - ! '>='
86
86
  - !ruby/object:Gem::Version
87
- version: 2.8.0
87
+ version: 0.7.2
88
88
  none: false
89
89
  requirement: !ruby/object:Gem::Requirement
90
90
  requirements:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
- version: 2.8.0
93
+ version: 0.7.2
94
94
  none: false
95
95
  prerelease: false
96
96
  type: :development
@@ -110,6 +110,24 @@ dependencies:
110
110
  none: false
111
111
  prerelease: false
112
112
  type: :development
113
+ - !ruby/object:Gem::Dependency
114
+ name: standalone_migrations
115
+ version_requirements: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: !binary |-
120
+ MA==
121
+ none: false
122
+ requirement: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: !binary |-
127
+ MA==
128
+ none: false
129
+ prerelease: false
130
+ type: :development
113
131
  - !ruby/object:Gem::Dependency
114
132
  name: my_scripts
115
133
  version_requirements: !ruby/object:Gem::Requirement
@@ -416,8 +434,6 @@ files:
416
434
  VkVSU0lPTg==
417
435
  - !binary |-
418
436
  SElTVE9SWQ==
419
- - !binary |-
420
- VE9ETw==
421
437
  - !binary |-
422
438
  LmdpdGlnbm9yZQ==
423
439
  homepage: https://github.com/pjlegato/ib-ruby
@@ -430,6 +446,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
430
446
  requirements:
431
447
  - - ! '>='
432
448
  - !ruby/object:Gem::Version
449
+ segments:
450
+ - 0
451
+ hash: 2
433
452
  version: !binary |-
434
453
  MA==
435
454
  none: false
@@ -437,12 +456,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
437
456
  requirements:
438
457
  - - ! '>='
439
458
  - !ruby/object:Gem::Version
459
+ segments:
460
+ - 0
461
+ hash: 2
440
462
  version: !binary |-
441
463
  MA==
442
464
  none: false
443
465
  requirements: []
444
466
  rubyforge_project:
445
- rubygems_version: 1.8.23
467
+ rubygems_version: 1.8.24
446
468
  signing_key:
447
469
  specification_version: 3
448
470
  summary: Ruby Implementation of the Interactive Brokers TWS API
@@ -535,4 +557,3 @@ test_files:
535
557
  c3BlYy9pbnRlZ3JhdGlvbi9vcmRlcnMvdHJhZGVzX3NwZWMucmI=
536
558
  - !binary |-
537
559
  c3BlYy9pbnRlZ3JhdGlvbi9vcmRlcnMvdmFsaWRfaWRzX3NwZWMucmI=
538
- ...
data/TODO DELETED
@@ -1,43 +0,0 @@
1
- Plan:
2
-
3
- 1. IB#send_message method should accept block, thus compressing subscribe/send_message
4
- pair into a single call - to simplify DSL.
5
-
6
- 2. IB Connection uses delays to prevent hitting 50 msgs/sec limit:
7
- http://finance.groups.yahoo.com/group/TWSAPI/message/25413
8
-
9
- 3. IB Connection reconnects gracefully in case if TWS disconnects/reconnects
10
-
11
- 4. Messages should be Models as well (audit trail), @received_at timestamp in messages
12
-
13
- 5. Detailed message documentation
14
-
15
- 6. Move Float values to Decimal (roundoff errors showed in spec!)
16
-
17
-
18
- Done:
19
-
20
- 1. Create integration tests for basic use cases
21
-
22
- 2. IB#subscribe should accept regexes.
23
-
24
- 3. Compatibility with API v.966, 967
25
-
26
- 4. Collect all received messages in Connection#received[:type] by default
27
-
28
- 5. Flow handlers: Connection#wait_for / Connection#received?
29
-
30
- 6. Add ActiveRecord backend to all Models
31
-
32
- 7. Make ActiveModel-like attributes Hash and serialization for tableless Models
33
-
34
-
35
- Ideas for future:
36
-
37
- 1. Decouple Broker-specific Adapter from universal high-level messaging layer
38
- (potentially adding other broker adapters)
39
-
40
- 2. Tweak IB::Message API for speed (use class methods)
41
-
42
- 3. Create integration tests for more use cases (spec/README)
43
-