ib-ruby 0.8.1 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|