ib-ruby 0.5.16 → 0.5.17

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 CHANGED
@@ -109,3 +109,7 @@
109
109
  == 0.5.16 / 2012-02-08
110
110
 
111
111
  * Message specs refactored
112
+
113
+ == 0.5.17 / 2012-02-12
114
+
115
+ * Connection#send_message bugfix
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.16
1
+ 0.5.17
@@ -19,7 +19,7 @@ module IB
19
19
 
20
20
  CLIENT_VERSION = 48 # Was 27 in original Ruby code
21
21
  SERVER_VERSION = 53 # Minimal server version. Latest, was 38 in current Java code.
22
- DEFAULT_OPTIONS = {:host =>"127.0.0.1",
22
+ DEFAULT_OPTIONS = {:host =>'127.0.0.1',
23
23
  :port => '4001', # IB Gateway connection (default)
24
24
  #:port => '7496', # TWS connection, with annoying pop-ups
25
25
  :client_id => nil, # Will be randomly assigned
@@ -45,7 +45,6 @@ module IB
45
45
  @server = Hash.new
46
46
 
47
47
  connect if @options[:connect]
48
- start_reader if @options[:reader]
49
48
  Connection.current = self
50
49
  end
51
50
 
@@ -58,7 +57,7 @@ module IB
58
57
  end
59
58
 
60
59
  def connect
61
- raise Exception.new("Already connected!") if @connected
60
+ raise "Already connected!" if connected?
62
61
 
63
62
  # TWS always sends NextValidID message at connect - save this id
64
63
  self.subscribe(:NextValidID) do |msg|
@@ -71,7 +70,7 @@ module IB
71
70
  # Secret handshake
72
71
  @server[:socket].send(CLIENT_VERSION)
73
72
  @server[:version] = @server[:socket].read_int
74
- raise(Exception.new("TWS version >= #{SERVER_VERSION} required.")) if @server[:version] < SERVER_VERSION
73
+ raise "TWS version >= #{SERVER_VERSION} required." if @server[:version] < SERVER_VERSION
75
74
 
76
75
  @server[:local_connect_time] = Time.now()
77
76
  @server[:remote_connect_time] = @server[:socket].read_string
@@ -86,6 +85,8 @@ module IB
86
85
  log.info "Connected to server, version: #{@server[:version]}, connection time: " +
87
86
  "#{@server[:local_connect_time]} local, " +
88
87
  "#{@server[:remote_connect_time]} remote."
88
+
89
+ start_reader if @options[:reader] # Allows reconnect
89
90
  end
90
91
 
91
92
  alias open connect # Legacy alias
@@ -95,9 +96,11 @@ module IB
95
96
  @reader_running = false
96
97
  @server[:reader].join
97
98
  end
98
- @server[:socket].close
99
- @server = Hash.new
100
- @connected = false
99
+ if connected?
100
+ @server[:socket].close
101
+ @server = Hash.new
102
+ @connected = false
103
+ end
101
104
  end
102
105
 
103
106
  alias close disconnect # Legacy alias
@@ -152,6 +155,7 @@ module IB
152
155
  else
153
156
  raise ArgumentError.new "Only able to send outgoing IB messages"
154
157
  end
158
+ raise "Not able to send messages, IB not connected!" unless connected?
155
159
  message.send_to(@server)
156
160
  end
157
161
 
@@ -55,8 +55,14 @@ module IB
55
55
  @data.has_key?(:id) ? @data[:id] : super
56
56
  end
57
57
 
58
+ def respond_to? method
59
+ getter = method.to_s.sub(/=$/, '').to_sym
60
+ @data.has_key?(method) || @data.has_key?(getter) || super
61
+ end
62
+
58
63
  protected
59
64
 
65
+ # TODO: method compilation instead of method_missing
60
66
  def method_missing method, *args
61
67
  getter = method.to_s.sub(/=$/, '').to_sym
62
68
  if @data.has_key? method
@@ -68,11 +74,6 @@ module IB
68
74
  end
69
75
  end
70
76
 
71
- def respond_to? method
72
- getter = method.to_s.sub(/=$/, '').to_sym
73
- @data.has_key?(method) || @data.has_key?(getter) || super
74
- end
75
-
76
77
  # Every message loads received message version first
77
78
  def load
78
79
  @data[:version] = @socket.read_int
@@ -156,11 +157,11 @@ module IB
156
157
  [:last_fill_price, :decimal],
157
158
  [:client_id, :int],
158
159
  [:why_held, :string] do
159
- "<OrderStatus: #{@data[:status]} filled: #{@data[:filled]}/#{@data[:remaining]+@data[:filled]}" +
160
- " @ last/avg: #{@data[:last_fill_price]}/#{@data[:average_fill_price]}" +
161
- (@data[:parent_id] > 0 ? "parent_id: #{@data[:parent_id]}" : "") +
162
- (@data[:why_held] != "" ? "why_held: #{@data[:why_held]}" : "") +
163
- " id/perm: #{@data[:id]}/#{@data[:perm_id]}>"
160
+ "<OrderStatus: #{status} filled: #{filled}/#{remaining + filled}" +
161
+ " @ last/avg: #{last_fill_price}/#{average_fill_price}" +
162
+ (parent_id > 0 ? "parent_id: #{parent_id}" : "") +
163
+ (why_held != "" ? "why_held: #{why_held}" : "") +
164
+ " id/perm: #{id}/#{perm_id}>"
164
165
  end
165
166
 
166
167
 
@@ -168,17 +169,17 @@ module IB
168
169
  [:value, :string],
169
170
  [:currency, :string],
170
171
  [:account_name, :string]) do
171
- "<AccountValue: #{@data[:account_name]}, #{@data[:key]}=#{@data[:value]} #{@data[:currency]}>"
172
+ "<AccountValue: #{account_name}, #{key}=#{value} #{currency}>"
172
173
  end
173
174
 
174
175
  AccountUpdateTime = def_message(8, [:time_stamp, :string]) do
175
- "<AccountUpdateTime: #{@data[:time_stamp]}>"
176
+ "<AccountUpdateTime: #{time_stamp}>"
176
177
  end
177
178
 
178
179
  # This message is always sent by TWS automatically at connect.
179
180
  # The IB::Connection class subscribes to it automatically and stores
180
181
  # the order id in its @next_order_id attribute.
181
- NextValidID = def_message(9, [:id, :int]) { "<NextValidID: #{@data[:id]}>" }
182
+ NextValidID = def_message(9, [:id, :int]) { "<NextValidID: #{id}>" }
182
183
 
183
184
  NewsBulletins =
184
185
  def_message 14, [:id, :int], # unique incrementing bulletin ID.
@@ -214,18 +215,18 @@ module IB
214
215
  FundamentalData = def_message 50, [:id, :int], # request_id
215
216
  [:data, :string]
216
217
 
217
- ContractDataEnd = def_message(52, [:id, :int]) { "<ContractDataEnd: #{@data[:id]}>" } # request_id
218
+ ContractDataEnd = def_message(52, [:id, :int]) { "<ContractDataEnd: #{id}>" } # request_id
218
219
 
219
220
  OpenOrderEnd = def_message(53) { "<OpenOrderEnd>" }
220
221
 
221
222
  AccountDownloadEnd = def_message(54, [:account_name, :string]) do
222
- "<AccountDownloadEnd: #{@data[:account_name]}}>"
223
+ "<AccountDownloadEnd: #{account_name}}>"
223
224
  end # request_id
224
225
 
225
226
 
226
- ExecutionDataEnd = def_message 55, [:id, :int] # request_id
227
+ ExecutionDataEnd = def_message(55, [:id, :int]) { "<ExecutionDataEnd: #{id}>" } # request_id
227
228
 
228
- TickSnapshotEnd = def_message 57, [:id, :int] # request_id
229
+ TickSnapshotEnd = def_message(57, [:id, :int]) { "<TickSnapshotEnd: #{id}>" } # request_id
229
230
 
230
231
  ### Actual message classes (long definitions):
231
232
 
@@ -344,10 +345,9 @@ module IB
344
345
  end
345
346
 
346
347
  def to_human
347
- "<TickOption #{type} for #{@data[:id]}: underlying @ #{@data[:under_price]}, "+
348
- "option @ #{@data[:option_price]}, IV #{@data[:implied_volatility]}%, " +
349
- "delta #{@data[:delta]}, gamma #{@data[:gamma]}, vega #{@data[:vega]}, " +
350
- "theta #{@data[:theta]}, pv_dividend #{@data[:pv_dividend]}>"
348
+ "<TickOption #{type} for #{:id}: underlying @ #{under_price}, "+
349
+ "option @ #{option_price}, IV #{implied_volatility}%, delta #{delta}, " +
350
+ "gamma #{gamma}, vega #{vega}, theta #{theta}, pv_dividend #{pv_dividend}>"
351
351
  end
352
352
  end # TickOption
353
353
  TickOptionComputation = TickOption
@@ -373,8 +373,8 @@ module IB
373
373
  end
374
374
 
375
375
  def to_human
376
- "<#{self.class.to_s.split('::').last}: #{operation} #{side} @ "+
377
- "#{@data[:position]} = #{@data[:price]} x #{@data[:size]}>"
376
+ "<#{self.class.to_s.split(/::/).last}: #{operation} #{side} @ "+
377
+ "#{position} = #{price} x #{size}>"
378
378
  end
379
379
  end
380
380
 
@@ -415,13 +415,14 @@ module IB
415
415
  "TWS #{ error? ? 'Error' : system? ? 'System' : 'Warning'
416
416
  } Message #{code}: #{message}"
417
417
  end
418
- end # class ErrorMessage
418
+ end # class Alert
419
419
  Error = Alert
420
420
  ErrorMessage = Alert
421
421
 
422
422
  class OpenOrder < AbstractMessage
423
423
  @message_id = 5
424
424
 
425
+ # TODO: Add id accessor to unify with OrderStatus message
425
426
  attr_accessor :order, :contract
426
427
 
427
428
  def load
@@ -657,6 +658,10 @@ module IB
657
658
  :cumulative_quantity => @socket.read_int,
658
659
  :average_price => @socket.read_decimal
659
660
  end
661
+
662
+ def to_human
663
+ "<HistoricalData: req: #{id}, #{item_count} items, #{start_date} to #{end_date}>"
664
+ end
660
665
  end # ExecutionData
661
666
 
662
667
  # HistoricalData contains following @data:
@@ -702,8 +707,7 @@ module IB
702
707
  end
703
708
 
704
709
  def to_human
705
- "<HistoricalData: req id #{@data[:id]}, #{@data[:item_count]
706
- } items, from #{@data[:start_date_str]} to #{@data[:end_date_str]}>"
710
+ "<HistoricalData: req: #{id}, #{item_count} items, #{start_date} to #{end_date}>"
707
711
  end
708
712
  end # HistoricalData
709
713
 
@@ -818,7 +822,7 @@ module IB
818
822
  end
819
823
 
820
824
  def to_human
821
- "<RealTimeBar: req id #{@data[:id]}, #{@bar}>"
825
+ "<RealTimeBar: req: #{id}, #{bar}>"
822
826
  end
823
827
  end # RealTimeBar
824
828
  RealTimeBars = RealTimeBar
@@ -430,7 +430,7 @@ module IB
430
430
  end
431
431
 
432
432
  def serialize_algo
433
- if algo_strategy.empty? || algo_strategy.nil?
433
+ if algo_strategy.nil? || algo_strategy.empty?
434
434
  ['']
435
435
  else
436
436
  [algo_strategy,
@@ -17,4 +17,7 @@ CONNECTION_OPTS = BROKERTRON ?
17
17
  :host => 'free.brokertron.com',
18
18
  :port=> 10501
19
19
  } :
20
- {:client_id => 1111}
20
+ {:client_id => 1111,
21
+ :host => '127.0.0.1',
22
+ :port=> 4001
23
+ }
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.16
5
+ version: 0.5.17
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: 2012-02-09 00:00:00 Z
14
+ date: 2012-02-12 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler