云子量化【盈透证券TWS API 官方文档翻译系列】3、TWS API的故障排除和支持以及TWS API的体系结构和连接

故障排除和支持

API 文档包含所有 API 函数的完整描述。此外,API本身的源代码是免费分发的,是更深入地了解API工作原理的重要资源。如果在查看这些资源后仍有关于可用 API 功能的问题,API 支持组可以提供帮助。

重要的是要记住,IB无法提供编程帮助或提供有关如何编写自定义应用程序代码的建议。API 组可以查看包含 API 应用程序与 TWS 之间通信记录的日志文件,并提供有关 API 可以提供哪些内容的详细信息。

关于从IB系统开始的一般建议:

  • 在使用API之前,请熟悉TWS中的类似功能:TWS API只不过是客户端应用程序和TWS之间的通信通道。每个 API 函数在 TWS 中都有一个对应的工具。例如,API 中的市场数据tick类型对应于 TWS 中的观察列表列。任何可以在API中创建的订单都可以首先在TWS中创建,建议这样做。此外,如果信息在TWS中不可用,则API中将不可用。在将IB网关与API配合使用之前,建议先熟悉TWS。
  • 利用示例API应用程序:与API下载一起分发的示例应用程序基本上具有每种可用编程语言中每个API函数的示例。如果相应的示例应用程序中未出现问题,则表示自定义实现存在问题。
  • 定期升级TWS或IB网关:TWS和IB网关通常具有具有增强功能的新软件版本,有时可以修复错误。因此,我们强烈建议我们的用户尽可能保持其软件的最新状态。保留 API 版本和升级 TWS 没有问题,因为 TWS/IB 网关设计为向后兼容较旧的 API 版本。如果您遇到在TWS或IB网关中而不是在API程序中发生的特定问题,则很可能在最近的软件版本中不会发生该问题。

日志文件

日志文件对于提供有关自定义应用程序如何发生故障的详细信息至关重要。它们是 API 应用程序程序员直接审阅的有用工具,此外,还可以上传以供 API 支持组审阅。

接口日志

TWS和IB网关可以配置为创建一个单独的日志文件,该文件仅包含与API应用程序的通信记录。默认情况下不启用此日志。但需要通过全局配置设置创建 API 消息日志文件启用(下图)。

  • API 日志包含 API 应用程序与 TWS/IB 网关之间交换的消息记录。由于仅记录 API 消息,因此 API 日志更紧凑,更易于处理。但是,它们不包含有关TWS/ IBG的一般诊断信息作为TWS / IBG日志。默认情况下,TWS/IBG 设置文件夹是C:\Jts(或 Mac/Linux 上的 IBJts)。API 日志名为api.客户端 Id].[day].log,其中 [clientId] 对应于客户端应用程序用于连接到 TWS 的 Id,[day] 对应于工作日(即 api.123.Thu.log)。
  • 还有一个设置”在 API 日志中包含市场数据”,该设置将在 API 日志文件中包含流式市场数据值。历史蜡烛图数据始终记录在 API 日志中。

注意:在TWS Build 977中,API和TWS日志都在本地加密。API 日志可以解密以供从关联的 TWS 或 IB 网关会话进行查看,就像 TWS 日志一样,如描述日志的本地位置部分所示。

启用 API 日志的创建

TWS:

  • 导航到”文件/编辑→ API →设置→全局配置”
  • 选中创建API 消息日志文件复选框
  • 单击应用和确定
enable_api_log.png

IB网关:

  • 导航到”→设置”→ API →设置”。
  • 选中创建API 消息日志文件复选框
  • 单击应用和确定

TWS 日志文件

TWS 日志记录级别必须设置为”详细信息”级别,以记录与 API 相关的信息。默认情况下,它处于”错误”级别,记录最少的诊断信息。要捕获 API 消息,必须将日志记录级别更改为”详细信息”。请注意,与所有TWS/IBG设置一样,”日志记录级别”是针对不同用户以及TWS和IBG单独保存的。

  • 重要:在问题发生之前,必须将TWS/IB网关日志文件设置设置为”详细信息”级别,以便在问题发生时正确记录信息。但是,由于在此级别下将生成大量信息,因此生成的日志的大小可能会大大增加。因此,建议仅在对非常具体的问题进行故障排除和/或跟踪时才使用”详细信息”级别。这也可以从 API 客户端本身使用IBApi.EClient.setServerLogLevel函数完成。某些第三方应用程序(如 NinjaTrader)配置为在每次连接时调用此功能以设置 TWS 日志记录级别,因此要将 TWS 日志设置为”详细信息”,则必须在 API 客户端程序中完成此操作。

将 TWS 日志记录级别设置为详细信息的步骤

TWS:

  • 导航到”文件/编辑→ API →设置→全局配置”
  • 将*“日志记录级别”设置为“详细信息”*
logging_detail.png

IB网关:

  • 导航到”→设置”→ API →设置”。
  • 将*“日志记录级别”设置为“详细信息”*

日志的本地位置

日志存储在 Windows 计算机上的 TWS 设置目录 C:\Jts\ 中(默认设置可以在登录屏幕上进行不同的配置)。

日志文件目录的路径可以通过使用组合键盘命令 Ctrl-Alt-U从 TWS 或 IB 网关会话中找到。这将显示诸如 C:\Jts\detcfsvirl\ (在 Windows 上)之类的路径。

根据隐私法规,日志在保存到磁盘之前会进行加密。它们可以从关联的TWS或IB网关会话中解密。在 TWS 中:经典 TWS -> 帐户 ->诊断 -> TWS 日志。在 IB 网关中,文件 ->网关日志。

上传日志

  • 如果在出现问题期间已使用”创建 API 消息日志”设置启用了 API 日志记录,则可以使用组合 Ctrl-Alt-Q将其上传到 API 组,然后单击提交。如果日志已上传,请在”帐户管理”(在”支持”下)的消息中心创建一个网页,指示关联TWS会话的用户名,让 API 支持组知道。在某些情况下,还可以在详细日志记录级别请求 TWS 日志。TWS日志可能会变得非常大,并且可能无法通过自动方法上传;在这种情况下,可以找到另一种上传方式。

自动化系统的注意事项

自动化系统的注意事项

下订单注意事项

在通过API下订单并构建强大的交易系统时,监控回调通知非常重要,特别是对于IBApi.EWrapper.error,IBApi.EWrapper.orderStatus更改,IBApi.EWrapper.openOrder警告和IBApi.EWrapper.execDetails以确保正常运行。 如果您在通过 API 下达的订单时遇到问题,例如订单未填写,首先要检查的是这些回调返回的内容。您的订单可能已被拒绝或取消。如果需要,请参阅API 日志部分,了解有关获取 API 日志或提交日志以供审核的信息。

有关订单被拒绝、取消和警告的常见情况以及返回的相应消息,请参阅下文:

  • 如果订单受到大批量 (LGSZ) 拒绝,API 客户端将通过IBApi.EWrapper.error收到错误 (201)。错误文本将指示订单大小过大,并建议另一个较小的大小。
    • 斜体部分以文书为条件
    • 根据我们作为经纪商的监管义务,我们不接受您提交的 ### 股的大额限价订单。请提交较小的订单(不超过 ###)或将您的订单转换为算法订单 (IBALGO)
  • 如果订单需要经过价格检查,客户可能会通过IBApi.EWrapper.orderStatus和IBApi.EWrapper.error收到状态(已取消)+错误(202)。错误文本表示价格与当前价格相差太远。
    • 根据我们作为经纪商的监管义务,我们不能以您选择的限价#.###接受您的订单,因为它在市场上走得太远了。请使用更接近当前市场价格的限价#.##提交您的订单。
  • 客户可以通过IBApi.EWrapper.openOrder收到waringText,表明订单可能会受到价格上限的限制。
    • 如果您的订单没有立即执行,根据我们作为经纪商的监管义务,如果您的订单限价超过当前参考价格的允许距离,我们可能会根据市场情况拒绝您的订单。这旨在确保您的订单价格符合有序的市场,并减少您的订单对市场的影响。请注意,此类拒绝将导致您无法收到成交。

美国盈透证券优惠信息(新、老盈透用户均适用):

盈透证券优惠开户链接:https://www.e-investingguide.com/interactivebrokers

无论你是已经在盈透证券入金交易的老客户或者是正准备在盈透证券开户的新客户,如果你需要免除盈透证券每月10美元账户维护费以及降低盈透证券账户交易佣金水平(具体能优惠和降低多少,取决于你的交易量,已经入金交易的盈透用户也能挂靠降低佣金),都可以联系我,在IB盈透证券出入金及TWS软件使用、API接口使用、开立机构类账户(离岸对冲基金、家族办公室、自营交易集团)等方面遇到问题的也可以联系我询问。 可以发Email邮件联系我,我的邮箱地址是 giftlord@gmail.com

我的微信号:47268101 或者打开微信,直接扫描下方二维码添加我为好友即可咨询:

对 API 进行编程 :体系结构

EClientSocket 和 EWrapper Classes

一旦TWS启动运行并主动监听传入的连接,我们就可以编写代码了。这就把我们带到了TWS API的两个主要类:IBApi.EWrapper接口和IBApi.EClientSocket。

实现 EWrapper 接口

IBApi.EWrapper接口是 TWS 向 API 客户端应用程序传递信息的机制。通过实现此接口,客户端应用程序将能够接收和处理来自TWS的信息。有关如何实现接口的更多信息,请参阅编程语言的文档。

 class TestWrapper(wrapper.EWrapper):

电子客户端会话类

用于向TWS发送消息的类是IBApi.EClientSocket。与 EWrapper 不同,此类不会被重写,因为 EClientSocket 中提供的函数被调用以将消息发送到 TWS。要使用 EClientSocket,首先可能需要将IBApi.EWrapper接口实现为其构造函数参数的一部分,以便应用程序可以处理所有返回的消息。从TWS发送的消息作为对IBApi.EClientSocket中函数调用的响应需要EWrapper实现,以便可以处理它们以满足API客户端的需求。

另一个关键元素是传递给EClientSocket的构造函数的IBApi.EReaderSignal对象。除 Python 外,此对象在 API 中用于指示消息已准备好在队列中进行处理。(在 Python 中,Queue 类直接处理此任务)。我们将在ereader线程部分中更详细地讨论此对象。

class TestClient(EClient):
         def __init__(self, wrapper):
             EClient.__init__(self, wrapper)
             
class TestApp(TestWrapper, TestClient):
         def __init__(self):
             TestWrapper.__init__(self)
             TestClient.__init__(self, wrapper=self)

注意:EReaderSignal 类不用于 Python API。Python 队列模块用于线程间通信和数据交换。

连接

API 客户端应用程序和 TWS 之间的socket连接是使用IBApi.EClientSocket.eConnect函数建立的。TWS 充当服务器来接收来自 API 应用程序(客户端)的请求,并通过采取适当的操作进行响应。第一步是 API 客户端在 TWS 已在监听的socket端口上启动与 TWS 的连接。如果每个实例配置了不同的 API socket端口号,则可以在同一台计算机上运行多个 TWS 实例。此外,每个TWS会话可以同时接收多达32个不同的客户端应用程序。API 连接中指定的客户端 ID字段用于区分不同的 API 客户端。

建立 API 连接

一旦创建了我们的两个主要对象,EWrapper和ESocketClient,客户端应用程序就可以通过IBApi.EClientSocket对象进行连接:

app.connect("127.0.0.1", args.port, clientId=0)

eConnect 首先从操作系统请求将 TCP socket 打开到指定的 IP 地址和socket端口。如果无法打开socket,操作系统(不是TWS)会将 API 客户端收到的错误作为错误代码 502 返回到IBApi.EWrapper.error(注意:由于此错误不是由 TWS 生成的,因此不会在 TWS 日志文件中捕获)。最常见的错误 502 将指示 TWS 未在启用 API 的情况下运行,或者它正在监听其他socket端口上的连接。如果通过网络连接,则当防火墙或防病毒程序阻止连接,或者路由器的 IP 地址未在 TWS 的”受信任的 IP”中列出时,也会发生此错误。

打开socket后,必须进行初始握手,其中交换有关TWS和API支持的最高版本的信息。这一点很重要,因为 API 消息在不同的版本中可以具有不同的长度和字段,并且必须具有版本号才能正确解释收到的消息。

  • 因此,在建立连接之前,不要创建主ereader对象,这一点很重要。初始连接会在TWS和API客户端之间产生协商的通用版本,ereader线程在解释后续消息时需要该版本。

在建立可用于通信的最高版本号后,TWS 将返回与已登录的 TWS 用户会话特别对应的某些数据片段。这包括 (1) 在此 TWS 会话中可访问的帐号,(2) 下一个有效的订单标识符 (ID) 和 (3) 连接时间。在最常见的操作模式下,EClient.AsyncEConnect 字段设置为 false,并且在建立socket连接后立即完成初始握手。然后,TWS 将立即向 API 客户端提供此信息。

  • 重要提示: IBApi.EWrapper.nextValidID回调通常用于指示连接已完成,并且可以将其他消息从 API 客户端发送到 TWS。在此时间之前进行的函数调用可能会被 TWS 删除。

在特殊情况下,有一种替代的、已弃用的连接模式,其中变量 AsyncEconnect 设置为 true,并且仅从 connectAck() 函数调用 startAPI。所有 IB 样本都使用模式 AsyncEconnect = False。

ereader线程

API 程序始终至少有两个执行线程。一个线程用于将消息发送到 TWS,另一个线程用于读取返回的消息。第二个线程使用 API EReader 类从socket读取消息并将消息添加到队列中。每次将新消息添加到消息队列时,都会触发一个通知标志,以便现在有消息等待处理,让其他线程进入。在 API 程序的双线程设计中,消息队列也由第一个线程处理。在三线程设计中,将创建一个附加线程来执行此任务。负责消息队列的线程将解码消息并调用 EWrapper 中的相应函数。双线程设计用于 IB Python 示例 Program.py 和C++示例 TestCppClient,而其他语言中的”Testbed”示例使用三线程设计。通常在Python异步网络应用程序中,asyncio模块将用于创建更具顺序性的代码设计。

具有读取和分析来自TWS的原始消息的功能的类是IBApi.EReader类。

在Python IB API中,下面的代码包含在Client::connect()中,因此ereader线程在连接时自动启动。用户无需启动reader。

 # You don't need to run this in your code!
  self.reader = reader.EReader(self.conn, self.msg_queue)
  self.reader.start()   # start thread

连接客户端后,将自动创建一个reader线程来处理传入的消息,并将消息放入消息队列中以进行进一步处理。用户需要在下面触发 Client::run() ,其中消息队列在无限循环中处理,并且自动触发 EWrapper 回调函数。

app.run()

现在是时候重新审视IBApi.EReaderSignal最初在EClientSocket类中引入的角色了。如上一段所述,在ereader线程将消息放入队列后,将发出通知以表明消息已准备好进行处理。在(C++,C#/.NET,Java)API中,这是通过我们在IBApi.EWrapper的实现器中启动的IBApi.EReaderSignal对象完成的。在 Python API 中,它由 Queue自动处理。

客户端应用程序现在已准备好与交易者工作站配合使用!连接完成后,API程序将开始接收诸如IBApi.EWrapper.nextValidIdIBApi.EWrapper.managedAccounts之类的事件。在TWS(不是IB网关)中,如果有一个活动的网络连接,也会立即回调到IBApi::EWrapper::error,errorId为-1,errorCode= 2104,2106,errorMsg = “市场数据服务器正常”,以指示存在与IB市场数据服务器的活动连接。对IBApi::EWrapper::error的回调,如果 errorId 为 -1,则不代表真正的”错误”,而仅表示已成功连接到 IB 市场数据场的通知。

相比之下,IB网关在IB客户端发出请求之前不会与市场数据场建立连接。在此之前,IB 网关 GUI 中的连接指示器将显示黄色的”非活动”,而不是”活动”的绿色指示。

最初从 API 应用程序发出请求时,重要的是要验证是否收到了响应,而不是假设网络连接正常且订阅请求(产品组合更新、帐户信息等)已成功进行。

接受来自 TWS 的 API 连接

出于安全原因,默认情况下,API 未配置为自动接受来自 API 应用程序的连接请求。尝试连接后,TWS 中将出现一个对话框,要求用户手动确认是否可以建立连接:

conn_prompt.png

为了防止TWS要求最终用户接受连接,可以将其配置为自动接受来自受信任IP地址和/或本地计算机的连接。这可以通过TWS API设置轻松完成:

tws_allow_connections.png

注意:在尝试向TWS执行任何请求之前,您必须确保连接已完全建立。如果不这样做,将导致TWS关闭连接。通常,这可以通过等待事件的回调和初始连接握手的结束来完成,例如IBApi.EWrapper.nextValidIdIBApi.EWrapper.managedAccounts

在极少数情况下,IB网关或TWS在建立连接到IB服务器时有短暂的延迟,在收到nextValidId后立即发送的消息可能会被删除,并且需要重新发送。如果 API 客户端尚未收到来自已发出请求的预期回调,则不应继续进行排序,因为连接是否正常。

API socket连接断开

如果TWS和API客户端之间的socket连接有问题,例如,如果TWS突然关闭,这将在从socket读取的ereader线程中触发异常。如果 API 客户端尝试使用已在使用的客户端 ID 进行连接,也会发生此异常。

socket EOF 在不同 API 语言中的处理方式略有不同。例如,在Java中,它被捕获并发送到客户端应用程序IBApi::EWrapper::error,错误代码为507:“坏消息”。在 C# 中,它被捕获并发送到IBApi::EWrapper::error,错误代码为 -1。客户端应用程序需要处理此错误消息,并使用它来指示套接字连接中已引发异常。关联的函数(如IBApi::EWrapper::connectionClosedIBApi::EClient::IsConnected函数)不会由 API 代码自动调用,但需要在 API 客户端级别*进行处理。

  • API 版本 973.04 中已更改

原文出处:

云子量化, https://www.yunjinqi.top/article/71

云子量化, https://www.yunjinqi.top/article/72

Be the first to comment on "云子量化【盈透证券TWS API 官方文档翻译系列】3、TWS API的故障排除和支持以及TWS API的体系结构和连接"

Leave a comment