【问题标题】:reqHistoricalData in IBPY doesn't return anything [python]IBPY 中的 reqHistoricalData 不返回任何内容 [python]
【发布时间】:2017-03-15 13:36:08
【问题描述】:

我正在尝试通过 Ibpy 从盈透证券 (IB) 获取历史数据。 我已经为此任务尝试了几个脚本,这些脚本是我从其他人那里改编而来的,他们指出它应该可以工作。但是,它们都不适合我! 我是 python 新手,所以我承认我没有完全了解这些方法的工作原理——但是,我应该尝试最明显的修复。下面我列出了我尝试过的两个脚本。 我正在使用python 2x。

在 TWS 中我有以下设置:

选中:启用 ActiveX 和 Socket 客户端。 未选中:启用 DDE 客户端。 未选中:只读 API。 选中:在连接时下载未结订单。 选中:发送投资组合时包括外汇头寸。 选中:发送 EEP 的状态更新。 套接字端口 = 7496。 选中:使用负数绑定自动订单。 未选中:创建 API 消息日志文件。 未选中:在 API 日志文件中包含市场数据。 日志记录级别 = 错误。 主 API 客户端 ID = 222。 向 API 发送批量数据的超时时间为 30 秒。 组件交换分隔符 = 空白。 选中:仅允许来自本地主机的连接。

API - 检查注意事项:绕过 API 订单的订单注意事项。此选项卡中的其他所有内容均未选中。

当我运行 python 脚本时,我已经登录并运行了 TWS,与其他人在网上所说的相比,上面的 TWS API 设置似乎是正确的。我有一个订阅美国股票数据的真实 IB 账户。还应该提到的是,我也尝试运行另一个通过 IBPY 下订单的脚本——这很有效,所以问题似乎只存在(至少目前)关于获取历史数据。

脚本 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()

这应该返回 csv 文件中的数据。 csv 文件已创建,但它是空的。

回复:

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

所以它显然不会返回任何东西。

脚本 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())

这里的回应:

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

再次没有返回任何内容。我不知道为什么,因为它似乎对其他人有用。我可能错过了一些基本的东西,因为我对 Python 还很陌生?

非常感谢任何帮助。

【问题讨论】:

    标签: python api ibpy


    【解决方案1】:

    始终实现错误处理程序,API 会告诉您出了什么问题。在这种情况下,它表示使用“1 天”作为条形大小。

    没有必要睡觉。使用nextValidId 了解连接何时准备就绪。使用不同的结束方法知道何时完成。 historicalDataEnd 似乎还没有在 IBpy 中实现,所以只需寻找“完成”

    不要关闭 api 日志记录,它会显示错误以及发送到 TWS 和从 TWS 发送的所有不同消息。您可以关闭日志文件中的市场数据,因为它很多。在 jts 目录中查找文件“api.222.Wed.log”。

    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())
    

    【讨论】:

    • 我希望不要要求太多,但是任何人都可以提供有关如何将输出放入 pd.DataFrame 的见解吗?
    • 我明白了 - 无论如何谢谢。顺便说一句:我现在有另一个奇怪的问题。该脚本有效,但是当我(通过 spyder)执行它时,数据不会“更新”,直到我单击控制台。因此,我无法通过循环获取多个证券的数据,因为我必须在每次运行后单击控制台才能实际获取数据。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多