ib-ruby 0.5.11 → 0.5.12
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/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
|