C# - Interactive Brokers API - 获取市场数据

C# - Interactive Brokers API - get market data

我正在尝试使用 C# 中的基础 Interactive Broker API 来获取外汇市场数据。我的目标是获得多个货币对的出价和要价。

这是我现在拥有的。主要:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IBApi;

namespace TWS_Data
{
    class Program
    {
        static void Main(string[] args)
        {
            //IB's main object
            EWrapperImpl ibClient = new EWrapperImpl();

            //Connect
            ibClient.ClientSocket.eConnect("127.0.0.1", 7497, 0);

            //Creat and define a contract to fetch data for
            Contract contract = new Contract();
            contract.Symbol = "EUR";
            contract.SecType = "CASH";
            contract.Currency = "USD";
            contract.Exchange = "IDEALPRO";

            // Create a new TagValue List object (for API version 9.71) 
            List<TagValue> mktDataOptions = new List<TagValue>();


            // calling method every X seconds
            var timer = new System.Threading.Timer(
            e => ibClient.ClientSocket.reqMktData(1, contract, "", true, mktDataOptions),
            null,
            TimeSpan.Zero,
            TimeSpan.FromSeconds(10));

         }
    }
}

API函数"reqMktData"调用了以下两个函数:

        public virtual void tickSize(int tickerId, int field, int size)
        {
            Console.WriteLine("Tick Size. Ticker Id:" + tickerId + ", Field: " + field + ", Size: " + size + "\n");
        }

        public virtual void tickPrice(int tickerId, int field, double price, int canAutoExecute)
        {
            Console.WriteLine("Tick Price. Ticker Id:" + tickerId + ", Field:" + field + ", Price:" + price + ", CanAutoExecute: " + canAutoExecute + "\n");
            string str = Convert.ToString(price);
            System.IO.File.WriteAllText(@"C:\Users\XYZ\Documents\price.txt", str);
        }

在这段代码中,我试图将市场数据保存在我的硬盘上作为虚拟测试。但是,这里出现了我的问题。在一个 运行 期间,函数 tickPrice(..) 被调用 6 次并提供 6 种不同的价格(参见此处的 API 指南:https://www.interactivebrokers.com/en/software/api/apiguide/java/tickprice.htm

我现在需要知道的是在 C# 中如何以某种方式保存这些单独的结果? (它们都被发布到控制台中,但显然只有最后的价格是保存在文件中的价格)。

我非常熟悉 Matlab 编码,但对 C# 语法不熟悉。所以我不知何故以向量或循环的形式思考来解决这个问题,但它并不是那样工作的。

感谢任何帮助或提示

您可以使用列表来存储所有值,例如:

    List<string> priceList = new List<string>();
    public virtual void tickPrice(int tickerId, int field, double price, int canAutoExecute)
    {
        Console.WriteLine("Tick Price. Ticker Id:" + tickerId + ", Field:" + field + ", Price:" + price + ", CanAutoExecute: " + canAutoExecute + "\n");

        // here you add your prices to list
        priceList.Add(price);

        string str = Convert.ToString(price);
        System.IO.File.WriteAllText(@"C:\Users\XYZ\Documents\price.txt", str);
    }

从列表中获取最后一个条目:

    string lastPrice = priceList[priceList.Count - 1];

你的问题是 File.WriteAllText 覆盖文件的内容(如果存在)。这就是为什么您只看到最新数据的原因。

但是您需要的是将数据追加到文件中,例如:

  using (var file = File.AppendText(@"C:\Users\XYZ\Documents\price.txt"))
       file.WriteLine(str);

但是,我相信您订阅了多种工具并从不同的主题中收到报价。在这种情况下,有时您会遇到异常,该文件很忙,因此您需要更复杂的东西来记录数据(例如 NLog)。

我通过将回调中的值存储为先前创建的对象列表集合中的实例变量来完成此操作。

我从循环内部调用了 reqMarketData() 函数,并在主程序 class 中将循环的迭代设为静态整数,因此可以从 EWrapperImpl 中识别出来回调函数,例如 tickPrice().

循环遍历对象集合的长度(在我的例子中,每个基础合约对应一个对象)。这样,EWrapperImpl 回调中的以下示例代码会将每个请求的数据保存在集合中的一个对象中。

public virtual void tickPrice(int tickerId, int field, double price, int canAutoExecute)      
{         
  Program.exampleCollection[Program.exampleIteration].ExamplePriceVar = price;
}

然后您可以使用集合访问 EWrapperImpl 回调之外的数据。 (示例代码没有显示集合实例、对象实例或实例变量的创建)

解决您的数据被多次返回而不是一次的问题:

-您需要确定要将 price 用于哪个字段。无论如何,它都会为您提供多个字段。在您使用 tickPrice() 的情况下,每个字段代表不同类型的价格。

public virtual void tickPrice(int tickerId, int field, double price, int canAutoExecute)
    {
        if (field == 4)
        {
            //here, price is equal to the "last" price.
        }
        else
        {
        }

        if (field == 9)
        {
            //here, price is equal to the "close" price.
        }
        else
        {
        }
    }