ib-ruby 0.8.4 → 0.8.5

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