您的位置:首页 > 其它

TWS API 开发手记——连接到TWS平台

2017-04-21 14:48 501 查看

TWS API 开发手记——连接到TWS平台

TWS 是世界著名的盈透证券的交易平台,可以交易全球股票、期货、外汇等金融产品。而盈透证券的老板,又是一个以量化交易起家的传奇人物,因此在盈透很早的时候,就提供了基于TWS的API,供全世界的玩家开发出自己的交易系统。

因为个人兴趣爱好的原因,所以一直想开发一款属于自己的交易软件,后来注意到这个产品后,决定自己也试一试。



想要使用TWS,需要先去册盈透证券的官网注册投资者账号,并且在账号开通后三个月内向你的投资人账号打款以激活账号,否则注册了账号而不打款,三个月后账户就会被注销掉,也意味着你不能使用TWS进行下一步的开发了。



注册了账户、打入资金后,就可以在盈透证券的官网下载TWS交易客户端,同时还有IB API。IB API目前提供有Linux,Windows,MacOS三个系统的版本,根据你自己擅长的系统和语言,选择对应的API进行下载就行。这里笔者选择的是Windows,因为之后考虑做UI的时候,C#.NET 会十分方便。当然,笔者本人会Java,Python等语言技术,而且IB API的使用方法基本一致,所以也就无所谓语言的优劣,只要方便使用就好。

通信前准备

使用Windows编程,需要准备的是Visual Studio或者支持相关语言的开发工具和IDE,因为笔者用C#做这个项目,所以选择了Visual Studio。另一方面,因为Windows系统的限制,需要提前准备好程序的通信端口,并在防火墙、杀毒软件设置为打开。



通信前还需要做最后一个操作,打开TWS,并在全局设置中将允许连接打开,如果你只允许本地连接,那么点击“Allow connection from localhost only”就行,推荐这样做,因为比较安全。

开始编程

打开Visual studio并新建一个C#的工程,同时在工程“Solution Explorer”位置,找到工程的“References”,并添加IB API的DLL链接库。



IB API的库文件,存储于你安装的位置,只要找一找就能很容易找到。

工程目前包含两个主要文件,一个是Program.cs和TWSDeliverInterfaceImp.cs。

TWSDeliverInterfaceImp,是对EWrapper类的实现,这个是非常重要的一个类,包含了对所有事件的处理和响应,不过当前我们并不需要做太多的事件处理,因此可以把所有需要实现的方法空置即可。

using IBApi;
using System;
using System.Collections.Generic;

namespace AbsZeroTWS
{
class TWSDeliverInterfaceImp : EWrapper
{
private EClientSocket clientSocket;
private int nextOrderId;
private int clientId;

public TWSDeliverInterfaceImp(EReaderSignal signal)
{
clientSocket = new EClientSocket(this, signal);
}

public int ClientId
{
get { return clientId; }
set { clientId = value; }
}

public EClientSocket ClientSocket
{
get { return clientSocket; }
set { clientSocket = value; }
}

public int NextOrderId
{
get { return nextOrderId; }
set { nextOrderId = value; }
}

public void accountDownloadEnd(string account) { }
public void accountSummary(int reqId, string account, string tag, string value, string currency) { }
public void accountSummaryEnd(int reqId) { }
public void accountUpdateMulti(int requestId, string account, string modelCode, string key, string value, string currency) { }
public void accountUpdateMultiEnd(int requestId) { }
public void bondContractDetails(int reqId, ContractDetails contract) { }
public void commissionReport(CommissionReport commissionReport) { }
public void connectAck() { }
public void connectionClosed() { }
public void contractDetails(int reqId, ContractDetails contractDetails) { }
public void contractDetailsEnd(int reqId) { }
public void currentTime(long time) { }
public void deltaNeutralValidation(int reqId, UnderComp underComp) { }
public void displayGroupList(int reqId, string groups) { }
public void displayGroupUpdated(int reqId, string contractInfo) { }
public void error(string str) { }
public void error(Exception e) { }
public void error(int id, int errorCode, string errorMsg) { }
public void execDetails(int reqId, Contract contract, Execution execution) { }
public void execDetailsEnd(int reqId) { }
public void fundamentalData(int reqId, string data) { }
public void historicalData(int reqId, string date, double open, double high, double low, double close, int volume, int count, double WAP, bool hasGaps) { }
public void historicalDataEnd(int reqId, string start, string end) { }
public void managedAccounts(string accountsList) { }
public void marketDataType(int reqId, int marketDataType) { }
public void nextValidId(int orderId) { }
public void openOrder(int orderId, Contract contract, Order order, OrderState orderState) { }
public void openOrderEnd() { }
public void orderStatus(int orderId, string status, double filled, double remaining, double avgFillPrice, int permId, int parentId, double lastFillPrice, int clientId, string whyHeld) { }
public void position(string account, Contract contract, double pos, double avgCost) { }
public void positionEnd() { }
public void positionMulti(int requestId, string account, string modelCode, Contract contract, double pos, double avgCost) { }
public void positionMultiEnd(int requestId) { }
public void realtimeBar(int reqId, long time, double open, double high, double low, double close, long volume, double WAP, int count) { }
public void receiveFA(int faDataType, string faXmlData) { }
public void scannerData(int reqId, int rank, ContractDetails contractDetails, string distance, string benchmark, string projection, string legsStr) { }
public void scannerDataEnd(int reqId) { }
public void scannerParameters(string xml) { }
public void securityDefinitionOptionParameter(int reqId, string exchange, int underlyingConId, string tradingClass, string multiplier, HashSet<string> expirations, HashSet<double> strikes) { }
public void securityDefinitionOptionParameterEnd(int reqId) { }
public void softDollarTiers(int reqId, SoftDollarTier[] tiers) { }
public void tickEFP(int tickerId, int tickType, double basisPoints, string formattedBasisPoints, double impliedFuture, int holdDays, string futureLastTradeDate, double dividendImpact, double dividendsToLastTradeDate) { }
public void tickGeneric(int tickerId, int field, double value) { }
public void tickOptionComputation(int tickerId, int field, double impliedVolatility, double delta, double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice) { }
public void tickPrice(int tickerId, int field, double price, int canAutoExecute) { }
public void tickSize(int tickerId, int field, int size) { }
public void tickSnapshotEnd(int tickerId) { }
public void tickString(int tickerId, int field, string value) { }
public void updateAccountTime(string timestamp) { }
public void updateAccountValue(string key, string value, string currency, string accountName) { }
public void updateMktDepth(int tickerId, int position, int operation, int side, double price, int size) { }
public void updateMktDepthL2(int tickerId, int position, string marketMaker, int operation, int side, double price, int size) { }
public void updateNewsBulletin(int msgId, int msgType, string message, string origExchange) { }
public void updatePortfolio(Contract contract, double position, double marketPrice, double marketValue, double averageCost, double unrealisedPNL, double realisedPNL, string accountName) { }
public void verifyAndAuthCompleted(bool isSuccessful, string errorText) { }
public void verifyAndAuthMessageAPI(string apiData, string xyzChallenge) { }
public void verifyCompleted(bool isSuccessful, string errorText) { }
public void verifyMessageAPI(string apiData) { }
}
}


令一个类是主类,我们实现以下代码。

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

namespace AbsZeroTWS
{
class Program
{
static void Main(string[] args)
{
EReaderMonitorSignal signal = new EReaderMonitorSignal();
TWSDeliverInterfaceImp tws = new TWSDeliverInterfaceImp(signal);
tws.ClientSocket.eConnect("localhost", 7000, 0);

var reader = new EReader(tws.ClientSocket, signal);
reader.Start();

if (tws.ClientSocket.IsConnected())
{
Console.WriteLine("Connection is established!");
}
/*
new Thread(() => {
while (tws.ClientSocket.IsConnected())
{
signal.waitForSignal();
reader.processMsgs();
}
}) { IsBackground = true }.Start();
*/
Console.ReadKey();
}
}
}


点击运行后,程序就能跟TWS进行连接,并打印出connection is established.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: