I want to use IBAPI to get historical stock data. My code does not work and returns nothings. Can anybody help me edit the code? Thanks
from ibapi import client
from ibapi import wrapper
import datetime
from ibapi.contract import Contract
from ibapi.common import BarData
# ! [socket_init]
class App(wrapper.EWrapper,client.EClient):
def __init__(self):
wrapper.EWrapper.__init__(self)
client.EClient.__init__(self, wrapper=self)
#Build a sample contract
contract = Contract();
contract.symbol = "9005.T";
contract.secType = "STK";
contract.currency = "JPY";
contract.exchange = "SMART";
app = App()
app.connect(host='localhost',port=7497, clientId=3)
print(app.isConnected())
queryTime = (datetime.datetime.today() - datetime.timedelta(days=180)).strftime("%Y%m%d %H:%M:%S")
print(app.reqHistoricalData(4102, contract, queryTime,"1 M", "1 day", "MIDPOINT", 1, 1, False, []))
queryTime = (datetime.datetime.today() - datetime.timedelta(days=180)).strftime("%Y%m%d %H:%M:%S")
print(app.historicalData(4102,BarData))
OUTPUT:
True
None
None
I tried to read the source code. But I found it is quite difficult to understand for me. Other posts showed the answer that appears not relevant to the newest api version.
Here's what I would do.
class App(wrapper.EWrapper,client.EClient):
I would only subclass EClient
if I wanted to override any of it's methods. I don't use python very much but it's like that in other languages.
Inside the class App
you need to override the methods you are interested in like historicalData
After app.connect
you must call app.run()
to start it's message reader thread. Once that thread takes control it will block in your program so you must do program flow asynchronously.
I will put numbers in comments so you see the flow.
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.common import BarData
import datetime
class MyWrapper(EWrapper):
def nextValidId(self, orderId:int):
#4 first message received is this one
print("setting nextValidOrderId: %d", orderId)
self.nextValidOrderId = orderId
#5 start requests here
self.start()
def historicalData(self, reqId:int, bar: BarData):
#7 data is received for every bar
print("HistoricalData. ReqId:", reqId, "BarData.", bar)
def historicalDataEnd(self, reqId: int, start: str, end: str):
#8 data is finished
print("HistoricalDataEnd. ReqId:", reqId, "from", start, "to", end)
#9 this is the logical end of your program
app.disconnect()
print("finished")
def error(self, reqId, errorCode, errorString):
# these messages can come anytime.
print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)
def start(self):
queryTime = (datetime.datetime.today() - datetime.timedelta(days=180)).strftime("%Y%m%d %H:%M:%S")
fx = Contract()
fx.secType = "CASH"
fx.symbol = "USD"
fx.currency = "JPY"
fx.exchange = "IDEALPRO"
#6 request data, using fx since I don't have Japanese data
app.reqHistoricalData(4102, fx, queryTime,"1 M", "1 day", "MIDPOINT", 1, 1, False, [])
app = EClient(MyWrapper()) #1 create wrapper subclass and pass it to EClient
app.connect("127.0.0.1", 7497, clientId=123) #2 connect to TWS/IBG
app.run() #3 start message thread