ib-ruby 0.4.3 → 0.4.20

Sign up to get free protection for your applications and to get access to all the features.
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
+