ibapi
ibapi copied to clipboard
Smarter "wait" for historical market data than a simple sleep?
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()
}