ib-ruby 0.5.11 → 0.5.12
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +4 -0
- data/VERSION +1 -1
- data/bin/account_info +3 -0
- data/lib/ib-ruby/connection.rb +7 -7
- data/lib/ib-ruby/logger.rb +22 -0
- data/lib/ib-ruby/messages/incoming.rb +39 -23
- data/lib/ib-ruby/messages/outgoing.rb +19 -19
- data/lib/ib-ruby/models/execution.rb +3 -2
- metadata +3 -2
data/HISTORY
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.12
|
data/bin/account_info
CHANGED
@@ -14,6 +14,9 @@ require 'ib-ruby'
|
|
14
14
|
# First, connect to IB TWS.
|
15
15
|
ib = IB::Connection.new
|
16
16
|
|
17
|
+
# Set log level
|
18
|
+
log.level = Logger::FATAL
|
19
|
+
|
17
20
|
# Subscribe to TWS alerts/errors and account-related messages
|
18
21
|
# that TWS sends in response to account data request
|
19
22
|
ib.subscribe(:Alert, :AccountValue,
|
data/lib/ib-ruby/connection.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'ib-ruby/socket'
|
2
|
-
require 'logger'
|
2
|
+
require 'ib-ruby/logger'
|
3
3
|
|
4
4
|
# Add method to_ib to render datetime in IB format (zero padded "yyyymmdd HH:mm:ss")
|
5
5
|
class Time
|
@@ -61,7 +61,7 @@ module IB
|
|
61
61
|
# TWS always sends NextValidID message at connect - save this id
|
62
62
|
self.subscribe(:NextValidID) do |msg|
|
63
63
|
@next_order_id = msg.data[:id]
|
64
|
-
|
64
|
+
log.info "Got next valid order id: #{@next_order_id}."
|
65
65
|
end
|
66
66
|
|
67
67
|
@server[:socket] = IBSocket.open(@options[:host], @options[:port])
|
@@ -81,9 +81,9 @@ module IB
|
|
81
81
|
@server[:socket].send(@server[:client_id])
|
82
82
|
|
83
83
|
@connected = true
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
log.info "Connected to server, version: #{@server[:version]}, connection time: " +
|
85
|
+
"#{@server[:local_connect_time]} local, " +
|
86
|
+
"#{@server[:remote_connect_time]} remote."
|
87
87
|
end
|
88
88
|
|
89
89
|
alias open connect # Legacy alias
|
@@ -171,7 +171,7 @@ module IB
|
|
171
171
|
|
172
172
|
# Debug:
|
173
173
|
unless [1, 2, 4, 6, 7, 8, 9, 12, 21, 53].include? msg_id
|
174
|
-
|
174
|
+
log.debug "Got message #{msg_id} (#{Messages::Incoming::Table[msg_id]})"
|
175
175
|
end
|
176
176
|
|
177
177
|
# Create new instance of the appropriate message type, and have it read the message.
|
@@ -179,7 +179,7 @@ module IB
|
|
179
179
|
msg = Messages::Incoming::Table[msg_id].new(@server[:socket])
|
180
180
|
|
181
181
|
subscribers[msg.class].each { |_, subscriber| subscriber.call(msg) }
|
182
|
-
|
182
|
+
log.warn "No subscribers for message #{msg.class}!" if subscribers[msg.class].empty?
|
183
183
|
end
|
184
184
|
|
185
185
|
# Place Order (convenience wrapper for message :PlaceOrder)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "logger"
|
2
|
+
|
3
|
+
# Hack in log method into Object
|
4
|
+
def log
|
5
|
+
@@log ||= Logger.new(STDOUT).tap do |log|
|
6
|
+
log.formatter = proc do |level, time, prog, msg|
|
7
|
+
"#{time.strftime('%m-%d %H:%M:%S.%3N')}-#{level[0]}: #{msg}\n"
|
8
|
+
end
|
9
|
+
log.level = Logger::WARN
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
@@ -133,29 +133,6 @@ module IB
|
|
133
133
|
# the order id in its @next_order_id attribute.
|
134
134
|
NextValidID = def_message 9, [:id, :int]
|
135
135
|
|
136
|
-
MarketDepth =
|
137
|
-
def_message 12, [:id, :int],
|
138
|
-
[:position, :int], # The row Id of this market depth entry.
|
139
|
-
[:operation, :int], # How it should be applied to the market depth:
|
140
|
-
# 0 = insert this new order into the row identified by :position
|
141
|
-
# 1 = update the existing order in the row identified by :position
|
142
|
-
# 2 = delete the existing order at the row identified by :position
|
143
|
-
[:side, :int], # side of the book: 0 = ask, 1 = bid
|
144
|
-
[:price, :decimal],
|
145
|
-
[:size, :int]
|
146
|
-
|
147
|
-
MarketDepthL2 =
|
148
|
-
def_message 13, [:id, :int],
|
149
|
-
[:position, :int], # The row Id of this market depth entry.
|
150
|
-
[:market_maker, :string], # The exchange hosting this order.
|
151
|
-
[:operation, :int], # How it should be applied to the market depth:
|
152
|
-
# 0 = insert this new order into the row identified by :position
|
153
|
-
# 1 = update the existing order in the row identified by :position
|
154
|
-
# 2 = delete the existing order at the row identified by :position
|
155
|
-
[:side, :int], # side of the book: 0 = ask, 1 = bid
|
156
|
-
[:price, :decimal],
|
157
|
-
[:size, :int]
|
158
|
-
|
159
136
|
NewsBulletins =
|
160
137
|
def_message 14, [:id, :int], # unique incrementing bulletin ID.
|
161
138
|
[:type, :int], # Type of bulletin. Valid values include:
|
@@ -325,6 +302,45 @@ module IB
|
|
325
302
|
end # TickOption
|
326
303
|
TickOptionComputation = TickOption
|
327
304
|
|
305
|
+
MarketDepth =
|
306
|
+
def_message 12, [:id, :int],
|
307
|
+
[:position, :int], # The row Id of this market depth entry.
|
308
|
+
[:operation, :int], # How it should be applied to the market depth:
|
309
|
+
# 0 = insert this new order into the row identified by :position
|
310
|
+
# 1 = update the existing order in the row identified by :position
|
311
|
+
# 2 = delete the existing order at the row identified by :position
|
312
|
+
[:side, :int], # side of the book: 0 = ask, 1 = bid
|
313
|
+
[:price, :decimal],
|
314
|
+
[:size, :int]
|
315
|
+
class MarketDepth
|
316
|
+
|
317
|
+
def side
|
318
|
+
@data[:side] == 0 ? :ask : :bid
|
319
|
+
end
|
320
|
+
|
321
|
+
def operation
|
322
|
+
@data[:operation] == 0 ? :insert : @data[:operation] == 1 ? :update : :delete
|
323
|
+
end
|
324
|
+
|
325
|
+
def to_human
|
326
|
+
"<#{self.class.to_s.split('::').last}: #{operation} #{side} @ "+
|
327
|
+
"#{@data[:position]} = #{@data[:price]} x #{@data[:size]}>"
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
MarketDepthL2 =
|
332
|
+
def_message 13, MarketDepth,
|
333
|
+
[:id, :int],
|
334
|
+
[:position, :int], # The row Id of this market depth entry.
|
335
|
+
[:market_maker, :string], # The exchange hosting this order.
|
336
|
+
[:operation, :int], # How it should be applied to the market depth:
|
337
|
+
# 0 = insert this new order into the row identified by :position
|
338
|
+
# 1 = update the existing order in the row identified by :position
|
339
|
+
# 2 = delete the existing order at the row identified by :position
|
340
|
+
[:side, :int], # side of the book: 0 = ask, 1 = bid
|
341
|
+
[:price, :decimal],
|
342
|
+
[:size, :int]
|
343
|
+
|
328
344
|
# Called Error in Java code, but in fact this type of messages also
|
329
345
|
# deliver system alerts and additional (non-error) info from TWS.
|
330
346
|
# It has additional accessors: #code and #message, derived from @data
|
@@ -209,25 +209,25 @@ module IB
|
|
209
209
|
|
210
210
|
# @data={:id => int: ticker_id - Must be a unique value. When the market data
|
211
211
|
# returns, it will be identified by this tag,
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
#
|
227
|
-
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
212
|
+
# :contract => Datatypes::Contract, requested contract.
|
213
|
+
# :tick_list => String: comma delimited list of requested tick groups:
|
214
|
+
# Group ID - Description - Requested Tick Types
|
215
|
+
# 100 - Option Volume (currently for stocks) - 29, 30
|
216
|
+
# 101 - Option Open Interest (currently for stocks) - 27, 28
|
217
|
+
# 104 - Historical Volatility (currently for stocks) - 23
|
218
|
+
# 106 - Option Implied Volatility (currently for stocks) - 24
|
219
|
+
# 162 - Index Future Premium - 31
|
220
|
+
# 165 - Miscellaneous Stats - 15, 16, 17, 18, 19, 20, 21
|
221
|
+
# 221 - Mark Price (used in TWS P&L computations) - 37
|
222
|
+
# 225 - Auction values (volume, price and imbalance) - 34, 35, 36
|
223
|
+
# 233 - RTVolume - 48
|
224
|
+
# 236 - Shortable - 46
|
225
|
+
# 256 - Inventory - ?
|
226
|
+
# 258 - Fundamental Ratios - 47
|
227
|
+
# 411 - Realtime Historical Volatility - 58
|
228
|
+
# :snapshot => bool: Check to return a single snapshot of market data and
|
229
|
+
# have the market data subscription canceled. Do not enter any
|
230
|
+
# :tick_list values if you use snapshot. }
|
231
231
|
class RequestMarketData < AbstractMessage
|
232
232
|
@message_id = 1
|
233
233
|
@version = 9 # message version number
|
@@ -47,8 +47,9 @@ module IB
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def to_s
|
50
|
-
"<Execution #{@time}: #{@side} #{@shares}
|
51
|
-
"
|
50
|
+
"<Execution #{@time}: #{@side} #{@shares} @ #{@price} on #{@exchange}, " +
|
51
|
+
"cumulative: #{@cumulative_quantity} @ #{@average_price}, " +
|
52
|
+
"ids: #{@order_id} order, #{@perm_id} perm, #{@exec_id} exec>"
|
52
53
|
end
|
53
54
|
end # Execution
|
54
55
|
end # module Models
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ib-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.5.
|
5
|
+
version: 0.5.12
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Paul Legato
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date:
|
14
|
+
date: 2012-01-02 00:00:00 +03:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- bin/time_and_sales
|
73
73
|
- lib/ib-ruby/connection.rb
|
74
74
|
- lib/ib-ruby/constants.rb
|
75
|
+
- lib/ib-ruby/logger.rb
|
75
76
|
- lib/ib-ruby/messages/incoming.rb
|
76
77
|
- lib/ib-ruby/messages/outgoing.rb
|
77
78
|
- lib/ib-ruby/messages.rb
|