问题
I have a python script that reads data from the TWS API (Interactive Brokers) and want to dump the data in a csv file.
Right now it just overwrites the data and prints the last line along with a bunch of other values I don't want.
It prints out the values fine with print(df).
Code:
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import *
from ibapi.contract import *
from threading import Timer
from ibapi.ticktype import *
import pandas as pd
import numpy as np
class TestApp(EWrapper, EClient):
def __init__(self):
EWrapper.__init__(self)
EClient.__init__(self, self)
def error(self, reqId, errorCode, errorString):
print("Error: ", reqId, " ", errorCode, " ", errorString)
def nextValidId(self, orderId):
self.start()
def contractDetails(self, reqId, contractDetails):
self.data = [contractDetails]
df = pd.DataFrame(self.data)
df.to_csv('options_test.csv')
print(df)
def contractDetailsEnd(self, reqId):
print("\ncontractDetails End\n")
def start(self):
#self.reqSecDefOptParams(1, "AAPL", "", "STK", 265598)
contract = Contract()
contract.symbol = 'AAPL'
contract.secType = 'OPT'
contract.exchange = 'SMART'
contract.currency = 'USD'
#contract.primaryExchange = 'NASDAQ'
contract.lastTradeDateOrContractMonth = '202010'
#contract.strike = 175
#contract.right = "C"
#contract.multiplier = "100"
global underlying
underlying = contract.symbol
self.reqMktData(1, contract, '106', False, False, [])
self.reqContractDetails(1, contract)
def stop(self):
self.done = True
self.disconnect()
def main():
app = TestApp()
app.nextOrderId = 0
app.connect('127.0.0.1', 7497, 123)
app.data = []
Timer(4, app.stop).start()
app.run()
if __name__ == "__main__":
main()
I tried using append() and it spit out an error.
def contractDetails(self, reqId, contractDetails):
self.data = [contractDetails]
df = pd.append(self.data)
df.to_csv('options_test.csv')
print(df)
..raise AttributeError(f"module 'pandas' has no attribute '{name}'")
AttributeError: module 'pandas' has no attribute 'append'
I just want to save the data received in "contractDetails" to a csv.
回答1:
contractDetails is a ContractDetails details object and I'm not sure how pandas would make a dataframe. The most used field is the contract object which has the conId that you can use for requesting data or placing orders. It also has the symbol so you know what you're trading. The contractDetails has other info like trading times and exchanges. Check the source code for Contract. I modified the way a dataframe gets made a little bit for efficiency. I also modified the code a bit and removed the unneeded Timer.
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import *
from ibapi.contract import *
from threading import Timer
from ibapi.ticktype import *
import collections
import pandas as pd
class TestApp(EWrapper, EClient):
def __init__(self):
EWrapper.__init__(self)
EClient.__init__(self, self)
self.data=collections.defaultdict(list)
def error(self, reqId, errorCode, errorString):
print("Error: ", reqId, " ", errorCode, " ", errorString)
def nextValidId(self, orderId):
self.nextOrderId=orderId
self.start()
def contractDetails(self, reqId, contractDetails):
self.data["conid"].append(contractDetails.contract.conId)
self.data["symbol"].append(contractDetails.contract.localSymbol)
def contractDetailsEnd(self, reqId):
print("\ncontractDetails End\n")
self.df=pd.DataFrame.from_dict(app.data)
self.stop()
def start(self):
#self.reqSecDefOptParams(1, "AAPL", "", "STK", 265598)
contract = Contract()
contract.symbol = 'AAPL'
contract.secType = 'OPT'
contract.exchange = 'SMART'
contract.currency = 'USD'
#contract.primaryExchange = 'NASDAQ'
contract.lastTradeDateOrContractMonth = '202010'
#contract.strike = 175
#contract.right = "C"
#contract.multiplier = "100"
self.reqContractDetails(1, contract)
def stop(self):
self.disconnect()
print(self.df)
#self.df.to_csv('options_test.csv')
def main():
app = TestApp()
app.connect('127.0.0.1', 7496, 123)
app.run()
来源:https://stackoverflow.com/questions/61604175/save-data-from-tws-api-to-csv-file