#!/usr/bin/env ruby # # This script downloads historic data for specific symbols from IB require 'pathname' LIB_DIR = (Pathname.new(__FILE__).dirname + '../lib/').realpath.to_s $LOAD_PATH.unshift LIB_DIR unless $LOAD_PATH.include?(LIB_DIR) require 'rubygems' require 'bundler/setup' require 'ib-ruby' # Definition of what we want data for. We have to keep track of what ticker id # corresponds to what symbol ourselves, because the ticks don't include any other # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary. @market = {123 => IB::Symbols::Stocks[:wfc], 456 => IB::Symbols::Futures[:ym], 789 => IB::Symbols::Forex[:gbpusd] # No historical data for GBP/CASH@IDEALPRO } # Connect to IB TWS. ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS # Subscribe to TWS alerts/errors ib.subscribe(:Alert) { |msg| puts msg.to_human } # Subscribe to HistoricalData incoming events. The code passed in the block # will be executed when a message of that type is received, with the received # message as its argument. In this case, we just print out the data. # # Note that we have to look the ticker id of each incoming message # up in local memory to figure out what it's for. ib.subscribe(IB::Messages::Incoming::HistoricalData) do |msg| puts @market[msg.request_id].description + ": #{msg.count} items:" msg.results.each { |entry| puts " #{entry}" } @last_msg_time = Time.now.to_i end # Now we actually request historical data for the symbols we're interested in. TWS will # respond with a HistoricalData message, which will be processed by the code above. @market.each_pair do |id, contract| ib.send_message IB::Messages::Outgoing::RequestHistoricalData.new( :request_id => id, :contract => contract, :end_date_time => Time.now.to_ib, :duration => '2 D', # ? :bar_size => '1 min', # IB::BAR_SIZES.key(:hour)? :what_to_show => :trades, :use_rth => 1, :format_date => 1) end # Wait for IB to respond to our request sleep 0.1 until @last_msg_time && @last_msg_time < Time.now.to_i + 0.5