简体   繁体   English

尝试使用 python 和 IB API 获取多种证券的历史数据 - df 不在循环之间清除

[英]Trying to get historical data for multiple securities using python and IB API - df not clearing between loops

I'm trying to get historical data for several products through the IB API, and store each product in a dataframe (which I need to save in separate csv files).我试图通过 IB API 获取多个产品的历史数据,并将每个产品存储在 dataframe 中(我需要将其保存在单独的 csv 文件中)。

This is my code, the main issue is that the dataframe isn't clearing between loops, when moving onto the second loop the df contains data for 2 products, the third for 3. I'm not sure where / how to clear the df.这是我的代码,主要问题是 dataframe 没有在循环之间清除,当进入第二个循环时,df 包含 2 个产品的数据,第三个包含 3 个产品的数据。我不确定在哪里/如何清除 df .

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
import pandas as pd
import threading
import time

class IBapi(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)
        self.data = []

    def historicalData(self, reqId, bar):
        self.data.append([bar.date, bar.open, bar.high, bar.low, bar.close, bar.volume])
           
    def error(self, reqId, errorCode, errorString):
        print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)

    def historicalDataEnd(self, reqId: int, start: str, end: str):
        print("HistoricalDataEnd. ReqId:", reqId, "from", start, "to", end)
        self.df = pd.DataFrame(self.data)

def run_loop():
    app.run()
    
app = IBapi()

#Create contract object
ES_contract = Contract()
ES_contract.symbol = 'ES'
ES_contract.secType = 'FUT'
ES_contract.exchange = 'GLOBEX'
ES_contract.lastTradeDateOrContractMonth  = '202209'

#Create contract object
VIX_contract = Contract()
VIX_contract.symbol = 'VIX'
VIX_contract.secType = 'IND'
VIX_contract.exchange = 'CBOE'
VIX_contract.currency = 'USD'

#Create contract object
DAX_contract = Contract()
DAX_contract.symbol = 'DAX'
DAX_contract.secType = 'FUT'
DAX_contract.exchange = 'EUREX'
DAX_contract.currency = 'EUR'
DAX_contract.lastTradeDateOrContractMonth  = '202209'
DAX_contract.multiplier = '25'

products={'ES': ES_contract, 'VIX': VIX_contract,  'DAX': DAX_contract}

nid=1

app.connect('127.0.0.1', 4001, 123)
#Start the socket in a thread
api_thread = threading.Thread(target=run_loop, daemon=True)
api_thread.start()
time.sleep(1) #Sleep interval to allow time for connection to server

def fetchdata_function(name,nid):
    df=pd.DataFrame()
    #Request historical candles
    app.reqHistoricalData(nid, products[name], '', '1 W', '5 mins', 'TRADES', 0, 2, False, [])
    time.sleep(10) #sleep to allow enough time for data to be returned
    df = pd.DataFrame(app.data, columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume'])
    df['Date'] = pd.to_datetime(df['Date'],unit='s')
    df=df.set_index('Date')
    df.to_csv('1week'+str(name)+'5min.csv')  
    print(df)

names=['ES', 'DAX', 'VIX']

for name in names:     
    fetchdata_function(name,nid)
    nid=nid+1   
    
app.disconnect()

create a dictionary and append the app.data as a key value pair in the historicaldata callback.创建字典和 append app.data 作为 historicaldata 回调中的键值对。 Then you can access them separately - in fact converting a dict to multi-level dataframe is also possible然后你可以单独访问它们 - 实际上将字典转换为多级 dataframe 也是可能的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM