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
data/db/schema.rb
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
|
4
|
+
#
|
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your
|
|
6
|
+
# database schema. If you need to create the application database on another
|
|
7
|
+
# system, you should be using db:schema:load, not running all the migrations
|
|
8
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
|
9
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
|
10
|
+
#
|
|
11
|
+
# It's strongly recommended to check this file into your version control system.
|
|
12
|
+
|
|
13
|
+
ActiveRecord::Schema.define(:version => 171) do
|
|
14
|
+
|
|
15
|
+
create_table "ib_bars", :force => true do |t|
|
|
16
|
+
t.float "open"
|
|
17
|
+
t.float "high"
|
|
18
|
+
t.float "low"
|
|
19
|
+
t.float "close"
|
|
20
|
+
t.float "wap"
|
|
21
|
+
t.integer "volume"
|
|
22
|
+
t.integer "trades"
|
|
23
|
+
t.boolean "has_gaps", :limit => 1
|
|
24
|
+
t.string "time", :limit => 18
|
|
25
|
+
t.datetime "created_at", :null => false
|
|
26
|
+
t.datetime "updated_at", :null => false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
create_table "ib_combo_legs", :force => true do |t|
|
|
30
|
+
t.integer "combo_id"
|
|
31
|
+
t.integer "leg_contract_id"
|
|
32
|
+
t.integer "con_id"
|
|
33
|
+
t.string "side", :limit => 1
|
|
34
|
+
t.integer "ratio", :limit => 2
|
|
35
|
+
t.string "exchange"
|
|
36
|
+
t.integer "exempt_code", :limit => 2
|
|
37
|
+
t.integer "short_sale_slot", :limit => 2
|
|
38
|
+
t.integer "open_close", :limit => 2
|
|
39
|
+
t.string "designated_location"
|
|
40
|
+
t.datetime "created_at", :null => false
|
|
41
|
+
t.datetime "updated_at", :null => false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
create_table "ib_contract_details", :force => true do |t|
|
|
45
|
+
t.integer "contract_id"
|
|
46
|
+
t.string "market_name"
|
|
47
|
+
t.string "trading_class"
|
|
48
|
+
t.float "min_tick"
|
|
49
|
+
t.integer "price_magnifier"
|
|
50
|
+
t.string "order_types"
|
|
51
|
+
t.string "valid_exchanges"
|
|
52
|
+
t.integer "under_con_id"
|
|
53
|
+
t.string "long_name"
|
|
54
|
+
t.string "contract_month"
|
|
55
|
+
t.string "industry"
|
|
56
|
+
t.string "category"
|
|
57
|
+
t.string "subcategory"
|
|
58
|
+
t.string "time_zone"
|
|
59
|
+
t.string "trading_hours"
|
|
60
|
+
t.string "liquid_hours"
|
|
61
|
+
t.string "cusip"
|
|
62
|
+
t.string "ratings"
|
|
63
|
+
t.string "desc_append"
|
|
64
|
+
t.string "bond_type"
|
|
65
|
+
t.string "coupon_type"
|
|
66
|
+
t.float "coupon"
|
|
67
|
+
t.string "maturity"
|
|
68
|
+
t.string "issue_date"
|
|
69
|
+
t.string "next_option_date"
|
|
70
|
+
t.string "next_option_type"
|
|
71
|
+
t.string "notes"
|
|
72
|
+
t.boolean "callable", :limit => 1
|
|
73
|
+
t.boolean "puttable", :limit => 1
|
|
74
|
+
t.boolean "convertible", :limit => 1
|
|
75
|
+
t.boolean "next_option_partial", :limit => 1
|
|
76
|
+
t.datetime "created_at", :null => false
|
|
77
|
+
t.datetime "updated_at", :null => false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
create_table "ib_contracts", :force => true do |t|
|
|
81
|
+
t.integer "con_id"
|
|
82
|
+
t.string "sec_type", :limit => 5
|
|
83
|
+
t.float "strike"
|
|
84
|
+
t.string "currency", :limit => 4
|
|
85
|
+
t.string "sec_id_type", :limit => 5
|
|
86
|
+
t.integer "sec_id"
|
|
87
|
+
t.string "legs_description"
|
|
88
|
+
t.string "symbol"
|
|
89
|
+
t.string "local_symbol"
|
|
90
|
+
t.integer "multiplier"
|
|
91
|
+
t.string "expiry"
|
|
92
|
+
t.string "exchange"
|
|
93
|
+
t.string "primary_exchange"
|
|
94
|
+
t.boolean "include_expired", :limit => 1
|
|
95
|
+
t.string "right", :limit => 1
|
|
96
|
+
t.string "type"
|
|
97
|
+
t.datetime "created_at", :null => false
|
|
98
|
+
t.datetime "updated_at", :null => false
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
create_table "ib_executions", :force => true do |t|
|
|
102
|
+
t.integer "order_id"
|
|
103
|
+
t.integer "local_id"
|
|
104
|
+
t.integer "client_id"
|
|
105
|
+
t.integer "perm_id"
|
|
106
|
+
t.string "order_ref"
|
|
107
|
+
t.string "exec_id"
|
|
108
|
+
t.string "side", :limit => 1
|
|
109
|
+
t.integer "quantity"
|
|
110
|
+
t.integer "cumulative_quantity"
|
|
111
|
+
t.float "price"
|
|
112
|
+
t.float "average_price"
|
|
113
|
+
t.string "exchange"
|
|
114
|
+
t.string "account_name"
|
|
115
|
+
t.boolean "liquidation", :limit => 1
|
|
116
|
+
t.string "time", :limit => 18
|
|
117
|
+
t.datetime "created_at", :null => false
|
|
118
|
+
t.datetime "updated_at", :null => false
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
create_table "ib_order_states", :force => true do |t|
|
|
122
|
+
t.integer "order_id"
|
|
123
|
+
t.integer "local_id"
|
|
124
|
+
t.integer "client_id"
|
|
125
|
+
t.integer "perm_id"
|
|
126
|
+
t.integer "parent_id"
|
|
127
|
+
t.string "status"
|
|
128
|
+
t.integer "filled"
|
|
129
|
+
t.integer "remaining"
|
|
130
|
+
t.float "price"
|
|
131
|
+
t.float "average_price"
|
|
132
|
+
t.string "why_held"
|
|
133
|
+
t.string "warning_text"
|
|
134
|
+
t.string "commission_currency", :limit => 4
|
|
135
|
+
t.float "commission"
|
|
136
|
+
t.float "min_commission"
|
|
137
|
+
t.float "max_commission"
|
|
138
|
+
t.float "init_margin"
|
|
139
|
+
t.float "maint_margin"
|
|
140
|
+
t.float "equity_with_loan"
|
|
141
|
+
t.datetime "created_at", :null => false
|
|
142
|
+
t.datetime "updated_at", :null => false
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
create_table "ib_orders", :force => true do |t|
|
|
146
|
+
t.integer "contract_id"
|
|
147
|
+
t.integer "local_id"
|
|
148
|
+
t.integer "client_id"
|
|
149
|
+
t.integer "perm_id"
|
|
150
|
+
t.integer "parent_id"
|
|
151
|
+
t.string "order_ref"
|
|
152
|
+
t.string "order_type", :limit => 20
|
|
153
|
+
t.string "tif", :limit => 3
|
|
154
|
+
t.string "side", :limit => 1
|
|
155
|
+
t.integer "quantity"
|
|
156
|
+
t.float "limit_price"
|
|
157
|
+
t.float "aux_price"
|
|
158
|
+
t.integer "open_close"
|
|
159
|
+
t.integer "oca_type"
|
|
160
|
+
t.string "oca_group"
|
|
161
|
+
t.boolean "transmit", :limit => 1
|
|
162
|
+
t.boolean "what_if", :limit => 1
|
|
163
|
+
t.boolean "outside_rth", :limit => 1
|
|
164
|
+
t.boolean "not_held", :limit => 1
|
|
165
|
+
t.boolean "hidden", :limit => 1
|
|
166
|
+
t.boolean "block_order", :limit => 1
|
|
167
|
+
t.boolean "sweep_to_fill", :limit => 1
|
|
168
|
+
t.boolean "all_or_none", :limit => 1
|
|
169
|
+
t.boolean "etrade_only", :limit => 1
|
|
170
|
+
t.boolean "firm_quote_only", :limit => 1
|
|
171
|
+
t.boolean "opt_out_smart_routing", :limit => 1
|
|
172
|
+
t.boolean "override_percentage_constraints", :limit => 1
|
|
173
|
+
t.integer "min_quantity"
|
|
174
|
+
t.integer "display_size"
|
|
175
|
+
t.integer "trigger_method"
|
|
176
|
+
t.integer "origin"
|
|
177
|
+
t.string "good_after_time"
|
|
178
|
+
t.string "good_till_date"
|
|
179
|
+
t.string "rule_80a"
|
|
180
|
+
t.float "percent_offset"
|
|
181
|
+
t.float "trail_stop_price"
|
|
182
|
+
t.float "trailing_percent"
|
|
183
|
+
t.string "fa_group"
|
|
184
|
+
t.string "fa_profile"
|
|
185
|
+
t.string "fa_method"
|
|
186
|
+
t.string "fa_percentage"
|
|
187
|
+
t.integer "short_sale_slot"
|
|
188
|
+
t.string "designated_location"
|
|
189
|
+
t.integer "exempt_code"
|
|
190
|
+
t.string "account"
|
|
191
|
+
t.string "settling_firm"
|
|
192
|
+
t.string "clearing_account"
|
|
193
|
+
t.string "clearing_intent"
|
|
194
|
+
t.float "discretionary_amount"
|
|
195
|
+
t.float "nbbo_price_cap"
|
|
196
|
+
t.integer "auction_strategy"
|
|
197
|
+
t.float "starting_price"
|
|
198
|
+
t.float "stock_ref_price"
|
|
199
|
+
t.float "delta"
|
|
200
|
+
t.float "stock_range_lower"
|
|
201
|
+
t.float "stock_range_upper"
|
|
202
|
+
t.float "volatility"
|
|
203
|
+
t.integer "volatility_type"
|
|
204
|
+
t.integer "reference_price_type"
|
|
205
|
+
t.integer "continuous_update"
|
|
206
|
+
t.string "delta_neutral_order_type"
|
|
207
|
+
t.string "delta_neutral_aux_price"
|
|
208
|
+
t.integer "delta_neutral_con_id"
|
|
209
|
+
t.string "delta_neutral_settling_firm"
|
|
210
|
+
t.string "delta_neutral_clearing_account"
|
|
211
|
+
t.string "delta_neutral_clearing_intent"
|
|
212
|
+
t.string "hedge_type"
|
|
213
|
+
t.string "hedge_param"
|
|
214
|
+
t.float "basis_points"
|
|
215
|
+
t.float "basis_points_type"
|
|
216
|
+
t.string "algo_strategy"
|
|
217
|
+
t.text "leg_prices"
|
|
218
|
+
t.text "algo_params"
|
|
219
|
+
t.text "combo_params"
|
|
220
|
+
t.integer "scale_init_level_size"
|
|
221
|
+
t.integer "scale_subs_level_size"
|
|
222
|
+
t.float "scale_price_increment"
|
|
223
|
+
t.float "scale_price_adjust_value"
|
|
224
|
+
t.integer "scale_price_adjust_interval"
|
|
225
|
+
t.float "scale_profit_offset"
|
|
226
|
+
t.integer "scale_init_position"
|
|
227
|
+
t.integer "scale_init_fill_qty"
|
|
228
|
+
t.boolean "scale_auto_reset", :limit => 1
|
|
229
|
+
t.boolean "scale_random_percent", :limit => 1
|
|
230
|
+
t.datetime "placed_at"
|
|
231
|
+
t.datetime "modified_at"
|
|
232
|
+
t.datetime "created_at", :null => false
|
|
233
|
+
t.datetime "updated_at", :null => false
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
create_table "ib_underlyings", :force => true do |t|
|
|
237
|
+
t.integer "contract_id"
|
|
238
|
+
t.integer "con_id"
|
|
239
|
+
t.float "delta"
|
|
240
|
+
t.float "price"
|
|
241
|
+
t.datetime "created_at", :null => false
|
|
242
|
+
t.datetime "updated_at", :null => false
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
end
|
data/lib/ib/base.rb
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
module IB
|
|
2
|
+
|
|
3
|
+
# Base class for tableless IB data Models, extends ActiveModel API
|
|
4
|
+
class Base
|
|
5
|
+
extend ActiveModel::Naming
|
|
6
|
+
extend ActiveModel::Callbacks
|
|
7
|
+
include ActiveModel::Validations
|
|
8
|
+
include ActiveModel::Serialization
|
|
9
|
+
include ActiveModel::Serializers::Xml
|
|
10
|
+
include ActiveModel::Serializers::JSON
|
|
11
|
+
|
|
12
|
+
# If a opts hash is given, keys are taken as attribute names, values as data.
|
|
13
|
+
# The model instance fields are then set automatically from the opts Hash.
|
|
14
|
+
def initialize attributes={}, opts={}
|
|
15
|
+
run_callbacks :initialize do
|
|
16
|
+
error "Argument must be a Hash", :args unless attributes.is_a?(Hash)
|
|
17
|
+
|
|
18
|
+
self.attributes = default_attributes.merge(attributes)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# ActiveModel API (for serialization)
|
|
23
|
+
|
|
24
|
+
def attributes
|
|
25
|
+
@attributes ||= HashWithIndifferentAccess.new
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def attributes= attrs
|
|
29
|
+
attrs.keys.each { |key| self.send("#{key}=", attrs[key]) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# ActiveModel-style read/write_attribute accessors
|
|
33
|
+
def [] key
|
|
34
|
+
attributes[key.to_sym]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def []= key, val
|
|
38
|
+
# p key, val
|
|
39
|
+
attributes[key.to_sym] = val
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def to_model
|
|
43
|
+
self
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def new_record?
|
|
47
|
+
true
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def save
|
|
51
|
+
valid?
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
alias save! save
|
|
55
|
+
|
|
56
|
+
### Noop methods mocking ActiveRecord::Base macros
|
|
57
|
+
|
|
58
|
+
def self.attr_protected *args
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.attr_accessible *args
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
### ActiveRecord::Base association API mocks
|
|
65
|
+
|
|
66
|
+
def self.belongs_to model, *args
|
|
67
|
+
attr_accessor model
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.has_one model, *args
|
|
71
|
+
attr_accessor model
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.has_many models, *args
|
|
75
|
+
attr_accessor models
|
|
76
|
+
|
|
77
|
+
define_method(models) do
|
|
78
|
+
self.instance_variable_get("@#{models}") ||
|
|
79
|
+
self.instance_variable_set("@#{models}", [])
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.find *args
|
|
84
|
+
[]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
### ActiveRecord::Base callback API mocks
|
|
88
|
+
|
|
89
|
+
define_model_callbacks :initialize, :only => :after
|
|
90
|
+
|
|
91
|
+
### ActiveRecord::Base misc
|
|
92
|
+
|
|
93
|
+
def self.serialize *properties
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end # Model
|
|
97
|
+
end # module IB
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
require 'active_model'
|
|
2
|
+
require 'active_support/concern'
|
|
3
|
+
require 'active_support/hash_with_indifferent_access'
|
|
4
|
+
|
|
5
|
+
module IB
|
|
6
|
+
|
|
7
|
+
# Module adds prop Macro and
|
|
8
|
+
module BaseProperties
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
def default_attributes
|
|
12
|
+
{:created_at => Time.now,
|
|
13
|
+
:updated_at => Time.now,
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
### Instance methods
|
|
18
|
+
|
|
19
|
+
# Default presentation
|
|
20
|
+
def to_human
|
|
21
|
+
"<#{self.class.to_s.demodulize}: " + attributes.map do |attr, value|
|
|
22
|
+
"#{attr}: #{value}" unless value.nil?
|
|
23
|
+
end.compact.sort.join(' ') + ">"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Comparison support
|
|
27
|
+
def content_attributes
|
|
28
|
+
HashWithIndifferentAccess[attributes.reject do |(attr, _)|
|
|
29
|
+
attr.to_s =~ /(_count)$/ ||
|
|
30
|
+
[:created_at, :updated_at, :type,
|
|
31
|
+
:id, :order_id, :contract_id].include?(attr.to_sym)
|
|
32
|
+
end]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Update nil attributes from given Hash or model
|
|
36
|
+
def update_missing attrs
|
|
37
|
+
attrs = attrs.content_attributes unless attrs.kind_of?(Hash)
|
|
38
|
+
|
|
39
|
+
attrs.each { |attr, val| send "#{attr}=", val if send(attr).blank? }
|
|
40
|
+
self # for chaining
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Default Model comparison
|
|
44
|
+
def == other
|
|
45
|
+
content_attributes.inject(true) { |res, (attr, value)| res && other.send(attr) == value } &&
|
|
46
|
+
other.content_attributes.inject(true) { |res, (attr, value)| res && send(attr) == value }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
included do
|
|
50
|
+
|
|
51
|
+
### Class macros
|
|
52
|
+
|
|
53
|
+
def self.prop *properties
|
|
54
|
+
prop_hash = properties.last.is_a?(Hash) ? properties.pop : {}
|
|
55
|
+
|
|
56
|
+
properties.each { |names| define_property names, nil }
|
|
57
|
+
prop_hash.each { |names, type| define_property names, type }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.define_property names, body
|
|
61
|
+
aliases = [names].flatten
|
|
62
|
+
name = aliases.shift
|
|
63
|
+
instance_eval do
|
|
64
|
+
|
|
65
|
+
define_property_methods name, body
|
|
66
|
+
|
|
67
|
+
aliases.each do |ali|
|
|
68
|
+
alias_method "#{ali}", name
|
|
69
|
+
alias_method "#{ali}=", "#{name}="
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.define_property_methods name, body={}
|
|
75
|
+
#p name, body
|
|
76
|
+
case body
|
|
77
|
+
when '' # default getter and setter
|
|
78
|
+
define_property_methods name
|
|
79
|
+
|
|
80
|
+
when Array # [setter, getter, validators]
|
|
81
|
+
define_property_methods name,
|
|
82
|
+
:get => body[0],
|
|
83
|
+
:set => body[1],
|
|
84
|
+
:validate => body[2]
|
|
85
|
+
|
|
86
|
+
when Hash # recursion base case
|
|
87
|
+
getter = case # Define getter
|
|
88
|
+
when body[:get].respond_to?(:call)
|
|
89
|
+
body[:get]
|
|
90
|
+
when body[:get]
|
|
91
|
+
proc { self[name].send "to_#{body[:get]}" }
|
|
92
|
+
when VALUES[name] # property is encoded
|
|
93
|
+
proc { VALUES[name][self[name]] }
|
|
94
|
+
else
|
|
95
|
+
proc { self[name] }
|
|
96
|
+
end
|
|
97
|
+
define_method name, &getter if getter
|
|
98
|
+
|
|
99
|
+
setter = case # Define setter
|
|
100
|
+
when body[:set].respond_to?(:call)
|
|
101
|
+
body[:set]
|
|
102
|
+
when body[:set]
|
|
103
|
+
proc { |value| self[name] = value.send "to_#{body[:set]}" }
|
|
104
|
+
when CODES[name] # property is encoded
|
|
105
|
+
proc { |value| self[name] = CODES[name][value] || value }
|
|
106
|
+
else
|
|
107
|
+
proc { |value| self[name] = value } # p name, value;
|
|
108
|
+
end
|
|
109
|
+
define_method "#{name}=", &setter if setter
|
|
110
|
+
|
|
111
|
+
# Define validator(s)
|
|
112
|
+
[body[:validate]].flatten.compact.each do |validator|
|
|
113
|
+
case validator
|
|
114
|
+
when Proc
|
|
115
|
+
validates_each name, &validator
|
|
116
|
+
when Hash
|
|
117
|
+
validates name, validator.dup
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# TODO define self[:name] accessors for :virtual and :flag properties
|
|
122
|
+
|
|
123
|
+
else # setter given
|
|
124
|
+
define_property_methods name, :set => body, :get => body
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Extending AR-backed Model class with attribute defaults
|
|
129
|
+
if defined?(ActiveRecord::Base) && ancestors.include?(ActiveRecord::Base)
|
|
130
|
+
def initialize attributes={}, opts={}
|
|
131
|
+
super default_attributes.merge(attributes), opts
|
|
132
|
+
end
|
|
133
|
+
else
|
|
134
|
+
# Timestamps
|
|
135
|
+
prop :created_at, :updated_at
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end # included
|
|
139
|
+
end # module BaseProperties
|
|
140
|
+
end
|
|
File without changes
|
data/lib/{ib-ruby → ib}/db.rb
RENAMED
|
@@ -9,17 +9,21 @@ module IB
|
|
|
9
9
|
ActiveRecord::Base.logger = logger
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# Use this method to establish DB connection unless you're running on Rails
|
|
13
13
|
def self.connect config
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
|
|
15
|
+
# Use ib prefix for all DB tables
|
|
16
|
+
ActiveRecord::Base.table_name_prefix = "ib_"
|
|
17
17
|
|
|
18
18
|
# Get rid of nasty conversion issues
|
|
19
19
|
ActiveRecord::Base.default_timezone = :utc
|
|
20
20
|
Time.zone = 'UTC'
|
|
21
|
+
|
|
22
|
+
ActiveRecord::Base.establish_connection(config)
|
|
23
|
+
#ActiveRecord.colorize_logging = false
|
|
21
24
|
end
|
|
22
25
|
|
|
23
|
-
# Load ActiveRecord::Schema ? where from ?
|
|
24
26
|
end # module DB
|
|
25
27
|
end
|
|
28
|
+
|
|
29
|
+
|
data/lib/ib/engine.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module IB
|
|
2
|
+
class Engine < ::Rails::Engine
|
|
3
|
+
isolate_namespace Ib
|
|
4
|
+
|
|
5
|
+
#paths["app"] # => ["app"]
|
|
6
|
+
#paths["app/controllers"] # => ["app/controllers"]
|
|
7
|
+
#paths["app/helpers"] # => ["app/helpers"]
|
|
8
|
+
paths["app/models"] = "lib/models"
|
|
9
|
+
#paths["app/views"] # => ["app/views"]
|
|
10
|
+
#paths["lib"] # => ["lib"]
|
|
11
|
+
#paths["lib/tasks"] # => ["lib/tasks"]
|
|
12
|
+
#paths["config"] # => ["config"]
|
|
13
|
+
#paths["config/initializers"] # => ["config/initializers"]
|
|
14
|
+
#paths["config/locales"] # => ["config/locales"]
|
|
15
|
+
#paths["config/routes"] # => ["config/routes.rb"]
|
|
16
|
+
|
|
17
|
+
config.generators do |gen|
|
|
18
|
+
gen.integration_tool :rspec
|
|
19
|
+
gen.test_framework :rspec
|
|
20
|
+
gen.helper_specs false
|
|
21
|
+
# gen.view_specs false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
config.to_prepare do
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
initializer "ib.active_record" do |app|
|
|
28
|
+
ActiveSupport.on_load :active_record do
|
|
29
|
+
require 'ib/db'
|
|
30
|
+
require 'ib/requires'
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
File without changes
|
|
@@ -61,10 +61,10 @@ class Object
|
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
### Patching Object#error in ib
|
|
64
|
+
### Patching Object#error in ib/errors
|
|
65
65
|
# def error message, type=:standard
|
|
66
66
|
|
|
67
|
-
### Patching Object#log, #default_logger= in ib
|
|
67
|
+
### Patching Object#log, #default_logger= in ib/logger
|
|
68
68
|
# def default_logger
|
|
69
69
|
# def default_logger= logger
|
|
70
70
|
# def log *args
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require 'ib
|
|
1
|
+
require 'ib/messages/incoming/abstract_message'
|
|
2
2
|
|
|
3
3
|
# EClientSocket.java uses sendMax() rather than send() for a number of these.
|
|
4
4
|
# It sends an EOL rather than a number if the value == Integer.MAX_VALUE (or Double.MAX_VALUE).
|
|
@@ -76,19 +76,19 @@ module IB
|
|
|
76
76
|
|
|
77
77
|
### Require standalone source files for more complex message classes:
|
|
78
78
|
|
|
79
|
-
require 'ib
|
|
80
|
-
require 'ib
|
|
81
|
-
require 'ib
|
|
82
|
-
require 'ib
|
|
83
|
-
require 'ib
|
|
84
|
-
require 'ib
|
|
85
|
-
require 'ib
|
|
86
|
-
require 'ib
|
|
87
|
-
require 'ib
|
|
88
|
-
require 'ib
|
|
89
|
-
require 'ib
|
|
90
|
-
require 'ib
|
|
91
|
-
require 'ib
|
|
79
|
+
require 'ib/messages/incoming/alert'
|
|
80
|
+
require 'ib/messages/incoming/contract_data'
|
|
81
|
+
require 'ib/messages/incoming/delta_neutral_validation'
|
|
82
|
+
require 'ib/messages/incoming/execution_data'
|
|
83
|
+
require 'ib/messages/incoming/historical_data'
|
|
84
|
+
require 'ib/messages/incoming/market_depths'
|
|
85
|
+
require 'ib/messages/incoming/next_valid_id'
|
|
86
|
+
require 'ib/messages/incoming/open_order'
|
|
87
|
+
require 'ib/messages/incoming/order_status'
|
|
88
|
+
require 'ib/messages/incoming/portfolio_value'
|
|
89
|
+
require 'ib/messages/incoming/real_time_bar'
|
|
90
|
+
require 'ib/messages/incoming/scanner_data'
|
|
91
|
+
require 'ib/messages/incoming/ticks'
|
|
92
92
|
|
|
93
93
|
end # module Incoming
|
|
94
94
|
end # module Messages
|
|
File without changes
|
|
File without changes
|