Wednesday, March 26, 2014

F#: Capture real time bars from InteractiveBrokers

Let's continue our journey of capturing data from InteractiveBrokers. In this blog, we discuss how to capture real time bars. A bar here means a summary of prices over the last 5-second interval. Currently you can choose one of the following 4 types of prices that occurred in the interval to generate bars:

  • TRADES: actual trade prices;
  • BID: bid prices;
  • ASK: ask prices;
  • MIDPOINT: mid prices.

For the type of prices you chose, the information in a bar includes OHLC (open-high-low-close), volume, WAP (weighted average price), and count (the number of trades that occurred, which is applicable to TRADES only). Compared to ad hoc data like tick prices or market depth, real time bars are sent over to you on a regular basis -- you receive an update every 5 seconds.
The code example here is to capture real time bars on TRADES. As in the previous two blog posts, the first thing we need to do is to specify the stock we are interested in. Again, here I chose Infosys listed in Mumbai.

        let contract = tws1.createContract()
        contract.secType <- "STK"
        contract.symbol <- "INFY"
        contract.exchange <- "NSE"
        contract.currency <- "INR"

Then, we use the reqRealTimeBarsEx method to subscribe to real time bar events. This method takes 5 parameters:

  • ticker ID and contract: the same as in the previous two blog posts;
  • bar size: the time length of each bar. Currently it must be 5, as only 5-second bars are supported;
  • price type: TRADES, BID, ASK, or MIDPOINT; 
  • useRTH: if a bar's interval fully or partially falls outside RTH (regular trading hours), this flag controls whether data outside RTH should be included in the bar. 0 means to exclude data outside RTH, and 1 means otherwise.

The following line instructs the broker that we wish to listen for real time bar events for the stock Infosys:

        tws1.reqRealTimeBarsEx(1, contract, 5, "TRADES", 0)

As for to unsubscribe, we just need invoke the cancelRealTimeBars method with the ticker ID for which we want to cancel subscription.

        tws1.cancelRealTimeBars(1)

Finally, below is a simple demo program, which captures real time bar events for 10 minutes and simply prints them out.

---------------------------------------------------------------------------------------
open AxTWSLib
open TWSLib
open System
open System.Drawing
open System.Windows.Forms

type RealTimeBarEvent =
    AxTWSLib._DTwsEvents_realtimeBarEvent

type RealTimeBarEventHandler =
    AxTWSLib._DTwsEvents_realtimeBarEventHandler

let now() = DateTime.Now

let formatTimeString (t:TimeSpan) =
    System.String.Format("{0:D2}:{1:D2}:{2:D2}",
            t.Hours, t.Minutes, t.Seconds)

let processRealTimeBarEvent _ (e:RealTimeBarEvent) =
    // ticker ID
    printf "id=%A," e.tickerId
    // time: the start of the bar interval
    let t = TimeSpan.FromSeconds(float e.time)
    printf "time=%s," (formatTimeString t)
    // open
    printf "o=%A," e.``open``
    // high
    printf "h=%A," e.high
    // low
    printf "l=%A," e.low
    // close
    printf "c=%A," e.close
    // wap
    printf "WAP=%A," e.wAP
    // volume
    printf "v=%A," e.volume
    // count
    printfn "cnt=%A" e.count

[<EntryPoint; STAThread>]
let main _ =
    printfn "start time: %A" (now())
    let form1 = new Form(Text="Dummy Form")
    let tws1 = new AxTws()
    tws1.BeginInit()
    form1.Controls.Add(tws1)
    tws1.EndInit()

    tws1.connect("", 7496, 1)
    printfn "server version = %d" tws1.serverVersion

    if tws1.serverVersion > 0 then
        tws1.realtimeBar.AddHandler(
            new RealTimeBarEventHandler(processRealTimeBarEvent))

        let contract = tws1.createContract()
        contract.secType <- "STK"
        contract.symbol <- "INFY"
        contract.exchange <- "NSE"
        contract.currency <- "INR"
        tws1.reqRealTimeBarsEx(1, contract, 5, "TRADES", 0)

        let timerWorkflow = async {
            do! Async.Sleep (60000 * 10)
            Application.Exit()
            }
        Async.Start timerWorkflow

        Application.Run()
        tws1.cancelRealTimeBars(1)
        tws1.disconnect()
        printfn "Diconnected!"

    printfn "end time: %A" (now())
    0

No comments:

Post a Comment