To use the End of Data Historical Data feature, include the ib-extensions Gem in the Gemfile and use
 
require 'ib-api' 
require 'ib/eod'  # or require 'ib-extensions'
in your scripts.

Historical Data

The historical data feature of the TWS is invoked by sending a :RequestHistoricalData-Message.
Next the script has to listen for a :HistoricalData-Response.

The IB::Contract.eod-method bundles the nesseary steps to get End of Day-Data for specified date ranges.

  • contract.eod( duration: '10 d' ) gets closing price of the last 10 trading days.
  • contract.eod( duration: '10 w', start: Date.new(2019,3,14) what: :historical_volatility ) gets the histrorical volatility for the 10 weeks starting on March 14th 2019.

IB::Contract.eod start: {a date}, to: {a date; Default: Date.today},
                 duration: {string  or integer},
                 what: {symbol; Default: :trades }

The duration can either be specified as Sting “ yx D”, “ yx W”, “yx M” , “xy Y” or as Integer. If the string-notation is used, ensure to include a space.

The parameter :what specifies the kind of received data.

Valid values:

  • :trades, :midpoint, :bid, :ask, :bid_ask,
  • :historical_volatility, :option_implied_volatility,
  • :option_volume, :option_open_interest

IB::Contract.eod returns an array of IB::Bar objects unless they are preprocessed in a block.

Examples

  • Retrieve close prices of the last ten days.
IB::Symbols.Index.estx.eod( duration: '10 d' ){ |r| r.close  }
  • Get price-ranges of the last ten days.
IB::Symbols.Index.estx.eod( duration: '10 d' ){ |r| r.high - r.low  }
  • Get close prices for General Electric between Jun 15 and Jun 21 2015
 IB::Stock.new( symbol: 'GE' ).
           eod( start: Date.new(2015,6,15), to: Date.new(2015,6,21) ).
           map( &:close ).
           join( " : " )
 => "26.19 : 26.17 : 26.24 : 26.18"
  • Get Overnight Gaps for the stock
 yesterdays_close = nil
 IB::Stock.new( symbol: 'GE').
           eod( start: Date.new(2010,6,15), duration: 10 ) do |r|
                  z= if  yesterdays_close.nil? 
                         0
                     else 
                         (yesterdays_close - r.open).abs
                     end
                  yesterdays_close = r.close 
                  z        #   return value 
          end.join( " : " )
=> "0 : 0.08 : 0.02 : 0.0 : 0.01 : 0.03 : 0.03 : 0.1 : 0.04 : 0.03" 

We save the close of each day in yesterdays_close and pass it to the next iteration. yesterdays_close has to be declared outside of the block!

  • Get the daily median of Implied Volatilities
 ge = IB::Stock.new symbol: :ge
 ge.eod( duration: 10, what: :option_implied_volatility){|x| (x.high + x.low)/2 }.round 3
=> [0.434, 0.425, 0.437, 0.442, 0.441, 0.436, 0.491, 0.491, 0.491, 0.494] 

  • Save historical data as csv file
 # reopen IB::Contrct and add to_csv method
 module IB
   class Contract 
     def to_csv file:nil
       file ||=  "#{symbol}.csv"
       if bars.present?
         headers = bars.first.invariant_attributes.keys
         CSV.open( file, 'w'  ) {|f| f << headers ; bars.each {|y| f << y.invariant_attributes.values } }
      end
    end
  end
 end

 ge = IB::Stock.new( symbol: :ge  )
 ge.eod( duration: '200 D' )
 ge.to_csv         # writes ohlc-data to ge.csv

Tags: