互动经纪人API执行详细信息,如何获得所获得的期货的入门价格?

问题描述

我想获得我实际购买的期货的价格。我变得疯狂起来,试图使其工作。我也想知道如何实时获得PnL。当我尝试这样做时,几乎需要5分钟才能更改该值。这是我从这里开始使用的一些代码,它确实可以工作,但是我无法获取执行细节。

导入时间

def read_positions():#读取所有帐户头寸并返回带有信息的DataFrame

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import TickerId
import pandas as pd
import time

class ib_class(EWrapper,EClient):
    def __init__(self):
        EClient.__init__(self,self)
        self.all_positions = pd.DataFrame([],columns=['Account','Symbol','Quantity','Average Cost','Sec Type'])

    def error(self,reqId: TickerId,errorCode: int,errorString: str):
        if reqId > -1:
            print("Error. Id: ",reqId," Code: ",errorCode," Msg: ",errorString)

    def position(self,account,contract,pos,avgCost):
        index = str(account) + str(contract.symbol)
        self.all_positions.loc[index] = account,contract.symbol,avgCost,contract.secType

    def positionEnd(self):
        self.disconnect()

ib_api = ib_class()
ib_api.connect("127.0.0.1",7496,10)
ib_api.reqPositions()
current_positions = ib_api.all_positions
ib_api.run()

return current_positions

def read_navs():#读取所有帐户的资产净值

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import TickerId
import pandas as pd
import time

class ib_class(EWrapper,self)
        self.all_accounts = pd.DataFrame([],columns=['reqId','Account','Tag','Value','Currency'])

    def error(self,errorString)

    def accountSummary(self,tag,value,currency):
        #if tag == 'NetLiquidationByCurrency':
            index = str(account)
            self.all_accounts.loc[index] = reqId,currency


    def accountSummaryEnd(self,reqId: int):
        self.disconnect()

    def execDetails(self,execution):
        print('Order Executed: ',contract.secType,contract.currency,execution.execId,execution.orderId,execution.shares,execution.lastLiquidity)

ib_api = ib_class()
ib_api.connect("127.0.0.1",10)
ib_api.reqAccountSummary(9001,"All","$LEDGER")
current_nav = ib_api.all_accounts
ib_api.run()

return current_nav

为True时: time.sleep(0.1); 打印(read_positions())

解决方法

我记得那个是reqPnLSingle的新功能,所以我写了这个来测试。

有些奇怪的数据,但该值似乎正确,并且会不断更新。

我在代码中添加了注释以进行解释。

import ibapi
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import *
from ibapi.contract import *

import pandas as pd
import collections 
import time

class TestApp(EClient,EWrapper):
    accts = []
    orderId = 0
    posns = collections.defaultdict(list)
    start = time.time()
    
    def __init__(self):
        EClient.__init__(self,self)
        
    def error(self,reqId:TickerId,errorCode:int,errorString:str):
        if (reqId > -1):
            # ignore many 2150 Invalid position trade derived value
            if (errorCode == 2150): return
            print("Error:",reqId,errorCode,errorString)
        else :
            print("Info: ",errorString)
        
    def managedAccounts(self,accountsList: str):
        # the accounts are sent when a connection is made
        # only needed to reqPosns for sub acct
        self.accts = accountsList.split(",")# probably just 1
        print("accts",self.accts)
        
    def nextValidId(self,orderId:int):
        # this is called when a connection is made
        self.orderId = orderId
        
        # to make sure the version is >= min 9.73.06,server > ~127?
        print(ibapi.VERSION,self.serverVersion())

        #use this as a signal to start making requests
        self.reqPositions()
    
    def position(self,account: str,contract: Contract,position: float,avgCost: float):
        self.posns["account"].append(account)
        self.posns["conId"].append(contract.conId)
        self.posns["symbol"].append(contract.localSymbol)
        self.posns["avgCost"].append(avgCost)
        self.posns["posn"].append(position)
        
    def positionEnd(self):
        self.df = pd.DataFrame.from_dict(self.posns) #will make an automatic int index
        
        if (self.df.empty):
            self.disconnect()
            return
        
        # make req for each posn,use index for reqId
        for index,row in self.df.iterrows():
            self.reqPnLSingle(index,row.account,"",row.conId)
    
    def pnlSingle(self,reqId: int,pos: int,dailyPnL: float,unrealizedPnL: float,realizedPnL: float,value: float):
        row = self.df.iloc[reqId]
        # all PnL's are maxint for me at night so I calc the right amount
        print(row.symbol,"PnL",unrealizedPnL,"calc",value - row.avgCost * row.posn)
        
        #just run for ~10 secs
        if (time.time() - self.start > 10): 
            print(self.df)
            self.disconnect()
    
def main():
    app = TestApp()
    app.connect("127.0.0.1",7497,123)
    app.run()
    
if __name__ == "__main__":
    main()