ib-ruby 0.8.1 → 0.8.3
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/.gitignore +0 -1
- data/HISTORY +5 -0
- data/README.md +47 -53
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/app/assets/javascripts/ib/application.js +15 -0
- data/app/assets/javascripts/ib/underlyings.js +2 -0
- data/app/assets/stylesheets/ib/application.css +13 -0
- data/app/assets/stylesheets/ib/underlyings.css +4 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/controllers/ib/application_controller.rb +5 -0
- data/app/controllers/ib/underlyings_controller.rb +87 -0
- data/app/helpers/ib/application_helper.rb +4 -0
- data/app/helpers/ib/underlyings_helper.rb +4 -0
- data/app/models/ib/underlying.rb +5 -0
- data/app/views/ib/underlyings/_form.html.erb +33 -0
- data/app/views/ib/underlyings/edit.html.erb +6 -0
- data/app/views/ib/underlyings/index.html.erb +29 -0
- data/app/views/ib/underlyings/new.html.erb +5 -0
- data/app/views/ib/underlyings/show.html.erb +25 -0
- data/app/views/layouts/ib/application.html.erb +14 -0
- data/config/routes.rb +6 -0
- data/db/config.yml +19 -0
- data/db/migrate/{101_add_executions.rb → 101_add_ib_executions.rb} +2 -2
- data/db/migrate/{111_add_bars.rb → 111_add_ib_bars.rb} +2 -2
- data/db/migrate/{121_add_order_states.rb → 121_add_ib_order_states.rb} +2 -2
- data/db/migrate/{131_add_orders.rb → 131_add_ib_orders.rb} +2 -2
- data/db/migrate/{141_add_combo_legs.rb → 141_add_ib_combo_legs.rb} +2 -2
- data/db/migrate/{151_add_underlyings.rb → 151_add_ib_underlyings.rb} +2 -2
- data/db/migrate/{161_add_contract_details.rb → 161_add_ib_contract_details.rb} +2 -2
- data/db/migrate/{171_add_contracts.rb → 171_add_ib_contracts.rb} +2 -2
- data/db/schema.rb +245 -0
- data/lib/ib/base.rb +97 -0
- data/lib/ib/base_properties.rb +140 -0
- data/lib/{ib-ruby → ib}/connection.rb +2 -2
- data/lib/{ib-ruby → ib}/constants.rb +0 -0
- data/lib/{ib-ruby → ib}/db.rb +9 -5
- data/lib/ib/engine.rb +35 -0
- data/lib/{ib-ruby → ib}/errors.rb +0 -0
- data/lib/{ib-ruby → ib}/extensions.rb +2 -2
- data/lib/{ib-ruby → ib}/logger.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/abstract_message.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/abstract_message.rb +1 -1
- data/lib/{ib-ruby → ib}/messages/incoming/alert.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/contract_data.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/delta_neutral_validation.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/execution_data.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/historical_data.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/market_depths.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/next_valid_id.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/open_order.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/order_status.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/portfolio_value.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/real_time_bar.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/scanner_data.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming/ticks.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/incoming.rb +14 -14
- data/lib/{ib-ruby → ib}/messages/outgoing/abstract_message.rb +1 -1
- data/lib/{ib-ruby → ib}/messages/outgoing/bar_requests.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/outgoing/place_order.rb +0 -0
- data/lib/{ib-ruby → ib}/messages/outgoing.rb +5 -5
- data/lib/ib/messages.rb +8 -0
- data/lib/ib/model.rb +8 -0
- data/lib/ib/models.rb +10 -0
- data/lib/ib/requires.rb +9 -0
- data/lib/{ib-ruby → ib}/socket.rb +0 -0
- data/lib/{ib-ruby → ib}/symbols/forex.rb +1 -1
- data/lib/{ib-ruby → ib}/symbols/futures.rb +2 -2
- data/lib/{ib-ruby → ib}/symbols/options.rb +1 -1
- data/lib/{ib-ruby → ib}/symbols/stocks.rb +1 -1
- data/lib/ib/symbols.rb +9 -0
- data/lib/{ib-ruby → ib}/version.rb +0 -0
- data/lib/ib-ruby.rb +2 -24
- data/lib/ib.rb +23 -0
- data/lib/models/ib/bag.rb +51 -0
- data/lib/models/ib/bar.rb +41 -0
- data/lib/models/ib/combo_leg.rb +102 -0
- data/lib/models/ib/contract.rb +287 -0
- data/lib/models/ib/contract_detail.rb +68 -0
- data/lib/models/ib/execution.rb +62 -0
- data/lib/models/ib/option.rb +60 -0
- data/lib/models/ib/order.rb +389 -0
- data/lib/models/ib/order_state.rb +126 -0
- data/lib/models/ib/underlying.rb +35 -0
- data/spec/README.md +34 -2
- data/spec/TODO +5 -1
- data/spec/comb.rb +13 -0
- data/spec/db.rb +1 -1
- data/spec/db_helper.rb +3 -3
- data/spec/dummy.rb +13 -0
- data/spec/gw.rb +4 -0
- data/spec/{ib-ruby → ib}/connection_spec.rb +0 -0
- data/spec/{ib-ruby → ib}/messages/incoming/alert_spec.rb +0 -0
- data/spec/{ib-ruby → ib}/messages/incoming/open_order_spec.rb +0 -0
- data/spec/{ib-ruby → ib}/messages/incoming/order_status_spec.rb +16 -17
- data/spec/{ib-ruby → ib}/messages/outgoing/account_data_spec.rb +0 -0
- data/spec/{ib-ruby → ib}/messages/outgoing/market_data_type_spec.rb +0 -0
- data/spec/integration/historic_data_spec.rb +3 -3
- data/spec/integration/orders/trades_spec.rb +1 -1
- data/spec/{ib-ruby/models → models/ib}/bag_spec.rb +2 -7
- data/spec/{ib-ruby/models → models/ib}/bar_spec.rb +1 -6
- data/spec/{ib-ruby/models → models/ib}/combo_leg_spec.rb +2 -12
- data/spec/{ib-ruby/models → models/ib}/contract_detail_spec.rb +3 -8
- data/spec/{ib-ruby/models → models/ib}/contract_spec.rb +4 -12
- data/spec/{ib-ruby/models → models/ib}/execution_spec.rb +2 -7
- data/spec/{ib-ruby/models → models/ib}/option_spec.rb +1 -6
- data/spec/{ib-ruby/models → models/ib}/order_spec.rb +5 -10
- data/spec/{ib-ruby/models → models/ib}/order_state_spec.rb +2 -7
- data/spec/{ib-ruby/models → models/ib}/underlying_spec.rb +3 -7
- data/spec/my.rb +5 -0
- data/spec/spec_helper.rb +62 -36
- metadata +417 -544
- data/lib/ib-ruby/messages.rb +0 -8
- data/lib/ib-ruby/models/bag.rb +0 -54
- data/lib/ib-ruby/models/bar.rb +0 -43
- data/lib/ib-ruby/models/combo_leg.rb +0 -104
- data/lib/ib-ruby/models/contract.rb +0 -287
- data/lib/ib-ruby/models/contract_detail.rb +0 -70
- data/lib/ib-ruby/models/execution.rb +0 -64
- data/lib/ib-ruby/models/model.rb +0 -105
- data/lib/ib-ruby/models/model_properties.rb +0 -146
- data/lib/ib-ruby/models/option.rb +0 -62
- data/lib/ib-ruby/models/order.rb +0 -389
- data/lib/ib-ruby/models/order_state.rb +0 -128
- data/lib/ib-ruby/models/underlying.rb +0 -36
- data/lib/ib-ruby/models.rb +0 -15
- data/lib/ib-ruby/symbols.rb +0 -9
- data/spec/test.rb +0 -61
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
module IB
|
|
2
|
+
|
|
3
|
+
# OrderState represents dynamic (changeable) info about a single Order,
|
|
4
|
+
# isolating these changes and making Order essentially immutable
|
|
5
|
+
class OrderState < IB::Model
|
|
6
|
+
include BaseProperties
|
|
7
|
+
|
|
8
|
+
#p column_names
|
|
9
|
+
belongs_to :order
|
|
10
|
+
|
|
11
|
+
# Properties arriving via OpenOrder message
|
|
12
|
+
prop :init_margin, # Float: The impact the order would have on your initial margin.
|
|
13
|
+
:maint_margin, # Float: The impact the order would have on your maintenance margin.
|
|
14
|
+
:equity_with_loan, # Float: The impact the order would have on your equity
|
|
15
|
+
:commission, # double: Shows the commission amount on the order.
|
|
16
|
+
:min_commission, # The possible min range of the actual order commission.
|
|
17
|
+
:max_commission, # The possible max range of the actual order commission.
|
|
18
|
+
:commission_currency, # String: Shows the currency of the commission.
|
|
19
|
+
:warning_text # String: Displays a warning message if warranted.
|
|
20
|
+
|
|
21
|
+
# Properties arriving via OrderStatus message:
|
|
22
|
+
prop :filled, # int
|
|
23
|
+
:remaining, # int
|
|
24
|
+
[:price, :last_fill_price,], # double
|
|
25
|
+
[:average_price, :average_fill_price], # double
|
|
26
|
+
:why_held # String: comma-separated list of reasons for order to be held.
|
|
27
|
+
|
|
28
|
+
# Properties arriving in both messages:
|
|
29
|
+
prop :local_id, # int: Order id associated with client (volatile).
|
|
30
|
+
:perm_id, # int: TWS permanent id, remains the same over TWS sessions.
|
|
31
|
+
:client_id, # int: The id of the client that placed this order.
|
|
32
|
+
:parent_id, # int: The order ID of the parent (original) order, used
|
|
33
|
+
:status => :s # String: Displays the order status. Possible values include:
|
|
34
|
+
# - PendingSubmit - indicates that you have transmitted the order, but
|
|
35
|
+
# have not yet received confirmation that it has been accepted by the
|
|
36
|
+
# order destination. NOTE: This order status is NOT sent back by TWS
|
|
37
|
+
# and should be explicitly set by YOU when an order is submitted.
|
|
38
|
+
# - PendingCancel - indicates that you have sent a request to cancel
|
|
39
|
+
# the order but have not yet received cancel confirmation from the
|
|
40
|
+
# order destination. At this point, your order cancel is not confirmed.
|
|
41
|
+
# You may still receive an execution while your cancellation request
|
|
42
|
+
# is pending. NOTE: This order status is not sent back by TWS and
|
|
43
|
+
# should be explicitly set by YOU when an order is canceled.
|
|
44
|
+
# - PreSubmitted - indicates that a simulated order type has been
|
|
45
|
+
# accepted by the IB system and that this order has yet to be elected.
|
|
46
|
+
# The order is held in the IB system until the election criteria are
|
|
47
|
+
# met. At that time the order is transmitted to the order destination
|
|
48
|
+
# as specified.
|
|
49
|
+
# - Submitted - indicates that your order has been accepted at the order
|
|
50
|
+
# destination and is working.
|
|
51
|
+
# - Cancelled - indicates that the balance of your order has been
|
|
52
|
+
# confirmed canceled by the IB system. This could occur unexpectedly
|
|
53
|
+
# when IB or the destination has rejected your order.
|
|
54
|
+
# - ApiCancelled - canceled via API
|
|
55
|
+
# - Filled - indicates that the order has been completely filled.
|
|
56
|
+
# - Inactive - indicates that the order has been accepted by the system
|
|
57
|
+
# (simulated orders) or an exchange (native orders) but that currently
|
|
58
|
+
# the order is inactive due to system, exchange or other issues.
|
|
59
|
+
|
|
60
|
+
validates_format_of :status, :without => /^$/, :message => 'must not be empty'
|
|
61
|
+
validates_numericality_of :price, :average_price, :allow_nil => true
|
|
62
|
+
validates_numericality_of :local_id, :perm_id, :client_id, :parent_id, :filled,
|
|
63
|
+
:remaining, :only_integer => true, :allow_nil => true
|
|
64
|
+
|
|
65
|
+
## Testing Order state:
|
|
66
|
+
|
|
67
|
+
def new?
|
|
68
|
+
status.empty? || status == 'New'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Order is in a valid, working state on TWS side
|
|
72
|
+
def submitted?
|
|
73
|
+
status == 'PreSubmitted' || status == 'Submitted'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Order is in a valid, working state on TWS side
|
|
77
|
+
def pending?
|
|
78
|
+
submitted? || status == 'PendingSubmit'
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Order is in invalid state
|
|
82
|
+
def active?
|
|
83
|
+
new? || pending?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Order is in invalid state
|
|
87
|
+
def inactive?
|
|
88
|
+
!active? # status == 'Inactive'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def complete_fill?
|
|
92
|
+
status == 'Filled' && remaining == 0 # filled >= total_quantity # Manually corrected
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Comparison
|
|
96
|
+
def == other
|
|
97
|
+
other && other.is_a?(OrderState) &&
|
|
98
|
+
status == other.status &&
|
|
99
|
+
local_id == other.local_id &&
|
|
100
|
+
perm_id == other.perm_id &&
|
|
101
|
+
client_id == other.client_id &&
|
|
102
|
+
filled == other.filled &&
|
|
103
|
+
remaining == other.remaining &&
|
|
104
|
+
last_fill_price == other.last_fill_price &&
|
|
105
|
+
init_margin == other.init_margin &&
|
|
106
|
+
maint_margin == other.maint_margin &&
|
|
107
|
+
equity_with_loan == other.equity_with_loan &&
|
|
108
|
+
why_held == other.why_held &&
|
|
109
|
+
warning_text == other.warning_text &&
|
|
110
|
+
commission == other.commission
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def to_human
|
|
114
|
+
"<OrderState: #{status} ##{local_id}/#{perm_id} from #{client_id}" +
|
|
115
|
+
(filled ? " filled #{filled}/#{remaining}" : '') +
|
|
116
|
+
(last_fill_price ? " at #{last_fill_price}/#{average_fill_price}" : '') +
|
|
117
|
+
(init_margin ? " margin #{init_margin}/#{maint_margin}" : '') +
|
|
118
|
+
(equity_with_loan ? " equity #{equity_with_loan}" : '') +
|
|
119
|
+
(commission && commission > 0 ? " fee #{commission}" : "") +
|
|
120
|
+
(why_held ? " why_held #{why_held}" : '') +
|
|
121
|
+
((warning_text && warning_text != '') ? " warning #{warning_text}" : '') + ">"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
alias to_s to_human
|
|
125
|
+
end # class Order
|
|
126
|
+
end # module IB
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module IB
|
|
2
|
+
|
|
3
|
+
# Calculated characteristics of underlying Contract (volatile)
|
|
4
|
+
class Underlying < IB::Model
|
|
5
|
+
include BaseProperties
|
|
6
|
+
|
|
7
|
+
attr_accessible :created_at, :updated_at
|
|
8
|
+
attr_protected :id
|
|
9
|
+
|
|
10
|
+
has_one :contract
|
|
11
|
+
|
|
12
|
+
prop :con_id, # Id of the Underlying Contract
|
|
13
|
+
:delta, # double: The underlying stock or future delta.
|
|
14
|
+
:price # double: The price of the underlying.
|
|
15
|
+
|
|
16
|
+
validates_numericality_of :con_id, :delta, :price #, :allow_nil => true
|
|
17
|
+
|
|
18
|
+
def default_attributes
|
|
19
|
+
super.merge :con_id => 0
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Serialize under_comp parameters
|
|
23
|
+
def serialize
|
|
24
|
+
[true, con_id, delta, price]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Comparison
|
|
28
|
+
def == other
|
|
29
|
+
con_id == other.con_id && delta == other.delta && price == other.price
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end # class Underlying
|
|
33
|
+
UnderComp = Underlying
|
|
34
|
+
|
|
35
|
+
end # module IB
|
data/spec/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
## RUNNING
|
|
1
|
+
## RUNNING TEST SUITE:
|
|
2
2
|
|
|
3
3
|
The gem comes with a spec suit that may be used to test ib-ruby compatibility
|
|
4
4
|
with your specific TWS/Gateway installation. The test suit should be run ONLY
|
|
@@ -28,10 +28,42 @@ with database backend, use:
|
|
|
28
28
|
$ rspec -rdb [spec/specific_spec.rb]
|
|
29
29
|
|
|
30
30
|
If you run your specs against both Gateway and TWS, you may want to use the following
|
|
31
|
-
|
|
31
|
+
switches (by default, TWS port is used):
|
|
32
32
|
|
|
33
|
+
$ rspec -rgw [spec/specific_spec.rb]
|
|
33
34
|
$ rspec -rtws [spec/specific_spec.rb]
|
|
34
35
|
|
|
36
|
+
Some of the specs may randomly fail from time to time when you are running the spec suit
|
|
37
|
+
against your IB paper account. This happens because these specs depend on live connection
|
|
38
|
+
to IB, which is inherently non-deterministic. Anything happening along the way - network
|
|
39
|
+
delay, problems with IB data farms, even high CPU load on your machine - may delay the
|
|
40
|
+
expected responce, so that the spec times out or does not find expected data. It is
|
|
41
|
+
suggested that you run the failing specs several times, and start debugging them only
|
|
42
|
+
if they are failing regularly. Otherwise, you may just waste time chasing an artifact of
|
|
43
|
+
unreliable IB connection, rather than some real problem with the specs.
|
|
44
|
+
|
|
45
|
+
## RUNNING RAILS-SPECIFIC SPECS:
|
|
46
|
+
|
|
47
|
+
This gem has two operating modes: standalone and Rails-engine. If you require it in a
|
|
48
|
+
Rails environment, it loads Rails engine automatically. Otherwise, it does not load any
|
|
49
|
+
Rails integration. So, Rails-specific specs are separated from generic spec suite and
|
|
50
|
+
located in 'rails_spec'.
|
|
51
|
+
|
|
52
|
+
There are two included Rails apps that can be used to test engine integration. One is
|
|
53
|
+
an auto-generated Dummy app, and another is [Combustion](https://github.com/freelancing-god/combustion) based.
|
|
54
|
+
|
|
55
|
+
To test Rails engine integration with Combustion-based Rails application, use:
|
|
56
|
+
|
|
57
|
+
$ rspec -rcomb rails_spec
|
|
58
|
+
$ rspec -rcomb [spec/specific_spec.rb]
|
|
59
|
+
|
|
60
|
+
To run specs with Dummy Rails application, use:
|
|
61
|
+
|
|
62
|
+
$ rspec -rdummy rails_spec
|
|
63
|
+
$ rspec -rdummy [spec/specific_spec.rb]
|
|
64
|
+
|
|
65
|
+
Other suit switches described in previous section should work with Rails as well.
|
|
66
|
+
|
|
35
67
|
# WRITING YOUR OWN INTEGRATION SPECS
|
|
36
68
|
|
|
37
69
|
You can easily create your own integration specs. Pattern for writing specs is like this:
|
data/spec/TODO
CHANGED
data/spec/comb.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
puts 'To run specs with Combustion-based Rails app, use:'
|
|
2
|
+
puts '$ rspec -rcomb rails_spec'
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'combustion'
|
|
6
|
+
require 'backports/1.9.2' if RUBY_VERSION =~ /1.8/
|
|
7
|
+
require 'ib'
|
|
8
|
+
|
|
9
|
+
Combustion.path = 'rails_spec/combustion'
|
|
10
|
+
Combustion.initialize!
|
|
11
|
+
|
|
12
|
+
require 'rspec/rails'
|
|
13
|
+
|
data/spec/db.rb
CHANGED
data/spec/db_helper.rb
CHANGED
|
@@ -81,7 +81,7 @@ shared_examples_for 'Model with associations' do
|
|
|
81
81
|
subject_name_plural = described_class.to_s.demodulize.tableize
|
|
82
82
|
|
|
83
83
|
associations.each do |name, item_props|
|
|
84
|
-
item = "IB
|
|
84
|
+
item = "IB::#{name.to_s.classify}".constantize.new item_props
|
|
85
85
|
#item = const_get("IB::#{name.to_s.classify}").new item_props
|
|
86
86
|
puts "Testing single association #{name}"
|
|
87
87
|
subject.association(name).reflection.should_not be_collection
|
|
@@ -119,7 +119,7 @@ shared_examples_for 'Model with associations' do
|
|
|
119
119
|
subject.association(name).reflection.should be_collection
|
|
120
120
|
|
|
121
121
|
[items].flatten.each do |item_props|
|
|
122
|
-
item = "IB
|
|
122
|
+
item = "IB::#{name.to_s.classify}".constantize.new item_props
|
|
123
123
|
#item = item_class.new item_props
|
|
124
124
|
association = subject.send name #, :reload
|
|
125
125
|
|
|
@@ -139,7 +139,7 @@ shared_examples_for 'Model with associations' do
|
|
|
139
139
|
subject.save
|
|
140
140
|
|
|
141
141
|
[items].flatten.each do |item_props|
|
|
142
|
-
item = "IB
|
|
142
|
+
item = "IB::#{name.to_s.classify}".constantize.new item_props
|
|
143
143
|
association = subject.send name #, :reload
|
|
144
144
|
|
|
145
145
|
association.should include item
|
data/spec/dummy.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
puts 'To run specs with dummy Rails app, use:'
|
|
2
|
+
puts '$ rspec -rdummy rails_spec'
|
|
3
|
+
|
|
4
|
+
# Configure Rails Environment
|
|
5
|
+
ENV["RAILS_ENV"] = "test"
|
|
6
|
+
|
|
7
|
+
require File.expand_path("../../rails_spec/dummy/config/environment.rb", __FILE__)
|
|
8
|
+
|
|
9
|
+
require 'rspec/rails'
|
|
10
|
+
require 'capybara/rails'
|
|
11
|
+
require 'capybara/dsl'
|
|
12
|
+
|
|
13
|
+
Rails.backtrace_cleaner.remove_silencers!
|
data/spec/gw.rb
ADDED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -9,7 +9,7 @@ shared_examples_for 'OrderStatus message' do
|
|
|
9
9
|
its(:local_id) { should be_an Integer }
|
|
10
10
|
its(:status) { should =~ /Submit/ }
|
|
11
11
|
its(:to_human) { should =~
|
|
12
|
-
|
|
12
|
+
/<OrderStatus: <OrderState: .*Submit.* #\d+\/\d+ from 1111 filled 0\/100/ }
|
|
13
13
|
|
|
14
14
|
it 'has proper order_state accessor' do
|
|
15
15
|
os = subject.order_state
|
|
@@ -38,18 +38,17 @@ describe IB::Messages::Incoming::OrderStatus do
|
|
|
38
38
|
context 'Instantiated with data Hash' do
|
|
39
39
|
subject do
|
|
40
40
|
IB::Messages::Incoming::OrderStatus.new :version => 6,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
end
|
|
41
|
+
:order_state => { :local_id => 1313,
|
|
42
|
+
:perm_id => 172323928,
|
|
43
|
+
:client_id => 1111,
|
|
44
|
+
:parent_id => 0,
|
|
45
|
+
:status => 'PreSubmitted',
|
|
46
|
+
:filled => 0,
|
|
47
|
+
:remaining => 100,
|
|
48
|
+
:average_fill_price => 0.0,
|
|
49
|
+
:last_fill_price => 0.0,
|
|
50
|
+
:why_held => 'child' }
|
|
51
|
+
end
|
|
53
52
|
|
|
54
53
|
it_behaves_like 'OrderStatus message'
|
|
55
54
|
end
|
|
@@ -58,15 +57,15 @@ describe IB::Messages::Incoming::OrderStatus do
|
|
|
58
57
|
before(:all) do
|
|
59
58
|
verify_account
|
|
60
59
|
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
|
61
|
-
@ib.wait_for :NextValidId
|
|
62
|
-
|
|
60
|
+
@ib.wait_for :NextValidId, 3
|
|
61
|
+
@local_id = @ib.next_local_id
|
|
63
62
|
place_order IB::Symbols::Stocks[:wfc]
|
|
64
|
-
@ib.wait_for
|
|
63
|
+
@ib.wait_for 2 # OrderStatus for cancelled orders from previous specs arrives first :(
|
|
65
64
|
end
|
|
66
65
|
|
|
67
66
|
after(:all) { close_connection } # implicitly cancels order
|
|
68
67
|
|
|
69
|
-
subject { @ib.received[:OrderStatus].
|
|
68
|
+
subject { @ib.received[:OrderStatus].find { |msg| msg.local_id == @local_id } }
|
|
70
69
|
|
|
71
70
|
it_behaves_like 'OrderStatus message'
|
|
72
71
|
end
|
|
File without changes
|
|
File without changes
|
|
@@ -2,7 +2,7 @@ require 'integration_helper'
|
|
|
2
2
|
|
|
3
3
|
describe 'Request Historic Data', :connected => true, :integration => true do
|
|
4
4
|
|
|
5
|
-
CORRECT_OPTS = {:id =>
|
|
5
|
+
CORRECT_OPTS = {:id => 567,
|
|
6
6
|
:contract => IB::Symbols::Stocks[:wfc],
|
|
7
7
|
:end_date_time => Time.now.to_ib,
|
|
8
8
|
:duration => '1 D',
|
|
@@ -37,7 +37,7 @@ describe 'Request Historic Data', :connected => true, :integration => true do
|
|
|
37
37
|
before(:all) do
|
|
38
38
|
# No historical data for GBP/CASH@IDEALPRO
|
|
39
39
|
@ib.send_message :RequestHistoricalData, CORRECT_OPTS
|
|
40
|
-
@ib.wait_for :HistoricalData,
|
|
40
|
+
@ib.wait_for :HistoricalData, 6 # sec
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
subject { @ib.received[:HistoricalData].last }
|
|
@@ -45,7 +45,7 @@ describe 'Request Historic Data', :connected => true, :integration => true do
|
|
|
45
45
|
it { @ib.received[:HistoricalData].should have_at_least(1).historic_data }
|
|
46
46
|
|
|
47
47
|
it { should be_an IB::Messages::Incoming::HistoricalData }
|
|
48
|
-
its(:request_id) { should ==
|
|
48
|
+
its(:request_id) { should == 567 }
|
|
49
49
|
its(:count) { should be_an Integer }
|
|
50
50
|
its(:start_date) { should =~ /\d{8} *\d\d:\d\d:\d\d/ } # "20120302 22:46:42"
|
|
51
51
|
its(:end_date) { should =~ /\d{8} *\d\d:\d\d:\d\d/ }
|
|
@@ -32,7 +32,7 @@ def execution_should_be side, opts={}
|
|
|
32
32
|
exec.local_id.should == @order.local_id if @order
|
|
33
33
|
exec.exec_id.should be_a String
|
|
34
34
|
exec.time.should =~ /\d\d:\d\d:\d\d/
|
|
35
|
-
exec.account_name.should == OPTS[:connection][:
|
|
35
|
+
exec.account_name.should == OPTS[:connection][:account]
|
|
36
36
|
exec.exchange.should == 'IDEALPRO'
|
|
37
37
|
exec.side.should == side
|
|
38
38
|
exec.shares.should == 20000
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'model_helper'
|
|
2
2
|
|
|
3
|
-
describe IB::
|
|
3
|
+
describe IB::Bag,
|
|
4
4
|
|
|
5
5
|
:props =>
|
|
6
6
|
{:symbol => 'GOOG',
|
|
@@ -41,16 +41,11 @@ describe IB::Models::Bag,
|
|
|
41
41
|
[:symbol, :local_symbol] => string_assigns,
|
|
42
42
|
|
|
43
43
|
:multiplier => to_i_assigns,
|
|
44
|
-
} do
|
|
44
|
+
} do
|
|
45
45
|
|
|
46
46
|
it_behaves_like 'Model with valid defaults'
|
|
47
47
|
it_behaves_like 'Self-equal Model'
|
|
48
48
|
|
|
49
|
-
it 'has class name shortcut' do
|
|
50
|
-
IB::Bag.should == IB::Models::Bag
|
|
51
|
-
IB::Bag.new.should == IB::Models::Bag.new
|
|
52
|
-
end
|
|
53
|
-
|
|
54
49
|
context 'properly initiated' do
|
|
55
50
|
subject { IB::Bag.new props }
|
|
56
51
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'model_helper'
|
|
2
2
|
|
|
3
|
-
describe IB::
|
|
3
|
+
describe IB::Bar,
|
|
4
4
|
:props =>
|
|
5
5
|
{:open => 1.31,
|
|
6
6
|
:high => 1.35,
|
|
@@ -33,9 +33,4 @@ describe IB::Models::Bar,
|
|
|
33
33
|
it_behaves_like 'Model with invalid defaults'
|
|
34
34
|
it_behaves_like 'Self-equal Model'
|
|
35
35
|
|
|
36
|
-
it 'has class name shortcut' do
|
|
37
|
-
IB::Bar.should == IB::Models::Bar
|
|
38
|
-
IB::Bar.new.should == IB::Models::Bar.new
|
|
39
|
-
end
|
|
40
|
-
|
|
41
36
|
end # describe IB::Bar
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'model_helper'
|
|
2
2
|
|
|
3
|
-
describe IB::
|
|
3
|
+
describe IB::ComboLeg,
|
|
4
4
|
:props =>
|
|
5
5
|
{:con_id => 81032967,
|
|
6
6
|
:ratio => 2,
|
|
@@ -40,12 +40,6 @@ describe IB::Models::ComboLeg,
|
|
|
40
40
|
it_behaves_like 'Model with valid defaults'
|
|
41
41
|
it_behaves_like 'Self-equal Model'
|
|
42
42
|
|
|
43
|
-
it 'has class name shortcut' do
|
|
44
|
-
IB::ComboLeg.should == IB::Models::ComboLeg
|
|
45
|
-
IB::ComboLeg.new.should == IB::Models::ComboLeg.new
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
|
|
49
43
|
context "serialization" do
|
|
50
44
|
subject { IB::ComboLeg.new props }
|
|
51
45
|
|
|
@@ -105,10 +99,6 @@ describe IB::Models::ComboLeg,
|
|
|
105
99
|
combo_leg = IB::ComboLeg.where(:con_id => 454).first
|
|
106
100
|
combo_leg.should be_valid
|
|
107
101
|
|
|
108
|
-
#p combo_leg.combo.attributes
|
|
109
|
-
#p combo_leg.combo.strike
|
|
110
|
-
#p combo_leg.combo.include_expired
|
|
111
|
-
|
|
112
102
|
combo = combo_leg.combo
|
|
113
103
|
google = combo_leg.leg_contract
|
|
114
104
|
#combo.should == @combo # NOT equal, different legs
|
|
@@ -138,4 +128,4 @@ describe IB::Models::ComboLeg,
|
|
|
138
128
|
end
|
|
139
129
|
end
|
|
140
130
|
|
|
141
|
-
end # describe IB::
|
|
131
|
+
end # describe IB::ComboLeg
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'model_helper'
|
|
2
2
|
|
|
3
|
-
describe IB::
|
|
3
|
+
describe IB::ContractDetail,
|
|
4
4
|
|
|
5
5
|
:props =>
|
|
6
6
|
{:market_name => 'AAPL',
|
|
@@ -33,14 +33,9 @@ describe IB::Models::ContractDetail,
|
|
|
33
33
|
|
|
34
34
|
:aliases =>
|
|
35
35
|
{[:contract, :summary] => {IB::Contract.new => IB::Contract.new}
|
|
36
|
-
} do
|
|
36
|
+
} do
|
|
37
37
|
|
|
38
38
|
it_behaves_like 'Model with invalid defaults'
|
|
39
39
|
it_behaves_like 'Self-equal Model'
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
IB::ContractDetail.should == IB::Models::ContractDetail
|
|
43
|
-
IB::ContractDetail.new.should == IB::Models::ContractDetail.new
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
end # describe IB::Contract
|
|
41
|
+
end # describe IB::ContractDetail
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'model_helper'
|
|
2
2
|
require 'combo_helper'
|
|
3
3
|
|
|
4
|
-
describe IB::
|
|
4
|
+
describe IB::Contract,
|
|
5
5
|
:props =>
|
|
6
6
|
{:symbol => 'AAPL',
|
|
7
7
|
:sec_type => :option,
|
|
@@ -51,16 +51,11 @@ describe IB::Models::Contract,
|
|
|
51
51
|
:strike => to_f_assigns,
|
|
52
52
|
|
|
53
53
|
:include_expired => boolean_assigns,
|
|
54
|
-
} do
|
|
54
|
+
} do
|
|
55
55
|
|
|
56
56
|
it_behaves_like 'Model with invalid defaults'
|
|
57
57
|
it_behaves_like 'Self-equal Model'
|
|
58
58
|
|
|
59
|
-
it 'has class name shortcut' do
|
|
60
|
-
IB::Contract.should == IB::Models::Contract
|
|
61
|
-
IB::Contract.new.should == IB::Models::Contract.new
|
|
62
|
-
end
|
|
63
|
-
|
|
64
59
|
context 'testing for Contract type (sec_type)' do
|
|
65
60
|
|
|
66
61
|
it 'correctly defines Contract type (sec_type) for Option contract' do
|
|
@@ -111,8 +106,9 @@ describe IB::Models::Contract,
|
|
|
111
106
|
|
|
112
107
|
end
|
|
113
108
|
|
|
114
|
-
context "serialization" do
|
|
109
|
+
context "serialization", :connected => true do
|
|
115
110
|
before(:all) do
|
|
111
|
+
# TODO: Change butterfly into a stub, reduce dependency on IB connection
|
|
116
112
|
@ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
|
|
117
113
|
@ib.wait_for :ManagedAccounts
|
|
118
114
|
@combo = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
|
|
@@ -152,7 +148,3 @@ describe IB::Models::Contract,
|
|
|
152
148
|
|
|
153
149
|
|
|
154
150
|
end # describe IB::Contract
|
|
155
|
-
|
|
156
|
-
__END__
|
|
157
|
-
IB::Models::ContractDetail id: nil, contract_id: nil, market_name: "AAPL", trading_class: "AAPL", min_tick: 0.01, price_magnifier: 1, order_types: "ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKE...", valid_exchanges: "SMART,AMEX,BATS,BOX,CBOE,CBOE2,IBSX,ISE,MIBSX,NASDA...", under_con_id: 265598, long_name: "APPLE INC", contract_month: "201301", industry: "Technology", category: "Computers", subcategory: "Computers", time_zone: "EST", trading_hours: "20120422:0930-1600;20120423:0930-1600", liquid_hours: "20120422:0930-1600;20120423:0930-1600", cusip: nil, ratings: nil, desc_append: nil, bond_type: nil, coupon_type: nil, coupon: 0.0, maturity: nil, issue_date: nil, next_option_date: nil, next_option_type: nil, notes: nil, callable: false, puttable: false, convertible: false, next_option_partial: false, created_at: "2012-04-23 13:58:05", updated_at: "2012-04-23 13:58:05"
|
|
158
|
-
IB::Models::ContractDetail id: nil, contract_id: nil, market_name: "AAPL", trading_class: "AAPL", min_tick: 0.01, price_magnifier: 1, order_types: "ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKE...", valid_exchanges: "SMART,AMEX,BATS,BOX,CBOE,CBOE2,IBSX,ISE,MIBSX,NASDA...", under_con_id: 265598, long_name: "APPLE INC", contract_month: "201301", industry: "Technology", category: "Computers", subcategory: "Computers", time_zone: "EST", trading_hours: "20120422:0930-1600;20120423:0930-1600", liquid_hours: "20120422:0930-1600;20120423:0930-1600", cusip: nil, ratings: nil, desc_append: nil, bond_type: nil, coupon_type: nil, coupon: 0.0, maturity: nil, issue_date: nil, next_option_date: nil, next_option_type: nil, notes: nil, callable: false, puttable: false, convertible: false, next_option_partial: false, created_at: "2012-04-23 13:58:04", updated_at: "2012-04-23 13:58:04">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'model_helper'
|
|
2
2
|
|
|
3
|
-
describe IB::
|
|
3
|
+
describe IB::Execution,
|
|
4
4
|
:props =>
|
|
5
5
|
{:account_name => "DU111110",
|
|
6
6
|
:client_id => 1111,
|
|
@@ -49,11 +49,6 @@ describe IB::Models::Execution,
|
|
|
49
49
|
it_behaves_like 'Model with invalid defaults'
|
|
50
50
|
it_behaves_like 'Self-equal Model'
|
|
51
51
|
|
|
52
|
-
it 'has class name shortcut' do
|
|
53
|
-
IB::Execution.should == IB::Models::Execution
|
|
54
|
-
IB::Execution.new.should == IB::Models::Execution.new
|
|
55
|
-
end
|
|
56
|
-
|
|
57
52
|
context 'DB backed associations', :db => true do
|
|
58
53
|
subject { IB::Execution.new props }
|
|
59
54
|
|
|
@@ -113,4 +108,4 @@ describe IB::Models::Execution,
|
|
|
113
108
|
end
|
|
114
109
|
end
|
|
115
110
|
|
|
116
|
-
end # describe IB::
|
|
111
|
+
end # describe IB::Execution
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'model_helper'
|
|
2
2
|
|
|
3
|
-
describe IB::
|
|
3
|
+
describe IB::Option,
|
|
4
4
|
:human => "<Option: AAPL 201301 put 600.5 SMART >",
|
|
5
5
|
|
|
6
6
|
:errors => {:right => ["should be put or call"],
|
|
@@ -50,11 +50,6 @@ describe IB::Models::Option,
|
|
|
50
50
|
it_behaves_like 'Self-equal Model'
|
|
51
51
|
it_behaves_like 'Model with invalid defaults'
|
|
52
52
|
|
|
53
|
-
it 'has class name shortcut' do
|
|
54
|
-
IB::Option.should == IB::Models::Option
|
|
55
|
-
IB::Option.new.should == IB::Models::Option.new
|
|
56
|
-
end
|
|
57
|
-
|
|
58
53
|
context 'properly initiated' do
|
|
59
54
|
subject { IB::Option.new props }
|
|
60
55
|
it_behaves_like 'Contract'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'model_helper'
|
|
2
2
|
|
|
3
|
-
describe IB::
|
|
3
|
+
describe IB::Order,
|
|
4
4
|
:props =>
|
|
5
5
|
{:local_id => 23,
|
|
6
6
|
:order_ref => 'Test',
|
|
@@ -86,13 +86,8 @@ describe IB::Models::Order,
|
|
|
86
86
|
it_behaves_like 'Self-equal Model'
|
|
87
87
|
it_behaves_like 'Model with invalid defaults'
|
|
88
88
|
|
|
89
|
-
it 'has class name shortcut' do
|
|
90
|
-
IB::Order.should == IB::Models::Order
|
|
91
|
-
IB::Order.new.should == IB::Models::Order.new
|
|
92
|
-
end
|
|
93
|
-
|
|
94
89
|
context 'Order associations' do
|
|
95
|
-
after(:all) { DatabaseCleaner.clean }
|
|
90
|
+
after(:all) { DatabaseCleaner.clean if IB::DB }
|
|
96
91
|
|
|
97
92
|
subject { IB::Order.new props }
|
|
98
93
|
|
|
@@ -107,7 +102,7 @@ describe IB::Models::Order,
|
|
|
107
102
|
last_state.should be_an IB::OrderState
|
|
108
103
|
last_state.status.should == 'New'
|
|
109
104
|
subject.save
|
|
110
|
-
last_state.order.should == subject if IB
|
|
105
|
+
last_state.order.should == subject if IB.db_backed?
|
|
111
106
|
end
|
|
112
107
|
|
|
113
108
|
it 'has abbreviated accessor to last (current) OrderState' do
|
|
@@ -152,7 +147,7 @@ describe IB::Models::Order,
|
|
|
152
147
|
subject.status.should == 'Bar'
|
|
153
148
|
subject.save
|
|
154
149
|
subject.order_states.should have_exactly(3).states
|
|
155
|
-
subject.order_states.first.order.should == subject if IB
|
|
150
|
+
subject.order_states.first.order.should == subject if IB.db_backed?
|
|
156
151
|
end
|
|
157
152
|
|
|
158
153
|
it 'or simply assigning to order_state accessor' do
|
|
@@ -240,7 +235,7 @@ describe IB::Models::Order,
|
|
|
240
235
|
|
|
241
236
|
subject { IB::Order.new(props.merge(serializable_props)) }
|
|
242
237
|
|
|
243
|
-
after(:all) { DatabaseCleaner.clean }
|
|
238
|
+
after(:all) { DatabaseCleaner.clean if IB::DB }
|
|
244
239
|
|
|
245
240
|
it 'is saved to DB with serializable_props' do
|
|
246
241
|
subject.save.should be_true
|