Reputation: 1
I want to distinguish the historical price data for e-mini S&P500 (ES) by RTH and ETH sessions and store them into xlsx files. The xlsx files are only showing 1 row containing: "Date, Open, High, Low, Close" without the historical price data. I am subscribed to the proper CME data. Any assistance with this issue would be greatly appreciated.
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
import pandas as pd
class HistoricalDataApp(EWrapper, EClient):
def __init__(self):
EWrapper.__init__(self)
EClient.__init__(self, wrapper=self)
self.rth_data = [] # Initialize rth_data attribute
self.eth_data = [] # Initialize eth_data attribute
def historicalData(self, reqId, bar):
# Callback function to receive historical data
if reqId == 1: # Check if this is the request you made
date = bar.date.strftime("%Y-%m-%d %H:%M:%S")
if bar.time == "16:00:00":
self.rth_data.append([date, bar.open, bar.high, bar.low, bar.close])
else:
self.eth_data.append([date, bar.open, bar.high, bar.low, bar.close])
def historicalDataEnd(self, reqId, start, end):
# Callback function indicating the end of historical data
if reqId == 1:
self.disconnect()
def get_futures_historical_data():
app = HistoricalDataApp()
app.connect("127.0.0.1", 7497, clientId=0) # Modify host and port as per your configuration
contract = Contract()
contract.symbol = "ES"
contract.secType = "FUT"
contract.exchange = "CME"
contract.currency = "USD"
contract.lastTradeDateOrContractMonth = "202309" # Modify contract expiry as per your requirement
# Request historical data
app.reqHistoricalData(1, contract, "", "3 Y", "1 day", "TRADES", 1, 1, False, [])
# Start the event loop
app.run()
# Store data in separate arrays
rth_df = pd.DataFrame(app.rth_data, columns=["Date", "Open", "High", "Low", "Close"])
eth_df = pd.DataFrame(app.eth_data, columns=["Date", "Open", "High", "Low", "Close"])
# Export data to Excel
rth_df.to_excel("rth_data.xlsx", index=False)
eth_df.to_excel("eth_data.xlsx", index=False)
if __name__ == "__main__":
get_futures_historical_data()
Added print(f"Received historical data. reqId: {reqId}, Date: {bar.date}, Time: {bar.time}")
to see if the historicalData is actually being called. When I run the code, nothing shows up in the console output. TWS is open and API ActiveX and socket clients are enabled.
I also added print statements before and after app.connect, which was successful.
def get_futures_historical_data():
app = HistoricalDataApp()
print("Before connecting to API")
app.connect("127.0.0.1", 7497, clientId=0) # Modify host and port as per your configuration
print("After connecting to API")
Upvotes: 0
Views: 164
Reputation: 10989
You have to wait for historicalDataEnd
before saving the data.
You ask for the data (possibly even before you have a connection) :
app.reqHistoricalData
And then you start the read loop :
app.run()
And then you immediately make a DF with data not yet returned :
rth_df = pd.DataFrame
If you are having a problem with asynchronous programming I would suggest:
https://nbviewer.org/github/erdewit/ib_insync/blob/master/notebooks/bar_data.ipynb
Main docs:https://ib-insync.readthedocs.io/readme.html
If you would like to see an asynchronous method: https://stackoverflow.com/a/57502748/2855515
Upvotes: 0