ib-ruby 0.5.2 → 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -30,3 +30,6 @@ tmp
30
30
 
31
31
  ## PROJECT::SPECIFIC
32
32
  *.db
33
+
34
+ # Yard cache files - used for the autogenerated documentation
35
+ .yardoc
data/HISTORY CHANGED
@@ -57,3 +57,19 @@
57
57
  == 0.5.2 / 2011-10-30
58
58
 
59
59
  * Add nonblocking Connection#process_messages API
60
+
61
+ == 0.5.4 / 2011-12-16
62
+
63
+ * Placing Version source file into its proper place
64
+
65
+ == 0.5.5 / 2011-12-16
66
+
67
+ * ComboLeg serialization signature changed
68
+
69
+ == 0.5.6 / 2011-12-16
70
+
71
+ * Models::ComboLeg given a source file of its own
72
+
73
+ == 0.5.7 / 2011-12-16
74
+
75
+ * Option subclass of Contract added
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # ib-ruby
2
+
3
+ Ruby Implementation of the Interactive Brokers Trader Workstation (TWS) API v.965.
4
+
5
+ Copyright (C) 2006-2011 Paul Legato, Wes Devauld, and Ar Vicco.
6
+
7
+ https://github.com/ib-ruby/ib-ruby
8
+
9
+ __WARNING:__ This software is provided __AS-IS__ with __NO WARRANTY__, express or
10
+ implied. Your use of this software is at your own risk. It may contain
11
+ any number of bugs, known or unknown, which might cause you to lose
12
+ money if you use it. You've been warned.
13
+
14
+ __It is specifically NOT RECOMMENDED that this code be used for live trading.__
15
+
16
+ This code is not sanctioned or supported by Interactive Brokers
17
+ This software is available under the LGPL. See the file LICENSE for full licensing details.
18
+
19
+
20
+ ## REQUIREMENTS:
21
+
22
+ Either the Interactive Brokers
23
+ [TWS](http://www.interactivebrokers.com/en/p.php?f=tws) or
24
+ [IB Gateway](http://www.interactivebrokers.com/en/control/systemstandalone-ibGateway.php?os=unix&ib_entity=llc)
25
+ software must be installed and configured to allow API connections
26
+ from the computer you plan to run ib-ruby on, which is typically
27
+ localhost if you're running ib-ruby on the same machine as TWS.
28
+
29
+ ## INSTALLATION:
30
+
31
+ ### From RubyGems
32
+
33
+ $ sudo gem install ib-ruby
34
+
35
+ ### From Source
36
+
37
+ $ git clone https://github.com/ib-ruby/ib-ruby
38
+ $ cd ib-ruby; rake gem:install
39
+
40
+ ## SYNOPSIS:
41
+
42
+ First, start up Interactive Broker's Trader Work Station or Gateway.
43
+ Make sure it is configured to allow API connections on localhost.
44
+
45
+ >> require 'ib-ruby'
46
+ >> ib = IB::Connection.new
47
+ >> ib.subscribe(:Alert, :AccountValue) { |msg| puts msg.to_human }
48
+ >> ib.send_message :RequestAccountData, :subscribe => true
49
+
50
+ Your code and TWS interact via an exchange of messages. You
51
+ subscribe to message types you're interested in using
52
+ `IB::Connection#subscribe` and request data from TWS using
53
+ `IB::Connection#send_message`.
54
+
55
+ The code blocks (or procs) given to `#subscribe` will be executed when
56
+ a message of the requested type is received, with the received message as
57
+ its argument.
58
+
59
+ See `lib/ib-ruby/messages` for a full list of supported incoming/outgoing messages and
60
+ their attributes. The original TWS docs and code samples can be found
61
+ in the `misc/` folder.
62
+
63
+ The sample scripts in the `bin/` directory provide examples of how
64
+ common tasks can be achieved using ib-ruby.
65
+
66
+
67
+ ## LICENSE:
68
+
69
+ This library is free software; you can redistribute it and/or modify
70
+ it under the terms of the GNU Lesser General Public License as
71
+ published by the Free Software Foundation; either version 2.1 of the
72
+ License, or (at your option) any later version.
73
+
74
+ This library is distributed in the hope that it will be useful, but
75
+ WITHOUT ANY WARRANTY; without even the implied warranty of
76
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
77
+ Lesser General Public License for more details.
78
+
79
+ You should have received a copy of the GNU Lesser General Public
80
+ License along with this library; if not, write to the Free Software
81
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
82
+ 02110-1301 USA
83
+
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ PKG_PATH = BASE_PATH + 'pkg'
14
14
  DOC_PATH = BASE_PATH + 'rdoc'
15
15
 
16
16
  $LOAD_PATH.unshift LIB_PATH.to_s
17
- require 'version'
17
+ require 'ib-ruby/version'
18
18
 
19
19
  NAME = 'ib-ruby'
20
20
  CLASS_NAME = IB
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2
1
+ 0.5.7
data/bin/account_info CHANGED
File without changes
data/bin/contract_details CHANGED
File without changes
data/bin/depth_of_market CHANGED
File without changes
data/bin/historic_data CHANGED
File without changes
File without changes
data/bin/market_data CHANGED
File without changes
data/bin/option_data CHANGED
@@ -13,8 +13,10 @@ require 'ib-ruby'
13
13
  # Definition of what we want market data for. We have to keep track of what ticker id
14
14
  # corresponds to what symbol ourselves, because the ticks don't include any other
15
15
  # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
16
- @market = {123 => IB::Symbols::Options[:wfc20],
17
- 125 => IB::Symbols::Options[:z50]}
16
+ @market = {13 => IB::Symbols::Options[:wfc20],
17
+ 15 => IB::Symbols::Options[:z50],
18
+ 17 => IB::Symbols::Options[:spy75],
19
+ 19 => IB::Symbols::Options[:spy100]}
18
20
 
19
21
  # First, connect to IB TWS.
20
22
  ib = IB::Connection.new
@@ -28,7 +30,7 @@ ib.subscribe(:Alert) { |msg| puts msg.to_human }
28
30
  #
29
31
  # (N.B. The description field is not from IB TWS. It is defined
30
32
  # locally in forex.rb, and is just arbitrary text.)
31
- ib.subscribe(:TickPrice, :TickSize, :TickOption) do |msg|
33
+ ib.subscribe(:TickPrice, :TickSize, :TickOption, :TickString) do |msg|
32
34
  puts @market[msg.data[:id]].description + ": " + msg.to_human
33
35
  end
34
36
 
data/bin/template CHANGED
File without changes
data/bin/time_and_sales CHANGED
File without changes
@@ -146,7 +146,7 @@ module IB
146
146
 
147
147
  alias dispatch send_message # Legacy alias
148
148
 
149
- # Process incoming messages during *poll_time* (200) msecs (nonblocking)
149
+ # Process incoming messages during *poll_time* (200) msecs
150
150
  def process_messages poll_time = 200 # in msec
151
151
  time_out = Time.now + poll_time/1000.0
152
152
  while (time_left = time_out - Time.now) > 0
@@ -161,9 +161,9 @@ module IB
161
161
  msg_id = @server[:socket].read_int
162
162
 
163
163
  # Debug:
164
- unless [1, 2, 4, 6, 7, 8, 9, 12, 21, 53].include? msg_id
165
- puts "Got message #{msg_id} (#{Messages::Incoming::Table[msg_id]})"
166
- end
164
+ #unless [1, 2, 4, 6, 7, 8, 9, 12, 21, 53].include? msg_id
165
+ # puts "Got message #{msg_id} (#{Messages::Incoming::Table[msg_id]})"
166
+ #end
167
167
 
168
168
  # Create new instance of the appropriate message type, and have it read the message.
169
169
  # NB: Failure here usually means unsupported message type received
@@ -185,10 +185,12 @@ module IB
185
185
  def start_reader
186
186
  Thread.abort_on_exception = true
187
187
  @reader_running = true
188
- @server[:reader] = Thread.new { process_messages while @reader_running }
188
+ @server[:reader] = Thread.new do
189
+ process_messages while @reader_running
190
+ end
189
191
  end
190
192
 
191
193
  end # class Connection
192
- IB = Connection # Legacy alias
194
+ #IB = Connection # Legacy alias
193
195
 
194
196
  end # module IB
@@ -97,4 +97,21 @@ module IB
97
97
  # this new tick type are: 0 = Not halted, 1 = Halted.
98
98
  # Note 3: Applies to bond contracts only.
99
99
  }
100
+
101
+ #
102
+ # Market depth messages contain these "operation" codes to tell you
103
+ # what to do with the data.
104
+ #
105
+ # See also http://www.interactivebrokers.com/php/apiUsersGuide/apiguide/java/updatemktdepth.htm
106
+ #
107
+ MARKET_DEPTH_OPERATIONS = {
108
+ 0 => :insert, # New order, insert into the row identified by :position
109
+ 1 => :update, # Update the existing order at the row identified by :position
110
+ 2 => :delete # Delete the existing order at the row identified by :position
111
+ }
112
+
113
+ MARKET_DEPTH_SIDES = {
114
+ 0 => :ask,
115
+ 1 => :bid
116
+ }
100
117
  end # module IB
@@ -0,0 +1,58 @@
1
+ module IB
2
+ module Models
3
+
4
+ # ComboLeg objects represent individual securities in a "BAG" contract - which
5
+ # is not really a contract, but a combination (combo) of securities. AKA basket
6
+ # or bag of securities.
7
+ class ComboLeg < Model
8
+ # // open/close leg value is same as combo
9
+ # Specifies whether the order is an open or close order. Valid values are:
10
+ SAME = 0 # Same as the parent security. The only option for retail customers.
11
+ OPEN = 1 # Open. This value is only valid for institutional customers.
12
+ CLOSE = 2 # Close. This value is only valid for institutional customers.
13
+ UNKNOWN = 3
14
+
15
+ attr_accessor :con_id, # int: The unique contract identifier specifying the security.
16
+ :ratio, # int: Select the relative number of contracts for the leg you
17
+ # are constructing. To help determine the ratio for a
18
+ # specific combination order, refer to the Interactive
19
+ # Analytics section of the User's Guide.
20
+
21
+ :action, # String: BUY/SELL/SSHORT/SSHORTX
22
+ # The side (buy or sell) for the leg you are constructing.
23
+ :exchange, # String: exchange to which the complete combination
24
+ # order will be routed.
25
+ :open_close, # int: Specifies whether the order is an open or close order.
26
+ # Valid values: ComboLeg::SAME/OPEN/CLOSE/UNKNOWN
27
+
28
+ # For institutional customers only! For stock legs when doing short sale
29
+ :short_sale_slot, # int: 0 - retail, 1 = clearing broker, 2 = third party
30
+ :designated_location, # String: Only for shortSaleSlot == 2.
31
+ # Otherwise leave blank or orders will be rejected.
32
+ :exempt_code # int: ?
33
+
34
+ def initialize opts = {}
35
+ @con_id = 0
36
+ @ratio = 0
37
+ @open_close = 0
38
+ @short_sale_slot = 0
39
+ @designated_location = ''
40
+ @exempt_code = -1
41
+
42
+ super opts
43
+ end
44
+
45
+ # Some messages include open_close, some don't. wtf.
46
+ def serialize *fields
47
+ [con_id,
48
+ ratio,
49
+ action,
50
+ exchange,
51
+ (fields.include?(:extended) ? [open_close, short_sale_slot,
52
+ designated_location, exempt_code] : [])
53
+ ].flatten
54
+ end
55
+ end # ComboLeg
56
+
57
+ end # module Models
58
+ end # module IB
@@ -0,0 +1,54 @@
1
+ require 'ib-ruby/models/contract'
2
+
3
+ module IB
4
+ module Models
5
+ class Contract
6
+ class Option < Contract
7
+
8
+ # For Options, this is contract's OSI (Option Symbology Initiative) name/code
9
+ alias osi local_symbol
10
+
11
+ def osi= value
12
+ # Normalize to 21 char
13
+ self.local_symbol = value.sub(/ /, ' '*(22-value.size))
14
+ end
15
+
16
+ def initialize opts = {}
17
+ super opts
18
+ @sec_type = IB::SECURITY_TYPES[:option]
19
+ @description ||= osi ? osi : "#{symbol} #{strike} #{right} #{expiry}"
20
+ end
21
+
22
+ # Make valid IB Contract definition from OSI (Option Symbology Initiative) code.
23
+ # NB: Simply making a new Contract with *local_symbol* (osi) property set to a
24
+ # valid OSI code works just as well, just do NOT set *expiry*, *right* or
25
+ # *strike* properties at the same time.
26
+ # This class method provided as a backup, to show how to analyse OSI codes.
27
+ def self.from_osi osi
28
+
29
+ # Parse contract's OSI (OCC Option Symbology Initiative) code
30
+ args = osi.match(/(\w+)\s?(\d\d)(\d\d)(\d\d)([pcPC])(\d+)/).to_a.drop(1)
31
+ symbol = args.shift
32
+ year = 2000 + args.shift.to_i
33
+ month = args.shift.to_i
34
+ day = args.shift.to_i
35
+ right = args.shift.upcase
36
+ strike = args.shift.to_i/1000.0
37
+ #p symbol, year, month, day, right, strike
38
+
39
+ # Set correct expiry date - IB expiry date differs from OSI if expiry date
40
+ # falls on Saturday (see https://github.com/arvicco/option_mower/issues/4)
41
+ expiry_date = Time.new(year, month, day)
42
+ expiry_date = Time.new(year, month, day-1) if expiry_date.saturday?
43
+
44
+ new :symbol => symbol,
45
+ :exchange => "SMART",
46
+ :expiry => expiry_date.to_ib,
47
+ :right => right,
48
+ :strike => strike
49
+ end
50
+
51
+ end # class Option
52
+ end # class Contract
53
+ end # module Models
54
+ end # module IB
@@ -168,7 +168,7 @@ module IB
168
168
  # This returns an Array of data from the given contract.
169
169
  # Different messages serialize contracts differently. Go figure.
170
170
  # Note that it does NOT include the combo legs.
171
- def serialize(*fields)
171
+ def serialize *fields
172
172
  [(fields.include?(:con_id) ? [con_id] : []),
173
173
  symbol,
174
174
  sec_type,
@@ -182,12 +182,12 @@ module IB
182
182
  ].flatten
183
183
  end
184
184
 
185
- def serialize_long(*fields)
186
- serialize(:option, :primary_exchange, *fields)
185
+ def serialize_long *fields
186
+ serialize :option, :primary_exchange, *fields
187
187
  end
188
188
 
189
- def serialize_short(*fields)
190
- serialize(:option, *fields)
189
+ def serialize_short *fields
190
+ serialize :option, *fields
191
191
  end
192
192
 
193
193
  # This produces a string uniquely identifying this contract, in the format used
@@ -202,12 +202,12 @@ module IB
202
202
  # expiring in September, 2008, the string is:
203
203
  #
204
204
  # GBP:FUT:200809:::62500:GLOBEX::USD:
205
- def serialize_ib_ruby(version)
205
+ def serialize_ib_ruby version
206
206
  serialize.join(":")
207
207
  end
208
208
 
209
209
  # This returns a Contract initialized from the serialize_ib_ruby format string.
210
- def self.from_ib_ruby(string)
210
+ def self.from_ib_ruby string
211
211
  c = Contract.new
212
212
  c.symbol, c.sec_type, c.expiry, c.strike, c.right, c.multiplier,
213
213
  c.exchange, c.primary_exchange, c.currency, c.local_symbol = string.split(":")
@@ -215,7 +215,7 @@ module IB
215
215
  end
216
216
 
217
217
  # Serialize under_comp parameters
218
- def serialize_under_comp(*args)
218
+ def serialize_under_comp *args
219
219
  # EClientSocket.java, line 471:
220
220
  if under_comp
221
221
  [true,
@@ -228,12 +228,14 @@ module IB
228
228
  end
229
229
 
230
230
  # Some messages send open_close too, some don't. WTF.
231
- def serialize_combo_legs(type = :short)
232
- # No idea what "BAG" means. Copied from the Java code.
231
+ # "BAG" is not really a contract, but a combination (combo) of securities.
232
+ # AKA basket or bag of securities. Individual securities in combo are represented
233
+ # by ComboLeg objects.
234
+ def serialize_combo_legs *fields
233
235
  return [] unless sec_type.upcase == "BAG"
234
236
  return [0] if combo_legs.empty? || combo_legs.nil?
235
237
  [combo_legs.size,
236
- combo_legs.map { |leg| leg.serialize(type) }]
238
+ combo_legs.map { |leg| leg.serialize *fields }]
237
239
  end
238
240
 
239
241
  def to_human
@@ -248,59 +250,6 @@ module IB
248
250
  to_human
249
251
  end
250
252
 
251
- # ComboLeg is an internal class of Contract, as it should be
252
- class ComboLeg < Model
253
- # // open/close leg value is same as combo
254
- # Specifies whether the order is an open or close order. Valid values are:
255
- SAME = 0 # Same as the parent security. The only option for retail customers.
256
- OPEN = 1 # Open. This value is only valid for institutional customers.
257
- CLOSE = 2 # Close. This value is only valid for institutional customers.
258
- UNKNOWN = 3
259
-
260
-
261
- attr_accessor :con_id, # int: The unique contract identifier specifying the security.
262
- :ratio, # int: Select the relative number of contracts for the leg you
263
- # are constructing. To help determine the ratio for a
264
- # specific combination order, refer to the Interactive
265
- # Analytics section of the User's Guide.
266
-
267
- :action, # String: BUY/SELL/SSHORT/SSHORTX
268
- # The side (buy or sell) for the leg you are constructing.
269
- :exchange, # String: exchange to which the complete combination
270
- # order will be routed.
271
- :open_close, # int: Specifies whether the order is an open or close order.
272
- # Valid values: ComboLeg::SAME/OPEN/CLOSE/UNKNOWN
273
-
274
- # For institutional customers only! For stock legs when doing short sale
275
- :short_sale_slot, # int: 0 - retail, 1 = clearing broker, 2 = third party
276
- :designated_location, # String: Only for shortSaleSlot == 2.
277
- # Otherwise leave blank or orders will be rejected.
278
- :exempt_code # int: ?
279
-
280
- def initialize opts = {}
281
- @con_id = 0
282
- @ratio = 0
283
- @open_close = 0
284
- @short_sale_slot = 0
285
- @designated_location = ''
286
- @exempt_code = -1
287
-
288
- super opts
289
- end
290
-
291
- # Some messages include open_close, some don't. wtf.
292
- def serialize(type = :short)
293
- [con_id,
294
- ratio,
295
- action,
296
- exchange] +
297
- type == :short ? [] : [open_close,
298
- short_sale_slot,
299
- designated_location,
300
- exempt_code]
301
- end
302
- end # ComboLeg
303
-
304
253
  end # class Contract
305
254
  end # module Models
306
255
  end # module IB
@@ -281,7 +281,7 @@ module IB
281
281
  trigger_method,
282
282
  outside_rth, # was: ignore_rth
283
283
  hidden,
284
- contract.serialize_combo_legs(:long),
284
+ contract.serialize_combo_legs(:extended),
285
285
  '', # deprecated shares_allocation field
286
286
  discretionary_amount,
287
287
  good_after_time,
@@ -6,6 +6,7 @@ end
6
6
 
7
7
  require 'ib-ruby/models/order'
8
8
  require 'ib-ruby/models/contract'
9
+ require 'ib-ruby/models/combo_leg'
9
10
  require 'ib-ruby/models/execution'
10
11
  require 'ib-ruby/models/bar'
11
12
 
@@ -17,7 +17,6 @@ module IB
17
17
  #
18
18
  # N.B. This will not work as expected near/after expiration during that month, as
19
19
  # volume rolls over to the next quarter even though the current month is still valid!
20
- #
21
20
  def self.next_quarter_month(time)
22
21
  sprintf("%02d", [3, 6, 9, 12].find { |month| month >= time.month })
23
22
  end
@@ -30,10 +29,46 @@ module IB
30
29
  end
31
30
  end
32
31
 
32
+ #
33
+ # WARNING: This is currently broken. It returns the next
34
+ # quarterly expiration month after the current month. Many futures
35
+ # instruments have monthly contracts for the near months. This
36
+ # method will not work for such contracts; it will return the next
37
+ # quarter after the current month, even though the present month
38
+ # has the majority of the trading volume.
39
+ #
40
+ # For example, in early November of 2011, many contracts have the
41
+ # vast majority of their volume in the Nov 2011 contract, but this
42
+ # method will return the Dec 2011 contract instead.
43
+ #
33
44
  def self.next_expiry(time)
34
45
  "#{ self.next_quarter_year(time) }#{ self.next_quarter_month(time) }"
35
46
  end
36
47
 
48
+ #
49
+ # Convenience method; generates a Models::Contract instance for a futures
50
+ # contract with the given parameters.
51
+ #
52
+ # If expiry is nil, it will use the end month of the current
53
+ # quarter. This will be wrong for most contracts most of the time,
54
+ # since most contracts have the majority of their volume in a
55
+ # nearby intraquarter month.
56
+ #
57
+ # It is recommended that you specify an expiration date manually
58
+ # until next_expiry is fixed. Expiry should be a string in the
59
+ # format "YYYYMM", where YYYY is the 4 digit year and MM is the 2
60
+ # digit month. For example, November 2011 is "201111".
61
+ #
62
+ def self.future(base_symbol, exchange, currency, description="", expiry=nil)
63
+ Models::Contract.new(:symbol => base_symbol,
64
+ :expiry => expiry.nil? ? self.next_expiry(Time.now) : expiry,
65
+ :exchange => exchange,
66
+ :currency => currency,
67
+ :sec_type => SECURITY_TYPES[:future],
68
+ :description => description)
69
+ end
70
+
71
+
37
72
  Futures ={
38
73
  :ym => Models::Contract.new(:symbol => "YM",
39
74
  :expiry => self.next_expiry(Time.now),
@@ -8,21 +8,27 @@ module IB
8
8
  module Symbols
9
9
 
10
10
  Options =
11
- {:wfc20 => Models::Contract.new(:symbol => "WFC",
12
- :exchange => "SMART",
13
- :expiry => "201112",
14
- :right => "CALL",
15
- :strike => 20.0,
16
- :sec_type => SECURITY_TYPES[:option],
17
- :description => "Wells Fargo 20 Call 2011-12"),
18
- :z50 => Models::Contract.new(:symbol => "Z",
19
- :exchange => "LIFFE",
20
- :expiry => "201112",
21
- :right => "CALL",
22
- :strike => 50.0,
23
- :sec_type => SECURITY_TYPES[:option],
24
- :description => " FTSE-100 index 50 Call 2011-12"),
25
-
11
+ {:wfc20 => Models::Contract::Option.new(:symbol => "WFC",
12
+ :exchange => "SMART",
13
+ :expiry => "201207",
14
+ :right => "CALL",
15
+ :strike => 20.0,
16
+ :description => "Wells Fargo 20 Call 2012-07"),
17
+ :z50 => Models::Contract::Option.new(:symbol => "Z",
18
+ :exchange => "LIFFE",
19
+ :expiry => "201206",
20
+ :right => "CALL",
21
+ :strike => 50.0,
22
+ :description => " FTSE-100 index 50 Call 2012-06"),
23
+ :spy75 => Models::Contract::Option.new(:symbol => 'SPY',
24
+ :exchange => "SMART",
25
+ :expiry => "20120615",
26
+ :right => "P",
27
+ :currency => "USD",
28
+ :strike => 75.0,
29
+ :description => "SPY 75.0 Put 2012-06-16"),
30
+ :spy100 => Models::Contract::Option.new(:osi => 'SPY 121222P00100000',
31
+ :exchange => "SMART"),
26
32
  }
27
33
  end
28
34
  end
@@ -1,6 +1,6 @@
1
1
  require 'pathname'
2
2
 
3
3
  module IB
4
- VERSION_FILE = Pathname.new(__FILE__).dirname + '../VERSION' # :nodoc:
4
+ VERSION_FILE = Pathname.new(__FILE__).dirname + '../../VERSION' # :nodoc:
5
5
  VERSION = VERSION_FILE.exist? ? VERSION_FILE.read.strip : nil
6
6
  end
data/lib/ib-ruby.rb CHANGED
@@ -2,9 +2,13 @@ module IB
2
2
  end # module IB
3
3
  IbRuby = IB
4
4
 
5
- require 'version'
5
+ require 'ib-ruby/version'
6
6
  require 'ib-ruby/constants'
7
7
  require 'ib-ruby/connection'
8
8
  require 'ib-ruby/models'
9
- require 'ib-ruby/symbols'
10
9
  require 'ib-ruby/messages'
10
+
11
+ # TODO Where should we require this?
12
+ require 'ib-ruby/models/contract/option'
13
+
14
+ require 'ib-ruby/symbols'
@@ -0,0 +1,55 @@
1
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
2
+
3
+ describe IB::Models::ComboLeg do
4
+
5
+ let(:properties) do
6
+ {:con_id => 123,
7
+ :ratio=> 1234,
8
+ :action => 'BUY',
9
+ :exchange => 'BLAH',
10
+ :open_close => IB::Models::ComboLeg::OPEN,
11
+ :short_sale_slot => 1,
12
+ :designated_location => 'BLEH',
13
+ :exempt_code => 12}
14
+ end
15
+
16
+ context "instantiation" do
17
+ context 'empty without properties' do
18
+ subject { IB::Models::ComboLeg.new }
19
+
20
+ it { should_not be_nil }
21
+ its (:con_id) {should == 0}
22
+ its (:ratio) {should == 0}
23
+ its (:open_close) {should == 0}
24
+ its (:short_sale_slot) {should == 0}
25
+ its (:exempt_code) {should == -1}
26
+
27
+ its (:created_at) {should be_a Time}
28
+ end
29
+
30
+ context 'with properties' do
31
+ subject { IB::Models::ComboLeg.new properties }
32
+
33
+ it 'sets properties right' do
34
+ properties.each do |name, value|
35
+ subject.send(name).should == value
36
+ end
37
+ end
38
+
39
+ context 'essential properties are still set, even if not given explicitely' do
40
+ its (:created_at) {should be_a Time}
41
+ end
42
+ end
43
+
44
+ it 'allows setting attributes' do
45
+ expect {
46
+ x = IB::Models::ComboLeg.new
47
+ properties.each do |name, value|
48
+ subject.send("#{name}=", value)
49
+ subject.send(name).should == value
50
+ end
51
+ }.to_not raise_error
52
+ end
53
+ end #instantiation
54
+
55
+ end # describe IB::Models::Contract::ComboLeg
@@ -205,57 +205,3 @@ describe IB::Models::Contract do
205
205
  end #serialization
206
206
 
207
207
  end # describe IB::Models::Contract
208
-
209
- describe IB::Models::Contract::ComboLeg do
210
-
211
- let(:properties) do
212
- {:con_id => 123,
213
- :ratio=> 1234,
214
- :action => 'BUY',
215
- :exchange => 'BLAH',
216
- :open_close => IB::Models::Contract::ComboLeg::OPEN,
217
- :short_sale_slot => 1,
218
- :designated_location => 'BLEH',
219
- :exempt_code => 12}
220
- end
221
-
222
- context "instantiation" do
223
- context 'empty without properties' do
224
- subject { IB::Models::Contract::ComboLeg.new }
225
-
226
- it { should_not be_nil }
227
- its (:con_id) {should == 0}
228
- its (:ratio) {should == 0}
229
- its (:open_close) {should == 0}
230
- its (:short_sale_slot) {should == 0}
231
- its (:exempt_code) {should == -1}
232
-
233
- its (:created_at) {should be_a Time}
234
- end
235
-
236
- context 'with properties' do
237
- subject { IB::Models::Contract::ComboLeg.new properties }
238
-
239
- it 'sets properties right' do
240
- properties.each do |name, value|
241
- subject.send(name).should == value
242
- end
243
- end
244
-
245
- context 'essential properties are still set, even if not given explicitely' do
246
- its (:created_at) {should be_a Time}
247
- end
248
- end
249
-
250
- it 'allows setting attributes' do
251
- expect {
252
- x = IB::Models::Contract::ComboLeg.new
253
- properties.each do |name, value|
254
- subject.send("#{name}=", value)
255
- subject.send(name).should == value
256
- end
257
- }.to_not raise_error
258
- end
259
- end #instantiation
260
-
261
- end # describe IB::Models::Contract::ComboLeg
metadata CHANGED
@@ -2,15 +2,16 @@
2
2
  name: ib-ruby
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.5.2
5
+ version: 0.5.7
6
6
  platform: ruby
7
7
  authors:
8
+ - Paul Legato
8
9
  - arvicco
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
13
 
13
- date: 2011-12-12 00:00:00 -08:00
14
+ date: 2011-12-16 00:00:00 -08:00
14
15
  default_executable:
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
@@ -35,8 +36,10 @@ dependencies:
35
36
  version: 2.5.0
36
37
  type: :development
37
38
  version_requirements: *id002
38
- description: Ruby Implementation of the Interactive Broker' TWS API
39
- email: arvitallian@gmail.com
39
+ description: Ruby Implementation of the Interactive Brokers TWS API
40
+ email:
41
+ - pjlegato@gmail.com
42
+ - arvitallian@gmail.com
40
43
  executables:
41
44
  - account_info
42
45
  - contract_details
@@ -49,10 +52,8 @@ executables:
49
52
  - time_and_sales
50
53
  extensions: []
51
54
 
52
- extra_rdoc_files:
53
- - LICENSE
54
- - HISTORY
55
- - README.rdoc
55
+ extra_rdoc_files: []
56
+
56
57
  files:
57
58
  - bin/account_info
58
59
  - bin/contract_details
@@ -69,6 +70,8 @@ files:
69
70
  - lib/ib-ruby/messages/outgoing.rb
70
71
  - lib/ib-ruby/messages.rb
71
72
  - lib/ib-ruby/models/bar.rb
73
+ - lib/ib-ruby/models/combo_leg.rb
74
+ - lib/ib-ruby/models/contract/option.rb
72
75
  - lib/ib-ruby/models/contract.rb
73
76
  - lib/ib-ruby/models/execution.rb
74
77
  - lib/ib-ruby/models/model.rb
@@ -80,9 +83,10 @@ files:
80
83
  - lib/ib-ruby/symbols/options.rb
81
84
  - lib/ib-ruby/symbols/stocks.rb
82
85
  - lib/ib-ruby/symbols.rb
86
+ - lib/ib-ruby/version.rb
83
87
  - lib/ib-ruby.rb
84
- - lib/version.rb
85
88
  - spec/ib-ruby/connection_spec.rb
89
+ - spec/ib-ruby/models/combo_leg_spec.rb
86
90
  - spec/ib-ruby/models/contract_spec.rb
87
91
  - spec/ib-ruby/models/order_spec.rb
88
92
  - spec/ib-ruby_spec.rb
@@ -94,23 +98,18 @@ files:
94
98
  - tasks/spec.rake
95
99
  - tasks/version.rake
96
100
  - Rakefile
97
- - README.rdoc
101
+ - README.md
98
102
  - LICENSE
99
103
  - VERSION
100
104
  - HISTORY
101
105
  - .gitignore
102
106
  has_rdoc: true
103
- homepage: http://github.com/arvicco/ib-ruby
107
+ homepage: https://github.com/pjlegato/ib-ruby
104
108
  licenses: []
105
109
 
106
110
  post_install_message:
107
- rdoc_options:
108
- - --charset
109
- - UTF-8
110
- - --main
111
- - README.rdoc
112
- - --title
113
- - mix
111
+ rdoc_options: []
112
+
114
113
  require_paths:
115
114
  - lib
116
115
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -131,9 +130,10 @@ rubyforge_project:
131
130
  rubygems_version: 1.6.2
132
131
  signing_key:
133
132
  specification_version: 3
134
- summary: Ruby Implementation of the Interactive Broker' TWS API
133
+ summary: Ruby Implementation of the Interactive Brokers TWS API
135
134
  test_files:
136
135
  - spec/ib-ruby/connection_spec.rb
136
+ - spec/ib-ruby/models/combo_leg_spec.rb
137
137
  - spec/ib-ruby/models/contract_spec.rb
138
138
  - spec/ib-ruby/models/order_spec.rb
139
139
  - spec/ib-ruby_spec.rb
data/README.rdoc DELETED
@@ -1,58 +0,0 @@
1
- = ib-ruby
2
- by:: Arvicco
3
- url:: http://github.com/arvicco/ib-ruby
4
-
5
- This is a fork of http://github.com/wdevauld/ib-ruby by Wes Devauld,
6
- that is in turn forked from http://github.com/pjlegato/ib-ruby by Paul Legato.
7
-
8
- == DESCRIPTION:
9
-
10
- Ruby Implementation of the Interactive Broker' Trader Work Station (TWS) API v.965.
11
-
12
- == FEATURES/PROBLEMS:
13
-
14
- * This is a BETA release, and should not be used for live trading.
15
- Any features contained within are AS-IS and may not work in all conditions
16
- * This code is not sanctioned or supported by Interactive Brokers
17
-
18
- == REQUIREMENTS:
19
-
20
- Interactive Broker's TWS or Gateway installed and configured to allow API
21
- connections on localhost.
22
-
23
- == INSTALL:
24
-
25
- === From Gem
26
-
27
- $ sudo gem install ib-ruby
28
-
29
- === From Source
30
-
31
- $ git clone http://github.com/arvicco/ib-ruby
32
- $ cd ib-ruby; rake gem:install
33
-
34
- == SYNOPSIS:
35
-
36
- First, start up Interactive Broker's Trader Work Station or Gateway.
37
- Make sure it is configured to allow API connections on localhost.
38
-
39
- >> require 'ib-ruby'
40
- >> ib = IB::Connection.new
41
- >> ib.subscribe(:Alert, :AccountValue) { |msg| puts msg.to_human }
42
- >> ib.send_message :RequestAccountData, :subscribe => true
43
-
44
- Essentially, all interaction of your code and TWS can be described as exchange
45
- of messages. You subscribe to message type(s) you're interested in using
46
- IB::Connection#subscribe and request data from TWS using IB::Connection#send_message.
47
- The code blocks (or procs) given to #subscribe will be executed when a message of
48
- requested type is received, with the received message as its argument.
49
-
50
- Use sample scripts in /bin folder as an example of how common tasks can be
51
- achieved using ib-ruby.
52
-
53
- See /lib/ib-ruby/messages for a full list of TWS incoming/outgoing messages and
54
- their attributes. Original TWS docs and code samples can be found in /misc folder.
55
-
56
- == LICENSE:
57
-
58
- Copyright (c) 2011 Arvicco. See LICENSE for details.