我如何使用 Interactive Brokers Java API 检测订单何时成交?
How can I detect when an order fills using the Interactive Brokers Java API?
问题
IBKR TWS(交易者工作站)是 Interactive Brokers 用于管理股票市场股票订单的工具。他们提供 API 来自动执行订单,例如下订单、取消订单等。
我正在使用 Interactive Brokers Java [=48= 创建一个程序来 在我的 Trader Workstation 中处理已执行的订单 ].
我在检测订单何时成交时遇到问题。
documentation describes that the execDetails 回调(这是一个 EWrapper 方法,见下面的代码)在订单完成时被调用,但我尝试使用它并且 execDetails 回调从未被调用(我通过记录reqid int 在那个回调中,我从来没有得到任何日志)。
我还研究了 completedOrder 回调,我不确定这是否是订单成交时将调用的回调,因为我用一个简单的日志测试了这两个回调,但没有正在控制台输出。
我不明白 reqExecutions 功能以及我是否需要它。我已经阅读了有关此回调的文档,但我不明白我做错了什么。我想知道我如何使用他们的 API.
检测订单何时填充或在 TWS 中执行
代码
这是我当前的代码:
import com.ib.client.*;
import java.util.*;
public class Main implements EWrapper {
private static EClientSocket clientSocket;
private static EJavaSignal readerSignal;
public static void main(String[] args) throws InterruptedException, IOException {
readerSignal = new EJavaSignal();
clientSocket = new EClientSocket(this, readerSignal);
clientSocket.eConnect("127.0.0.1", 7497, 0);
}
clientSocket.placeOrder(orderidE, contractFill("CUSIP", "USD", tickSymbol, "STK", "SMART"), orderFill(lmtPriceDouble, actionString, "LMT", "GTC", orderQuantity, account, 0));
//Order executes successfully after sometime
public static Order orderFill(double lmtPrice, String action, String orderType, String tif, int totalQuantity, String account, int clientId){
Order order = new Order();
order.m_lmtPrice = lmtPrice;
order.m_action = action;
order.m_orderType = orderType;
order.m_tif = tif;
order.m_totalQuantity = totalQuantity;
order.m_account = account;
order.m_clientId = clientId;
return order;
}
public static Contract contractFill(String secIdType, String currency, String symbol, String secType, String exchange){
Contract contract = new Contract();
contract.m_secIdType = secIdType;
contract.m_currency = currency;
contract.m_symbol = symbol;
contract.m_secType = secType;
contract.m_exchange = exchange;
return contract;
}
/*Implemented EWrapper methods
...
*/
@Override
public void execDetails(int reqId, Contract contract, Execution execution) {
System.out.println(execution + " " + contract + " " + reqId);
}
@Override
public void execDetailsEnd(int reqId) {
System.out.println(reqId);
}
/*Implemented EWrapper methods
...
*/
@Override
public void completedOrder(Contract contract, Order order, OrderState orderState) {
System.out.println(contract);
System.out.println(order);
System.out.println(orderState);
}
@Override
public void completedOrdersEnd() {
System.out.println("cOE");
}/*Implemented rest of EWrapper methods
...
*/
}
我在代码为 运行 时手动下单,订单成交相当快(代码为 运行),因此代码应检测到它,但是(我的问题 -->)none 的回调被调用。
我应该做什么来检测订单执行情况?
(注意:我现在在 TWS 中手动和代码下订单)。
这是有效的代码,我用 api 9.81.
测试过
请注意,如果您使用的是 clientID 0,那么您还应该从 TWS 中的交易地点获得回调。我从未尝试过,但文档很清楚。
import com.ib.client.*;
import java.io.IOException;
import java.util.*;
public class MainIB implements EWrapper {
private EClientSocket clientSocket;
private EJavaSignal readerSignal;
public static void main(String[] args) throws IOException {
new MainIB().connect();
System.in.read();//press enter to exit
System.exit(0);
}
private void connect() {
readerSignal = new EJavaSignal();
clientSocket = new EClientSocket(this, readerSignal);
clientSocket.eConnect("127.0.0.1", 7497, 0);
//Create a reader to consume messages from the TWS. The EReader will consume the incoming messages and put them in a queue
EReader reader = new EReader(clientSocket, readerSignal);
reader.start();
//Once the messages are in the queue, an additional thread can be created to fetch them
Thread processer = new Thread(() -> {
while ( clientSocket.isConnected() ) {
readerSignal.waitForSignal();
try {
reader.processMsgs();
} catch (IOException ex) {}
}
});
processer.setDaemon(true);
processer.start();
}
public Order orderFill(double lmtPrice, String action, String orderType, String tif, int totalQuantity, String account, int clientId){
Order order = new Order();
order.lmtPrice(lmtPrice);
order.action(action);
order.orderType(orderType);
order.tif(tif);
order.totalQuantity(totalQuantity);
//order.account(account);
//order.clientId(clientId);
return order;
}
public Contract contractFill(String secIdType, String currency, String symbol, String secType, String exchange){
Contract contract = new Contract();
//contract.secIdType(secIdType);
contract.currency(currency);
contract.symbol(symbol);
contract.secType(secType);
contract.exchange(exchange);
return contract;
}
@Override
public void error(int id, int errorCode, String errorMsg) {
System.out.println(errorCode + " " + errorMsg);
}
@Override
public void nextValidId(int i) {
int orderidE = i;
clientSocket.placeOrder(orderidE++, contractFill("", "CAD", "USD", "CASH", "IDEALPRO"),
orderFill(0, "SELL", "MKT", "GTC", 100000, "", 0));
}
@Override
public void orderStatus(int i, String status, double d, double d1, double d2, int i1, int i2, double d3, int i3, String string1, double d4) {
System.out.println("status " + status);
}
@Override
public void execDetails(int reqId, Contract contract, Execution execution) {
System.out.println(execution + " " + contract + " " + reqId);
}
/*Implemented rest of EWrapper methods
...
*/
}
这是我的 api.Day.0.log 文件
的一部分
t:ms <-> msg# # desc
9:064 -> 15-1-DU123456- 15 my account #
9:065 -> 9-1-2- 9 next valid id
9:065 -> 4-2--1-2104-Market da 4 errors(or info)
9:065 -> 4-2--1-2104-Market da
9:072 <- 3-45-2-0-USD-CASH--0. <- 3 means an order I sent
9:671 -> 5-34-2-15016062-USD-C 5 order status
9:722 -> 11--1-2-15016062-USD- 11 exec
9:724 -> 5-34-2-15016062-USD-C more status
9:727 -> 5-34-2-15016062-USD-C
9:728 -> 59-1-0000e215.60b94f1 59 commission report
问题
IBKR TWS(交易者工作站)是 Interactive Brokers 用于管理股票市场股票订单的工具。他们提供 API 来自动执行订单,例如下订单、取消订单等。
我正在使用 Interactive Brokers Java [=48= 创建一个程序来 在我的 Trader Workstation 中处理已执行的订单 ].
我在检测订单何时成交时遇到问题。
documentation describes that the execDetails 回调(这是一个 EWrapper 方法,见下面的代码)在订单完成时被调用,但我尝试使用它并且 execDetails 回调从未被调用(我通过记录reqid int 在那个回调中,我从来没有得到任何日志)。
我还研究了 completedOrder 回调,我不确定这是否是订单成交时将调用的回调,因为我用一个简单的日志测试了这两个回调,但没有正在控制台输出。
我不明白 reqExecutions 功能以及我是否需要它。我已经阅读了有关此回调的文档,但我不明白我做错了什么。我想知道我如何使用他们的 API.
检测订单何时填充或在 TWS 中执行代码
这是我当前的代码:
import com.ib.client.*;
import java.util.*;
public class Main implements EWrapper {
private static EClientSocket clientSocket;
private static EJavaSignal readerSignal;
public static void main(String[] args) throws InterruptedException, IOException {
readerSignal = new EJavaSignal();
clientSocket = new EClientSocket(this, readerSignal);
clientSocket.eConnect("127.0.0.1", 7497, 0);
}
clientSocket.placeOrder(orderidE, contractFill("CUSIP", "USD", tickSymbol, "STK", "SMART"), orderFill(lmtPriceDouble, actionString, "LMT", "GTC", orderQuantity, account, 0));
//Order executes successfully after sometime
public static Order orderFill(double lmtPrice, String action, String orderType, String tif, int totalQuantity, String account, int clientId){
Order order = new Order();
order.m_lmtPrice = lmtPrice;
order.m_action = action;
order.m_orderType = orderType;
order.m_tif = tif;
order.m_totalQuantity = totalQuantity;
order.m_account = account;
order.m_clientId = clientId;
return order;
}
public static Contract contractFill(String secIdType, String currency, String symbol, String secType, String exchange){
Contract contract = new Contract();
contract.m_secIdType = secIdType;
contract.m_currency = currency;
contract.m_symbol = symbol;
contract.m_secType = secType;
contract.m_exchange = exchange;
return contract;
}
/*Implemented EWrapper methods
...
*/
@Override
public void execDetails(int reqId, Contract contract, Execution execution) {
System.out.println(execution + " " + contract + " " + reqId);
}
@Override
public void execDetailsEnd(int reqId) {
System.out.println(reqId);
}
/*Implemented EWrapper methods
...
*/
@Override
public void completedOrder(Contract contract, Order order, OrderState orderState) {
System.out.println(contract);
System.out.println(order);
System.out.println(orderState);
}
@Override
public void completedOrdersEnd() {
System.out.println("cOE");
}/*Implemented rest of EWrapper methods
...
*/
}
我在代码为 运行 时手动下单,订单成交相当快(代码为 运行),因此代码应检测到它,但是(我的问题 -->)none 的回调被调用。 我应该做什么来检测订单执行情况? (注意:我现在在 TWS 中手动和代码下订单)。
这是有效的代码,我用 api 9.81.
测试过请注意,如果您使用的是 clientID 0,那么您还应该从 TWS 中的交易地点获得回调。我从未尝试过,但文档很清楚。
import com.ib.client.*;
import java.io.IOException;
import java.util.*;
public class MainIB implements EWrapper {
private EClientSocket clientSocket;
private EJavaSignal readerSignal;
public static void main(String[] args) throws IOException {
new MainIB().connect();
System.in.read();//press enter to exit
System.exit(0);
}
private void connect() {
readerSignal = new EJavaSignal();
clientSocket = new EClientSocket(this, readerSignal);
clientSocket.eConnect("127.0.0.1", 7497, 0);
//Create a reader to consume messages from the TWS. The EReader will consume the incoming messages and put them in a queue
EReader reader = new EReader(clientSocket, readerSignal);
reader.start();
//Once the messages are in the queue, an additional thread can be created to fetch them
Thread processer = new Thread(() -> {
while ( clientSocket.isConnected() ) {
readerSignal.waitForSignal();
try {
reader.processMsgs();
} catch (IOException ex) {}
}
});
processer.setDaemon(true);
processer.start();
}
public Order orderFill(double lmtPrice, String action, String orderType, String tif, int totalQuantity, String account, int clientId){
Order order = new Order();
order.lmtPrice(lmtPrice);
order.action(action);
order.orderType(orderType);
order.tif(tif);
order.totalQuantity(totalQuantity);
//order.account(account);
//order.clientId(clientId);
return order;
}
public Contract contractFill(String secIdType, String currency, String symbol, String secType, String exchange){
Contract contract = new Contract();
//contract.secIdType(secIdType);
contract.currency(currency);
contract.symbol(symbol);
contract.secType(secType);
contract.exchange(exchange);
return contract;
}
@Override
public void error(int id, int errorCode, String errorMsg) {
System.out.println(errorCode + " " + errorMsg);
}
@Override
public void nextValidId(int i) {
int orderidE = i;
clientSocket.placeOrder(orderidE++, contractFill("", "CAD", "USD", "CASH", "IDEALPRO"),
orderFill(0, "SELL", "MKT", "GTC", 100000, "", 0));
}
@Override
public void orderStatus(int i, String status, double d, double d1, double d2, int i1, int i2, double d3, int i3, String string1, double d4) {
System.out.println("status " + status);
}
@Override
public void execDetails(int reqId, Contract contract, Execution execution) {
System.out.println(execution + " " + contract + " " + reqId);
}
/*Implemented rest of EWrapper methods
...
*/
}
这是我的 api.Day.0.log 文件
的一部分t:ms <-> msg# # desc
9:064 -> 15-1-DU123456- 15 my account #
9:065 -> 9-1-2- 9 next valid id
9:065 -> 4-2--1-2104-Market da 4 errors(or info)
9:065 -> 4-2--1-2104-Market da
9:072 <- 3-45-2-0-USD-CASH--0. <- 3 means an order I sent
9:671 -> 5-34-2-15016062-USD-C 5 order status
9:722 -> 11--1-2-15016062-USD- 11 exec
9:724 -> 5-34-2-15016062-USD-C more status
9:727 -> 5-34-2-15016062-USD-C
9:728 -> 59-1-0000e215.60b94f1 59 commission report