Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Combo routing parameters and algo parameters support #28

Merged
merged 4 commits into from

1 participant

This page is out of date. Refresh to see the latest.
View
17 Gemfile
@@ -1,22 +1,11 @@
source :gemcutter
+gemspec
+
# Gems used in bin scripts
gem 'getopt'
-# Dependencies
-gem 'bundler', '>= 1.1.3'
-gem 'activerecord', '>= 3.2.0'
+# Platform-specific dependencies
gem 'sqlite3', '> 1.3.3', :platforms => [:ruby_18, :ruby_19] #:ruby
gem 'activerecord-jdbcsqlite3-adapter', '>= 1.2.2', :platforms => :jruby
gem 'jdbc-sqlite3', '>= 3.7.2', :platforms => :jruby
-gem 'xml-simple' , '>= 1.1.1'
-
-#gem.add_dependency 'pg', '>= 0.12.1'
-
-group :development do
- gem 'standalone_migrations'
- gem 'database_cleaner', '>= 0.7.2'
- gem 'rspec', '>= 2.10.0'
- gem 'my_scripts'
-end
-#gemspec
View
15 Gemfile.lock
@@ -1,3 +1,12 @@
+PATH
+ remote: .
+ specs:
+ ib-ruby (0.8.1)
+ activerecord (>= 3.2.0)
+ bundler (>= 1.1.3)
+ standalone_migrations
+ xml-simple (>= 1.1.1)
+
GEM
remote: http://rubygems.org/
specs:
@@ -45,14 +54,12 @@ PLATFORMS
java
DEPENDENCIES
- activerecord (>= 3.2.0)
activerecord-jdbcsqlite3-adapter (>= 1.2.2)
- bundler (>= 1.1.3)
database_cleaner (>= 0.7.2)
getopt
+ ib-ruby!
jdbc-sqlite3 (>= 3.7.2)
my_scripts
- rspec (>= 2.9.0)
+ rspec (>= 2.10.0)
sqlite3 (> 1.3.3)
standalone_migrations
- xml-simple (>= 1.1.1)
View
4 HISTORY
@@ -189,3 +189,7 @@
== 0.8.0 / 2012-06-07
* TWS 926 support
+
+== 0.8.1 / 2012-06-13
+
+* Combo routing parameters and algo parameters supported
View
2  TODO
@@ -1,5 +1,7 @@
Plan:
+0. Full Rails compatibility as a Rails engine.
+
1. IB#send_message method should accept block, thus compressing subscribe/send_message
pair into a single call - to simplify DSL.
View
2  VERSION
@@ -1 +1 @@
-0.8.0
+0.8.1
View
6 db/migrate/131_add_orders.rb
@@ -83,9 +83,9 @@ def change
t.float :basis_points_type # double: EFP orders only
t.string :algo_strategy
- # t.string :algo_params # public Vector<TagValue> m_algoParams; ?!
- # t.string :leg_prices # Vector<OrderComboLeg> m_orderComboLegs
- # t.string :combo_params # not used yet
+ t.text :leg_prices # Vector<OrderComboLeg> m_orderComboLegs
+ t.text :algo_params # public Vector<TagValue> m_algoParams; ?!
+ t.text :combo_params # not used yet
t.integer :scale_init_level_size # int: Size of the first (initial) order component.
t.integer :scale_subs_level_size # int: Order size of the subsequent scale order
View
4 db/schema.rb
@@ -1,3 +1,4 @@
+# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
@@ -214,6 +215,9 @@
t.float "basis_points"
t.float "basis_points_type"
t.string "algo_strategy"
+ t.text "leg_prices"
+ t.text "algo_params"
+ t.text "combo_params"
t.integer "scale_init_level_size"
t.integer "scale_subs_level_size"
t.float "scale_price_increment"
View
7 ib-ruby.gemspec
@@ -15,21 +15,22 @@ Gem::Specification.new do |gem|
versioned = `git ls-files -z`.split("\0")
gem.files = Dir['{bin,lib,man,spec,features,tasks}/**/*', 'db/migrate/**/*',
'Rakefile', 'README*', 'LICENSE*',
- 'VERSION*', 'HISTORY*', 'TODO*', '.gitignore'] & versioned
+ 'VERSION*', 'HISTORY*', '.gitignore'] & versioned
gem.executables = (Dir['bin/**/*'] & versioned).map { |file| File.basename(file) }
gem.test_files = Dir['spec/**/*'] & versioned
gem.require_paths = ['lib']
# Dependencies
gem.add_dependency 'bundler', '>= 1.1.3'
- gem.add_dependency 'activerecord', '>= 0.0.1'
+ gem.add_dependency 'activerecord', '>= 3.2.0'
#gem.add_dependency 'activerecord-jdbcsqlite3-adapter', '>= 1.2.2'
#gem.add_dependency 'jdbc-sqlite3', '>= 3.7.2'
gem.add_dependency 'xml-simple', '>= 1.1.1'
gem.add_dependency 'standalone_migrations'
#gem.add_dependency 'pg', '>= 0.12.1'
- gem.add_development_dependency 'database_cleaner', '>= 2.8.0'
+ gem.add_development_dependency 'database_cleaner', '>= 0.7.2'
gem.add_development_dependency 'rspec', '>= 2.10.0'
+ gem.add_development_dependency 'standalone_migrations'
gem.add_development_dependency 'my_scripts'
end
View
1  lib/ib-ruby/models/model.rb
@@ -49,6 +49,7 @@ def [] key
end
def []= key, val
+ # p key, val
attributes[key.to_sym] = val
end
View
17 lib/ib-ruby/models/order.rb
@@ -222,9 +222,9 @@ class Order < Model.for(:order)
alias order_combo_legs leg_prices
alias smart_combo_routing_params combo_params
- #serialize :leg_prices
- #serialize :algo_params
- #serialize :combo_params
+ serialize :leg_prices
+ serialize :algo_params, Hash
+ serialize :combo_params
# Order is always placed for a contract. Here, we explicitly set this link.
belongs_to :contract
@@ -306,8 +306,8 @@ def default_attributes
:transmit => true,
:what_if => false,
:leg_prices => [],
- :algo_params => [],
- :combo_params => [],
+ :algo_params => HashWithIndifferentAccess.new, #{},
+ :combo_params => HashWithIndifferentAccess.new, #{},
:order_state => IB::OrderState.new(:status => 'New',
:filled => 0,
:remaining => 0,
@@ -315,13 +315,6 @@ def default_attributes
:average_price => 0)
end
- #after_initialize do #opts = {}
- # #self.leg_prices = []
- # #self.algo_params = {}
- # #self.combo_params = {}
- # #self.order_state ||= IB::OrderState.new :status => 'New'
- #end
-
def serialize_algo
if algo_strategy.nil? || algo_strategy.empty?
''
View
2  spec/ib-ruby/connection_spec.rb
@@ -103,7 +103,7 @@ def create_connection opts={}
before(:all) do
@ib.send_message :RequestAccountData
- @ib.wait_for :AccountDownloadEnd
+ @ib.wait_for :AccountDownloadEnd, 3
end
after(:all) { @ib.send_message :RequestAccountData, :subscribe => false }
View
234 spec/ib-ruby/models/order_spec.rb
@@ -1,87 +1,87 @@
require 'model_helper'
describe IB::Models::Order,
- :props =>
- {:local_id => 23,
- :order_ref => 'Test',
- :client_id => 1111,
- :perm_id => 173276893,
- :parent_id => 0,
- :side => :buy,
- :order_type => :market_if_touched,
- :limit_price => 0.1,
- :quantity => 100,
- :tif => :good_till_cancelled,
- :open_close => :close,
- :oca_group => '',
- :oca_type => :reduce_no_block,
- :origin => :firm,
- :designated_location => "WHATEVER",
- :exempt_code => 123,
- :delta_neutral_order_type => :market,
- :transmit => false,
- :outside_rth => true,
- :what_if => true,
- :not_held => true},
-
- # TODO: :presents => { Object => "Formatted"}
- :human => "<Order: Test MIT GTC buy 100 New 0.1 #23/173276893 from 1111>",
-
- :errors => {:side =>["should be buy/sell/short"]},
-
- :assigns =>
- {[:order_type, :delta_neutral_order_type] => codes_and_values_for(:order_type),
-
- :open_close =>
- {[42, nil, 'Foo', :bar] => /should be same.open.close.unknown/,
- ['SAME', 'same', 'S', 's', :same, 0, '0'] => :same,
- ['OPEN', 'open', 'O', 'o', :open, 1, '1'] => :open,
- ['CLOSE', 'close', 'C', 'c', :close, 2, '2'] => :close,
- ['UNKNOWN', 'unknown', 'U', 'u', :unknown, 3, '3'] => :unknown,
- },
-
- [:what_if, :not_held, :outside_rth, :hidden, :transmit, :block_order,
- :sweep_to_fill, :override_percentage_constraints, :all_or_none,
- :etrade_only, :firm_quote_only, :opt_out_smart_routing, :scale_auto_reset,
- :scale_random_percent] => boolean_assigns,
-
- [:local_id, :perm_id, :parent_id] => numeric_or_nil_assigns,
- },
-
- :aliases =>
- {[:side, :action] => buy_sell_short_assigns,
- [:quantity, :total_quantity] => numeric_or_nil_assigns,
- },
-
- :collections =>
- {:order_states =>[{:status => :Foo},
- {:status => 'Bar'},],
-
- :executions =>
- [{:local_id => 23,
- :client_id => 1111,
- :perm_id => 173276893,
- :exchange => "IDEALPRO",
- :exec_id => "0001f4e8.4f5d48f1.01.01",
- :price => 0.1,
- :average_price => 0.1,
- :shares => 40,
- :cumulative_quantity => 40,
- :side => :buy,
- :time => "20120312 15:41:09"},
-
- {:local_id => 23,
- :client_id => 1111,
- :perm_id => 173276893,
- :exchange => "IDEALPRO",
- :exec_id => "0001f4e8.4f5d48f1.01.02",
- :price => 0.1,
- :average_price => 0.1,
- :shares => 60,
- :cumulative_quantity => 100,
- :side => :buy,
- :time => "20120312 15:41:10"}]
- } do
+ :props =>
+ {:local_id => 23,
+ :order_ref => 'Test',
+ :client_id => 1111,
+ :perm_id => 173276893,
+ :parent_id => 0,
+ :side => :buy,
+ :order_type => :market_if_touched,
+ :limit_price => 0.1,
+ :quantity => 100,
+ :tif => :good_till_cancelled,
+ :open_close => :close,
+ :oca_group => '',
+ :oca_type => :reduce_no_block,
+ :origin => :firm,
+ :designated_location => "WHATEVER",
+ :exempt_code => 123,
+ :delta_neutral_order_type => :market,
+ :transmit => false,
+ :outside_rth => true,
+ :what_if => true,
+ :not_held => true},
+
+ # TODO: :presents => { Object => "Formatted"}
+ :human => "<Order: Test MIT GTC buy 100 New 0.1 #23/173276893 from 1111>",
+
+ :errors => {:side =>["should be buy/sell/short"]},
+
+ :assigns =>
+ {[:order_type, :delta_neutral_order_type] => codes_and_values_for(:order_type),
+
+ :open_close =>
+ {[42, nil, 'Foo', :bar] => /should be same.open.close.unknown/,
+ ['SAME', 'same', 'S', 's', :same, 0, '0'] => :same,
+ ['OPEN', 'open', 'O', 'o', :open, 1, '1'] => :open,
+ ['CLOSE', 'close', 'C', 'c', :close, 2, '2'] => :close,
+ ['UNKNOWN', 'unknown', 'U', 'u', :unknown, 3, '3'] => :unknown,
+ },
+
+ [:what_if, :not_held, :outside_rth, :hidden, :transmit, :block_order,
+ :sweep_to_fill, :override_percentage_constraints, :all_or_none,
+ :etrade_only, :firm_quote_only, :opt_out_smart_routing, :scale_auto_reset,
+ :scale_random_percent] => boolean_assigns,
+
+ [:local_id, :perm_id, :parent_id] => numeric_or_nil_assigns,
+ },
+
+ :aliases =>
+ {[:side, :action] => buy_sell_short_assigns,
+ [:quantity, :total_quantity] => numeric_or_nil_assigns,
+ },
+
+ :collections =>
+ {:order_states =>[{:status => :Foo},
+ {:status => 'Bar'},],
+
+ :executions =>
+ [{:local_id => 23,
+ :client_id => 1111,
+ :perm_id => 173276893,
+ :exchange => "IDEALPRO",
+ :exec_id => "0001f4e8.4f5d48f1.01.01",
+ :price => 0.1,
+ :average_price => 0.1,
+ :shares => 40,
+ :cumulative_quantity => 40,
+ :side => :buy,
+ :time => "20120312 15:41:09"},
+
+ {:local_id => 23,
+ :client_id => 1111,
+ :perm_id => 173276893,
+ :exchange => "IDEALPRO",
+ :exec_id => "0001f4e8.4f5d48f1.01.02",
+ :price => 0.1,
+ :average_price => 0.1,
+ :shares => 60,
+ :cumulative_quantity => 100,
+ :side => :buy,
+ :time => "20120312 15:41:10"}]
+} do
it_behaves_like 'Self-equal Model'
it_behaves_like 'Model with invalid defaults'
@@ -173,53 +173,89 @@
it 'is not equal for Orders with different limit price' do
order1 = IB::Order.new :quantity => 100,
- :limit_price => 1,
- :action => 'BUY'
+ :limit_price => 1,
+ :action => 'BUY'
order2 = IB::Order.new :total_quantity => 100,
- :limit_price => 2,
- :action => 'BUY'
+ :limit_price => 2,
+ :action => 'BUY'
order1.should_not == order2
order2.should_not == order1
end
it 'is not equal for Orders with different total_quantity' do
order1 = IB::Order.new :quantity => 20000,
- :limit_price => 1,
- :action => 'BUY'
+ :limit_price => 1,
+ :action => 'BUY'
order2 = IB::Order.new :total_quantity => 100,
- :action => 'BUY',
- :limit_price => 1
+ :action => 'BUY',
+ :limit_price => 1
order1.should_not == order2
order2.should_not == order1
end
it 'is not equal for Orders with different action/side' do
order1 = IB::Order.new :quantity => 100,
- :limit_price => 1,
- :action => 'SELL'
+ :limit_price => 1,
+ :action => 'SELL'
order2 = IB::Order.new :quantity => 100,
- :action => 'BUY',
- :limit_price => 1
+ :action => 'BUY',
+ :limit_price => 1
order1.should_not == order2
order2.should_not == order1
end
it 'is not equal for Orders with different order_type' do
order1 = IB::Order.new :quantity => 100,
- :limit_price => 1,
- :action => 'BUY',
- :order_type => 'LMT'
+ :limit_price => 1,
+ :action => 'BUY',
+ :order_type => 'LMT'
order2 = IB::Order.new :quantity => 100,
- :action => 'BUY',
- :limit_price => 1,
- :order_type => 'MKT'
+ :action => 'BUY',
+ :limit_price => 1,
+ :order_type => 'MKT'
order1.should_not == order2
order2.should_not == order1
end
end
+ context 'DB-backed serialization of properties', :db => true do
+ let(:serializable_props) do
+ {
+ :algo_strategy => "ArrivalPx",
+ :algo_params => { "maxPctVol" => "0.01",
+ "riskAversion" => "Passive",
+ "startTime" => "9:00:00 EST",
+ "endTime" => "15:00:00 EST",
+ "forceCompletion" => "0",
+ "allowPastEndTime" => "1"},
+ :combo_params => {"NonGuaranteed" => "1",
+ "LeginPrio" => "0"},
+ :leg_prices => [1,2,3],
+ }
+ end
+
+ subject { IB::Order.new(props.merge(serializable_props)) }
+
+ after(:all) { DatabaseCleaner.clean }
+
+ it 'is saved to DB with serializable_props' do
+ subject.save.should be_true
+ end
+
+ it 'is loaded from DB with serializable_props' do
+ models = described_class.find(:all)
+ models.should have_exactly(1).model
+ order = models.first
+ order.algo_strategy.should == serializable_props[:algo_strategy]
+ order.algo_params.should == serializable_props[:algo_params]
+ order.combo_params.should == serializable_props[:combo_params]
+ order.leg_prices.should == serializable_props[:leg_prices]
+ p order.combo_params
+ end
+ end # DB
+
end # describe IB::Order
View
15 tasks/common.rake
@@ -1,18 +1,5 @@
-#task :default => 'test:run'
-#task 'gem:release' => 'test:run'
+task :default => 'spec:spec'
task :notes do
puts 'Output annotations (TBD)'
end
-
-#Bundler not ready for prime time just yet
-#desc 'Bundle dependencies'
-#task :bundle do
-# output = `bundle check 2>&1`
-#
-# unless $?.to_i == 0
-# puts output
-# system "bundle install"
-# puts
-# end
-#end
Something went wrong with that request. Please try again.