如何从Interactive Brokers API获取合同详细信息?

时间:2019-01-17 06:17:34

标签: python python-3.x interactive-brokers ib-api

Interactive Brokers documentation之后,我尝试使用以下代码获取合同详细信息:

from ibapi.client import EClient
from ibapi.wrapper import EWrapper

class MyWrapper(EWrapper):

    def contractDetails(self, reqId, contractDetails):
        super().contractDetails(reqId, contractDetails)

        print("ContractDetails. ReqId:", reqId,
              contractDetails.summary.symbol,
              contractDetails.summary.secType,
              "ConId:", contractDetails.summary.conId,
              "@", contractDetails.summary.exchange)

    def contractDetailsEnd(self, reqId):
        super().contractDetailsEnd(reqId)
        print("ContractDetailsEnd. ", reqId, "\n")


wrapper = MyWrapper()
app = EClient(wrapper)
app.connect("127.0.0.1", 7497, clientId=0)
print("serverVersion:%s connectionTime:%s" % (app.serverVersion(), app.twsConnectionTime()))

from ibapi.contract import Contract
contract = Contract()
contract.symbol = "XAUUSD"
contract.secType = "CMDTY"
contract.exchange = "SMART"
contract.currency = "USD"

app.reqContractDetails(4444, contract)
app.run()

返回的输出是:

serverVersion:148 connectionTime:b'20190117 17:11:38 AEST'

An exception has occurred, use %tb to see the full traceback.

SystemExit


C:\Users\Greg\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2969: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
  warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

如何从Interactive Brokers API获取合同详细信息?我尝试使用%tb,但不认为我把它放在正确的行上。

2 个答案:

答案 0 :(得分:1)

from ibapi.client import EClient
from ibapi.wrapper import EWrapper


class MyWrapper(EWrapper):

    def nextValidId(self, orderId:int):
        print("setting nextValidOrderId: %d", orderId)
        self.nextValidOrderId = orderId
        # start program here or use threading
        app.reqContractDetails(4444, contract)

    def contractDetails(self, reqId, contractDetails):
        print(reqId, contractDetails.contract)# my version doesnt use summary

    def contractDetailsEnd(self, reqId):
        print("ContractDetailsEnd. ", reqId)
        # this is the logical end of your program
        app.disconnect() # delete if threading and you want to stay connected

    def error(self, reqId, errorCode, errorString):
        print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)


wrapper = MyWrapper()
app = EClient(wrapper)
app.connect("127.0.0.1", 7497, clientId=123)
print("serverVersion:%s connectionTime:%s" % (app.serverVersion(), app.twsConnectionTime()))

from ibapi.contract import Contract
contract = Contract()
contract.symbol = "XAUUSD"
contract.secType = "CMDTY"
contract.exchange = "SMART"
contract.currency = "USD"

app.run() # delete this line if threading

# def runMe():
#     app.run()

# import threading
# thread = threading.Thread(target = runMe)
# thread.start()

# input('enter to disconnect')
# app.disconnect()

在启动消息阅读器之前,您需要数据。也许您在开始之前就已经得到了数据。

IB建议您在收到nextValidId之后启动程序,以使您知道一切正常运行。由于python API在消息读取循环中阻塞,因此您需要实现线程化或结构化程序以异步运行。

我已经展示了如何做到这一点,因此它将在没有用户输入的情况下运行,并且是事件驱动的或异步的。这意味着程序会等到应该执行某项操作后再执行。

我包含了线程选项,只需更改注释即可。

ContractDetails.summary已更改为合同。我不确定它是否是python中的摘要,不知道您从哪里得到的。

答案 1 :(得分:0)

在 Python 3 中使用 ib_insync 包,如果您想获取所有存储在 df 中的合约列表的详细信息,您还可以执行以下操作:

from ib_insync import *
import pandas as pd


def add_contract_details(ib_client, ib_contract, df):
    list_of_contract_details = ib_client.reqContractDetails(contract=ib_contract)
    if list_of_contract_details:
        print(
            f"Found {len(list_of_contract_details)} contract{'s' if len(list_of_contract_details) > 1 else ''} for {ib_contract.symbol}: "
        )
        for contract_details in list_of_contract_details:
            data = {}
            for k, v in contract_details.contract.__dict__.items():
                data[k] = v
            for k, v in contract_details.__dict__.items():
                if k != "contract":
                    data[k] = v
            df = pd.DataFrame([data]) if df is None else df.append(pd.DataFrame([data]))
    else:
        print(f"No details found for contract {ib_contract.symbol}.")
    return df



ib = IB()
ib.connect(host="127.0.0.1", port=7497, clientId=1)
btc_fut_cont_contract = ContFuture("BRR", "CMECRYPTO")
ib.qualifyContracts(btc_fut_cont_contract)
fx_contract_usdjpy = Forex('USDJPY')
ib.qualifyContracts(fx_contract_usdjpy)

df_contract_details = None
for c in [btc_fut_cont_contract, fx_contract_usdjpy]:
    df_contract_details = add_contract_details(ib, c, df_contract_details)
print(df_contract_details)
相关问题