当前位置: 首页 > 知识库问答 >
问题:

如何使用Python API获取我的账户在交互式经纪人处的位置?

叶恩
2023-03-14

编辑:我找到了一个关于错误消息的解决方案——这是IB应用编程接口上的一个错误。我在下面作为答案显示的代码应该对那些寻找一个干净的解决方案来从他们在IB的账户中读取头寸和导航的人有用。

原始问题[参见下面的解决方案;将原始问题留待上下文]:我正试图使用公司的API获取我在Interactive Brokers[IB]的所有账户头寸。他们的文档虽然内容丰富,但却极为混乱。示例代码中充满了不必要的命令——我想要一些非常精简的命令。

我需要帮助:

  1. 如何获取信息"每个帐户"[已解决]
  2. 如何将变量带到DataFrame[解决]
  3. 如何避免IB的API打印一系列错误消息[SOLVED]

迄今为止的准则是:

from ibapi.client import EClient 
from ibapi.wrapper import EWrapper
from ibapi.common import * #for TickerId type
import pandas as pd

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

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

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

    def positionEnd(self):
        self.disconnect()

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

当我运行上面的代码时,我得到了一系列(一)账号,(二)合同符号,(三)头寸和(四)平均成本。因此,这回答了问题1。你可能想“打印”这些值,看看IB的应用编程接口是如何向你发送信息的。

我还能够定义一个数据帧变量all_positions,它接收我正在寻找的信息。请参见下面的结果。注意,我必须创建一个“索引”变量,它是数据帧每一行的唯一标识符(作为帐号和符号的组合)。在没有这个“索引”的情况下,我没有找到将信息“附加”到数据帧的方法(欢迎提供任何关于如何执行的想法):

关于最后一个问题(错误消息):

Brian对“error”函数的建议(见下文)消除了“-1”错误。但我仍然得到了以下信息:

EReader线程回溯中未处理的异常(最后一次调用):文件“C:\Users\danil\Anaconda3\lib\site packages\ibapi-9.76.1-py3.7.egg\ibapi\reader.py”,第34行,in run data=self。conn.recvMsg()文件“C:\Users\danil\Anaconda3\lib\site packages\ibapi-9.76.1-py3.7.egg\ibapi\connection.py”,第99行,在recvMsg buf=self中_recvAllMsg()文件“C:\Users\danil\Anaconda3\lib\site packages\ibapi-9.76.1-py3.7.egg\ibapi\connection.py”,第119行,在_recvallmsgbuf=self中。插座recv(4096)OSError:[WinError 10038]尝试对非套接字的对象执行操作

共有3个答案

公羊喜
2023-03-14

你的代码很好。如果想忽略错误,只需覆盖错误回调。

from ibapi.common import * #for TickerId type

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

错误

如果您正在获取数据或下订单,我仍然会跟踪连接状态。

初始化ddf两次。你也可以调用super,我想它只是记录数据。

断开连接时的套接字错误是一个bug,或者只是他们在IB上的做法。应该已经修复了,但可能需要一段时间才能发布。也许可以尝试更新,我在4月26日看到了修复它的请求。

孟高峰
2023-03-14

我得到的错误是由IB的API上的一个错误产生的(你可以看到我问的关于具体错误的另一个问题)。我添加这个答案是为了提供关于如何降级到旧版本的更清晰步骤:

1)从这里下载旧版本:http://interactivebrokers.github.io/downloads/TWSAPI安装974.01.msi

IB不会显示旧版本的链接,但会将文件保存在Github上(注意链接地址末尾的版本名)

2) 卸载当前版本。在IB自己的网站上,执行以下操作:

  • 像往常一样,从Windows控制面板中的添加/删除工具中卸载API
  • 如果还有文件,请删除C:\TWS API\文件夹,以防止版本不匹配
  • 找到文件C:\Windows\SysWOW64\TwsSocketClient。dll。删除此文件。[未找到此文件]
  • 重新启动计算机,然后再安装其他API版本

3) 使用安装程序安装API。msi文件

4)运行Anaconda提示符并导航到目录C:\TWS API\source\pythonClient

5) 运行:python安装程序。py安装

6)在pythonsetup.py安装后,重启Spyder(如果它被打开;我在上面的步骤#5之前关闭了我的)

在我安装了这个旧版本后,错误消失了!现在我控制台上的输出又干净了!

黄丰
2023-03-14

经过大量的实验,下面是我编写的最后一段代码,我把它放在一个名为AB_API的“.py”文件中(这样我就可以将其作为库“导入”):

def read_positions(): #read all accounts positions and return DataFrame with information

    from ibapi.client import EClient
    from ibapi.wrapper import EWrapper
    from ibapi.common import TickerId
    from threading import Thread

    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, pos, avgCost, contract.secType

    def run_loop():
        app.run()
    
    app = ib_class()
    app.connect('127.0.0.1', 7496, 0)
    #Start the socket in a thread
    api_thread = Thread(target=run_loop, daemon=True)
    api_thread.start()
    time.sleep(1) #Sleep interval to allow time for connection to server

    app.reqPositions() # associated callback: position
    print("Waiting for IB's API response for accounts positions requests...\n")
    time.sleep(3)
    current_positions = app.all_positions
    current_positions.set_index('Account',inplace=True,drop=True) #set all_positions DataFrame index to "Account"
    
    app.disconnect()

    return(current_positions)


def read_navs(): #read all accounts NAVs

    from ibapi.client import EClient
    from ibapi.wrapper import EWrapper
    from ibapi.common import TickerId
    from threading import Thread

    import pandas as pd
    import time

    class ib_class(EWrapper, EClient):

        def __init__(self):
            EClient.__init__(self, self)

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

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

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

    def run_loop():
        app.run()
    
    app = ib_class()
    app.connect('127.0.0.1', 7496, 0)
    #Start the socket in a thread
    api_thread = Thread(target=run_loop, daemon=True)
    api_thread.start()
    time.sleep(1) #Sleep interval to allow time for connection to server

    app.reqAccountSummary(0,"All","NetLiquidation")  # associated callback: accountSummary / Can use "All" up to 50 accounts; after that might need to use specific group name(s) created on TWS workstation
    print("Waiting for IB's API response for NAVs requests...\n")
    time.sleep(3)
    current_nav = app.all_accounts
    
    app.disconnect()

    return(current_nav)

我现在可以通过两个单行函数读取所有账户头寸和资产净值:

import IB_API

print("Testing IB's API as an imported library:")

all_positions = IB_API.read_positions()
all_navs = IB_API.read_navs()

如果要运行非常快速的测试(无需导入/调用函数),请在read_positions()和read_navs()下方执行以下操作:

print("Testing IB's API as an imported library:")

all_positions = read_positions()
print(all_positions)
print()
all_navs = read_navs()
print(all_navs)

我意识到一些用户对导入函数的概念感到困惑,因此提出了上面的快速建议。

我希望Interactive Brokers能为客户提供一些简单的示例,让人们更容易测试一些想法,并决定是否要使用他们的应用编程接口。

 类似资料:
  • 我曾尝试在VisualStudio2008中设置Interactive Broker的C API,但我知道的C非常有限,并且不断出现错误: 1)是否有任何方法可以使用某种轻量级的脚本语言来连接到Interactive Brokers并进行交易。 像Python这样轻量级的东西就可以了,是的,我已经研究过IBMY,但我不明白java2python系统是如何工作的。 2) 您是如何设置您的自动系统的,

  • 我想使用IB Api,但无法计算我们如何请求完整的符号列表和信息。 在我找到的文档中:reqScannerParameters()——但不清楚如何获得纳斯达克股票的列表? 有更好的办法吗?

  • 我正在尝试为API创建一个程序,一次进行多个交易,然后获取股票价格,然后每隔一段时间重新平衡一次。我使用了一个在线教程来获取一些代码,并做了一些调整。 但是,当我运行代码时,它经常连接,如果我重新启动IB TWS,它会下订单。但是如果我再次运行代码,它就不起作用,或者显示它将连接的任何指示。有人能帮我弄清楚如何保持连接,这样我就可以运行main.java文件,它会执行多个交易,然后结束连接吗?我需

  • 我正在尝试为Python应用编程接口创建一个程序,以便一次下多个交易/市场订单。我在网上使用了一个教程来获取一些代码,并做了一些更改。但是,我不能一次下多个订单。我使用了2个列表1是用于符号,另一个是用于它们的数量。(例如:购买3只苹果股票)。我的代码只执行最后一个订单:即“购买3只客户关系管理股票”。有人能帮我弄清楚如何下多个订单吗? 下面是我的Python代码:

  • Noob是个问题,但我正试图弄清楚Matlab交易工具箱使用的是哪种API,以便我可以参考适当的指南。 Matlab网站表示,有关如何实现交易系统的详细信息,请参考交互式经纪人API指南。。http://www.mathworks.com/help/trading/ibtws.createorder.html#inputarg_ibContract 但是,当我打开Interactive Broke

  • 我已经在python中构建了一个IB TWS应用程序。一切似乎都很好,但是我正在努力处理最后一个元素。 TWS需要每天注销或重新启动。我选择了在设定的时间每天重新启动,这样我就可以很容易地预测在特定的时间重新启动我的应用程序(至少,我是这么想的) 我的程序有一个名为的类,它是ECClient和EWrapper的子类。在我的程序开始时,我创建了这个实例,它成功地连接到TWS并与之协同工作。现在,假设