我正在尝试将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函数&#34; reqMktData&#34;调用以下两个函数:
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#语法不熟悉。所以我在某种程度上以向量或循环的形式思考来解决这个问题,但它并没有以这种方式解决。
感谢您提供任何帮助或提示
答案 0 :(得分:1)
您可以使用List存储所有值,例如:
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];
答案 1 :(得分:1)
我是通过将回调中的值作为实例变量存储在先前创建的List对象集合中来实现的。
我在循环内调用了reqMarketData()
函数,并且我在主程序类中使循环迭代成为一个静态整数,因此可以从EWrapperImpl
&#39; s回调函数,例如tickPrice()
。
循环遍历对象集合的长度(在我的情况下,每个底层契约的一个对象)。这样,EWrapperImpl回调中的以下示例代码将保存集合中对象中每个请求的数据。
public virtual void tickPrice(int tickerId, int field, double price, int canAutoExecute)
{
Program.exampleCollection[Program.exampleIteration].ExamplePriceVar = price;
}
然后,您可以使用该集合访问EWrapperImpl
回调之外的数据。 (示例代码不显示集合实例,对象实例或实例变量的创建)
答案 2 :(得分:1)
要解决多次返回数据的问题,而不仅仅是一次:
- 您需要确定要使用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
{
}
}
答案 3 :(得分:0)
问题是File.WriteAllText
会覆盖文件内容(如果存在)。这就是为什么你只看到最新的数据。
但您需要的是将数据附加到文件,例如:
using (var file = File.AppendText(@"C:\Users\XYZ\Documents\price.txt"))
file.WriteLine(str);
但是,我相信您订阅了多种乐器并接收来自不同线程的滴答声。在这种情况下,在某些时候你会得到异常,那个文件很忙,所以你需要更复杂的东西来记录数据(例如NLog)。