You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用IB TWS API C#批量获取Level II数据触发309错误咨询

解决IB API Level II数据请求触发309错误的问题

问题原因

你遇到的309错误核心原因是:IB API的reqMarketDepth和cancelMktDepth是异步操作。在你的同步循环中,调用cancelMktDepth后,服务器并不会立即终止对应请求——它需要先处理取消指令,再通过updateMktDepthEnd回调通知客户端取消完成。而你的循环在极短时间内连续发送多个请求,此时前一个请求的取消操作还未生效,并发请求数直接突破了IB限制的3个上限,触发了错误。

解决方案

必须改用异步回调驱动的串行/可控并发处理,确保只有在当前请求的取消确认(或数据接收完成)后,再发起下一个标的的请求。以下是具体实现思路和代码示例:

1. 改用队列+回调的串行处理模式

维护一个待处理标的队列,每次在收到当前标的的updateMktDepthEnd回调后,再发起下一个请求:

// 存储待处理的标的队列
private Queue<string> _symbolQueue = new Queue<string>();
// 当前使用的ticker ID
private int _currentTicker = 1;
// 复用合约对象
private IBApi.Contract _contract = new IBApi.Contract();

// 初始化标的队列并启动第一个请求
public void StartMarketDepthRequests(string filePath)
{
    // 读取所有标的到队列
    foreach (var line in File.ReadLines(filePath))
    {
        _symbolQueue.Enqueue(line);
    }
    // 发起第一个请求
    ProcessNextSymbol();
}

// 处理队列中的下一个标的
private void ProcessNextSymbol()
{
    if (_symbolQueue.Count == 0)
    {
        // 所有标的处理完成
        return;
    }

    var targetSymbol = _symbolQueue.Dequeue();
    // 配置合约参数
    _contract.Symbol = targetSymbol;
    _contract.SecType = "STK";
    _contract.Exchange = "SMART";
    _contract.Currency = "GBP";

    // 发起市场深度请求
    ibClient.ClientSocket.reqMarketDepth(_currentTicker, _contract, 5, true, new List<IBApi.TagValue>());
}

// 重写IB API的updateMktDepthEnd回调(需继承EWrapper接口)
public override void updateMktDepthEnd(int tickerId)
{
    // 确认当前请求完成,执行取消操作
    ibClient.ClientSocket.cancelMktDepth(tickerId, false);
    // 更新ticker ID
    _currentTicker++;
    // 处理下一个标的
    ProcessNextSymbol();
}

2. 补充说明

  • 若你的账户支持最多3个并发请求,也可以调整为同时发起3个请求,每个请求完成后补充新的,但串行处理是最稳妥的方式,避免触发限制。
  • 必须确保正确实现IB API的EWrapper接口,覆盖所有必要的回调方法,否则无法接收请求完成的通知。

内容的提问来源于stack exchange,提问作者Marc Jone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:20:33