ib-ruby 0.8.4 → 0.8.5

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 (118) hide show
  1. data/.gitignore +3 -0
  2. data/HISTORY +3 -0
  3. data/README.md +29 -9
  4. data/VERSION +1 -1
  5. data/app/assets/javascripts/ib/bars.js +2 -0
  6. data/app/assets/javascripts/ib/executions.js +2 -0
  7. data/app/assets/javascripts/ib/order_states.js +2 -0
  8. data/app/assets/stylesheets/ib/bars.css +4 -0
  9. data/app/assets/stylesheets/ib/executions.css +4 -0
  10. data/app/assets/stylesheets/ib/order_states.css +4 -0
  11. data/app/controllers/ib/bars_controller.rb +87 -0
  12. data/app/controllers/ib/combo_legs_controller.rb +87 -0
  13. data/app/controllers/ib/contract_details_controller.rb +87 -0
  14. data/app/controllers/ib/contracts_controller.rb +87 -0
  15. data/app/controllers/ib/executions_controller.rb +87 -0
  16. data/app/controllers/ib/order_states_controller.rb +87 -0
  17. data/app/controllers/ib/orders_controller.rb +87 -0
  18. data/app/helpers/ib/bars_helper.rb +4 -0
  19. data/app/helpers/ib/combo_legs_helper.rb +4 -0
  20. data/app/helpers/ib/contract_details_helper.rb +4 -0
  21. data/app/helpers/ib/contracts_helper.rb +4 -0
  22. data/app/helpers/ib/executions_helper.rb +4 -0
  23. data/app/helpers/ib/order_states_helper.rb +4 -0
  24. data/app/helpers/ib/orders_helper.rb +4 -0
  25. data/app/views/ib/bars/_form.html.erb +57 -0
  26. data/app/views/ib/bars/edit.html.erb +6 -0
  27. data/app/views/ib/bars/index.html.erb +41 -0
  28. data/app/views/ib/bars/new.html.erb +5 -0
  29. data/app/views/ib/bars/show.html.erb +55 -0
  30. data/app/views/ib/combo_legs/_form.html.erb +53 -0
  31. data/app/views/ib/combo_legs/edit.html.erb +6 -0
  32. data/app/views/ib/combo_legs/index.html.erb +39 -0
  33. data/app/views/ib/combo_legs/new.html.erb +5 -0
  34. data/app/views/ib/combo_legs/show.html.erb +55 -0
  35. data/app/views/ib/contract_details/_form.html.erb +141 -0
  36. data/app/views/ib/contract_details/edit.html.erb +6 -0
  37. data/app/views/ib/contract_details/index.html.erb +83 -0
  38. data/app/views/ib/contract_details/new.html.erb +5 -0
  39. data/app/views/ib/contract_details/show.html.erb +160 -0
  40. data/app/views/ib/contracts/_form.html.erb +77 -0
  41. data/app/views/ib/contracts/edit.html.erb +6 -0
  42. data/app/views/ib/contracts/index.html.erb +53 -0
  43. data/app/views/ib/contracts/new.html.erb +5 -0
  44. data/app/views/ib/contracts/show.html.erb +85 -0
  45. data/app/views/ib/executions/_form.html.erb +77 -0
  46. data/app/views/ib/executions/edit.html.erb +6 -0
  47. data/app/views/ib/executions/index.html.erb +51 -0
  48. data/app/views/ib/executions/new.html.erb +5 -0
  49. data/app/views/ib/executions/show.html.erb +80 -0
  50. data/app/views/ib/order_states/_form.html.erb +93 -0
  51. data/app/views/ib/order_states/edit.html.erb +6 -0
  52. data/app/views/ib/order_states/index.html.erb +59 -0
  53. data/app/views/ib/order_states/new.html.erb +5 -0
  54. data/app/views/ib/order_states/show.html.erb +100 -0
  55. data/app/views/ib/orders/_form.html.erb +353 -0
  56. data/app/views/ib/orders/edit.html.erb +6 -0
  57. data/app/views/ib/orders/index.html.erb +193 -0
  58. data/app/views/ib/orders/new.html.erb +5 -0
  59. data/app/views/ib/orders/show.html.erb +435 -0
  60. data/bin/scaffold.rb +29 -0
  61. data/config/routes.rb +8 -1
  62. data/db/config.yml +5 -0
  63. data/db/migrate/101_add_ib_executions.rb +3 -0
  64. data/db/migrate/111_add_ib_bars.rb +6 -0
  65. data/db/migrate/121_add_ib_order_states.rb +8 -0
  66. data/db/migrate/131_add_ib_orders.rb +24 -0
  67. data/db/migrate/141_add_ib_combo_legs.rb +6 -0
  68. data/db/migrate/151_add_ib_underlyings.rb +3 -0
  69. data/db/migrate/161_add_ib_contract_details.rb +11 -0
  70. data/db/migrate/171_add_ib_contracts.rb +8 -1
  71. data/db/schema.rb +6 -5
  72. data/lib/ib/base.rb +3 -1
  73. data/lib/ib/base_properties.rb +26 -15
  74. data/lib/ib/connection.rb +3 -2
  75. data/lib/ib/errors.rb +16 -9
  76. data/lib/ib/extensions.rb +6 -4
  77. data/lib/ib/symbols.rb +10 -3
  78. data/lib/ib/symbols/forex.rb +49 -64
  79. data/lib/ib/symbols/futures.rb +2 -3
  80. data/lib/ib/symbols/options.rb +2 -1
  81. data/lib/ib/symbols/stocks.rb +2 -1
  82. data/lib/models/ib/bar.rb +6 -2
  83. data/lib/models/ib/combo_leg.rb +4 -3
  84. data/lib/models/ib/contract.rb +9 -5
  85. data/lib/models/ib/contract_detail.rb +1 -1
  86. data/lib/models/ib/execution.rb +3 -1
  87. data/lib/models/ib/order.rb +22 -20
  88. data/lib/models/ib/order_state.rb +4 -2
  89. data/lib/models/ib/underlying.rb +3 -4
  90. data/spec/README.md +12 -10
  91. data/spec/ib/symbols/symbols_spec.rb +10 -0
  92. data/spec/integration_helper.rb +1 -1
  93. data/spec/model_helper.rb +9 -8
  94. data/spec/models/ib/combo_leg_spec.rb +29 -28
  95. data/spec/models/ib/contract_detail_spec.rb +4 -1
  96. data/spec/models/ib/contract_spec.rb +66 -58
  97. data/spec/models/ib/execution_spec.rb +50 -44
  98. data/spec/models/ib/order_spec.rb +2 -2
  99. data/spec/order_helper.rb +5 -4
  100. data/spec/spec_helper.rb +3 -3
  101. metadata +59 -35
  102. data/app/models/ib/underlying.rb +0 -5
  103. data/bin/account_info +0 -29
  104. data/bin/cancel_orders +0 -27
  105. data/bin/contract_details +0 -35
  106. data/bin/depth_of_market +0 -43
  107. data/bin/fa_accounts +0 -22
  108. data/bin/fundamental_data +0 -39
  109. data/bin/historic_data +0 -51
  110. data/bin/historic_data_cli +0 -182
  111. data/bin/list_orders +0 -28
  112. data/bin/market_data +0 -41
  113. data/bin/option_data +0 -44
  114. data/bin/place_combo_order +0 -58
  115. data/bin/place_order +0 -27
  116. data/bin/template +0 -18
  117. data/bin/tick_data +0 -26
  118. data/bin/time_and_sales +0 -53
@@ -1,5 +0,0 @@
1
- module Ib
2
- class Underlying < ActiveRecord::Base
3
- attr_accessible :con_id, :contract_id, :delta, :price
4
- end
5
- end
@@ -1,29 +0,0 @@
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 'rubygems'
7
- require 'bundler/setup'
8
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
9
- require 'ib-ruby'
10
-
11
- # First, connect to IB TWS.
12
- ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
13
-
14
- # Set log level
15
- log.level = Logger::FATAL
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_message :RequestAccountData, :subscribe => true
23
-
24
- puts "\nSubscribing to IB account data"
25
- puts "\n******** Press <Enter> to cancel... *********\n\n"
26
- STDIN.gets
27
- puts "Cancelling account data subscription.."
28
-
29
- ib.send_message :RequestAccountData, :subscribe => false
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This script allows you to cancel either a set of open Orders by their ids,
4
- # or ALL Orders opened via IB API at once. The latter is useful when your
5
- # robot goes crazy and opens gazillions of wrong limit orders.
6
-
7
- require 'rubygems'
8
- require 'bundler/setup'
9
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
10
- require 'ib-ruby'
11
-
12
- # First, connect to IB TWS.
13
- ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
14
-
15
- # Subscribe to TWS alerts/errors and order-related messages
16
- ib.subscribe(:Alert, :OpenOrder, :OrderStatus, :OpenOrderEnd) { |msg| puts msg.to_human }
17
-
18
- if ARGV.empty?
19
- ib.send_message :RequestGlobalCancel
20
- else
21
- # Will only work for Orders placed under the same :client_id
22
- ib.cancel_order *ARGV
23
- end
24
-
25
- ib.send_message :RequestAllOpenOrders
26
-
27
- sleep 3
@@ -1,35 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This script gets details for specific contract from IB
4
-
5
- require 'rubygems'
6
- require 'bundler/setup'
7
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
8
- require 'ib-ruby'
9
-
10
- # Definition of what we want market data for. We have to keep track of what ticker id
11
- # corresponds to what symbol ourselves, because the ticks don't include any other
12
- # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
13
- @market = {122 => IB::Symbols::Stocks[:wfc],
14
- 133 => IB::Symbols::Options[:wfc20],
15
- 144 => IB::Symbols::Stocks[:wrong]}
16
-
17
- # Connect to IB TWS.
18
- ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
19
-
20
- # Subscribe to TWS alerts/errors
21
- ib.subscribe(IB::Messages::Incoming::Alert) { |msg| puts msg.to_human }
22
-
23
- # Now, subscribe to ContractData incoming events. The code passed in the block
24
- # will be executed when a message of that type is received, with the received
25
- # message as its argument. In this case, we just print out the data.
26
- ib.subscribe(:ContractData) { |msg| puts msg.contract.inspect }
27
-
28
- # Now we actually request Contract details for the symbols we're interested in. TWS will
29
- # respond with ContractData messages, which will be processed by the code above.
30
- @market.each_pair do |id, contract|
31
- ib.send_message :RequestContractData, :id => id, :contract => contract
32
- end
33
-
34
- # Wait for IB to respond to our request
35
- ib.wait_for :ContractDataEnd
@@ -1,43 +0,0 @@
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 'rubygems'
7
- require 'bundler/setup'
8
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
9
- require 'ib-ruby'
10
-
11
- # Definition of what we want L2 data for. We have to keep track of what ticker id
12
- # corresponds to what symbol ourselves, because the ticks don't include any other
13
- # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
14
- @market = {123 => IB::Symbols::Stocks[:wfc],
15
- 456 => IB::Symbols::Futures[:es],
16
- 789 => IB::Symbols::Forex[:gbpusd]
17
- }
18
-
19
- # First, connect to IB TWS.
20
- ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
21
-
22
- # Subscribe to TWS alerts/errors
23
- ib.subscribe(:Alert) { |msg| puts msg.to_human }
24
-
25
- # Subscribe to MarketDepth events.
26
- ib.subscribe(:MarketDepth) do |msg|
27
- puts @market[msg.request_id].description + ": " + msg.to_human
28
- end
29
-
30
- # Now we actually request L2 market data for the symbols we're interested in.
31
- @market.each_pair do |id, contract|
32
- ib.send_message :RequestMarketDepth,
33
- :id => id,
34
- :contract => contract,
35
- :num_rows => 5
36
- end
37
-
38
- puts "\nSubscribed to market data"
39
- puts "\n******** Press <Enter> to cancel... *********\n\n"
40
- STDIN.gets
41
- puts "Cancelling market data subscription.."
42
-
43
- @market.each_pair { |id, contract| ib.send_message :CancelMarketDepth, :id => id }
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This script receives Financial Adviser and Managed Accounts info
4
-
5
- require 'rubygems'
6
- require 'bundler/setup'
7
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
8
- require 'ib-ruby'
9
-
10
- # First, connect to IB TWS.
11
- ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
12
-
13
- # Subscribe to TWS alerts/errors and FA/managed account info
14
- ib.subscribe(:Alert, :ManagedAccounts, :ReceiveFA) { |msg| puts msg.to_human }
15
-
16
- ib.send_message :RequestFA
17
- ib.send_message :RequestManagedAccounts
18
-
19
- ib.wait_for :Alert
20
-
21
- puts "\n******** Press <Enter> to cancel... *********\n\n"
22
- STDIN.gets
@@ -1,39 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This script downloads Fundamental data for specific symbols from IB
4
- # This only works IF you have Reuters data subscription!
5
-
6
- require 'rubygems'
7
- require 'bundler/setup'
8
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
9
-
10
- require 'ib-ruby'
11
- require 'xmlsimple'
12
- require 'pp'
13
-
14
-
15
- ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
16
-
17
- ib.subscribe(:Alert) { |msg| puts msg.to_human }
18
-
19
- # Fundamental Data will arrive as XML, parse it
20
- ib.subscribe(:FundamentalData) { |msg| @xml = XmlSimple.xml_in(msg.data) }
21
-
22
- ibm = IB::Contract.new :symbol => 'IBM',
23
- :exchange => 'NYSE',
24
- :currency => 'USD',
25
- :sec_type => 'STK'
26
-
27
- # Request Fundamental Data for IBM. Possible report types:
28
- # 'estimates' - Estimates
29
- # 'finstat' - Financial statements
30
- # 'snapshot' - Summary
31
- ib.send_message :RequestFundamentalData,
32
- :id => 10,
33
- :contract => ibm,
34
- :report_type => 'snapshot'
35
-
36
- # Needs some time to receive and parse XML. Standard timeout of 1 sec is just too low.
37
- ib.wait_for(30) { @xml}
38
-
39
- pp @xml
@@ -1,51 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This script downloads historic data for specific symbols from IB
4
-
5
- require 'rubygems'
6
- require 'bundler/setup'
7
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
8
- require 'ib-ruby'
9
-
10
- # Definition of what we want data for. We have to keep track of what ticker id
11
- # corresponds to what symbol ourselves, because the ticks don't include any other
12
- # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
13
- @market = {123 => IB::Symbols::Stocks[:wfc],
14
- 456 => IB::Symbols::Futures[:ym],
15
- 789 => IB::Symbols::Forex[:gbpusd] # No historical data for GBP/CASH@IDEALPRO
16
- }
17
-
18
- # Connect to IB TWS.
19
- ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
20
-
21
- # Subscribe to TWS alerts/errors
22
- ib.subscribe(:Alert) { |msg| puts msg.to_human }
23
-
24
- # Subscribe to HistoricalData incoming events. The code passed in the block
25
- # will be executed when a message of that type is received, with the received
26
- # message as its argument. In this case, we just print out the data.
27
- #
28
- # Note that we have to look the ticker id of each incoming message
29
- # up in local memory to figure out what it's for.
30
- ib.subscribe(IB::Messages::Incoming::HistoricalData) do |msg|
31
- puts @market[msg.request_id].description + ": #{msg.count} items:"
32
- msg.results.each { |entry| puts " #{entry}" }
33
- @last_msg_time = Time.now.to_i
34
- end
35
-
36
- # Now we actually request historical data for the symbols we're interested in. TWS will
37
- # respond with a HistoricalData message, which will be processed by the code above.
38
- @market.each_pair do |id, contract|
39
- ib.send_message IB::Messages::Outgoing::RequestHistoricalData.new(
40
- :request_id => id,
41
- :contract => contract,
42
- :end_date_time => Time.now.to_ib,
43
- :duration => '2 D', # ?
44
- :bar_size => '1 min', # IB::BAR_SIZES.key(:hour)?
45
- :what_to_show => :trades,
46
- :use_rth => 1,
47
- :format_date => 1)
48
- end
49
-
50
- # Wait for IB to respond to our request
51
- sleep 0.1 until @last_msg_time && @last_msg_time < Time.now.to_i + 0.5
@@ -1,182 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # This script connects to IB API, and downloads historic data
3
-
4
- require 'rubygems'
5
- require 'time'
6
- require 'getopt/long'
7
- require 'bundler/setup'
8
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
9
- require 'ib-ruby'
10
-
11
- include Getopt
12
-
13
- opt = Getopt::Long.getopts(
14
- ["--help", BOOLEAN],
15
- ["--end", REQUIRED],
16
- ["--port", REQUIRED],
17
- ["--security", REQUIRED],
18
- ["--duration", REQUIRED],
19
- ["--barsize", REQUIRED],
20
- ["--csv", BOOLEAN],
21
- ["--dateformat", REQUIRED],
22
- ["--nonregularhours", BOOLEAN]
23
- )
24
-
25
- if opt["help"] || opt["security"].nil? || opt["security"].empty?
26
- puts <<ENDHELP
27
-
28
- This program requires a TWS or Gateway running on localhost.
29
-
30
- ----------
31
-
32
- One argument is required: --security, the security specification you want, in
33
- "long serialized IB-Ruby" format. This is a colon-separated string of the format:
34
-
35
- symbol:security_type:expiry:strike:right:multiplier:exchange:primary_exchange:currency:local_symbol
36
-
37
- Fields not needed for a particular security should be left blank (e.g. strike and right are only relevant for options.)
38
-
39
- For example, to query the Apple 500 Strike Call expiring in January 2013, use:
40
-
41
- $ historic_data_cli --security AAPL:OPT:201301:500:CALL::SMART::USD:
42
-
43
- Consult contract.rb for allowed values, and see also the examples in the symbols/ directory
44
- (load them in irb and run security#serialize_ib_ruby to see the appropriate string.)
45
-
46
- ----------
47
-
48
- Options:
49
-
50
- --end is is the last time we want data for. The default is now.
51
- This is eval'ed by Ruby, so you can use a Ruby expression, which must return a Time object.
52
-
53
- --duration is time period before --end, in seconds. The default is 86400 sec (1 day).
54
- TWS imposes limit of 86400 sec (1 day) worth of historic data per request.
55
-
56
- --what determines what the data will be comprised of. This can be
57
- "trades", "midpoint", "bid", or "ask". The default is "trades".
58
-
59
- --barsize determines how long each bar will be.
60
-
61
- Possible bar values (from the IB documentation):
62
- Values less than 30 sec do not appear to work for some securities.
63
-
64
- sec1 = 1 sec
65
- sec5 = 5 sec
66
- sec15 = 15 sec
67
- sec30 = 30 sec
68
- min1 = 1 minute
69
- min2 = 2 minutes
70
- min5 = 5 minutes
71
- min15 = 15 minutes (default)
72
- min30 = 30 minutes
73
- hour1 = 1 hour
74
- day1 = 1 day
75
-
76
- --nonregularhours : Normally, only data from the instrument's regular trading
77
- hours is returned. If --nonregularhours is given, all data available during the time
78
- span requested is returned, even for time intervals when the market was illiquid.
79
-
80
- --dateformat : 1 (default) human-readable time/date format, like "20050307 11:32:16".
81
- If you set it to 2 instead, you will get UNIX epoch offsets (seconds since Jan 1, 1970).
82
-
83
- --csv : print out the historic data in CSV format, with header.
84
-
85
- --port : 4001 for Gateway (default), 7496 for TWS, or your custom port
86
-
87
- ENDHELP
88
- exit
89
- end
90
-
91
- ### Parameters
92
-
93
- # DURATION is how much historic data we want, in seconds, before END_DATE_TIME.
94
- DURATION = (opt["duration"] && opt["duration"].to_i) || 86400
95
-
96
- if DURATION > 86400
97
- STDERR.puts("\nTWS rejects --duration longer than 86400 seconds (1 day).\n")
98
- exit(1)
99
- end
100
-
101
- # This is the last time we want data for.
102
- END_DATE_TIME = (opt["end"] && eval(opt["end"]).to_ib) || Time.now.to_ib
103
-
104
- # This can be :trades, :midpoint, :bid, or :asked
105
- WHAT = (opt["what"] && opt["what"].to_sym) || :trades
106
-
107
-
108
- # Values less than 4 do not appear to actually work; they are rejected by the server.
109
- #
110
- BAR_SIZE = (opt["barsize"] && opt["barsize"].to_sym) || :min15
111
-
112
- # If REGULAR_HOURS_ONLY is set to 0, all data available during the time
113
- # span requested is returned, even data bars covering time
114
- # intervals where the market in question was illiquid. If useRTH
115
- # has a non-zero value, only data within the "Regular Trading
116
- # Hours" of the product in question is returned, even if the time
117
- # span requested falls partially or completely outside of them.
118
-
119
- REGULAR_HOURS_ONLY = opt["nonregularhours"] ? 0 : 1
120
-
121
- # Using a DATE_FORMAT of 1 will cause the dates in the returned
122
- # messages with the historic data to be in a text format, like
123
- # "20050307 11:32:16". If you set :format_date to 2 instead, you
124
- # will get an offset in seconds from the beginning of 1970, which
125
- # is the same format as the UNIX epoch time.
126
-
127
- DATE_FORMAT = (opt["dateformat"] && opt["dateformat"].to_i) || 1
128
-
129
- PORT = (opt["port"] && opt["port"]) || '4001'
130
-
131
- # First, connect to IB TWS.
132
- ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
133
-
134
- # Subscribe to TWS alerts/errors
135
- ib.subscribe(:Alert) { |msg| puts msg.to_human }
136
-
137
- lastMessageTime = Queue.new # for communicating with the reader thread.
138
-
139
- # Subscribe to incoming HistoricalData events. The code passed in the
140
- # block will be executed when a message of the subscribed type is
141
- # received, with the received message as its argument. In this case,
142
- # we just print out the data.
143
- #
144
- # Note that we have to look the ticker id of each incoming message
145
- # up in local memory to figure out what security it relates to.
146
- # The incoming message packet from TWS just identifies it by ticker id.
147
- #
148
- ib.subscribe(:HistoricalData) do |msg|
149
- if opt["csv"]
150
- puts "date,time,open,high,low,close,volume,wap,has_gaps"
151
- msg.results.each do |datum|
152
- puts "#{datum.time},#{datum.open},#{datum.high},#{datum.low}," +
153
- "#{datum.close},#{datum.volume},#{datum.wap},#{datum.has_gaps}"
154
- end
155
- else
156
- STDERR.puts "Received #{msg.count} items:"
157
- msg.results.each { |datum| puts datum.to_s }
158
- end
159
- lastMessageTime.push(Time.now)
160
- end
161
-
162
- # Now we actually request historical data for the symbols we're
163
- # interested in. TWS will respond with a HistoricalData message,
164
- # which will be received by the code above.
165
- ib.send_message :RequestHistoricalData,
166
- :request_id => 123,
167
- :contract => opt["security"],
168
- :end_date_time => END_DATE_TIME,
169
- :duration => DURATION, # seconds == 1 hour
170
- :bar_size => BAR_SIZE, # 1 minute bars
171
- :what_to_show => WHAT,
172
- :use_RTH => REGULAR_HOURS_ONLY,
173
- :format_date => DATE_FORMAT
174
-
175
- # A complication here is that IB does not send any indication when all historic data is done being delivered.
176
- # So we have to guess - when there is no more new data for some period, we interpret that as "end of data" and exit.
177
- while true
178
- lastTime = lastMessageTime.pop # blocks until a message is ready on the queue
179
- sleep 2 # .. wait ..
180
- exit if lastMessageTime.empty? # if still no more messages after 2 more seconds, exit.
181
- end
182
-
@@ -1,28 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This script retrieves list of all Orders from TWS
4
-
5
- require 'rubygems'
6
- require 'bundler/setup'
7
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
8
- require 'ib-ruby'
9
-
10
- # Connect to IB as 0 (TWS) to retrieve all Orders, including TWS-generated ones
11
- ib = IB::Connection.new :client_id => 0 #, :port => 7496 # TWS
12
-
13
- # Subscribe to TWS alerts/errors and order-related messages
14
- @counter = 0
15
-
16
- ib.subscribe(:Alert, :OrderStatus, :OpenOrderEnd) { |msg| puts msg.to_human }
17
-
18
- ib.subscribe(:OpenOrder) do |msg|
19
- @counter += 1
20
- puts "#{@counter}: #{msg.to_human}"
21
- #pp msg.order
22
- end
23
-
24
- ib.send_message :RequestAllOpenOrders
25
-
26
- # Wait for IB to respond to our request
27
- ib.wait_for :OpenOrderEnd
28
- sleep 1 # Let printer do the job