ib-ruby 0.4.3 → 0.4.20

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.
Files changed (50) hide show
  1. data/.gitignore +32 -0
  2. data/HISTORY +68 -0
  3. data/README.rdoc +9 -6
  4. data/VERSION +1 -1
  5. data/bin/account_info +29 -0
  6. data/bin/contract_details +37 -0
  7. data/bin/depth_of_market +43 -0
  8. data/bin/historic_data +62 -0
  9. data/bin/{RequestHistoricData → historic_data_cli} +46 -91
  10. data/bin/market_data +49 -0
  11. data/bin/option_data +45 -0
  12. data/bin/template +21 -0
  13. data/bin/time_and_sales +63 -0
  14. data/lib/ib-ruby/connection.rb +166 -0
  15. data/lib/ib-ruby/constants.rb +91 -0
  16. data/lib/ib-ruby/messages/incoming.rb +807 -0
  17. data/lib/ib-ruby/messages/outgoing.rb +573 -0
  18. data/lib/ib-ruby/messages.rb +8 -1445
  19. data/lib/ib-ruby/models/bar.rb +26 -0
  20. data/lib/ib-ruby/models/contract.rb +335 -0
  21. data/lib/ib-ruby/models/execution.rb +55 -0
  22. data/lib/ib-ruby/models/model.rb +20 -0
  23. data/lib/ib-ruby/models/order.rb +262 -0
  24. data/lib/ib-ruby/models.rb +11 -0
  25. data/lib/ib-ruby/socket.rb +50 -0
  26. data/lib/ib-ruby/symbols/forex.rb +32 -72
  27. data/lib/ib-ruby/symbols/futures.rb +47 -68
  28. data/lib/ib-ruby/symbols/options.rb +30 -0
  29. data/lib/ib-ruby/symbols/stocks.rb +23 -0
  30. data/lib/ib-ruby/symbols.rb +9 -0
  31. data/lib/ib-ruby.rb +7 -8
  32. data/lib/legacy/bin/account_info_old +36 -0
  33. data/lib/legacy/bin/historic_data_old +81 -0
  34. data/lib/legacy/bin/market_data_old +68 -0
  35. data/lib/legacy/datatypes.rb +485 -0
  36. data/lib/legacy/ib-ruby.rb +10 -0
  37. data/lib/legacy/ib.rb +226 -0
  38. data/lib/legacy/messages.rb +1458 -0
  39. data/lib/version.rb +2 -3
  40. data/spec/ib-ruby/models/contract_spec.rb +261 -0
  41. data/spec/ib-ruby/models/order_spec.rb +64 -0
  42. data/spec/ib-ruby_spec.rb +0 -131
  43. metadata +106 -76
  44. data/bin/AccountInfo +0 -67
  45. data/bin/HistoricToCSV +0 -111
  46. data/bin/RequestMarketData +0 -78
  47. data/bin/SimpleTimeAndSales +0 -98
  48. data/bin/ib-ruby +0 -8
  49. data/lib/ib-ruby/datatypes.rb +0 -400
  50. data/lib/ib-ruby/ib.rb +0 -242
data/.gitignore ADDED
@@ -0,0 +1,32 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## Idea
17
+ .idea
18
+ .bundle
19
+ .rakeTasks
20
+ *.iml
21
+
22
+ ## PROJECT::GENERAL
23
+ coverage
24
+ config
25
+ data
26
+ rdoc
27
+ pkg
28
+ log
29
+ tmp
30
+
31
+ ## PROJECT::SPECIFIC
32
+ *.db
data/HISTORY CHANGED
@@ -21,3 +21,71 @@
21
21
  == 0.4.3 / 2011-09-05
22
22
 
23
23
  * Old tests converted into specs
24
+
25
+ == 0.4.4 / 2011-09-05
26
+
27
+ * IB references and Java examples added
28
+
29
+ == 0.4.5 / 2011-09-06
30
+
31
+ * Sample scripts updated
32
+
33
+ == 0.4.6 / 2011-09-07
34
+
35
+ * CSV Downloader Java examples added
36
+
37
+ == 0.4.7 / 2011-09-12
38
+
39
+ * Datatypes turned into Models
40
+
41
+ == 0.4.8 / 2011-09-12
42
+
43
+ * IB::Messages::Outgoing code compacted using macros
44
+
45
+ == 0.4.9 / 2011-09-15
46
+
47
+ * IB::Messages::Incoming rewritten
48
+
49
+ == 0.4.10 / 2011-09-16
50
+
51
+ * Market data request now working
52
+
53
+ == 0.4.11 / 2011-09-17
54
+
55
+ * New scripts working
56
+
57
+ == 0.4.12 / 2011-09-18
58
+
59
+ * historic_data script now functional
60
+
61
+ == 0.4.13 / 2011-09-18
62
+
63
+ * time_and_sales script now working
64
+
65
+ == 0.4.14 / 2011-09-18
66
+
67
+ * DOM script added
68
+
69
+ == 0.4.15 / 2011-09-18
70
+
71
+ * Messages like RTBars etc implemented
72
+
73
+ == 0.4.16 / 2011-09-19
74
+
75
+ * Execution Model added
76
+
77
+ == 0.4.17 / 2011-09-19
78
+
79
+ * option_data script now working
80
+
81
+ == 0.4.18 / 2011-09-19
82
+
83
+ * IB::Connection#subscribe syntax changed
84
+
85
+ == 0.4.19 / 2011-09-19
86
+
87
+ * All IB messages implemented
88
+
89
+ == 0.4.20 / 2011-09-19
90
+
91
+ * IB::Connection#subscribe now accepts Symbols with message names
data/README.rdoc CHANGED
@@ -1,16 +1,16 @@
1
- = mix
1
+ = ib-ruby
2
2
  by:: Arvicco
3
3
  url:: http://github.com/arvicco/ib-ruby
4
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
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
7
 
8
8
  == DESCRIPTION:
9
9
 
10
10
  Ruby Implementation of the Interactive Broker' TWS API
11
11
 
12
12
  The goal of this fork is to modernize library structure (Bundler/Gemfile/etc) and
13
- then roll out a new version based on latest IB TWS API.
13
+ then roll out a new version based on latest IB TWS API v.965.
14
14
 
15
15
  == FEATURES/PROBLEMS:
16
16
 
@@ -39,8 +39,11 @@ connections on localhost.
39
39
  First, start up Interactive Broker's Trader Work Station.
40
40
  Ensure it is configured to allow API connections on localhost.
41
41
 
42
- >> require 'ib-ruby'
43
- >> ib_connection = IB::IB.new()
42
+ >> require 'ib-ruby'
43
+ >> ib = IB::Connection.new
44
+ >> ib.subscribe(IB::Messages::Incoming::Alert) { |msg| puts msg.to_human }
45
+ >> ib.subscribe(IB::Messages::Incoming::AccountValue) { |msg| puts msg.to_human }
46
+ >> ib.send IB::Messages::Outgoing::RequestAccountData.new :subscribe => true
44
47
 
45
48
  == LICENSE:
46
49
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.3
1
+ 0.4.20
data/bin/account_info ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This script connects to IB API, subscribes to account info and prints out
4
+ # messages received from IB (update every 3 minute or so)
5
+
6
+ require 'pathname'
7
+ LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s
8
+ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
9
+
10
+ require 'rubygems'
11
+ require 'bundler/setup'
12
+ require 'ib-ruby'
13
+
14
+ # First, connect to IB TWS.
15
+ ib = IB::Connection.new
16
+
17
+ # Subscribe to TWS alerts/errors and account-related messages
18
+ # that TWS sends in response to account data request
19
+ ib.subscribe(:Alert, :AccountValue,
20
+ :PortfolioValue, :AccountUpdateTime) { |msg| puts msg.to_human }
21
+
22
+ ib.send :RequestAccountData, :subscribe => true
23
+
24
+ puts "\nSubscribing to IB account data"
25
+ puts "\n******** Press <Enter> to cancel... *********\n\n"
26
+ gets
27
+ puts "Cancelling account data subscription.."
28
+
29
+ ib.send :RequestAccountData, :subscribe => false
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This script gets details for specific symbol from IB
4
+
5
+ require 'pathname'
6
+ LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s
7
+ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
8
+
9
+ require 'rubygems'
10
+ require 'bundler/setup'
11
+ require 'ib-ruby'
12
+
13
+ # Definition of what we want market data for. We have to keep track of what ticker id
14
+ # corresponds to what symbol ourselves, because the ticks don't include any other
15
+ # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
16
+ @market = {123 => IB::Symbols::Stocks[:wfc],
17
+ 125 => IB::Symbols::Options[:wfc20],
18
+ 129 => IB::Symbols::Stocks[:wrong]}
19
+
20
+ # Connect to IB TWS.
21
+ ib = IB::Connection.new
22
+
23
+ # Subscribe to TWS alerts/errors
24
+ ib.subscribe(IB::Messages::Incoming::Alert) { |msg| puts msg.to_human }
25
+
26
+ # Now, subscribe to ContractData incoming events. The code passed in the block
27
+ # will be executed when a message of that type is received, with the received
28
+ # message as its argument. In this case, we just print out the data.
29
+ ib.subscribe(:ContractData) { |msg| puts msg.contract.inspect }
30
+
31
+ # Now we actually request historical data for the symbols we're interested in. TWS will
32
+ # respond with a HistoricalData message, which will be processed by the code above.
33
+ @market.each_pair do |id, contract|
34
+ ib.send :RequestContractData, :id => id, :contract => contract
35
+ end
36
+
37
+ sleep 3 # Wait for IB to respond to our request
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This script connects to IB API and subscribes to L2 (depth of market) data for
4
+ # specific symbols
5
+
6
+ require 'pathname'
7
+ LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s
8
+ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
9
+
10
+ require 'rubygems'
11
+ require 'bundler/setup'
12
+ require 'ib-ruby'
13
+
14
+ # Definition of what we want L2 data for. We have to keep track of what ticker id
15
+ # corresponds to what symbol ourselves, because the ticks don't include any other
16
+ # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
17
+ @market = {123 => IB::Symbols::Stocks[:wfc],
18
+ 456 => IB::Symbols::Futures[:ym],
19
+ 789 => IB::Symbols::Forex[:gbpusd]
20
+ }
21
+
22
+ # First, connect to IB TWS.
23
+ ib = IB::Connection.new
24
+
25
+ # Subscribe to TWS alerts/errors
26
+ ib.subscribe(:Alert) { |msg| puts msg.to_human }
27
+
28
+ # Subscribe to MarketDepth events.
29
+ ib.subscribe(:MarketDepth) do |msg|
30
+ puts @market[msg.data[:id]].description + ": " + msg.to_human
31
+ end
32
+
33
+ # Now we actually request market data for the symbols we're interested in.
34
+ @market.each_pair do |id, contract|
35
+ ib.send :RequestMarketDepth, :id => id, :contract => contract, :num_rows => 5
36
+ end
37
+
38
+ puts "\nSubscribed to market data"
39
+ puts "\n******** Press <Enter> to cancel... *********\n\n"
40
+ gets
41
+ puts "Cancelling market data subscription.."
42
+
43
+ @market.each_pair { |id, contract| ib.send :CancelMarketDepth, :id => id }
data/bin/historic_data ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This script downloads historic data for specific symbols from IB
4
+
5
+ require 'pathname'
6
+ LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s
7
+ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
8
+
9
+ require 'rubygems'
10
+ require 'bundler/setup'
11
+ require 'ib-ruby'
12
+
13
+ ### Configurable Options
14
+ Quiet = false # if Quiet == false, status data will be printed to STDERR
15
+ Timeout = 10 # How long to wait for messages from TWS before exiting, sec
16
+
17
+ # Definition of what we want data for. We have to keep track of what ticker id
18
+ # corresponds to what symbol ourselves, because the ticks don't include any other
19
+ # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
20
+ @market = {123 => IB::Symbols::Stocks[:wfc],
21
+ 456 => IB::Symbols::Futures[:ym],
22
+ 789 => IB::Symbols::Forex[:gbpusd] # No historical market data for GBP/CASH@IDEALPRO Last 60
23
+ }
24
+
25
+ # Connect to IB TWS.
26
+ ib = IB::Connection.new
27
+
28
+ # Subscribe to TWS alerts/errors
29
+ ib.subscribe(IB::Messages::Incoming::Alert) { |msg| puts msg.to_human }
30
+
31
+ # Now, subscribe to HistoricalData incoming events. The code passed in the block
32
+ # will be executed when a message of that type is received, with the received
33
+ # message as its argument. In this case, we just print out the data.
34
+ #
35
+ # Note that we have to look the ticker id of each incoming message
36
+ # up in local memory to figure out what it's for.
37
+ ib.subscribe(IB::Messages::Incoming::HistoricalData) do |msg|
38
+ STDERR.puts @market[msg.data[:id]].description + ": " + msg.data[:count].to_s + " items:" unless Quiet
39
+
40
+ msg.data[:results].each do |datum|
41
+ @last_msg_time = Time.now.to_i
42
+
43
+ STDERR.puts " " + datum.to_s unless Quiet
44
+ #STDOUT.puts "#{datum.date},#{datum.open},#{datum.high},#{datum.low},#{datum.close},#{datum.volume}"
45
+ end
46
+ end
47
+
48
+ # Now we actually request historical data for the symbols we're interested in. TWS will
49
+ # respond with a HistoricalData message, which will be processed by the code above.
50
+ @market.each_pair do |id, contract|
51
+ ib.send IB::Messages::Outgoing::RequestHistoricalData.new(
52
+ :id => id,
53
+ :contract => contract,
54
+ :end_date_time => Time.now.to_ib,
55
+ :duration => '2 D', # ?
56
+ :bar_size => '1 min', #IB::OutgoingMessages::BAR_SIZES.key(:hour),
57
+ :what_to_show => :trades,
58
+ :use_rth => 1,
59
+ :format_date => 1)
60
+ end
61
+
62
+ sleep 5 # Wait for IB to respond to our request
@@ -1,77 +1,39 @@
1
- #!/usr/bin/env ruby -w
1
+ #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (C) 2009 Wes Devauld
4
- #
5
- # This library is free software; you can redistribute it and/or modify
6
- # it under the terms of the GNU Lesser General Public License as
7
- # published by the Free Software Foundation; either version 2.1 of the
8
- # License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful, but
11
- # WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
- # 02110-1301 USA
19
- #
20
-
21
- require File.expand_path(
22
- File.join(File.dirname(__FILE__), '..', 'lib', 'ib-ruby'))
3
+ # This script connects to IB API, and downloads historic data
4
+ # TODO: Fix the Historical command line client
23
5
 
24
6
  require 'rubygems'
25
7
  require 'time'
26
8
  require 'duration'
9
+ require 'pathname'
27
10
  require 'getopt/long'
11
+ require 'bundler/setup'
12
+
13
+ LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s
14
+ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
15
+
16
+ require 'ib-ruby'
28
17
 
29
18
  include Getopt
30
19
 
31
20
  opt = Getopt::Long.getopts(
32
- ["--help", BOOLEAN],
33
- ["--end", REQUIRED],
34
- ["--security", REQUIRED],
35
- ["--duration", REQUIRED],
36
- ["--barsize", REQUIRED],
37
- ["--header",BOOLEAN],
38
- ["--dateformat", REQUIRED],
39
- ["--nonregularhours", BOOLEAN],
40
- ["--verbose", BOOLEAN],
41
- ["--veryverbose", BOOLEAN]
21
+ ["--help", BOOLEAN],
22
+ ["--end", REQUIRED],
23
+ ["--security", REQUIRED],
24
+ ["--duration", REQUIRED],
25
+ ["--barsize", REQUIRED],
26
+ ["--header", BOOLEAN],
27
+ ["--dateformat", REQUIRED],
28
+ ["--nonregularhours", BOOLEAN],
29
+ ["--verbose", BOOLEAN],
30
+ ["--veryverbose", BOOLEAN]
42
31
  )
43
32
 
44
33
  if opt["help"] || opt["security"].nil? || opt["security"].empty?
45
34
  puts <<ENDHELP
46
35
 
47
- ** RequestHistoricData.rb - Copyright (C) 2007-8 Paul Legato.
48
-
49
- This library is free software; you can redistribute it and/or modify
50
- it under the terms of the GNU Lesser General Public License as
51
- published by the Free Software Foundation; either version 2.1 of the
52
- License, or (at your option) any later version.
53
-
54
- This library is distributed in the hope that it will be useful, but
55
- WITHOUT ANY WARRANTY; without even the implied warranty of
56
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
57
- Lesser General Public License for more details.
58
-
59
- You should have received a copy of the GNU Lesser General Public
60
- License along with this library; if not, write to the Free Software
61
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
62
- 02110-1301 USA
63
-
64
- The author and this software are not connected with Interactive
65
- Brokers in any way, nor do they endorse us.
66
-
67
- ************************************************************************************
68
-
69
- >> YOUR USE OF THIS PROGRAM IS ENTIRELY AT YOUR OWN RISK. <<
70
- >> IT MAY CONTAIN POTENTIALLY COSTLY BUGS, ERRORS, ETC., BOTH KNOWN AND UNKNOWN. <<
71
- >> DO NOT USE THIS SOFTWARE IF YOU ARE UNWILLING TO ACCEPT ALL RISK IN DOING SO. <<
72
-
73
- ************************************************************************************
74
-
36
+ ***
75
37
 
76
38
  This program requires a TWS running on localhost on the standard port
77
39
  that uses API protocol version 15 or higher. Any modern TWS should
@@ -153,7 +115,7 @@ Possible values (from the IB documentation):
153
115
  data in CSV format.
154
116
 
155
117
  ENDHELP
156
- #' <- fix broken syntax highlighting in Aquamacs
118
+
157
119
  exit
158
120
 
159
121
  end
@@ -169,11 +131,9 @@ if DURATION > 86400
169
131
  exit(1)
170
132
  end
171
133
 
172
-
173
134
  # This is the last time we want data for.
174
135
  END_DATE_TIME = (opt["end"] && eval(opt["end"]).to_ib) || Time.now.to_ib
175
136
 
176
-
177
137
  # This can be :trades, :midpoint, :bid, or :asked
178
138
  WHAT = (opt["what"] && opt["what"].to_sym) || :trades
179
139
 
@@ -223,16 +183,11 @@ VERBOSE = !opt["verbose"].nil?
223
183
  #
224
184
  # Note that as of 4/07 there is no historical data available for forex spot.
225
185
  #
226
- @market =
227
- {
228
- 123 => opt["security"]
229
- }
230
-
186
+ @market = {123 => opt["security"]}
231
187
 
232
188
  # First, connect to IB TWS.
233
189
  ib = IB::IB.new
234
190
 
235
-
236
191
  # Default level is quiet, only warnings printed.
237
192
  # IB::IBLogger.level = Logger::Severity::ERROR
238
193
 
@@ -256,35 +211,35 @@ lastMessageTime = Queue.new # for communicating with the reader thread.
256
211
  # up in local memory to figure out what security it relates to.
257
212
  # The incoming message packet from TWS just identifies it by ticker id.
258
213
  #
259
- ib.subscribe(IB::IncomingMessages::HistoricalData, lambda {|msg|
260
- STDERR.puts @market[msg.data[:req_id]].description + ": " + msg.data[:item_count].to_s("F") + " items:" if VERBOSE
261
-
262
- msg.data[:history].each { |datum|
263
- puts(if VERBOSE
264
- datum.to_s
265
- else
266
- "#{datum.date},#{datum.open.to_s("F")},#{datum.high.to_s("F")},#{datum.low.to_s("F")}," +
267
- "#{datum.close.to_s("F")},#{datum.volume},#{datum.wap.to_s("F")},#{datum.has_gaps}"
268
- end
269
- )
270
- }
271
- lastMessageTime.push(Time.now)
272
- })
214
+ ib.subscribe(IB::IncomingMessages::HistoricalData, lambda { |msg|
215
+ STDERR.puts @market[msg.data[:req_id]].description + ": " + msg.data[:item_count].to_s("F") + " items:" if VERBOSE
216
+
217
+ msg.data[:history].each { |datum|
218
+ puts(if VERBOSE
219
+ datum.to_s
220
+ else
221
+ "#{datum.date},#{datum.open.to_s("F")},#{datum.high.to_s("F")},#{datum.low.to_s("F")}," +
222
+ "#{datum.close.to_s("F")},#{datum.volume},#{datum.wap.to_s("F")},#{datum.has_gaps}"
223
+ end
224
+ )
225
+ }
226
+ lastMessageTime.push(Time.now)
227
+ })
273
228
 
274
229
  # Now we actually request historical data for the symbols we're
275
230
  # interested in. TWS will respond with a HistoricalData message,
276
231
  # which will be received by the code above.
277
232
 
278
- @market.each_pair {|id, contract|
233
+ @market.each_pair { |id, contract|
279
234
  msg = IB::OutgoingMessages::RequestHistoricalData.new({
280
- :ticker_id => id,
281
- :contract => contract,
282
- :end_date_time => END_DATE_TIME,
283
- :duration => DURATION, # seconds == 1 hour
284
- :bar_size => BAR_SIZE, # 1 minute bars
285
- :what_to_show => WHAT,
286
- :use_RTH => REGULAR_HOURS_ONLY,
287
- :format_date => DATE_FORMAT
235
+ :ticker_id => id,
236
+ :contract => contract,
237
+ :end_date_time => END_DATE_TIME,
238
+ :duration => DURATION, # seconds == 1 hour
239
+ :bar_size => BAR_SIZE, # 1 minute bars
240
+ :what_to_show => WHAT,
241
+ :use_RTH => REGULAR_HOURS_ONLY,
242
+ :format_date => DATE_FORMAT
288
243
  })
289
244
  ib.dispatch(msg)
290
245
  }
data/bin/market_data ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This script connects to IB API and subscribes to market data for specific symbols
4
+
5
+ require 'pathname'
6
+ LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s
7
+ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
8
+
9
+ require 'rubygems'
10
+ require 'bundler/setup'
11
+ require 'ib-ruby'
12
+
13
+ # Definition of what we want market data for. We have to keep track of what ticker id
14
+ # corresponds to what symbol ourselves, because the ticks don't include any other
15
+ # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
16
+ @market = {123 => IB::Symbols::Forex[:gbpusd],
17
+ 456 => IB::Symbols::Forex[:eurusd],
18
+ 789 => IB::Symbols::Forex[:usdcad]}
19
+
20
+ # First, connect to IB TWS.
21
+ ib = IB::Connection.new
22
+
23
+ ## Subscribe to TWS alerts/errors
24
+ ib.subscribe(:Alert) { |msg| puts msg.to_human }
25
+
26
+ # Subscribe to TickerPrice and TickerSize events. The code passed in the block will
27
+ # be executed when a message of that type is received, with the received message as its
28
+ # argument. In this case, we just print out the tick.
29
+ #
30
+ # Note that we have to look the ticker id of each incoming message
31
+ # up in local memory to figure out what it's for.
32
+ #
33
+ # (N.B. The description field is not from IB TWS. It is defined
34
+ # locally in forex.rb, and is just arbitrary text.)
35
+ ib.subscribe(:TickPrice, :TickSize) do |msg|
36
+ puts @market[msg.data[:id]].description + ": " + msg.to_human
37
+ end
38
+
39
+ # Now we actually request market data for the symbols we're interested in.
40
+ @market.each_pair do |id, contract|
41
+ ib.send :RequestMarketData, :id => id, :contract => contract
42
+ end
43
+
44
+ puts "\nSubscribed to market data"
45
+ puts "\n******** Press <Enter> to cancel... *********\n\n"
46
+ gets
47
+ puts "Cancelling market data subscription.."
48
+
49
+ @market.each_pair { |id, _| ib.send :CancelMarketData, :id => id }
data/bin/option_data ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This script connects to IB API and subscribes to market data for specific symbols
4
+
5
+ require 'pathname'
6
+ LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s
7
+ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
8
+
9
+ require 'rubygems'
10
+ require 'bundler/setup'
11
+ require 'ib-ruby'
12
+
13
+ # Definition of what we want market data for. We have to keep track of what ticker id
14
+ # corresponds to what symbol ourselves, because the ticks don't include any other
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]}
18
+
19
+ # First, connect to IB TWS.
20
+ ib = IB::Connection.new
21
+
22
+ ## Subscribe to TWS alerts/errors
23
+ ib.subscribe(:Alert) { |msg| puts msg.to_human }
24
+
25
+ # Subscribe to Ticker... events. The code passed in the block will be executed when
26
+ # any message of that type is received, with the received message as its argument.
27
+ # In this case, we just print out the tick.
28
+ #
29
+ # (N.B. The description field is not from IB TWS. It is defined
30
+ # locally in forex.rb, and is just arbitrary text.)
31
+ ib.subscribe(:TickPrice, :TickSize, :TickOption) do |msg|
32
+ puts @market[msg.data[:id]].description + ": " + msg.to_human
33
+ end
34
+
35
+ # Now we actually request market data for the symbols we're interested in.
36
+ @market.each_pair do |id, contract|
37
+ ib.send :RequestMarketData, :id => id, :contract => contract
38
+ end
39
+
40
+ puts "\nSubscribed to market data"
41
+ puts "\n******** Press <Enter> to cancel... *********\n\n"
42
+ gets
43
+ puts "Cancelling market data subscription.."
44
+
45
+ @market.each_pair { |id, contract| ib.send :CancelMarketData, :id => id }
data/bin/template ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Your script description here...
4
+
5
+ require 'pathname'
6
+ LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s
7
+ $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR)
8
+
9
+ require 'rubygems'
10
+ require 'bundler/setup'
11
+ require 'ib-ruby'
12
+
13
+ # Connect to IB TWS.
14
+ ib = IB::Connection.new
15
+
16
+ # Subscribe to TWS alerts/errors
17
+ ib.subscribe(IB::Messages::Incoming::Alert) { |msg| puts msg.to_human }
18
+
19
+ # Put your code here
20
+ # ...
21
+