ibapi icon indicating copy to clipboard operation
ibapi copied to clipboard

Smarter "wait" for historical market data than a simple sleep?

Open windowshopr opened this issue 1 year ago • 0 comments

Waiting for a set amount of seconds is a bit of a naive approach to waiting for data to come back from TWS. Is there a better way to wait/block code for, say, the "msg": "<HistoricalDataEnd>" when waiting for historical data? For this simple example, we can assume that we're wanting data for 1, synchronous request:

package main

import (
	"time"

	"github.com/hadrianl/ibapi"
)

func main() {
	// internal api log is zap log, you could use GetLogger to get the logger
	// besides, you could use SetAPILogger to set you own log option
	// or you can just use the other logger
	log := ibapi.GetLogger().Sugar()
	defer log.Sync()

	// implement your own IbWrapper to handle the msg delivered via tws or gateway
	// Wrapper{} below is a default implement which just log the msg
	ic := ibapi.NewIbClient(&ibapi.Wrapper{})

	// tcp connect with tws or gateway
	// fail if tws or gateway had not yet set the trust IP
	if err := ic.Connect("127.0.0.1", 4002, 0); err != nil {
		log.Panic("Connect failed:", err)
	}

	// handshake with tws or gateway, send handshake protocol to tell tws or gateway the version of client
	// and receive the server version and connection time from tws or gateway.
	// fail if someone else had already connected to tws or gateway with same clientID
	if err := ic.HandShake(); err != nil {
		log.Panic("HandShake failed:", err)
	}

	// Create a contract for SPY ETF
	spyContract := ibapi.Contract{
		Symbol:       "SPY",
		SecurityType: "STK",
		Exchange:     "SMART",
		Currency:     "USD",
	}

	// Set the request ID
	reqID := ic.GetReqID()

	// Get the contract details to ensure proper contract is created
	// ic.ReqContractDetails(reqID, &spyContract)

	// Request delayed market data for SPY
	ic.ReqMarketDataType(3) // 3 or 4 for delayed, 1 when you have subscribed to real-time market data

	// Request historical data for SPY
	ic.ReqHistoricalData(reqID, &spyContract, time.Now().Format("20060102 15:04:05"), "1 W", "5 mins", "TRADES", false, 2, false, []ibapi.TagValue{})

	ic.Run()

	// Wait for a response (naive)
	<-time.After(time.Second * 15)

	// Wait for the log message {"level":"info","ts":1.......,"msg":"<HistoricalDataEnd>","reqID":1,"startDate":"20240101  19:32:40","endDate":"20240108  19:32:40"}
	// i.e. "msg":"<HistoricalDataEnd>" is received
	// ??????????

	// Cancel the historical data request
	ic.CancelHistoricalData(reqID)

	ic.Disconnect()
}

windowshopr avatar Jan 09 '24 02:01 windowshopr