reqHistoricalData in IBPY doesn't return anything [python]

ε祈祈猫儿з 提交于 2019-12-12 19:21:00

问题


I am trying to obtain historical data from Interactive Brokers (IB) through Ibpy. I have tried several scripts for this task, which I have adapted from others who indicate that it should work. None of them work for me, however! I am new to python, so I admit that I do not have complete insight into the workings of these methods - however, I should have tried the most obvious fixes. Below I have listed two of the scripts I have tried. I'm using python 2x.

In TWS I have the following settings:

checked: Enable ActiveX and Socket Clients. unchecked: Enable DDE clients. unchecked: Read-Only API. checked: Download open orders on connection. checked: Include FX posistions when sending portfolio. checked: Send status updates for EEP. Socket port = 7496. checked: Use negative numbers to bind automatic orders. unchecked: Create API message log file. unchecked: Include market data in API log file. Logging Level = Error. Master API client ID = 222. Timeout to send bulk data to API is 30 seconds. Component Exch Separator = Blank. checked: Allow connections from localhost only.

API - Precautions checked: Bypass Order Precautions for API Orders. everything else all unchecked in this tab.

I have got TWS logged in and running when I run the python scripts and the TWS API settings above seem correct compared with what everyone else is saying online. I have a real IB account subscribed to US equity data. It should further be mentioned that I tried to run another script placing an order through IBPY as well - this worked, so the problem seems to exist only (at the moment at least) regarding obtaining the historical data.

Script 1:

from time import sleep, strftime, localtime  
from ib.ext.Contract import Contract  
from ib.opt import ibConnection, message  


new_symbolinput = ['AAPL']
newDataList = []  
dataDownload = []  

def historical_data_handler(msg):  
    global newDataList  
    print (msg.reqId, msg.date, msg.close)
    if ('finished' in str(msg.date)) == False:  
        new_symbol = new_symbolinput[msg.reqId]  
        dataStr = '%s, %s, %s' % (new_symbol, strftime("%Y-%m-%d", localtime(int(msg.date))), msg.close)  
        newDataList = newDataList + [dataStr]
    else:  
        new_symbol = new_symbolinput[msg.reqId]  
        filename = 'minutetrades' + new_symbol + '.csv'  
        csvfile = open('IBdata/' + filename,'w')
        for item in newDataList:  
            csvfile.write('{} \n'.format(item))
        csvfile.close()  
        newDataList = []  
        global dataDownload  
        dataDownload.append(new_symbol)  


con = ibConnection(port=7496, clientId=222)  
con.register(historical_data_handler, message.historicalData)  
con.connect()  

symbol_id = 0  
for i in new_symbolinput:  
    print (i)  
    qqq = Contract()  
    qqq.m_symbol = i  
    qqq.m_secType = 'STK'  
    qqq.m_exchange = 'SMART'  
    qqq.m_currency = 'USD'
    con.reqHistoricalData(symbol_id, qqq, '20161101', '1 W', '1 D', 'MIDPOINT', 1, 2)  

    symbol_id = symbol_id + 1  
    sleep(10)  

print (dataDownload) 
filename = 'downloaded_symbols.csv'  
csvfile = open('IBdata/' + filename,'w')  
for item in dataDownload:  
    csvfile.write('%s \n' % item)  
csvfile.close()

this should return the data in a csv file. The csv file is created, but it is empty.

Response:

Server Version: 76
TWS Time at connection:20170315 14:18:06 CET
AAPL
[]

So it clearly doesn't return anything.

Script 2:

from time import sleep, strftime
from ib.ext.Contract import Contract
from ib.opt import ibConnection, message

def my_account_handler(msg):
    print(msg)

def my_tick_handler(msg):
    print(msg)

def my_hist_data_handler(msg):
    print(msg)


if __name__ == '__main__':

    con = ibConnection(port=7496,clientId=222)
    con.register(my_account_handler, 'UpdateAccountValue')
    con.register(my_tick_handler, message.tickSize, message.tickPrice)
    con.register(my_hist_data_handler, message.historicalData)
    con.connect()

    print(con.isConnected())

    def inner():

        qqqq = Contract()
        qqqq.m_secType = "STK" 
        qqqq.m_symbol = "AAPL"
        qqqq.m_currency = "USD"
        qqqq.m_exchange = "SMART"
        endtime = strftime('%Y%m%d %H:%M:%S')
        print(endtime)
        print(con.reqHistoricalData(1,qqqq,endtime,"1 W","1 D","MIDPOINT",1,2))



    sleep(10)

    inner()
    sleep(5)
    print('disconnected', con.disconnect())
    print(con.isConnected())

The response here:

Server Version: 76
TWS Time at connection:20170315 14:29:53 CET
True
20170315 14:30:05
None
('disconnected', True)
False

Again nothing is returned. I have no idea why, as it seems to work for others. I might have missed something fundamental as I'm quite new to Python?

Any help is very much appreciated.


回答1:


Always implement an error handler and the API will tell you what's wrong. In this case it says use "1 day" for a bar size.

There's no need to sleep. Use nextValidId to know when the connection is ready. Use the different end methods to know when you're done. historicalDataEnd doesn't seem to be implemented yet in IBpy so just look for 'finished'

Don't shut off api logging, it would have shown the error as well as all the different messages sent to and from TWS. You can shut off market data in the log file as it's quite a lot. Look for a file 'api.222.Wed.log' in your jts dir.

from time import sleep, strftime
from ib.ext.Contract import Contract
from ib.opt import ibConnection, message
import pandas as pd
import numpy as np

def nextValidId_handler(msg):
    print(msg)
    inner()

hist = []

def my_hist_data_handler(msg):
    print(msg)
    if "finished" in msg.date:
        print('disconnecting', con.disconnect())
        df = df = pd.DataFrame(index=np.arange(0, len(hist)), columns=('date', 'close', 'volume'))
        for index, msg in enumerate(hist):
            df.loc[index,'date':'volume'] = msg.date, msg.close, msg.volume
        print(df )
    else:
        hist.append(msg)    

def error_handler(msg):
    print(msg)

if __name__ == '__main__':

    con = ibConnection(port=7497,clientId=222)
    con.register(error_handler, message.Error)
    con.register(nextValidId_handler, message.nextValidId)
    con.register(my_hist_data_handler, message.historicalData)
    con.connect()

    print(con.isConnected())

    def inner():

        qqqq = Contract()
        qqqq.m_secType = "STK" 
        qqqq.m_symbol = "AAPL"
        qqqq.m_currency = "USD"
        qqqq.m_exchange = "SMART"
        endtime = strftime('%Y%m%d %H:%M:%S')
        print(endtime)
        con.reqHistoricalData(1,qqqq,endtime,"1 W","1 day","MIDPOINT",1,2)

    print(con.isConnected())


来源:https://stackoverflow.com/questions/42811393/reqhistoricaldata-in-ibpy-doesnt-return-anything-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!