From d37520f6a3e55660466112fe0de7b47835a6570b Mon Sep 17 00:00:00 2001 From: James Leigh Date: Tue, 24 Jan 2023 10:21:19 -0500 Subject: [PATCH] Add test sample code --- test/samples/dnhedge/DNHedgeOrder.java | 38 + test/samples/dnhedge/SampleDNHedge.java | 233 +++++ test/samples/rfq/RfqOrder.java | 27 + test/samples/rfq/SampleRfq.java | 447 +++++++++ test/samples/rfq/SimpleWrapper.java | 557 ++++++++++ test/samples/testbed/EWrapperImpl.java | 700 +++++++++++++ test/samples/testbed/Testbed.java | 949 ++++++++++++++++++ .../testbed/advisor/FAMethodSamples.java | 107 ++ .../testbed/contracts/ContractSamples.java | 601 +++++++++++ .../testbed/orders/AvailableAlgoParams.java | 312 ++++++ test/samples/testbed/orders/OrderSamples.java | 728 ++++++++++++++ .../scanner/ScannerSubscriptionSamples.java | 75 ++ 12 files changed, 4774 insertions(+) create mode 100644 test/samples/dnhedge/DNHedgeOrder.java create mode 100644 test/samples/dnhedge/SampleDNHedge.java create mode 100644 test/samples/rfq/RfqOrder.java create mode 100644 test/samples/rfq/SampleRfq.java create mode 100644 test/samples/rfq/SimpleWrapper.java create mode 100644 test/samples/testbed/EWrapperImpl.java create mode 100644 test/samples/testbed/Testbed.java create mode 100644 test/samples/testbed/advisor/FAMethodSamples.java create mode 100644 test/samples/testbed/contracts/ContractSamples.java create mode 100644 test/samples/testbed/orders/AvailableAlgoParams.java create mode 100644 test/samples/testbed/orders/OrderSamples.java create mode 100644 test/samples/testbed/scanner/ScannerSubscriptionSamples.java diff --git a/test/samples/dnhedge/DNHedgeOrder.java b/test/samples/dnhedge/DNHedgeOrder.java new file mode 100644 index 0000000..73b7e20 --- /dev/null +++ b/test/samples/dnhedge/DNHedgeOrder.java @@ -0,0 +1,38 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.dnhedge; + +import com.ib.client.Order; +import com.ib.client.OrderType; +import com.ib.client.Types.Action; +import com.ib.client.Types.VolatilityType; + +public class DNHedgeOrder extends Order { + public DNHedgeOrder(int clientId, int id, int size, String account, + String settlingFirm, int underConId, String designatedLocation) { + clientId(clientId); + orderId(id); + permId(id); + + account(account); + clearingIntent("AWAY"); + settlingFirm(settlingFirm); + + orderType(OrderType.VOL); + action(Action.BUY); + totalQuantity(size); + + volatility(0.1); + volatilityType(VolatilityType.Daily); + continuousUpdate(1); + deltaNeutralOrderType(OrderType.LMT); + + deltaNeutralConId(underConId); + deltaNeutralOpenClose("O"); + deltaNeutralShortSale(true); + + deltaNeutralDesignatedLocation(designatedLocation); + deltaNeutralShortSaleSlot(deltaNeutralDesignatedLocation().length() == 0 ? 1 : 2); + } +} diff --git a/test/samples/dnhedge/SampleDNHedge.java b/test/samples/dnhedge/SampleDNHedge.java new file mode 100644 index 0000000..706c6a1 --- /dev/null +++ b/test/samples/dnhedge/SampleDNHedge.java @@ -0,0 +1,233 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.dnhedge; + + +import com.ib.client.Contract; +import com.ib.client.ContractDetails; +import com.ib.contracts.OptContract; +import com.ib.contracts.StkContract; + +import samples.rfq.SimpleWrapper; + + +public class SampleDNHedge extends SimpleWrapper { + private enum Status { None, SecDef, Order, Done, Error } + + private static final int ParentAcked = 1; + private static final int ChildAcked = 2; + + private static final int AllAcked = ParentAcked | ChildAcked; + + private final Object m_mutex = new Object(); + private Status m_status = Status.None; + + private int m_clientId; + private int m_orderId; + + private String m_account; + private String m_settlingFirm; + private String m_designatedLocation; + + private Contract m_contract = null; + private int m_underConId = 0; + + private int m_receivedAcks = 0; + + public SampleDNHedge(int clientId, int orderId, String account, + String settlingFirm, String designatedLocation) { + + m_clientId = clientId; + m_orderId = orderId; + + m_account = account; + m_settlingFirm = settlingFirm; + m_designatedLocation = designatedLocation; + } + + public void testOrder() throws Exception { + connect(m_clientId); + + if (client() != null && client().isConnected()) { + try { + synchronized (m_mutex) { + + if (client().serverVersion() < 66) { + error ("Sample will not work with TWS older that 932"); + } + + while (m_status != Status.Done && + m_status != Status.Error) { + + if (m_status == Status.None) { + obtainContract(); + if (m_status != Status.Error && + m_status != Status.SecDef) { + submitOrder(); + } + } + m_mutex.wait(); + } + } + } + + finally { + disconnect(); + } + + if (m_status == Status.Done) { + + consoleMsg("Done"); + } + } + } + + private void obtainContract() { + m_contract = new OptContract("IBM", "20121019", 200, "CALL"); + m_contract.currency("USD"); + m_contract.multiplier("100"); + + Contract underlying = new StkContract("IBM"); + submitSecDef(1, underlying); + + m_status = Status.SecDef; + } + + private void submitSecDef(int reqId, Contract contract) { + consoleMsg("REQ: secDef " + reqId); + + client().reqContractDetails(reqId, contract); + } + + private void submitOrder() { + consoleMsg("REQ: order " + m_orderId); + + m_status = Status.Order; + + client().placeOrder(m_orderId, m_contract, + new DNHedgeOrder(m_clientId, m_orderId, 1, m_account, + m_settlingFirm, m_underConId, m_designatedLocation)); + } + + private void checkReceivedAllAcks() { + if ((m_receivedAcks & AllAcked) == AllAcked) { + m_status = Status.Done; + m_mutex.notify(); + } + } + + public void contractDetails(int reqId, ContractDetails contractDetails) { + consoleMsg("contractDetails: " + reqId); + + try { + synchronized (m_mutex) { + if (m_status == Status.SecDef) { + /* + * Store underConId if needed + */ + if (m_underConId == 0) { + m_underConId = contractDetails.contract().conid(); + } + + consoleMsg("using " + m_underConId + " for hedging"); + + /* + * And finally submit RFQ + */ + submitOrder(); + } + } + } + catch (Exception e) { + // will update status and notify main thread + error (e.toString()); + } + } + + public void contractDetailsEnd(int reqId) { + consoleMsg("contractDetailsEnd: " + reqId); + + try { + synchronized (m_mutex) { + if (m_status == Status.SecDef) { + error ("Could not find hedge contract id"); + } + } + } + catch (Exception e) { + // will update status and notify main thread + error (e.toString()); + } + } + + public void orderStatus(int orderId, String status, int filled, + int remaining, double avgFillPrice, int permId, int parentId, + double lastFillPrice, int clientId, String whyHeld) { + consoleMsg("orderStatus:" + orderId + " status=" + status); + + synchronized (m_mutex) { + if (status.equals("Cancelled")) { + m_status = Status.Error; + m_mutex.notify(); + } + else if (status.equals("Submitted") || + status.equals("PreSubmitted")) { + + if (orderId == m_orderId) { + m_receivedAcks |= ParentAcked; + } + else if (orderId < 0) { + m_receivedAcks |= ChildAcked; + } + + checkReceivedAllAcks(); + } + } + } + + public void error(String str) { + consoleMsg("Error=" + str); + + synchronized (m_mutex) { + m_status = Status.Error; + m_mutex.notify(); + } + } + + public void error(int id, int errorCode, String errorMsg) { + consoleMsg("Error id=" + id + " code=" + errorCode + " msg=" + errorMsg); + + if (errorCode >= 2100 && errorCode < 2200) { + return; + } + + synchronized (m_mutex) { + m_status = Status.Error; + m_mutex.notify(); + } + } + + /* *************************************************************** + * Main Method + *****************************************************************/ + public static void main(String[] args) { + try { + if (args.length < 2) { + System.err.println("Account and settlingFirm parameters " + + "are required"); + return; + } + + int orderId = (int) (System.currentTimeMillis() / 1000); + String account = args[0]; + String settlingFirm = args[1]; + String designatedLocation = (args.length >= 3) ? args[2] : ""; + SampleDNHedge ut = new SampleDNHedge(/* clientId */ 2, orderId, + account, settlingFirm, designatedLocation); + ut.testOrder(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/test/samples/rfq/RfqOrder.java b/test/samples/rfq/RfqOrder.java new file mode 100644 index 0000000..891dd41 --- /dev/null +++ b/test/samples/rfq/RfqOrder.java @@ -0,0 +1,27 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.rfq; + +import com.ib.client.Order; +import com.ib.client.OrderType; + +public class RfqOrder extends Order { + + public RfqOrder(int clientId, int id, int size) { + + clientId(clientId); + orderId(id); + permId(id); + totalQuantity(size); + orderType(OrderType.QUOTE); + + /* + * Note: this will be overridden by the backend + * because it could not keep such order + * (and it does not make too much sense) + */ + transmit(false); + } +} + diff --git a/test/samples/rfq/SampleRfq.java b/test/samples/rfq/SampleRfq.java new file mode 100644 index 0000000..fb7aa78 --- /dev/null +++ b/test/samples/rfq/SampleRfq.java @@ -0,0 +1,447 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.rfq; + +import java.util.ArrayList; + +import com.ib.client.ComboLeg; +import com.ib.client.Contract; +import com.ib.client.ContractDetails; +import com.ib.client.DeltaNeutralContract; +import com.ib.client.TickType; +import com.ib.contracts.ComboContract; +import com.ib.contracts.FutContract; +import com.ib.contracts.OptContract; +import com.ib.contracts.StkContract; + + +public class SampleRfq extends SimpleWrapper { + private enum Status { None, SecDef, SecDefFMF, Rfq, Ticks, Done, Error } + + private static final int MaskBidPrice = 1; + private static final int MaskAskPrice = 2; + private static final int MaskBidSize = 4; + private static final int MaskAskSize = 8; + + private static final int MaskRecvAll = MaskBidPrice | MaskBidSize | + MaskAskPrice | MaskAskSize ; + + private final Object m_mutex = new Object(); + private Status m_status = Status.None; + + private int m_clientId; + private int m_rfqId; + private int m_mode; + + private Contract m_contract = null; + + private int m_underConId = 0; + + private boolean m_needFrontMonthFuture = false; + private Contract m_frontMonthFuture = null; + private int m_frontMonthFutureLastTradeDate = 0; + private int m_frontMonthFutureMult = 0; + + private double m_bidPrice = 0; + private double m_askPrice = 0; + + private int m_bidSize = 0; + private int m_askSize = 0; + + private int m_receivedTicks = 0; + + public SampleRfq(int clientId, int rfqId, int mode) { + m_clientId = clientId; + m_rfqId = rfqId; + m_mode = mode; + } + + public void testOrder() throws Exception { + int clientId = 2; + connect(clientId); + + if (client() != null && client().isConnected()) { + try { + synchronized (m_mutex) { + if (client().serverVersion() < 42) { + error ("Sample will not work with TWS older that 877"); + } + + while (m_status != Status.Done && + m_status != Status.Error) { + + if (m_status == Status.None) { + obtainContract(); + if (m_status != Status.Error && + m_status != Status.SecDef) { + submitRfq(); + } + } + m_mutex.wait(); + } + } + } + finally { + disconnect(); + } + + if (m_status == Status.Done) { + String msg = "Done, bid=" + m_bidSize + "@" + m_bidPrice + + " ask=" + m_askSize + "@" + m_askPrice; + + DeltaNeutralContract deltaNeutralContract = m_contract.deltaNeutralContract(); + if (deltaNeutralContract != null) { + msg += " DN: conId=" + deltaNeutralContract.conid() + + " price=" + deltaNeutralContract.price() + + " delta=" + deltaNeutralContract.delta(); + } + consoleMsg(msg); + } + } + } + + private void obtainContract() { + switch (m_mode) { + case 0: + m_contract = new StkContract("IBM"); + m_contract.currency("EUR"); + break; + case 1: + m_contract = new FutContract("IBM", "200809"); + break; + case 2: + m_contract = new OptContract("IBM", "200809", 120, "CALL"); + break; + case 3: + m_contract = new OptContract("Z", "LIFFE", "200809", 54.75, "CALL"); + m_contract.currency("GBP"); + break; + case 4: + m_contract = new ComboContract("Z", "GBP", "LIFFE"); + m_contract.comboLegs(new ArrayList<>(2)); + { + Contract l1 = new OptContract("Z", "LIFFE", "200809", 54.75, "CALL"); + l1.currency("GBP"); + submitSecDef(1, l1); + } + { + Contract l2 = new OptContract("Z", "LIFFE", "200810", 55.00, "CALL"); + l2.currency("GBP"); + submitSecDef(2, l2); + } + m_status = Status.SecDef; + break; + case 5: + m_contract = new ComboContract("IBM"); + m_contract.comboLegs(new ArrayList<>(1)); + m_contract.deltaNeutralContract(new DeltaNeutralContract()); + //m_contract.m_deltaNeutralContract.m_delta = 0.8; + // m_contract.m_deltaNeutralContract.m_price = 120; + { + Contract l1 = new OptContract("IBM", "200809", 120, "CALL"); + submitSecDef(1, l1); + } + m_status = Status.SecDef; + break; + case 6: + m_contract = new ComboContract("RUT"); + m_contract.comboLegs(new ArrayList<>(1)); + m_contract.deltaNeutralContract(new DeltaNeutralContract()); + m_needFrontMonthFuture = true; + { + Contract l1 = new OptContract("RUT", "200809", 740, "CALL"); + submitSecDef(1, l1); + } + m_status = Status.SecDef; + break; + case 7: + m_contract = new ComboContract("Z", "GBP", "LIFFE"); + m_contract.comboLegs(new ArrayList<>(1)); + m_contract.deltaNeutralContract(new DeltaNeutralContract()); + m_needFrontMonthFuture = true; + { + Contract l1 = new OptContract("Z", "LIFFE", "200808", 55.00, "CALL"); + l1.currency("GBP"); + submitSecDef(1, l1); + } + m_status = Status.SecDef; + break; + default: + break; + } + } + + private void submitSecDef(int reqId, Contract contract) { + consoleMsg("REQ: secDef " + reqId); + client().reqContractDetails(reqId, contract); + } + + private void submitRfq() { + consoleMsg("REQ: rfq " + m_rfqId); + + m_status = m_contract.deltaNeutralContract() != null ? Status.Rfq : Status.Ticks; + + client().placeOrder(m_rfqId, m_contract, new RfqOrder(m_clientId, m_rfqId, 1)); + } + + private void checkReceivedAllTicks() { + if ((m_receivedTicks & MaskRecvAll) == MaskRecvAll) { + m_status = Status.Done; + m_mutex.notify(); + } + } + + public void contractDetails(int reqId, ContractDetails contractDetails) { + consoleMsg("contractDetails: " + reqId); + + try { + synchronized (m_mutex) { + if (m_status == Status.SecDef) { + /* + * Note: we are requesting SecDefs only if we need Combo's + */ + + int legId = reqId - 1; + + ComboLeg comboLeg = new ComboLeg( + contractDetails.contract().conid(), /* ratio */ 1, + (reqId == 1 ? "BUY" : "SELL"), m_contract.exchange(), 0); + + m_contract.comboLegs().set(legId, comboLeg); + + /* + * Do we have all legs? + */ + for (int i = 0; i < m_contract.comboLegs().size(); ++i) { + if (i == legId) + continue; + if (m_contract.comboLegs().get(i) == null) + return; + } + + if (m_contract.deltaNeutralContract() != null) { + /* + * Store underConId if needed + */ + if (m_underConId == 0) { + m_underConId = contractDetails.underConid(); + } + + /* + * Do we need to request front month future for hedging? + */ + + if (m_needFrontMonthFuture) { + m_status = Status.SecDefFMF; + + Contract futContract = new FutContract( + contractDetails.contract().symbol(), + /* all expirations */ "", + contractDetails.contract().currency()); + + submitSecDef(0, futContract); + return; + } + + consoleMsg("using " + m_underConId + " for hedging"); + m_contract.deltaNeutralContract().conid(m_underConId); + } + + /* + * And finally submit RFQ + */ + submitRfq(); + } + else if (m_status == Status.SecDefFMF) { + /* + * Ignore unknown reqId's + */ + if (reqId != 0) { + return; + } + + /* + * Ignore secDefs with different underConId + */ + if (contractDetails.underConid() != m_underConId) { + return; + } + + Contract contract = contractDetails.contract(); + + /* + * Check if we have a better match + */ + int contractLastTradeDate = Integer.parseInt(contract.lastTradeDateOrContractMonth()); + int contractMult = Integer.parseInt(contract.multiplier()); + + if (m_frontMonthFuture != null) { + if (m_frontMonthFutureLastTradeDate <= contractLastTradeDate) { + return; + } + if (m_frontMonthFutureLastTradeDate == contractLastTradeDate && + m_frontMonthFutureMult <= contractMult) { + return; + } + } + + m_frontMonthFuture = contract; + m_frontMonthFutureLastTradeDate = contractLastTradeDate; + m_frontMonthFutureMult = contractMult; + } + } + } + catch (Exception e) { + // will update status and notify main thread + error (e.toString()); + } + } + + public void contractDetailsEnd(int reqId) { + consoleMsg("contractDetailsEnd: " + reqId); + + try { + synchronized (m_mutex) { + if (m_status == Status.SecDefFMF) { + + if (reqId != 0) { + // ignore details end for leg requests + return; + } + + if (m_frontMonthFuture == null) { + error ("Could not find front month future for hedging"); + return; + } + + consoleMsg("using " + m_frontMonthFuture.conid() + + " for hedging"); + + m_contract.deltaNeutralContract().conid(m_frontMonthFuture.conid()); + + /* + * And finally submit RFQ + */ + submitRfq(); + } + } + } + catch (Exception e) { + // will update status and notify main thread + error (e.toString()); + } + } + + public void deltaNeutralValidation(int reqId, DeltaNeutralContract deltaNeutralContract) { + consoleMsg("deltaNeutralValidation:" + reqId); + + synchronized (m_mutex) { + if (m_status == Status.Rfq) { + if (reqId != m_rfqId) { + // unexpected dn validation + return; + } + + // update deltaNeutralContract + m_contract.deltaNeutralContract(deltaNeutralContract); + m_status = Status.Ticks; + } + } + } + public void orderStatus(int orderId, String status, int filled, + int remaining, double avgFillPrice, int permId, int parentId, + double lastFillPrice, int clientId, String whyHeld) { + consoleMsg("orderStatus:" + orderId + " status=" + status); + + synchronized (m_mutex) { + if (status.equals("Cancelled")) { + m_status = Status.Error; + m_mutex.notify(); + } + } + } + + public void tickPrice(int tickerId, int field, double price, int canAutoExecute) { + TickType tick = TickType.get(field); + consoleMsg("tickPrice:" + tickerId + " field:" + field + + " (" + tick.field() + ") value:" + price); + + synchronized (m_mutex) { + if (m_status == Status.Ticks) { + switch (tick) { + case BID: + m_bidPrice = price; + m_receivedTicks |= MaskBidPrice; + break; + case ASK: + m_askPrice = price; + m_receivedTicks |= MaskAskPrice; + break; + default: break; + } + checkReceivedAllTicks(); + } + } + } + + public void tickSize(int tickerId, int field, int size) { + TickType tick = TickType.get(field); + consoleMsg("tickSize:" + tickerId + " field:" + field + + " (" + tick.field() + ") value:" + size); + + synchronized (m_mutex) { + if (m_status == Status.Ticks) { + switch (tick) { + case BID_SIZE: + m_bidSize = size; + if (!(m_bidSize == 0 && m_bidPrice == -1)) { + m_receivedTicks |= MaskBidSize; + } + break; + case ASK_SIZE: + m_askSize = size; + if (!(m_askSize == 0 && m_askPrice == -1)) { + m_receivedTicks |= MaskAskSize; + } + break; + default: break; + } + checkReceivedAllTicks(); + } + } + } + + public void error(String str) { + consoleMsg("Error=" + str); + synchronized (m_mutex) { + m_status = Status.Error; + m_mutex.notify(); + } + } + + public void error(int id, int errorCode, String errorMsg) { + consoleMsg("Error id=" + id + " code=" + errorCode + " msg=" + errorMsg); + if (errorCode >= 2100 && errorCode < 2200) { + return; + } + synchronized (m_mutex) { + m_status = Status.Error; + m_mutex.notify(); + } + } + + /* *************************************************************** + * Main Method + *****************************************************************/ + public static void main(String[] args) { + try { + int rfqId = (int) (System.currentTimeMillis() / 1000); + int mode = (args.length > 0) ? Integer.parseInt(args[0]) : 0; + SampleRfq ut = new SampleRfq(/* clientId */ 2, rfqId, mode); + ut.testOrder(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/test/samples/rfq/SimpleWrapper.java b/test/samples/rfq/SimpleWrapper.java new file mode 100644 index 0000000..5dbd678 --- /dev/null +++ b/test/samples/rfq/SimpleWrapper.java @@ -0,0 +1,557 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.rfq; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.swing.SwingUtilities; + +import com.ib.client.*; + + +public class SimpleWrapper implements EWrapper { + private static final int MAX_MESSAGES = 1000000; + private final static SimpleDateFormat m_df = new SimpleDateFormat("HH:mm:ss"); + + // main client + private EJavaSignal m_signal = new EJavaSignal(); + private EClientSocket m_client = new EClientSocket(this, m_signal); + + // utils + private long ts; + private PrintStream m_output; + private int m_outputCounter = 0; + private int m_messageCounter; + + protected EClientSocket client() { return m_client; } + + protected SimpleWrapper() { + initNextOutput(); + attachDisconnectHook(this); + } + + public void connect() { + connect(1); + } + + public void connect(int clientId) { + String host = System.getProperty("jts.host"); + host = host != null ? host : ""; + m_client.eConnect(host, 7497, clientId); + + final EReader reader = new EReader(m_client, m_signal); + + reader.start(); + + new Thread(() -> { + while (m_client.isConnected()) { + m_signal.waitForSignal(); + try { + SwingUtilities.invokeAndWait(() -> { + try { + reader.processMsgs(); + } catch (IOException e) { + error(e); + } + }); + } catch (Exception e) { + error(e); + } + } + }).start(); + } + + public void disconnect() { + m_client.eDisconnect(); + } + + /* *************************************************************** + * AnyWrapper + *****************************************************************/ + + public void error(Exception e) { + e.printStackTrace(m_output); + } + + public void error(String str) { + m_output.println(str); + } + + public void error(int id, int errorCode, String errorMsg) { + logIn("Error id=" + id + " code=" + errorCode + " msg=" + errorMsg); + } + + public void connectionClosed() { + m_output.println("--------------------- CLOSED ---------------------"); + } + + /* *************************************************************** + * EWrapper + *****************************************************************/ + + public void tickPrice(int tickerId, int field, double price, TickAttrib attribs) { + logIn("tickPrice"); + } + + public void tickSize(int tickerId, int field, int size) { + logIn("tickSize"); + } + + public void tickGeneric(int tickerId, int tickType, double value) { + logIn("tickGeneric"); + } + + public void tickString(int tickerId, int tickType, String value) { + logIn("tickString"); + } + + public void tickSnapshotEnd(int tickerId) { + logIn("tickSnapshotEnd"); + } + + @Override + public void tickOptionComputation(int tickerId, int field, int tickAttrib, double impliedVol, + double delta, double optPrice, double pvDividend, + double gamma, double vega, double theta, double undPrice) { + logIn("tickOptionComputation"); + } + + public void tickEFP(int tickerId, int tickType, double basisPoints, + String formattedBasisPoints, double impliedFuture, int holdDays, + String futureLastTradeDate, double dividendImpact, double dividendsToLastTradeDate) { + logIn("tickEFP"); + } + + public void orderStatus(int orderId, String status, double filled, double remaining, + double avgFillPrice, int permId, int parentId, double lastFillPrice, + int clientId, String whyHeld, double mktCapPrice) { + logIn("orderStatus"); + } + + public void openOrder(int orderId, Contract contract, Order order, OrderState orderState) { + logIn("openOrder"); + } + + public void openOrderEnd() { + logIn("openOrderEnd"); + } + + public void updateAccountValue(String key, String value, String currency, String accountName) { + logIn("updateAccountValue"); + } + + public void updatePortfolio(Contract contract, double position, double marketPrice, double marketValue, + double averageCost, double unrealizedPNL, double realizedPNL, String accountName) { + logIn("updatePortfolio"); + } + + public void updateAccountTime(String timeStamp) { + logIn("updateAccountTime"); + } + + public void accountDownloadEnd(String accountName) { + logIn("accountDownloadEnd"); + } + + public void nextValidId(int orderId) { + logIn("nextValidId"); + } + + public void contractDetails(int reqId, ContractDetails contractDetails) { + logIn("contractDetails"); + } + + public void contractDetailsEnd(int reqId) { + logIn("contractDetailsEnd"); + } + + public void bondContractDetails(int reqId, ContractDetails contractDetails) { + logIn("bondContractDetails"); + } + + public void execDetails(int reqId, Contract contract, Execution execution) { + logIn("execDetails"); + } + + public void execDetailsEnd(int reqId) { + logIn("execDetailsEnd"); + } + + public void updateMktDepth(int tickerId, int position, int operation, int side, double price, int size) { + logIn("updateMktDepth"); + } + + public void updateMktDepthL2(int tickerId, int position, String marketMaker, int operation, + int side, double price, int size, boolean isSmartDepth) { + logIn("updateMktDepthL2"); + } + + public void updateNewsBulletin(int msgId, int msgType, String message, String origExchange) { + logIn("updateNewsBulletin"); + } + + public void managedAccounts(String accountsList) { + logIn("managedAccounts"); + } + + public void receiveFA(int faDataType, String xml) { + logIn("receiveFA"); + } + + @Override + public void replaceFAEnd(int faDataType, String xml) { + logIn("replaceFAEnd"); + } + + public void historicalData(int reqId, Bar bar) { + logIn("historicalData"); + } + + public void scannerParameters(String xml) { + logIn("scannerParameters"); + } + + public void scannerData(int reqId, int rank, ContractDetails contractDetails, String distance, + String benchmark, String projection, String legsStr) { + logIn("scannerData"); + } + + public void scannerDataEnd(int reqId) { + logIn("scannerDataEnd"); + } + + public void realtimeBar(int reqId, long time, double open, double high, double low, double close, + long volume, double wap, int count) { + logIn("realtimeBar"); + } + + public void currentTime(long millis) { + logIn("currentTime"); + } + + public void fundamentalData(int reqId, String data) { + logIn("fundamentalData"); + } + + public void deltaNeutralValidation(int reqId, DeltaNeutralContract deltaNeutralContract) { + logIn("deltaNeutralValidation"); + } + + public void marketDataType(int reqId, int marketDataType) { + logIn("marketDataType"); + } + + public void commissionReport(CommissionReport commissionReport) { + logIn("commissionReport"); + } + + + public void position(String account, Contract contract, double pos, double avgCost) { + logIn("position"); + } + + public void positionEnd() { + logIn("positionEnd"); + } + + public void accountSummary( int reqId, String account, String tag, String value, String currency) { + logIn("accountSummary"); + } + + public void accountSummaryEnd( int reqId) { + logIn("accountSummaryEnd"); + } + + public void verifyMessageAPI( String apiData) { + logIn("verifyMessageAPI"); + } + + public void verifyCompleted( boolean isSuccessful, String errorText){ + logIn("verifyCompleted"); + } + + public void verifyAndAuthMessageAPI( String apiData, String xyzChallenge) { + logIn("verifyAndAuthMessageAPI"); + } + + public void verifyAndAuthCompleted( boolean isSuccessful, String errorText){ + logIn("verifyAndAuthCompleted"); + } + + public void displayGroupList( int reqId, String groups){ + logIn("displayGroupList"); + } + + public void displayGroupUpdated( int reqId, String contractInfo){ + logIn("displayGroupUpdated"); + } + + public void positionMulti( int reqId, String account, String modelCode, Contract contract, double pos, double avgCost) { + logIn("positionMulti"); + } + + public void positionMultiEnd( int reqId) { + logIn("positionMultiEnd"); + } + + public void accountUpdateMulti( int reqId, String account, String modelCode, String key, String value, String currency) { + logIn("accountUpdateMulti"); + } + + public void accountUpdateMultiEnd( int reqId) { + logIn("accountUpdateMultiEnd"); + } + + /* *************************************************************** + * Helpers + *****************************************************************/ + protected void logIn(String method) { + m_messageCounter++; + if (m_messageCounter == MAX_MESSAGES) { + m_output.close(); + initNextOutput(); + m_messageCounter = 0; + } + m_output.println("[W] > " + method); + } + + protected static void consoleMsg(String str) { + System.out.println(Thread.currentThread().getName() + " (" + tsStr() + "): " + str); + } + + protected static String tsStr() { + synchronized (m_df) { + return m_df.format(new Date()); + } + } + + protected static void sleepSec(int sec) { + sleep(sec * 1000); + } + + private static void sleep(int msec) { + try { + Thread.sleep(msec); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + protected void swStart() { + ts = System.currentTimeMillis(); + } + + protected void swStop() { + long dt = System.currentTimeMillis() - ts; + m_output.println("[API]" + " Time=" + dt); + } + + private void initNextOutput() { + try { + m_output = new PrintStream(new File("sysout_" + (++m_outputCounter) + ".log"), "UTF-8"); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + private static void attachDisconnectHook(final SimpleWrapper ut) { + Runtime.getRuntime().addShutdownHook(new Thread(ut::disconnect)); + } + + public void connectAck() { + m_client.startAPI(); + } + + @Override + public void securityDefinitionOptionalParameter(int reqId, String exchange, int underlyingConId, String tradingClass, + String multiplier, Set expirations, Set strikes) { + // TODO Auto-generated method stub + + } + + @Override + public void securityDefinitionOptionalParameterEnd(int reqId) { + // TODO Auto-generated method stub + + } + + @Override + public void softDollarTiers(int reqId, SoftDollarTier[] tiers) { + // TODO Auto-generated method stub + + } + + @Override + public void familyCodes(FamilyCode[] familyCodes) { + // TODO Auto-generated method stub + + } + + @Override + public void symbolSamples(int reqId, ContractDescription[] contractDescriptions) { + // TODO Auto-generated method stub + + } + @Override + public void historicalDataEnd(int reqId, String startDateStr, String endDateStr) { + // TODO Auto-generated method stub + + } + + @Override + public void mktDepthExchanges(DepthMktDataDescription[] depthMktDataDescriptions) { + // TODO Auto-generated method stub + + } + + @Override + public void tickNews(int tickerId, long timeStamp, String providerCode, String articleId, String headline, + String extraData) { + // TODO Auto-generated method stub + + } + + @Override + public void smartComponents(int reqId, Map> theMap) { + // TODO Auto-generated method stub + + } + + @Override + public void tickReqParams(int tickerId, double minTick, String bboExchange, int snapshotPermissions) { + // TODO Auto-generated method stub + + } + + @Override + public void newsProviders(NewsProvider[] newsProviders) { + // TODO Auto-generated method stub + + } + + @Override + public void newsArticle(int requestId, int articleType, String articleText) { + // TODO Auto-generated method stub + + } + + @Override + public void historicalNews(int requestId, String time, String providerCode, String articleId, String headline) { + // TODO Auto-generated method stub + + } + + @Override + public void historicalNewsEnd(int requestId, boolean hasMore) { + // TODO Auto-generated method stub + + } + + @Override + public void headTimestamp(int reqId, String headTimestamp) { + // TODO Auto-generated method stub + + } + + @Override + public void histogramData(int reqId, List items) { + // TODO Auto-generated method stub + + } + + @Override + public void historicalDataUpdate(int reqId, Bar bar) { + // TODO Auto-generated method stub + + } + + @Override + public void pnl(int reqId, double dailyPnL, double unrealizedPnL, double realizedPnL) { + // TODO Auto-generated method stub + + } + + @Override + public void rerouteMktDataReq(int reqId, int conId, String exchange) { + // TODO Auto-generated method stub + + } + + @Override + public void rerouteMktDepthReq(int reqId, int conId, String exchange) { + // TODO Auto-generated method stub + + } + + @Override + public void marketRule(int marketRuleId, PriceIncrement[] priceIncrements) { + // TODO Auto-generated method stub + + } + + @Override + public void pnlSingle(int reqId, int pos, double dailyPnL, double unrealizedPnL, double realizedPnL, double value) { + // TODO Auto-generated method stub + + } + + @Override + public void historicalTicks(int reqId, List ticks, boolean last) { + // TODO Auto-generated method stub + + } + + @Override + public void historicalTicksBidAsk(int reqId, List ticks, boolean done) { + // TODO Auto-generated method stub + + } + + + @Override + public void historicalTicksLast(int reqId, List ticks, boolean done) { + // TODO Auto-generated method stub + + } + + @Override + public void tickByTickAllLast(int reqId, int tickType, long time, double price, int size, TickAttribLast tickAttribLast, + String exchange, String specialConditions) { + // TODO Auto-generated method stub + } + + @Override + public void tickByTickBidAsk(int reqId, long time, double bidPrice, double askPrice, int bidSize, int askSize, + TickAttribBidAsk tickAttribBidAsk) { + // TODO Auto-generated method stub + } + + @Override + public void tickByTickMidPoint(int reqId, long time, double midPoint) { + // TODO Auto-generated method stub + } + + @Override + public void orderBound(long orderId, int apiClientId, int apiOrderId) { + // TODO Auto-generated method stub + } + + @Override + public void completedOrder(Contract contract, Order order, OrderState orderState) { + // TODO Auto-generated method stub + } + + @Override + public void completedOrdersEnd() { + // TODO Auto-generated method stub + } +} diff --git a/test/samples/testbed/EWrapperImpl.java b/test/samples/testbed/EWrapperImpl.java new file mode 100644 index 0000000..393d832 --- /dev/null +++ b/test/samples/testbed/EWrapperImpl.java @@ -0,0 +1,700 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.testbed; + +import java.text.DecimalFormat; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.ib.client.*; + +//! [ewrapperimpl] +public class EWrapperImpl implements EWrapper { + //! [ewrapperimpl] + + //! [socket_declare] + private EReaderSignal readerSignal; + private EClientSocket clientSocket; + protected int currentOrderId = -1; + //! [socket_declare] + + //! [socket_init] + public EWrapperImpl() { + readerSignal = new EJavaSignal(); + clientSocket = new EClientSocket(this, readerSignal); + } + //! [socket_init] + public EClientSocket getClient() { + return clientSocket; + } + + public EReaderSignal getSignal() { + return readerSignal; + } + + public int getCurrentOrderId() { + return currentOrderId; + } + + //! [tickprice] + @Override + public void tickPrice(int tickerId, int field, double price, TickAttrib attribs) { + System.out.println("Tick Price. Ticker Id:"+tickerId+", Field: "+field+", Price: "+price+", CanAutoExecute: "+ attribs.canAutoExecute() + + ", pastLimit: " + attribs.pastLimit() + ", pre-open: " + attribs.preOpen()); + } + //! [tickprice] + + //! [ticksize] + @Override + public void tickSize(int tickerId, int field, int size) { + System.out.println("Tick Size. Ticker Id:" + tickerId + ", Field: " + field + ", Size: " + size); + } + //! [ticksize] + + //! [tickoptioncomputation] + @Override + public void tickOptionComputation(int tickerId, int field, int tickAttrib, + double impliedVol, double delta, double optPrice, + double pvDividend, double gamma, double vega, double theta, + double undPrice) { + System.out.println("TickOptionComputation. TickerId: "+tickerId+", field: "+field+", ImpliedVolatility: "+impliedVol+", Delta: "+delta + +", OptionPrice: "+optPrice+", pvDividend: "+pvDividend+", Gamma: "+gamma+", Vega: "+vega+", Theta: "+theta+", UnderlyingPrice: "+undPrice); + } + //! [tickoptioncomputation] + + //! [tickgeneric] + @Override + public void tickGeneric(int tickerId, int tickType, double value) { + System.out.println("Tick Generic. Ticker Id:" + tickerId + ", Field: " + TickType.getField(tickType) + ", Value: " + value); + } + //! [tickgeneric] + + //! [tickstring] + @Override + public void tickString(int tickerId, int tickType, String value) { + System.out.println("Tick string. Ticker Id:" + tickerId + ", Type: " + tickType + ", Value: " + value); + } + //! [tickstring] + @Override + public void tickEFP(int tickerId, int tickType, double basisPoints, + String formattedBasisPoints, double impliedFuture, int holdDays, + String futureLastTradeDate, double dividendImpact, + double dividendsToLastTradeDate) { + System.out.println("TickEFP. "+tickerId+", Type: "+tickType+", BasisPoints: "+basisPoints+", FormattedBasisPoints: "+ + formattedBasisPoints+", ImpliedFuture: "+impliedFuture+", HoldDays: "+holdDays+", FutureLastTradeDate: "+futureLastTradeDate+ + ", DividendImpact: "+dividendImpact+", DividendsToLastTradeDate: "+dividendsToLastTradeDate); + } + //! [orderstatus] + @Override + public void orderStatus(int orderId, String status, double filled, + double remaining, double avgFillPrice, int permId, int parentId, + double lastFillPrice, int clientId, String whyHeld, double mktCapPrice) { + System.out.println("OrderStatus. Id: "+orderId+", Status: "+status+", Filled"+filled+", Remaining: "+remaining + +", AvgFillPrice: "+avgFillPrice+", PermId: "+permId+", ParentId: "+parentId+", LastFillPrice: "+lastFillPrice+ + ", ClientId: "+clientId+", WhyHeld: "+whyHeld+", MktCapPrice: "+mktCapPrice); + } + //! [orderstatus] + + //! [openorder] + @Override + public void openOrder(int orderId, Contract contract, Order order, + OrderState orderState) { + System.out.println(EWrapperMsgGenerator.openOrder(orderId, contract, order, orderState)); + } + //! [openorder] + + //! [openorderend] + @Override + public void openOrderEnd() { + System.out.println("OpenOrderEnd"); + } + //! [openorderend] + + //! [updateaccountvalue] + @Override + public void updateAccountValue(String key, String value, String currency, + String accountName) { + System.out.println("UpdateAccountValue. Key: " + key + ", Value: " + value + ", Currency: " + currency + ", AccountName: " + accountName); + } + //! [updateaccountvalue] + + //! [updateportfolio] + @Override + public void updatePortfolio(Contract contract, double position, + double marketPrice, double marketValue, double averageCost, + double unrealizedPNL, double realizedPNL, String accountName) { + System.out.println("UpdatePortfolio. "+contract.symbol()+", "+contract.secType()+" @ "+contract.exchange() + +": Position: "+position+", MarketPrice: "+marketPrice+", MarketValue: "+marketValue+", AverageCost: "+averageCost + +", UnrealizedPNL: "+unrealizedPNL+", RealizedPNL: "+realizedPNL+", AccountName: "+accountName); + } + //! [updateportfolio] + + //! [updateaccounttime] + @Override + public void updateAccountTime(String timeStamp) { + System.out.println("UpdateAccountTime. Time: " + timeStamp+"\n"); + } + //! [updateaccounttime] + + //! [accountdownloadend] + @Override + public void accountDownloadEnd(String accountName) { + System.out.println("Account download finished: "+accountName+"\n"); + } + //! [accountdownloadend] + + //! [nextvalidid] + @Override + public void nextValidId(int orderId) { + System.out.println("Next Valid Id: ["+orderId+"]"); + currentOrderId = orderId; + } + //! [nextvalidid] + + //! [contractdetails] + @Override + public void contractDetails(int reqId, ContractDetails contractDetails) { + System.out.println(EWrapperMsgGenerator.contractDetails(reqId, contractDetails)); + } + //! [contractdetails] + @Override + public void bondContractDetails(int reqId, ContractDetails contractDetails) { + System.out.println(EWrapperMsgGenerator.bondContractDetails(reqId, contractDetails)); + } + //! [contractdetailsend] + @Override + public void contractDetailsEnd(int reqId) { + System.out.println("ContractDetailsEnd. "+reqId+"\n"); + } + //! [contractdetailsend] + + //! [execdetails] + @Override + public void execDetails(int reqId, Contract contract, Execution execution) { + System.out.println("ExecDetails. "+reqId+" - ["+contract.symbol()+"], ["+contract.secType()+"], ["+contract.currency()+"], ["+execution.execId()+ + "], ["+execution.orderId()+"], ["+execution.shares()+"]" + ", [" + execution.lastLiquidity() + "]"); + } + //! [execdetails] + + //! [execdetailsend] + @Override + public void execDetailsEnd(int reqId) { + System.out.println("ExecDetailsEnd. "+reqId+"\n"); + } + //! [execdetailsend] + + //! [updatemktdepth] + @Override + public void updateMktDepth(int tickerId, int position, int operation, + int side, double price, int size) { + System.out.println("UpdateMarketDepth. "+tickerId+" - Position: "+position+", Operation: "+operation+", Side: "+side+", Price: "+price+", Size: "+size+""); + } + //! [updatemktdepth] + + //! [updatemktdepthl2] + @Override + public void updateMktDepthL2(int tickerId, int position, + String marketMaker, int operation, int side, double price, int size, boolean isSmartDepth) { + System.out.println("UpdateMarketDepthL2. "+tickerId+" - Position: "+position+", Operation: "+operation+", Side: "+side+", Price: "+price+", Size: "+size+", isSmartDepth: "+isSmartDepth); + } + //! [updatemktdepthl2] + + //! [updatenewsbulletin] + @Override + public void updateNewsBulletin(int msgId, int msgType, String message, + String origExchange) { + System.out.println("News Bulletins. "+msgId+" - Type: "+msgType+", Message: "+message+", Exchange of Origin: "+origExchange+"\n"); + } + //! [updatenewsbulletin] + + //! [managedaccounts] + @Override + public void managedAccounts(String accountsList) { + System.out.println("Account list: " +accountsList); + } + //! [managedaccounts] + + //! [receivefa] + @Override + public void receiveFA(int faDataType, String xml) { + System.out.println("Receiving FA: "+faDataType+" - "+xml); + } + //! [receivefa] + + //! [replaceFAEnd] + @Override + public void replaceFAEnd(int faDataType, String xml) { + System.out.println("Replace FA End: "+faDataType+" - "+xml); + } + //! [replaceFAEnd] + + //! [historicaldata] + @Override + public void historicalData(int reqId, Bar bar) { + System.out.println("HistoricalData. "+reqId+" - Date: "+bar.time()+", Open: "+bar.open()+", High: "+bar.high()+", Low: "+bar.low()+", Close: "+bar.close()+", Volume: "+bar.volume()+", Count: "+bar.count()+", WAP: "+bar.wap()); + } + //! [historicaldata] + + //! [historicaldataend] + @Override + public void historicalDataEnd(int reqId, String startDateStr, String endDateStr) { + System.out.println("HistoricalDataEnd. "+reqId+" - Start Date: "+startDateStr+", End Date: "+endDateStr); + } + //! [historicaldataend] + + + //! [scannerparameters] + @Override + public void scannerParameters(String xml) { + System.out.println("ScannerParameters. "+xml+"\n"); + } + //! [scannerparameters] + + //! [scannerdata] + @Override + public void scannerData(int reqId, int rank, + ContractDetails contractDetails, String distance, String benchmark, + String projection, String legsStr) { + System.out.println("ScannerData. "+reqId+" - Rank: "+rank+", Symbol: "+contractDetails.contract().symbol()+", SecType: "+contractDetails.contract().secType()+", Currency: "+contractDetails.contract().currency() + +", Distance: "+distance+", Benchmark: "+benchmark+", Projection: "+projection+", Legs String: "+legsStr); + } + //! [scannerdata] + + //! [scannerdataend] + @Override + public void scannerDataEnd(int reqId) { + System.out.println("ScannerDataEnd. "+reqId); + } + //! [scannerdataend] + + //! [realtimebar] + @Override + public void realtimeBar(int reqId, long time, double open, double high, + double low, double close, long volume, double wap, int count) { + System.out.println("RealTimeBars. " + reqId + " - Time: " + time + ", Open: " + open + ", High: " + high + ", Low: " + low + ", Close: " + close + ", Volume: " + volume + ", Count: " + count + ", WAP: " + wap); + } + //! [realtimebar] + @Override + public void currentTime(long time) { + System.out.println("currentTime"); + } + //! [fundamentaldata] + @Override + public void fundamentalData(int reqId, String data) { + System.out.println("FundamentalData. ReqId: ["+reqId+"] - Data: ["+data+"]"); + } + //! [fundamentaldata] + @Override + public void deltaNeutralValidation(int reqId, DeltaNeutralContract deltaNeutralContract) { + System.out.println("deltaNeutralValidation"); + } + //! [ticksnapshotend] + @Override + public void tickSnapshotEnd(int reqId) { + System.out.println("TickSnapshotEnd: "+reqId); + } + //! [ticksnapshotend] + + //! [marketdatatype] + @Override + public void marketDataType(int reqId, int marketDataType) { + System.out.println("MarketDataType. ["+reqId+"], Type: ["+marketDataType+"]\n"); + } + //! [marketdatatype] + + //! [commissionreport] + @Override + public void commissionReport(CommissionReport commissionReport) { + System.out.println("CommissionReport. ["+commissionReport.execId()+"] - ["+commissionReport.commission()+"] ["+commissionReport.currency()+"] RPNL ["+commissionReport.realizedPNL()+"]"); + } + //! [commissionreport] + + //! [position] + @Override + public void position(String account, Contract contract, double pos, + double avgCost) { + System.out.println("Position. "+account+" - Symbol: "+contract.symbol()+", SecType: "+contract.secType()+", Currency: "+contract.currency()+", Position: "+pos+", Avg cost: "+avgCost); + } + //! [position] + + //! [positionend] + @Override + public void positionEnd() { + System.out.println("PositionEnd \n"); + } + //! [positionend] + + //! [accountsummary] + @Override + public void accountSummary(int reqId, String account, String tag, + String value, String currency) { + System.out.println("Acct Summary. ReqId: " + reqId + ", Acct: " + account + ", Tag: " + tag + ", Value: " + value + ", Currency: " + currency); + } + //! [accountsummary] + + //! [accountsummaryend] + @Override + public void accountSummaryEnd(int reqId) { + System.out.println("AccountSummaryEnd. Req Id: "+reqId+"\n"); + } + //! [accountsummaryend] + @Override + public void verifyMessageAPI(String apiData) { + System.out.println("verifyMessageAPI"); + } + + @Override + public void verifyCompleted(boolean isSuccessful, String errorText) { + System.out.println("verifyCompleted"); + } + + @Override + public void verifyAndAuthMessageAPI(String apiData, String xyzChallenge) { + System.out.println("verifyAndAuthMessageAPI"); + } + + @Override + public void verifyAndAuthCompleted(boolean isSuccessful, String errorText) { + System.out.println("verifyAndAuthCompleted"); + } + //! [displaygrouplist] + @Override + public void displayGroupList(int reqId, String groups) { + System.out.println("Display Group List. ReqId: "+reqId+", Groups: "+groups+"\n"); + } + //! [displaygrouplist] + + //! [displaygroupupdated] + @Override + public void displayGroupUpdated(int reqId, String contractInfo) { + System.out.println("Display Group Updated. ReqId: "+reqId+", Contract info: "+contractInfo+"\n"); + } + //! [displaygroupupdated] + @Override + public void error(Exception e) { + System.out.println("Exception: "+e.getMessage()); + } + + @Override + public void error(String str) { + System.out.println("Error STR"); + } + //! [error] + @Override + public void error(int id, int errorCode, String errorMsg) { + System.out.println("Error. Id: " + id + ", Code: " + errorCode + ", Msg: " + errorMsg + "\n"); + } + //! [error] + @Override + public void connectionClosed() { + System.out.println("Connection closed"); + } + + //! [connectack] + @Override + public void connectAck() { + if (clientSocket.isAsyncEConnect()) { + System.out.println("Acknowledging connection"); + clientSocket.startAPI(); + } + } + //! [connectack] + + //! [positionmulti] + @Override + public void positionMulti(int reqId, String account, String modelCode, + Contract contract, double pos, double avgCost) { + System.out.println("Position Multi. Request: " + reqId + ", Account: " + account + ", ModelCode: " + modelCode + ", Symbol: " + contract.symbol() + ", SecType: " + contract.secType() + ", Currency: " + contract.currency() + ", Position: " + pos + ", Avg cost: " + avgCost + "\n"); + } + //! [positionmulti] + + //! [positionmultiend] + @Override + public void positionMultiEnd(int reqId) { + System.out.println("Position Multi End. Request: " + reqId + "\n"); + } + //! [positionmultiend] + + //! [accountupdatemulti] + @Override + public void accountUpdateMulti(int reqId, String account, String modelCode, + String key, String value, String currency) { + System.out.println("Account Update Multi. Request: " + reqId + ", Account: " + account + ", ModelCode: " + modelCode + ", Key: " + key + ", Value: " + value + ", Currency: " + currency + "\n"); + } + //! [accountupdatemulti] + + //! [accountupdatemultiend] + @Override + public void accountUpdateMultiEnd(int reqId) { + System.out.println("Account Update Multi End. Request: " + reqId + "\n"); + } + //! [accountupdatemultiend] + + //! [securityDefinitionOptionParameter] + @Override + public void securityDefinitionOptionalParameter(int reqId, String exchange, + int underlyingConId, String tradingClass, String multiplier, + Set expirations, Set strikes) { + System.out.println("Security Definition Optional Parameter. Request: "+reqId+", Trading Class: "+tradingClass+", Multiplier: "+multiplier+" \n"); + } + //! [securityDefinitionOptionParameter] + + //! [securityDefinitionOptionParameterEnd] + @Override + public void securityDefinitionOptionalParameterEnd(int reqId) { + System.out.println("Security Definition Optional Parameter End. Request: " + reqId); + } + //! [securityDefinitionOptionParameterEnd] + + //! [softDollarTiers] + @Override + public void softDollarTiers(int reqId, SoftDollarTier[] tiers) { + for (SoftDollarTier tier : tiers) { + System.out.print("tier: " + tier.toString() + ", "); + } + + System.out.println(); + } + //! [softDollarTiers] + + //! [familyCodes] + @Override + public void familyCodes(FamilyCode[] familyCodes) { + for (FamilyCode fc : familyCodes) { + System.out.print("Family Code. AccountID: " + fc.accountID() + ", FamilyCode: " + fc.familyCodeStr()); + } + + System.out.println(); + } + //! [familyCodes] + + //! [symbolSamples] + @Override + public void symbolSamples(int reqId, ContractDescription[] contractDescriptions) { + System.out.println("Contract Descriptions. Request: " + reqId + "\n"); + for (ContractDescription cd : contractDescriptions) { + Contract c = cd.contract(); + StringBuilder derivativeSecTypesSB = new StringBuilder(); + for (String str : cd.derivativeSecTypes()) { + derivativeSecTypesSB.append(str); + derivativeSecTypesSB.append(","); + } + System.out.print("Contract. ConId: " + c.conid() + ", Symbol: " + c.symbol() + ", SecType: " + c.secType() + + ", PrimaryExch: " + c.primaryExch() + ", Currency: " + c.currency() + + ", DerivativeSecTypes:[" + derivativeSecTypesSB.toString() + "]"); + } + + System.out.println(); + } + //! [symbolSamples] + + //! [mktDepthExchanges] + @Override + public void mktDepthExchanges(DepthMktDataDescription[] depthMktDataDescriptions) { + for (DepthMktDataDescription depthMktDataDescription : depthMktDataDescriptions) { + System.out.println("Depth Mkt Data Description. Exchange: " + depthMktDataDescription.exchange() + + ", ListingExch: " + depthMktDataDescription.listingExch() + + ", SecType: " + depthMktDataDescription.secType() + + ", ServiceDataType: " + depthMktDataDescription.serviceDataType() + + ", AggGroup: " + depthMktDataDescription.aggGroup() + ); + } + } + //! [mktDepthExchanges] + + //! [tickNews] + @Override + public void tickNews(int tickerId, long timeStamp, String providerCode, String articleId, String headline, String extraData) { + System.out.println("Tick News. TickerId: " + tickerId + ", TimeStamp: " + timeStamp + ", ProviderCode: " + providerCode + ", ArticleId: " + articleId + ", Headline: " + headline + ", ExtraData: " + extraData + "\n"); + } + //! [tickNews] + + //! [smartcomponents] + @Override + public void smartComponents(int reqId, Map> theMap) { + System.out.println("smart components req id:" + reqId); + + for (Map.Entry> item : theMap.entrySet()) { + System.out.println("bit number: " + item.getKey() + + ", exchange: " + item.getValue().getKey() + ", exchange letter: " + item.getValue().getValue()); + } + } + //! [smartcomponents] + + //! [tickReqParams] + @Override + public void tickReqParams(int tickerId, double minTick, String bboExchange, int snapshotPermissions) { + System.out.println("Tick req params. Ticker Id:" + tickerId + ", Min tick: " + minTick + ", bbo exchange: " + bboExchange + ", Snapshot permissions: " + snapshotPermissions); + } + //! [tickReqParams] + + //! [newsProviders] + @Override + public void newsProviders(NewsProvider[] newsProviders) { + for (NewsProvider np : newsProviders) { + System.out.print("News Provider. ProviderCode: " + np.providerCode() + ", ProviderName: " + np.providerName() + "\n"); + } + + System.out.println(); + } + //! [newsProviders] + + //! [newsArticle] + @Override + public void newsArticle(int requestId, int articleType, String articleText) { + System.out.println("News Article. Request Id: " + requestId + ", ArticleType: " + articleType + + ", ArticleText: " + articleText); + } + //! [newsArticle] + + //! [historicalNews] + @Override + public void historicalNews(int requestId, String time, String providerCode, String articleId, String headline) { + System.out.println("Historical News. RequestId: " + requestId + ", Time: " + time + ", ProviderCode: " + providerCode + ", ArticleId: " + articleId + ", Headline: " + headline + "\n"); + } + //! [historicalNews] + + //! [historicalNewsEnd] + @Override + public void historicalNewsEnd(int requestId, boolean hasMore) { + System.out.println("Historical News End. RequestId: " + requestId + ", HasMore: " + hasMore + "\n"); + } + //! [historicalNewsEnd] + + //! [headTimestamp] + @Override + public void headTimestamp(int reqId, String headTimestamp) { + System.out.println("Head timestamp. Req Id: " + reqId + ", headTimestamp: " + headTimestamp); + } + //! [headTimestamp] + + //! [histogramData] + @Override + public void histogramData(int reqId, List items) { + System.out.println(EWrapperMsgGenerator.histogramData(reqId, items)); + } + //! [histogramData] + + //! [historicalDataUpdate] + @Override + public void historicalDataUpdate(int reqId, Bar bar) { + System.out.println("HistoricalDataUpdate. "+reqId+" - Date: "+bar.time()+", Open: "+bar.open()+", High: "+bar.high()+", Low: "+bar.low()+", Close: "+bar.close()+", Volume: "+bar.volume()+", Count: "+bar.count()+", WAP: "+bar.wap()); + } + //! [historicalDataUpdate] + + //! [rerouteMktDataReq] + @Override + public void rerouteMktDataReq(int reqId, int conId, String exchange) { + System.out.println(EWrapperMsgGenerator.rerouteMktDataReq(reqId, conId, exchange)); + } + //! [rerouteMktDataReq] + + //! [rerouteMktDepthReq] + @Override + public void rerouteMktDepthReq(int reqId, int conId, String exchange) { + System.out.println(EWrapperMsgGenerator.rerouteMktDepthReq(reqId, conId, exchange)); + } + //! [rerouteMktDepthReq] + + //! [marketRule] + @Override + public void marketRule(int marketRuleId, PriceIncrement[] priceIncrements) { + DecimalFormat df = new DecimalFormat("#.#"); + df.setMaximumFractionDigits(340); + System.out.println("Market Rule Id: " + marketRuleId); + for (PriceIncrement pi : priceIncrements) { + System.out.println("Price Increment. Low Edge: " + df.format(pi.lowEdge()) + ", Increment: " + df.format(pi.increment())); + } + } + //! [marketRule] + + //! [pnl] + @Override + public void pnl(int reqId, double dailyPnL, double unrealizedPnL, double realizedPnL) { + System.out.println(EWrapperMsgGenerator.pnl(reqId, dailyPnL, unrealizedPnL, realizedPnL)); + } + //! [pnl] + + //! [pnlsingle] + @Override + public void pnlSingle(int reqId, int pos, double dailyPnL, double unrealizedPnL, double realizedPnL, double value) { + System.out.println(EWrapperMsgGenerator.pnlSingle(reqId, pos, dailyPnL, unrealizedPnL, realizedPnL, value)); + } + //! [pnlsingle] + + //! [historicalticks] + @Override + public void historicalTicks(int reqId, List ticks, boolean done) { + for (HistoricalTick tick : ticks) { + System.out.println(EWrapperMsgGenerator.historicalTick(reqId, tick.time(), tick.price(), tick.size())); + } + } + //! [historicalticks] + + //! [historicalticksbidask] + @Override + public void historicalTicksBidAsk(int reqId, List ticks, boolean done) { + for (HistoricalTickBidAsk tick : ticks) { + System.out.println(EWrapperMsgGenerator.historicalTickBidAsk(reqId, tick.time(), tick.tickAttribBidAsk(), tick.priceBid(), tick.priceAsk(), tick.sizeBid(), + tick.sizeAsk())); + } + } + //! [historicalticksbidask] + + @Override + //! [historicaltickslast] + public void historicalTicksLast(int reqId, List ticks, boolean done) { + for (HistoricalTickLast tick : ticks) { + System.out.println(EWrapperMsgGenerator.historicalTickLast(reqId, tick.time(), tick.tickAttribLast(), tick.price(), tick.size(), tick.exchange(), + tick.specialConditions())); + } + } + //! [historicaltickslast] + + //! [tickbytickalllast] + @Override + public void tickByTickAllLast(int reqId, int tickType, long time, double price, int size, TickAttribLast tickAttribLast, + String exchange, String specialConditions) { + System.out.println(EWrapperMsgGenerator.tickByTickAllLast(reqId, tickType, time, price, size, tickAttribLast, exchange, specialConditions)); + } + //! [tickbytickalllast] + + //! [tickbytickbidask] + @Override + public void tickByTickBidAsk(int reqId, long time, double bidPrice, double askPrice, int bidSize, int askSize, + TickAttribBidAsk tickAttribBidAsk) { + System.out.println(EWrapperMsgGenerator.tickByTickBidAsk(reqId, time, bidPrice, askPrice, bidSize, askSize, tickAttribBidAsk)); + } + //! [tickbytickbidask] + + //! [tickbytickmidpoint] + @Override + public void tickByTickMidPoint(int reqId, long time, double midPoint) { + System.out.println(EWrapperMsgGenerator.tickByTickMidPoint(reqId, time, midPoint)); + } + //! [tickbytickmidpoint] + + //! [orderbound] + @Override + public void orderBound(long orderId, int apiClientId, int apiOrderId) { + System.out.println(EWrapperMsgGenerator.orderBound(orderId, apiClientId, apiOrderId)); + } + //! [orderbound] + + //! [completedorder] + @Override + public void completedOrder(Contract contract, Order order, OrderState orderState) { + System.out.println(EWrapperMsgGenerator.completedOrder(contract, order, orderState)); + } + //! [completedorder] + + //! [completedordersend] + @Override + public void completedOrdersEnd() { + System.out.println(EWrapperMsgGenerator.completedOrdersEnd()); + } + //! [completedordersend] +} diff --git a/test/samples/testbed/Testbed.java b/test/samples/testbed/Testbed.java new file mode 100644 index 0000000..b1c2340 --- /dev/null +++ b/test/samples/testbed/Testbed.java @@ -0,0 +1,949 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.testbed; +import java.text.SimpleDateFormat; +import java.util.*; + +import com.ib.client.*; +import samples.testbed.advisor.FAMethodSamples; +import samples.testbed.contracts.ContractSamples; +import samples.testbed.orders.AvailableAlgoParams; +import samples.testbed.orders.OrderSamples; +import samples.testbed.scanner.ScannerSubscriptionSamples; + +import com.ib.client.Types.FADataType; + +public class Testbed { + + public static void main(String[] args) throws InterruptedException { + EWrapperImpl wrapper = new EWrapperImpl(); + + final EClientSocket m_client = wrapper.getClient(); + final EReaderSignal m_signal = wrapper.getSignal(); + //! [connect] + m_client.eConnect("127.0.0.1", 7497, 2); + //! [connect] + //! [ereader] + final EReader reader = new EReader(m_client, m_signal); + + reader.start(); + //An additional thread is created in this program design to empty the messaging queue + new Thread(() -> { + while (m_client.isConnected()) { + m_signal.waitForSignal(); + try { + reader.processMsgs(); + } catch (Exception e) { + System.out.println("Exception: "+e.getMessage()); + } + } + }).start(); + //! [ereader] + // A pause to give the application time to establish the connection + // In a production application, it would be best to wait for callbacks to confirm the connection is complete + Thread.sleep(1000); + + //tickByTickOperations(wrapper.getClient()); + //tickDataOperations(wrapper.getClient()); + //tickOptionComputations(wrapper.getClient()); + orderOperations(wrapper.getClient(), wrapper.getCurrentOrderId()); + //contractOperations(wrapper.getClient()); + //hedgeSample(wrapper.getClient(), wrapper.getCurrentOrderId()); + //testAlgoSamples(wrapper.getClient(), wrapper.getCurrentOrderId()); + //bracketSample(wrapper.getClient(), wrapper.getCurrentOrderId()); + //bulletins(wrapper.getClient()); + //fundamentals(wrapper.getClient()); + //marketScanners(wrapper.getClient()); + //marketDataType(wrapper.getClient()); + //historicalDataRequests(wrapper.getClient()); + //accountOperations(wrapper.getClient()); + //newsOperations(wrapper.getClient()); + //marketDepthOperations(wrapper.getClient()); + //rerouteCFDOperations(wrapper.getClient()); + //marketRuleOperations(wrapper.getClient()); + //tickDataOperations(wrapper.getClient()); + //pnlSingle(wrapper.getClient()); + //continuousFuturesOperations(wrapper.getClient()); + //pnlSingle(wrapper.getClient()); + //histogram(wrapper.getClient()); + //whatIfSamples(wrapper.getClient(), wrapper.getCurrentOrderId()); + //historicalTicks(wrapper.getClient()); + + Thread.sleep(100000); + m_client.eDisconnect(); + } + + private static void histogram(EClientSocket client) { + client.reqHistogramData(4002, ContractSamples.USStock(), false, "3 days"); + + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + client.cancelHistogramData(4002); + } + + private static void historicalTicks(EClientSocket client) { + //! [reqhistoricalticks] + client.reqHistoricalTicks(18001, ContractSamples.USStockAtSmart(), "20170712 21:39:33", null, 10, "TRADES", 1, true, null); + client.reqHistoricalTicks(18002, ContractSamples.USStockAtSmart(), "20170712 21:39:33", null, 10, "BID_ASK", 1, true, null); + client.reqHistoricalTicks(18003, ContractSamples.USStockAtSmart(), "20170712 21:39:33", null, 10, "MIDPOINT", 1, true, null); + //! [reqhistoricalticks] + } + + private static void pnl(EClientSocket client) throws InterruptedException { + //! [reqpnl] + client.reqPnL(17001, "DUD00029", ""); + //! [reqpnl] + Thread.sleep(1000); + //! [cancelpnl] + client.cancelPnL(17001); + //! [cancelpnl] + } + + private static void pnlSingle(EClientSocket client) throws InterruptedException + { + //! [reqpnlsingle] + client.reqPnLSingle(17001, "DUD00029", "", 268084); + //! [reqpnlsingle] + Thread.sleep(1000); + //! [cancelpnlsingle] + client.cancelPnLSingle(17001); + //! [cancelpnlsingle] + } + + private static void orderOperations(EClientSocket client, int nextOrderId) throws InterruptedException { + + /*** Requesting the next valid id ***/ + //! [reqids] + //The parameter is always ignored. + client.reqIds(-1); + //! [reqids] + //Thread.sleep(1000); + /*** Requesting all open orders ***/ + //! [reqallopenorders] + client.reqAllOpenOrders(); + //! [reqallopenorders] + //Thread.sleep(1000); + /*** Taking over orders to be submitted via TWS ***/ + //! [reqautoopenorders] + client.reqAutoOpenOrders(true); + //! [reqautoopenorders] + //Thread.sleep(1000); + /*** Requesting this API client's orders ***/ + //! [reqopenorders] + client.reqOpenOrders(); + //! [reqopenorders] + //Thread.sleep(1000); + + /*** Placing/modifying an order - remember to ALWAYS increment the nextValidId after placing an order so it can be used for the next one! ***/ + //! [order_submission] + client.placeOrder(nextOrderId++, ContractSamples.USStock(), OrderSamples.LimitOrder("SELL", 1, 50)); + //! [order_submission] + + //! [place_midprice] + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), OrderSamples.Midprice("BUY", 1, 150)); + //! [place_midprice] + + //! [faorderoneaccount] + Order faOrderOneAccount = OrderSamples.MarketOrder("BUY", 100); + // Specify the Account Number directly + faOrderOneAccount.account("DU119915"); + client.placeOrder(nextOrderId++, ContractSamples.USStock(), faOrderOneAccount); + //! [faorderoneaccount] + + //! [faordergroupequalquantity] + Order faOrderGroupEQ = OrderSamples.LimitOrder("SELL", 200, 2000); + faOrderGroupEQ.faGroup("Group_Equal_Quantity"); + faOrderGroupEQ.faMethod("EqualQuantity"); + client.placeOrder(nextOrderId++, ContractSamples.USStock(), faOrderGroupEQ); + //! [faordergroupequalquantity] + + //! [faordergrouppctchange] + Order faOrderGroupPC = OrderSamples.MarketOrder("BUY", 0); + // You should not specify any order quantity for PctChange allocation method + faOrderGroupPC.faGroup("Pct_Change"); + faOrderGroupPC.faMethod("PctChange"); + faOrderGroupPC.faPercentage("100"); + client.placeOrder(nextOrderId++, ContractSamples.EurGbpFx(), faOrderGroupPC); + //! [faordergrouppctchange] + + //! [faorderprofile] + Order faOrderProfile = OrderSamples.LimitOrder("BUY", 200, 100); + faOrderProfile.faProfile("Percent_60_40"); + client.placeOrder(nextOrderId++, ContractSamples.EuropeanStock(), faOrderProfile); + //! [faorderprofile] + + //! [modelorder] + Order modelOrder = OrderSamples.LimitOrder("BUY", 200, 100); + modelOrder.account("DF12345"); // master FA account number + modelOrder.modelCode("Technology"); // model for tech stocks first created in TWS + client.placeOrder(nextOrderId++, ContractSamples.USStock(), modelOrder); + //! [modelorder] + + //client.placeOrder(nextOrderId++, ContractSamples.USStock(), OrderSamples.PeggedToMarket("BUY", 10, 0.01)); + //client.placeOrder(nextOrderId++, ContractSamples.EurGbpFx(), OrderSamples.MarketOrder("BUY", 10)); + //client.placeOrder(nextOrderId++, ContractSamples.USStock(), OrderSamples.Discretionary("SELL", 1, 45, 0.5)); + + //! [reqexecutions] + client.reqExecutions(10001, new ExecutionFilter()); + //! [reqexecutions] + + int cancelID = nextOrderId -1; + //! [cancelorder] + client.cancelOrder(cancelID); + //! [cancelorder] + + //! [reqglobalcancel] + client.reqGlobalCancel(); + //! [reqglobalcancel] + + /*** Completed orders ***/ + //! [reqcompletedorders] + client.reqCompletedOrders(false); + //! [reqcompletedorders] + + Thread.sleep(10000); + + } + + private static void OcaSample(EClientSocket client, int nextOrderId) { + + //OCA order + //! [ocasubmit] + List OcaOrders = new ArrayList<>(); + OcaOrders.add(OrderSamples.LimitOrder("BUY", 1, 10)); + OcaOrders.add(OrderSamples.LimitOrder("BUY", 1, 11)); + OcaOrders.add(OrderSamples.LimitOrder("BUY", 1, 12)); + OcaOrders = OrderSamples.OneCancelsAll("TestOCA_" + nextOrderId, OcaOrders, 2); + for (Order o : OcaOrders) { + + client.placeOrder(nextOrderId++, ContractSamples.USStock(), o); + } + //! [ocasubmit] + + } + + private static void tickDataOperations(EClientSocket client) throws InterruptedException { + + /*** Requesting real time market data ***/ + //Thread.sleep(1000); + //! [reqmktdata] + client.reqMktData(1001, ContractSamples.StockComboContract(), "", false, false, null); + //! [reqmktdata] + + //! [reqsmartcomponents] + client.reqSmartComponents(1013, "a6"); + //! [reqsmartcomponents] + + //! [reqmktdata_snapshot] + client.reqMktData(1003, ContractSamples.FutureComboContract(), "", true, false, null); + //! [reqmktdata_snapshot] + + /* + //! [regulatorysnapshot] + // Each regulatory snapshot request incurs a 0.01 USD fee + client.reqMktData(1014, ContractSamples.USStock(), "", false, true, null); + //! [regulatorysnapshot] + */ + + //! [reqmktdata_genticks] + //Requesting RTVolume (Time & Sales), shortable and Fundamental Ratios generic ticks + client.reqMktData(1004, ContractSamples.USStockAtSmart(), "233,236,258", false, false, null); + //! [reqmktdata_genticks] + //! [reqmktdata_contractnews] + // Without the API news subscription this will generate an "invalid tick type" error + client.reqMktData(1005, ContractSamples.USStock(), "mdoff,292:BZ", false, false, null); + client.reqMktData(1006, ContractSamples.USStock(), "mdoff,292:BT", false, false, null); + client.reqMktData(1007, ContractSamples.USStock(), "mdoff,292:FLY", false, false, null); + client.reqMktData(1008, ContractSamples.USStock(), "mdoff,292:MT", false, false, null); + //! [reqmktdata_contractnews] + //! [reqmktdata_broadtapenews] + client.reqMktData(1009, ContractSamples.BTbroadtapeNewsFeed(), "mdoff,292", false, false, null); + client.reqMktData(1010, ContractSamples.BZbroadtapeNewsFeed(), "mdoff,292", false, false, null); + client.reqMktData(1011, ContractSamples.FLYbroadtapeNewsFeed(), "mdoff,292", false, false, null); + client.reqMktData(1012, ContractSamples.MTbroadtapeNewsFeed(), "mdoff,292", false, false, null); + //! [reqmktdata_broadtapenews] + //! [reqoptiondatagenticks] + //Requesting data for an option contract will return the greek values + client.reqMktData(1002, ContractSamples.OptionWithLocalSymbol(), "", false, false, null); + //! [reqoptiondatagenticks] + //! [reqfuturesopeninterest] + //Requesting data for a futures contract will return the futures open interest + client.reqMktData(1014, ContractSamples.SimpleFuture(), "mdoff,588", false, false, null); + //! [reqfuturesopeninterest] + + //! [reqmktdata_preopenbidask] + //Requesting data for a futures contract will return the pre-open bid/ask flag + client.reqMktData(1015, ContractSamples.SimpleFuture(), "", false, false, null); + //! [reqmktData_preopenbidask] + + //! [reqavgoptvolume] + //Requesting data for a stock will return the average option volume + client.reqMktData(1016, ContractSamples.USStockAtSmart(), "mdoff,105", false, false, null); + //! [reqavgoptvolume] + + Thread.sleep(10000); + //! [cancelmktdata] + client.cancelMktData(1001); + client.cancelMktData(1002); + client.cancelMktData(1003); + client.cancelMktData(1014); + client.cancelMktData(1015); + client.cancelMktData(1016); + //! [cancelmktdata] + + } + + private static void tickOptionComputations(EClientSocket client) throws InterruptedException { + + /*** Requesting real time market data ***/ + //! [reqmktdata] + client.reqMktData(2001, ContractSamples.FuturesOnOptions(), "", false, false, null); + //! [reqmktdata] + + Thread.sleep(10000); + + //! [cancelmktdata] + client.cancelMktData(2001); + //! [cancelmktdata] + } + + private static void historicalDataRequests(EClientSocket client) throws InterruptedException { + + /*** Requesting historical data ***/ + + //! [reqHeadTimeStamp] + client.reqHeadTimestamp(4003, ContractSamples.USStock(), "TRADES", 1, 1); + //! [reqHeadTimeStamp] + + //! [cancelHeadTimestamp] + client.cancelHeadTimestamp(4003); + //! [cancelHeadTimestamp] + + //! [reqhistoricaldata] + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MONTH, -6); + SimpleDateFormat form = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); + String formatted = form.format(cal.getTime()); + client.reqHistoricalData(4001, ContractSamples.EurGbpFx(), formatted, "1 M", "1 day", "MIDPOINT", 1, 1, false, null); + client.reqHistoricalData(4002, ContractSamples.EuropeanStock(), formatted, "10 D", "1 min", "TRADES", 1, 1, false, null); + Thread.sleep(2000); + /*** Canceling historical data requests ***/ + client.cancelHistoricalData(4001); + client.cancelHistoricalData(4002); + //! [reqhistoricaldata] + return; + //! [reqHistogramData] + /*client.reqHistogramData(4004, ContractSamples.USStock(), false, "3 days"); + //! [reqHistogramData] + Thread.sleep(5); + + //! [cancelHistogramData] + client.cancelHistogramData(4004);*/ + //! [cancelHistogramData] + } + + private static void realTimeBars(EClientSocket client) throws InterruptedException { + + /*** Requesting real time bars ***/ + //! [reqrealtimebars] + client.reqRealTimeBars(3001, ContractSamples.EurGbpFx(), 5, "MIDPOINT", true, null); + //! [reqrealtimebars] + Thread.sleep(2000); + /*** Canceling real time bars ***/ + //! [cancelrealtimebars] + client.cancelRealTimeBars(3001); + //! [cancelrealtimebars] + + } + + private static void marketDepthOperations(EClientSocket client) throws InterruptedException { + + /*** Requesting the Deep Book ***/ + + //! [reqMktDepthExchanges] + client.reqMktDepthExchanges(); + //! [reqMktDepthExchanges] + + //! [reqmarketdepth] + client.reqMktDepth(2001, ContractSamples.EurGbpFx(), 5, false, null); + //! [reqmarketdepth] + Thread.sleep(2000); + /*** Canceling the Deep Book request ***/ + //! [cancelmktdepth] + client.cancelMktDepth(2001, false); + //! [cancelmktdepth] + + //! [reqmarketdepth] + client.reqMktDepth(2002, ContractSamples.EuropeanStock(), 5, true, null); + //! [reqmarketdepth] + Thread.sleep(5000); + //! [cancelmktdepth] + client.cancelMktDepth(2002, true); + //! [cancelmktdepth] + } + + private static void accountOperations(EClientSocket client) throws InterruptedException { + + //client.reqAccountUpdatesMulti(9002, null, "EUstocks", true); + //! [reqpositionsmulti] + client.reqPositionsMulti(9003, "DU74649", "EUstocks"); + //! [reqpositionsmulti] + Thread.sleep(10000); + + /*** Requesting managed accounts***/ + //! [reqmanagedaccts] + client.reqManagedAccts(); + //! [reqmanagedaccts] + + /*** Requesting family codes***/ + //! [reqfamilycodes] + client.reqFamilyCodes(); + //! [reqfamilycodes] + + /*** Requesting accounts' summary ***/ + Thread.sleep(2000); + //! [reqaaccountsummary] + client.reqAccountSummary(9001, "All", "AccountType,NetLiquidation,TotalCashValue,SettledCash,AccruedCash,BuyingPower,EquityWithLoanValue,PreviousEquityWithLoanValue,GrossPositionValue,ReqTEquity,ReqTMargin,SMA,InitMarginReq,MaintMarginReq,AvailableFunds,ExcessLiquidity,Cushion,FullInitMarginReq,FullMaintMarginReq,FullAvailableFunds,FullExcessLiquidity,LookAheadNextChange,LookAheadInitMarginReq ,LookAheadMaintMarginReq,LookAheadAvailableFunds,LookAheadExcessLiquidity,HighestSeverity,DayTradesRemaining,Leverage"); + //! [reqaaccountsummary] + + //! [reqaaccountsummaryledger] + client.reqAccountSummary(9002, "All", "$LEDGER"); + //! [reqaaccountsummaryledger] + Thread.sleep(2000); + //! [reqaaccountsummaryledgercurrency] + client.reqAccountSummary(9003, "All", "$LEDGER:EUR"); + //! [reqaaccountsummaryledgercurrency] + Thread.sleep(2000); + //! [reqaaccountsummaryledgerall] + client.reqAccountSummary(9004, "All", "$LEDGER:ALL"); + //! [reqaaccountsummaryledgerall] + + //! [cancelaaccountsummary] + client.cancelAccountSummary(9001); + client.cancelAccountSummary(9002); + client.cancelAccountSummary(9003); + client.cancelAccountSummary(9004); + //! [cancelaaccountsummary] + + /*** Subscribing to an account's information. Only one at a time! ***/ + Thread.sleep(2000); + //! [reqaaccountupdates] + client.reqAccountUpdates(true, "U150462"); + //! [reqaaccountupdates] + Thread.sleep(2000); + //! [cancelaaccountupdates] + client.reqAccountUpdates(false, "U150462"); + //! [cancelaaccountupdates] + + //! [reqaaccountupdatesmulti] + client.reqAccountUpdatesMulti(9002, "U150462", "EUstocks", true); + //! [reqaaccountupdatesmulti] + Thread.sleep(2000); + /*** Requesting all accounts' positions. ***/ + //! [reqpositions] + client.reqPositions(); + //! [reqpositions] + Thread.sleep(2000); + //! [cancelpositions] + client.cancelPositions(); + //! [cancelpositions] + } + + private static void newsOperations(EClientSocket client) throws InterruptedException { + + /*** Requesting news ticks ***/ + //! [reqNewsTicks] + client.reqMktData(10001, ContractSamples.USStockAtSmart(), "mdoff,292", false, false, null); + //! [reqNewsTicks] + + Thread.sleep(10000); + + /*** Canceling news ticks ***/ + //! [cancelNewsTicks] + client.cancelMktData(10001); + //! [cancelNewsTicks] + + Thread.sleep(2000); + + /*** Requesting news providers ***/ + //! [reqNewsProviders] + client.reqNewsProviders(); + //! [reqNewsProviders] + + Thread.sleep(2000); + + /*** Requesting news article ***/ + //! [reqNewsArticle] + client.reqNewsArticle(10002, "BZ", "BZ$04507322", null); + //! [reqNewsArticle] + + Thread.sleep(5000); + + /*** Requesting historical news ***/ + //! [reqHistoricalNews] + client.reqHistoricalNews(10003, 8314, "BZ+FLY", "", "", 10, null); + //! [reqHistoricalNews] + } + + private static void conditionSamples(EClientSocket client, int nextOrderId) { + + //! [order_conditioning_activate] + Order mkt = OrderSamples.MarketOrder("BUY", 100); + //Order will become active if conditioning criteria is met + mkt.conditionsCancelOrder(true); + mkt.conditions().add(OrderSamples.PriceCondition(208813720, "SMART", 600, false, false)); + mkt.conditions().add(OrderSamples.ExecutionCondition("EUR.USD", "CASH", "IDEALPRO", true)); + mkt.conditions().add(OrderSamples.MarginCondition(30, true, false)); + mkt.conditions().add(OrderSamples.PercentageChangeCondition(15.0, 208813720, "SMART", true, true)); + mkt.conditions().add(OrderSamples.TimeCondition("20160118 23:59:59", true, false)); + mkt.conditions().add(OrderSamples.VolumeCondition(208813720, "SMART", false, 100, true)); + client.placeOrder(nextOrderId++, ContractSamples.EuropeanStock(), mkt); + //! [order_conditioning_activate] + + //Conditions can make the order active or cancel it. Only LMT orders can be conditionally canceled. + //! [order_conditioning_cancel] + Order lmt = OrderSamples.LimitOrder("BUY", 100, 20); + //The active order will be cancelled if conditioning criteria is met + lmt.conditionsCancelOrder(true); + lmt.conditions().add(OrderSamples.PriceCondition(208813720, "SMART", 600, false, false)); + client.placeOrder(nextOrderId++, ContractSamples.EuropeanStock(), lmt); + //! [order_conditioning_cancel] + + } + + private static void contractOperations(EClientSocket client) { + + //! [reqcontractdetails] + client.reqContractDetails(210, ContractSamples.OptionForQuery()); + client.reqContractDetails(211, ContractSamples.EurGbpFx()); + client.reqContractDetails(212, ContractSamples.Bond()); + client.reqContractDetails(213, ContractSamples.FuturesOnOptions()); + client.reqContractDetails(214, ContractSamples.SimpleFuture()); + //! [reqcontractdetails] + + //! [reqmatchingsymbols] + client.reqMatchingSymbols(211, "IB"); + //! [reqmatchingsymbols] + + } + + private static void contractNewsFeed(EClientSocket client) { + + //! [reqcontractdetailsnews] + client.reqContractDetails(211, ContractSamples.NewsFeedForQuery()); + //! [reqcontractdetailsnews] + + } + + private static void hedgeSample(EClientSocket client, int nextOrderId) { + + //F Hedge order + //! [hedgesubmit] + //Parent order on a contract which currency differs from your base currency + Order parent = OrderSamples.LimitOrder("BUY", 100, 10); + parent.orderId(nextOrderId++); + parent.transmit(false); + //Hedge on the currency conversion + Order hedge = OrderSamples.MarketFHedge(parent.orderId(), "BUY"); + //Place the parent first... + client.placeOrder(parent.orderId(), ContractSamples.EuropeanStock(), parent); + //Then the hedge order + client.placeOrder(nextOrderId++, ContractSamples.EurGbpFx(), hedge); + //! [hedgesubmit] + + } + + private static void testAlgoSamples(EClientSocket client, int nextOrderId) throws InterruptedException { + + //! [scale_order] + Order scaleOrder = OrderSamples.RelativePeggedToPrimary("BUY", 70000, 189, 0.01); + AvailableAlgoParams.FillScaleParams(scaleOrder, 2000, 500, true, .02, 189.00, 3600, 2.00, true, 10, 40); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), scaleOrder); + //! [scale_order] + + Thread.sleep(500); + + //! [algo_base_order] + Order baseOrder = OrderSamples.LimitOrder("BUY", 1000, 1); + //! [algo_base_order] + + //! [arrivalpx] + AvailableAlgoParams.FillArrivalPriceParams(baseOrder, 0.1, "Aggressive", "09:00:00 CET", "16:00:00 CET", true, true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [arrivalpx] + + Thread.sleep(500); + + //! [darkice] + AvailableAlgoParams.FillDarkIceParams(baseOrder, 10, "09:00:00 CET", "16:00:00 CET", true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [darkice] + + Thread.sleep(500); + + //! [ad] + // The Time Zone in "startTime" and "endTime" attributes is ignored and always defaulted to GMT + AvailableAlgoParams.FillAccumulateDistributeParams(baseOrder, 10, 60, true, true, 1, true, true, "20161010-12:00:00 GMT", "20161010-16:00:00 GMT"); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [ad] + + Thread.sleep(500); + + //! [twap] + AvailableAlgoParams.FillTwapParams(baseOrder, "Marketable", "09:00:00 CET", "16:00:00 CET", true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [twap] + + Thread.sleep(500); + + //! [vwap] + AvailableAlgoParams.FillVwapParams(baseOrder, 0.2, "09:00:00 CET", "16:00:00 CET", true, true, true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [vwap] + + Thread.sleep(500); + + //! [balanceimpactrisk] + AvailableAlgoParams.FillBalanceImpactRiskParams(baseOrder, 0.1, "Aggressive", true); + client.placeOrder(nextOrderId++, ContractSamples.USOptionContract(), baseOrder); + //! [balanceimpactrisk] + + Thread.sleep(500); + + //! [minimpact] + AvailableAlgoParams.FillMinImpactParams(baseOrder, 0.3); + client.placeOrder(nextOrderId++, ContractSamples.USOptionContract(), baseOrder); + //! [minimpact] + + //! [adaptive] + AvailableAlgoParams.FillAdaptiveParams(baseOrder, "Normal"); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [adaptive] + + //! [closepx] + AvailableAlgoParams.FillClosePriceParams(baseOrder, 0.5, "Neutral", "12:00:00 EST", true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [closepx] + + //! [pctvol] + AvailableAlgoParams.FillPctVolParams(baseOrder, 0.5, "12:00:00 EST", "14:00:00 EST", true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [pctvol] + + //! [pctvolpx] + AvailableAlgoParams.FillPriceVariantPctVolParams(baseOrder, 0.1, 0.05, 0.01, 0.2, "12:00:00 EST", "14:00:00 EST", true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [pctvolpx] + + //! [pctvolsz] + AvailableAlgoParams.FillSizeVariantPctVolParams(baseOrder, 0.2, 0.4, "12:00:00 EST", "14:00:00 EST", true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [pctvolsz] + + //! [pctvoltm] + AvailableAlgoParams.FillTimeVariantPctVolParams(baseOrder, 0.2, 0.4, "12:00:00 EST", "14:00:00 EST", true, 100000); + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), baseOrder); + //! [pctvoltm] + + //! [jeff_vwap_algo] + AvailableAlgoParams.FillJefferiesVWAPParams(baseOrder, "10:00:00 EST", "16:00:00 EST", 10, 10, "Exclude_Both", 130, 135, 1, 10, "Patience", false, "Midpoint"); + client.placeOrder(nextOrderId++, ContractSamples.JefferiesContract(), baseOrder); + //! [jeff_vwap_algo] + + //! [csfb_inline_algo] + AvailableAlgoParams.FillCSFBInlineParams(baseOrder, "10:00:00 EST", "16:00:00 EST", "Patient", 10, 20, 100, "Default", false, 40, 100, 100, 35 ); + client.placeOrder(nextOrderId++, ContractSamples.CSFBContract(), baseOrder); + //! [csfb_inline_algo] + + //! [qbalgo_strobe_algo] + AvailableAlgoParams.FillQBAlgoInlineParams(baseOrder, "10:00:00 EST", "16:00:00 EST", -99, "TWAP", 0.25, true ); + client.placeOrder(nextOrderId++, ContractSamples.QBAlgoContract(), baseOrder); + //! [qbalgo_strobe_algo] + + } + + private static void bracketSample(EClientSocket client, int nextOrderId) { + + //BRACKET ORDER + //! [bracketsubmit] + List bracket = OrderSamples.BracketOrder(nextOrderId++, "BUY", 100, 30, 40, 20); + for(Order o : bracket) { + client.placeOrder(o.orderId(), ContractSamples.EuropeanStock(), o); + } + //! [bracketsubmit] + + } + + private static void bulletins(EClientSocket client) throws InterruptedException { + + //! [reqnewsbulletins] + client.reqNewsBulletins(true); + //! [reqnewsbulletins] + + Thread.sleep(2000); + + //! [cancelnewsbulletins] + client.cancelNewsBulletins(); + //! [cancelnewsbulletins] + + } + + private static void fundamentals(EClientSocket client) throws InterruptedException { + + //! [reqfundamentaldata] + client.reqFundamentalData(8001, ContractSamples.USStock(), "ReportsFinSummary", null); + //! [reqfundamentaldata] + + Thread.sleep(2000); + + //! [fundamentalexamples] + client.reqFundamentalData(8002, ContractSamples.USStock(), "ReportSnapshot", null); //for company overview + client.reqFundamentalData(8003, ContractSamples.USStock(), "ReportRatios", null); //for financial ratios + client.reqFundamentalData(8004, ContractSamples.USStock(), "ReportsFinStatements", null); //for financial statements + client.reqFundamentalData(8005, ContractSamples.USStock(), "RESC", null); //for analyst estimates + client.reqFundamentalData(8006, ContractSamples.USStock(), "CalendarReport", null); //for company calendar + //! [fundamentalexamples] + + //! [cancelfundamentaldata] + client.cancelFundamentalData(8001); + //! [cancelfundamentaldata] + + } + + private static void marketScanners(EClientSocket client) throws InterruptedException { + + /*** Requesting all available parameters which can be used to build a scanner request ***/ + //! [reqscannerparameters] + client.reqScannerParameters(); + //! [reqscannerparameters] + Thread.sleep(2000); + + /*** Triggering a scanner subscription ***/ + //! [reqscannersubscription] + client.reqScannerSubscription(7001, ScannerSubscriptionSamples.HighOptVolumePCRatioUSIndexes(), null, null); + + TagValue t1 = new TagValue("usdMarketCapAbove", "10000"); + TagValue t2 = new TagValue("optVolumeAbove", "1000"); + TagValue t3 = new TagValue("avgVolumeAbove", "100000000"); + + List TagValues = Arrays.asList(t1, t2, t3); + client.reqScannerSubscription(7002, ScannerSubscriptionSamples.HotUSStkByVolume(), null, TagValues); // requires TWS v973+ + + //! [reqscannersubscription] + + //! [reqcomplexscanner] + List AAPLConIDTag = Collections.singletonList(new TagValue("underConID", "265598")); // 265598 is the conID for AAPL stock + client.reqScannerSubscription(7003, ScannerSubscriptionSamples.ComplexOrdersAndTrades(), null, AAPLConIDTag); // requires TWS v975+ + + //! [reqcomplexscanner] + + + Thread.sleep(4000); + /*** Canceling the scanner subscription ***/ + //! [cancelscannersubscription] + client.cancelScannerSubscription(7001); + client.cancelScannerSubscription(7002); + client.cancelScannerSubscription(7003); + //! [cancelscannersubscription] + + } + + private static void financialAdvisorOperations(EClientSocket client) { + + /*** Requesting FA information ***/ + //! [requestfaaliases] + client.requestFA(FADataType.ALIASES.ordinal()); + //! [requestfaaliases] + + //! [requestfagroups] + client.requestFA(FADataType.GROUPS.ordinal()); + //! [requestfagroups] + + //! [requestfaprofiles] + client.requestFA(FADataType.PROFILES.ordinal()); + //! [requestfaprofiles] + + /*** Replacing FA information - Fill in with the appropriate XML string. ***/ + //! [replacefaonegroup] + client.replaceFA(100, FADataType.GROUPS.ordinal(), FAMethodSamples.FA_ONE_GROUP); + //! [replacefaonegroup] + + //! [replacefatwogroups] + client.replaceFA(101, FADataType.GROUPS.ordinal(), FAMethodSamples.FA_TWO_GROUPS); + //! [replacefatwogroups] + + //! [replacefaoneprofile] + client.replaceFA(102, FADataType.PROFILES.ordinal(), FAMethodSamples.FA_ONE_PROFILE); + //! [replacefaoneprofile] + + //! [replacefatwoprofiles] + client.replaceFA(103, FADataType.PROFILES.ordinal(), FAMethodSamples.FA_TWO_PROFILES); + //! [replacefatwoprofiles] + + //! [reqSoftDollarTiers] + client.reqSoftDollarTiers(4001); + //! [reqSoftDollarTiers] + } + + private static void testDisplayGroups(EClientSocket client) throws InterruptedException { + + //! [querydisplaygroups] + client.queryDisplayGroups(9001); + //! [querydisplaygroups] + + Thread.sleep(500); + + //! [subscribetogroupevents] + client.subscribeToGroupEvents(9002, 1); + //! [subscribetogroupevents] + + Thread.sleep(500); + + //! [updatedisplaygroup] + client.updateDisplayGroup(9002, "8314@SMART"); + //! [updatedisplaygroup] + + Thread.sleep(500); + + //! [subscribefromgroupevents] + client.unsubscribeFromGroupEvents(9002); + //! [subscribefromgroupevents] + + } + + private static void marketDataType(EClientSocket client) { + + //! [reqmarketdatatype] + /*** Switch to live (1) frozen (2) delayed (3) or delayed frozen (4)***/ + client.reqMarketDataType(2); + //! [reqmarketdatatype] + + } + + private static void optionsOperations(EClientSocket client) { + + //! [reqsecdefoptparams] + client.reqSecDefOptParams(0, "IBM", "", "STK", 8314); + //! [reqsecdefoptparams] + + //! [calculateimpliedvolatility] + client.calculateImpliedVolatility(5001, ContractSamples.OptionAtBOX(), 5, 85, null); + //! [calculateimpliedvolatility] + + //** Canceling implied volatility *** + client.cancelCalculateImpliedVolatility(5001); + + //! [calculateoptionprice] + client.calculateOptionPrice(5002, ContractSamples.OptionAtBOX(), 0.22, 85, null); + //! [calculateoptionprice] + + //** Canceling option's price calculation *** + client.cancelCalculateOptionPrice(5002); + + //! [exercise_options] + //** Exercising options *** + client.exerciseOptions(5003, ContractSamples.OptionWithTradingClass(), 1, 1, "", 1); + //! [exercise_options] + } + + private static void rerouteCFDOperations(EClientSocket client) throws InterruptedException { + + //! [reqmktdatacfd] + client.reqMktData(16001, ContractSamples.USStockCFD(), "", false, false, null); + Thread.sleep(1000); + client.reqMktData(16002, ContractSamples.EuropeanStockCFD(), "", false, false, null); + Thread.sleep(1000); + client.reqMktData(16003, ContractSamples.CashCFD(), "", false, false, null); + Thread.sleep(1000); + //! [reqmktdatacfd] + + //! [reqmktdepthcfd] + client.reqMktDepth(16004, ContractSamples.USStockCFD(), 10, false, null); + Thread.sleep(1000); + client.reqMktDepth(16005, ContractSamples.EuropeanStockCFD(), 10, false, null); + Thread.sleep(1000); + client.reqMktDepth(16006, ContractSamples.CashCFD(), 10, false, null); + Thread.sleep(1000); + //! [reqmktdepthcfd] + } + + private static void marketRuleOperations(EClientSocket client) throws InterruptedException { + client.reqContractDetails(17001, ContractSamples.USStock()); + client.reqContractDetails(17002, ContractSamples.Bond()); + + Thread.sleep(2000); + + //! [reqmarketrule] + client.reqMarketRule(26); + client.reqMarketRule(240); + //! [reqmarketrule] + } + + private static void continuousFuturesOperations(EClientSocket client) throws InterruptedException { + + /*** Requesting continuous futures contract details ***/ + client.reqContractDetails(18001, ContractSamples.ContFut()); + + /*** Requesting historical data for continuous futures ***/ + //! [reqhistoricaldatacontfut] + Calendar cal = Calendar.getInstance(); + SimpleDateFormat form = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); + String formatted = form.format(cal.getTime()); + client.reqHistoricalData(18002, ContractSamples.ContFut(), formatted, "1 Y", "1 month", "TRADES", 0, 1, false, null); + Thread.sleep(10000); + /*** Canceling historical data request for continuous futures ***/ + client.cancelHistoricalData(18002); + //! [reqhistoricaldatacontfut] + } + + private static void tickByTickOperations(EClientSocket client) throws InterruptedException { + + /*** Requesting tick-by-tick data (only refresh) ***/ + //! [reqtickbytick] + client.reqTickByTickData(19001, ContractSamples.USStockAtSmart(), "Last", 0, false); + client.reqTickByTickData(19002, ContractSamples.USStockAtSmart(), "AllLast", 0, false); + client.reqTickByTickData(19003, ContractSamples.USStockAtSmart(), "BidAsk", 0, true); + client.reqTickByTickData(19004, ContractSamples.EurGbpFx(), "MidPoint", 0, false); + //! [reqtickbytick] + + Thread.sleep(10000); + + //! [canceltickbytick] + client.cancelTickByTickData(19001); + client.cancelTickByTickData(19002); + client.cancelTickByTickData(19003); + client.cancelTickByTickData(19004); + //! [canceltickbytick] + + /*** Requesting tick-by-tick data (refresh + historical ticks) ***/ + //! [reqtickbytick] + client.reqTickByTickData(19005, ContractSamples.EuropeanStock(), "Last", 10, false); + client.reqTickByTickData(19006, ContractSamples.EuropeanStock(), "AllLast", 10, false); + client.reqTickByTickData(19007, ContractSamples.EuropeanStock(), "BidAsk", 10, false); + client.reqTickByTickData(19008, ContractSamples.EurGbpFx(), "MidPoint", 10, true); + //! [reqtickbytick] + + Thread.sleep(10000); + + //! [canceltickbytick] + client.cancelTickByTickData(19005); + client.cancelTickByTickData(19006); + client.cancelTickByTickData(19007); + client.cancelTickByTickData(19008); + //! [canceltickbytick] + } + + private static void whatIfSamples(EClientSocket client, int nextOrderId) throws InterruptedException { + + /*** Placing what-if order ***/ + //! [whatiforder] + client.placeOrder(nextOrderId++, ContractSamples.USStockAtSmart(), OrderSamples.WhatIfLimitOrder("BUY", 200, 120)); + //! [whatiforder] + } +} diff --git a/test/samples/testbed/advisor/FAMethodSamples.java b/test/samples/testbed/advisor/FAMethodSamples.java new file mode 100644 index 0000000..1866705 --- /dev/null +++ b/test/samples/testbed/advisor/FAMethodSamples.java @@ -0,0 +1,107 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.testbed.advisor; + +public class FAMethodSamples { + + //! [faonegroup] + public static final String FA_ONE_GROUP = "" + + "" + + "" + + "Equal_Quantity" + + "" + //Replace with your own accountIds + + "DU119915" + + "DU119916" + + "" + + "EqualQuantity" + + "" + + ""; + //! [faonegroup] + + //! [fatwogroups] + public static final String FA_TWO_GROUPS = "" + +"" + + "" + + "Equal_Quantity" + + "" + //Replace with your own accountIds + + "DU119915" + + "DU119916" + + "" + + "EqualQuantity" + + "" + + "" + + "Pct_Change" + + "" + //Replace with your own accountIds + + "DU119915" + + "DU119916" + + "" + + "PctChange" + + "" + + ""; + //! [fatwogroups] + + //! [faoneprofile] + public static final String FA_ONE_PROFILE = "" + + "" + + "" + + "Percent_60_40" + + "1" + + "" + + "" + //Replace with your own accountIds + + "DU119915" + + "60.0" + + "" + + "" + //Replace with your own accountIds + + "DU119916" + + "40.0" + + "" + + "" + + "" + + ""; + //! [faoneprofile] + + //! [fatwoprofiles] + public static final String FA_TWO_PROFILES = "" + + "" + + "" + + "Percent_60_40" + + "1" + + "" + + "" + //Replace with your own accountIds + + "DU119915" + + "60.0" + + "" + + "" + //Replace with your own accountIds + + "DU119916" + + "40.0" + + "" + + "" + + "" + + "" + + "Ratios_2_1" + + "1" + + "" + + "" + //Replace with your own accountIds + + "DU119915" + + "2.0" + + "" + + "" + //Replace with your own accountIds + + "DU119916" + + "1.0" + + "" + + "" + + "" + + ""; + //! [fatwoprofiles] + +} diff --git a/test/samples/testbed/contracts/ContractSamples.java b/test/samples/testbed/contracts/ContractSamples.java new file mode 100644 index 0000000..089c2f9 --- /dev/null +++ b/test/samples/testbed/contracts/ContractSamples.java @@ -0,0 +1,601 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.testbed.contracts; + +import java.util.ArrayList; +import java.util.List; + +import com.ib.client.ComboLeg; +import com.ib.client.Contract; + +public class ContractSamples { + + public static Contract USStockWithPrimaryExch() { + //! [stkcontractwithprimary] + Contract contract = new Contract(); + contract.symbol("MSFT"); + contract.secType("STK"); + contract.currency("USD"); + contract.exchange("SMART"); + // Specify the Primary Exchange attribute to avoid contract ambiguity + // (there is an ambiguity because there is also a MSFT contract with primary exchange = "AEB") + contract.primaryExch("ISLAND"); + //! [stkcontractwithprimary] + return contract; + } + + public static Contract BondWithCusip() { + //! [bondwithcusip] + Contract contract = new Contract(); + // enter CUSIP as symbol + contract.symbol("912828C57"); + contract.secType("BOND"); + contract.exchange("SMART"); + contract.currency("USD"); + //! [bondwithcusip] + return contract; + } + + public static Contract Bond() { + //! [bond] + Contract contract = new Contract(); + contract.conid(285191782); + contract.exchange("SMART"); + //! [bond] + return contract; + } + + public static Contract MutualFund() { + //! [fundcontract] + Contract contract = new Contract(); + contract.symbol("VINIX"); + contract.secType("FUND"); + contract.exchange("FUNDSERV"); + contract.currency("USD"); + //! [fundcontract] + return contract; + } + + public static Contract Commodity() { + //! [commoditycontract] + Contract contract = new Contract(); + contract.symbol("XAUUSD"); + contract.secType("CMDTY"); + contract.exchange("SMART"); + contract.currency("USD"); + //! [commoditycontract] + return contract; + } + + + public static Contract EurGbpFx() { + //! [cashcontract] + Contract contract = new Contract(); + contract.symbol("EUR"); + contract.secType("CASH"); + contract.currency("GBP"); + contract.exchange("IDEALPRO"); + //! [cashcontract] + return contract; + } + + public static Contract Index() { + //! [indcontract] + Contract contract = new Contract(); + contract.symbol("DAX"); + contract.secType("IND"); + contract.currency("EUR"); + contract.exchange("DTB"); + //! [indcontract] + return contract; + } + + public static Contract CFD() { + //! [cfdcontract] + Contract contract = new Contract(); + contract.symbol("IBDE30"); + contract.secType("CFD"); + contract.currency("EUR"); + contract.exchange("SMART"); + //! [cfdcontract] + return contract; + } + + public static Contract USStockCFD() { + //! [usstockcfd] + Contract contract = new Contract(); + contract.symbol("IBM"); + contract.secType("CFD"); + contract.currency("USD"); + contract.exchange("SMART"); + //! [usstockcfd] + return contract; + } + + public static Contract EuropeanStockCFD() { + //! [europeanstockcfd] + Contract contract = new Contract(); + contract.symbol("BMW"); + contract.secType("CFD"); + contract.currency("EUR"); + contract.exchange("SMART"); + //! [europeanstockcfd] + return contract; + } + + public static Contract CashCFD() { + //! [cashcfd] + Contract contract = new Contract(); + contract.symbol("EUR"); + contract.secType("CFD"); + contract.currency("USD"); + contract.exchange("SMART"); + //! [cashcfd] + return contract; + } + + public static Contract EuropeanStock() { + Contract contract = new Contract(); + contract.symbol("NOKIA"); + contract.secType("STK"); + contract.currency("EUR"); + contract.exchange("SMART"); + contract.primaryExch("HEX"); + return contract; + } + + public static Contract OptionAtIse() { + Contract contract = new Contract(); + contract.symbol("BPX"); + contract.secType("OPT"); + contract.currency("USD"); + contract.exchange("ISE"); + contract.lastTradeDateOrContractMonth("20160916"); + contract.right("C"); + contract.strike(65); + contract.multiplier("100"); + return contract; + } + + public static Contract USStock() { + //! [stkcontract] + Contract contract = new Contract(); + contract.symbol("IBKR"); + contract.secType("STK"); + contract.currency("USD"); + //In the API side, NASDAQ is always defined as ISLAND + contract.exchange("ISLAND"); + //! [stkcontract] + return contract; + } + + public static Contract USStockAtSmart() { + Contract contract = new Contract(); + contract.symbol("IBM"); + contract.secType("STK"); + contract.currency("USD"); + contract.exchange("SMART"); + return contract; + } + + public static Contract USOptionContract() { + Contract contract = new Contract(); + contract.symbol("GOOG"); + contract.secType("OPT"); + contract.currency("USD"); + contract.exchange("SMART"); + contract.lastTradeDateOrContractMonth("20170120"); + contract.strike(615); + contract.right("C"); + contract.multiplier("100"); + return contract; + } + + public static Contract OptionAtBOX() { + //! [optcontract] + Contract contract = new Contract(); + contract.symbol("GOOG"); + contract.secType("OPT"); + contract.currency("USD"); + contract.exchange("BOX"); + contract.lastTradeDateOrContractMonth("20170120"); + contract.right("C"); + contract.strike(615); + contract.multiplier("100"); + //! [optcontract] + return contract; + } + + public static Contract OptionWithTradingClass() { + //! [optcontract_tradingclass] + Contract contract = new Contract(); + contract.symbol("SANT"); + contract.secType("OPT"); + contract.currency("EUR"); + contract.exchange("MEFFRV"); + contract.lastTradeDateOrContractMonth("20190621"); + contract.right("C"); + contract.strike(7.5); + contract.multiplier("100"); + contract.tradingClass("SANEU"); + //! [optcontract_tradingclass] + return contract; + } + + public static Contract OptionWithLocalSymbol() { + //! [optcontract_localsymbol] + Contract contract = new Contract(); + //Watch out for the spaces within the local symbol! + contract.localSymbol("C DBK DEC 20 1600"); + contract.secType("OPT"); + contract.exchange("DTB"); + contract.currency("EUR"); + //! [optcontract_localsymbol] + return contract; + } + + public static Contract DutchWarrant() { + //! [ioptcontract] + Contract contract = new Contract(); + contract.localSymbol("B881G"); + contract.secType("IOPT"); + contract.exchange("SBF"); + contract.currency("EUR"); + //! [ioptcontract] + return contract; + } + + public static Contract SimpleFuture() { + //! [futcontract] + Contract contract = new Contract(); + contract.symbol("ES"); + contract.secType("FUT"); + contract.currency("USD"); + contract.exchange("GLOBEX"); + contract.lastTradeDateOrContractMonth("201803"); + //! [futcontract] + return contract; + } + + public static Contract FutureWithLocalSymbol() { + //! [futcontract_local_symbol] + Contract contract = new Contract(); + contract.localSymbol("ESU6"); + contract.secType("FUT"); + contract.currency("USD"); + contract.exchange("GLOBEX"); + //! [futcontract_local_symbol] + return contract; + } + + public static Contract FutureWithMultiplier() { + //! [futcontract_multiplier] + Contract contract = new Contract(); + contract.symbol("DAX"); + contract.secType("FUT"); + contract.currency("EUR"); + contract.exchange("DTB"); + contract.lastTradeDateOrContractMonth("201609"); + contract.multiplier("5"); + //! [futcontract_multiplier] + return contract; + } + + public static Contract WrongContract() { + Contract contract = new Contract(); + contract.localSymbol(" IJR "); + contract.conid(9579976); + contract.secType("STK"); + contract.currency("USD"); + contract.exchange("SMART"); + return contract; + } + + public static Contract FuturesOnOptions() { + //! [fopcontract] + Contract contract = new Contract(); + contract.symbol("ES"); + contract.secType("FOP"); + contract.currency("USD"); + contract.exchange("GLOBEX"); + contract.lastTradeDateOrContractMonth("20180316"); + contract.right("C"); + contract.strike(2800); + contract.multiplier("50"); + //! [fopcontract] + return contract; + } + + public static Contract ByISIN() { + Contract contract = new Contract(); + contract.secIdType("ISIN"); + contract.secId("US45841N1072"); + contract.secType("STK"); + contract.currency("USD"); + contract.exchange("SMART"); + return contract; + } + + public static Contract ByConId() { + Contract contract = new Contract(); + contract.conid(12087792); + contract.secType("CASH"); + contract.exchange("IDEALPRO"); + return contract; + } + + public static Contract OptionForQuery() { + //! [optionforquery] + Contract contract = new Contract(); + contract.symbol("FISV"); + contract.secType("OPT"); + contract.currency("USD"); + contract.exchange("SMART"); + //! [optionforquery] + return contract; + } + + public static Contract OptionComboContract() { + //! [bagoptcontract] + Contract contract = new Contract(); + contract.symbol("DBK"); + contract.secType("BAG"); + contract.currency("EUR"); + contract.exchange("DTB"); + + ComboLeg leg1 = new ComboLeg(); + ComboLeg leg2 = new ComboLeg(); + + List addAllLegs = new ArrayList<>(); + + leg1.conid(197397509);//DBK JUN 15 '18 C + leg1.ratio(1); + leg1.action("BUY"); + leg1.exchange("DTB"); + + leg2.conid(197397584);//DBK JUN 15 '18 P + leg2.ratio(1); + leg2.action("SELL"); + leg2.exchange("DTB"); + + addAllLegs.add(leg1); + addAllLegs.add(leg2); + + contract.comboLegs(addAllLegs); + //! [bagoptcontract] + + return contract; + } + + public static Contract StockComboContract() { + //! [bagstkcontract] + Contract contract = new Contract(); + contract.symbol("MCD"); + contract.secType("BAG"); + contract.currency("USD"); + contract.exchange("SMART"); + + ComboLeg leg1 = new ComboLeg(); + ComboLeg leg2 = new ComboLeg(); + + List addAllLegs = new ArrayList<>(); + + leg1.conid(43645865);//IBKR STK + leg1.ratio(1); + leg1.action("BUY"); + leg1.exchange("SMART"); + + leg2.conid(9408);//MCD STK + leg2.ratio(1); + leg2.action("SELL"); + leg2.exchange("SMART"); + + addAllLegs.add(leg1); + addAllLegs.add(leg2); + + contract.comboLegs(addAllLegs); + //! [bagstkcontract] + + return contract; + } + + public static Contract FutureComboContract() { + //! [bagfutcontract] + Contract contract = new Contract(); + contract.symbol("VIX"); + contract.secType("BAG"); + contract.currency("USD"); + contract.exchange("CFE"); + + ComboLeg leg1 = new ComboLeg(); + ComboLeg leg2 = new ComboLeg(); + + List addAllLegs = new ArrayList<>(); + + leg1.conid(195538625);//VIX FUT 20160217 + leg1.ratio(1); + leg1.action("BUY"); + leg1.exchange("CFE"); + + leg2.conid(197436571);//VIX FUT 20160316 + leg2.ratio(1); + leg2.action("SELL"); + leg2.exchange("CFE"); + + addAllLegs.add(leg1); + addAllLegs.add(leg2); + + contract.comboLegs(addAllLegs); + //! [bagfutcontract] + + return contract; + } + + public static Contract SmartFutureComboContract() { + //! [smartfuturespread] + Contract contract = new Contract(); + contract.symbol("WTI"); // WTI,COIL spread. Symbol can be defined as first leg symbol ("WTI") or currency ("USD"). + contract.secType("BAG"); + contract.currency("USD"); + contract.exchange("SMART"); // smart-routed rather than direct routed + + ComboLeg leg1 = new ComboLeg(); + ComboLeg leg2 = new ComboLeg(); + + List addAllLegs = new ArrayList<>(); + + leg1.conid(55928698);// WTI future June 2017 + leg1.ratio(1); + leg1.action("BUY"); + leg1.exchange("IPE"); + + leg2.conid(55850663);// COIL future June 2017 + leg2.ratio(1); + leg2.action("SELL"); + leg2.exchange("IPE"); + + addAllLegs.add(leg1); + addAllLegs.add(leg2); + + contract.comboLegs(addAllLegs); + //! [smartfuturespread] + + return contract; + } + + public static Contract InterCmdtyFuturesContract() { + //! [intcmdfutcontract] + Contract contract = new Contract(); + contract.symbol("CL.BZ"); + contract.secType("BAG"); + contract.currency("USD"); + contract.exchange("NYMEX"); + + ComboLeg leg1 = new ComboLeg(); + ComboLeg leg2 = new ComboLeg(); + + List addAllLegs = new ArrayList<>(); + + leg1.conid(47207310); //CL Dec'16 @NYMEX + leg1.ratio(1); + leg1.action("BUY"); + leg1.exchange("NYMEX"); + + leg2.conid(47195961); //BZ Dec'16 @NYMEX + leg2.ratio(1); + leg2.action("SELL"); + leg2.exchange("NYMEX"); + + addAllLegs.add(leg1); + addAllLegs.add(leg2); + + contract.comboLegs(addAllLegs); + //! [intcmdfutcontract] + + return contract; + } + + public static Contract NewsFeedForQuery() { + //! [newsfeedforquery] + Contract contract = new Contract(); + contract.secType("NEWS"); + contract.exchange("BRF"); //Briefing Trader + //! [newsfeedforquery] + return contract; + } + + public static Contract BTbroadtapeNewsFeed() { + //! [newscontractbt] + Contract contract = new Contract(); + contract.symbol("BRF:BRF_ALL"); //BroadTape All News + contract.secType("NEWS"); + contract.exchange("BRF"); //Briefing Trader + //! [newscontractbt] + return contract; + } + + public static Contract BZbroadtapeNewsFeed() { + //! [newscontractbz] + Contract contract = new Contract(); + contract.symbol("BZ:BZ_ALL"); //BroadTape All News + contract.secType("NEWS"); + contract.exchange("BZ"); //Benzinga Pro + //! [newscontractbz] + return contract; + } + + public static Contract FLYbroadtapeNewsFeed() { + //! [newscontractfly] + Contract contract = new Contract(); + contract.symbol("FLY:FLY_ALL"); //BroadTape All News + contract.secType("NEWS"); + contract.exchange("FLY"); //Fly on the Wall + //! [newscontractfly] + return contract; + } + + public static Contract MTbroadtapeNewsFeed() { + //! [newscontractmt] + Contract contract = new Contract(); + contract.symbol("MT:MT_ALL"); //BroadTape All News + contract.secType("NEWS"); + contract.exchange("MT"); //Midnight Trader + //! [newscontractmt] + return contract; + } + + public static Contract ContFut() { + //! [continuousfuturescontract] + Contract contract = new Contract(); + contract.symbol("ES"); + contract.secType("CONTFUT"); + contract.exchange("GLOBEX"); + //! [continuousfuturescontract] + return contract; + } + + public static Contract ContAndExpiringFut() { + //! [contandexpiringfut] + Contract contract = new Contract(); + contract.symbol("ES"); + contract.secType("FUT+CONTFUT"); + contract.exchange("GLOBEX"); + //! [contandexpiringfut] + return contract; + } + + public static Contract JefferiesContract() { + //! [jefferies_contract] + Contract contract = new Contract(); + contract.symbol("AAPL"); + contract.secType("STK"); + contract.exchange("JEFFALGO"); // must be direct-routed to JEFFALGO + contract.currency("USD"); // only available for US stocks + //! [jefferies_contract] + return contract; + } + + public static Contract CSFBContract() { + //! [csfb_contract] + Contract contract = new Contract(); + contract.symbol("IBKR"); + contract.secType("STK"); + contract.exchange("CSFBALGO"); // must be direct-routed to CSFBALGO + contract.currency("USD"); // only available for US stocks + //! [csfb_contract] + return contract; + } + + public static Contract QBAlgoContract() { + //! [qbalgo_contract] + Contract contract = new Contract(); + contract.symbol("ES"); + contract.secType("FUT"); + contract.exchange("QBALGO"); + contract.currency("USD"); + contract.lastTradeDateOrContractMonth("202003"); + //! [qbalgo_contract] + return contract; + } +} \ No newline at end of file diff --git a/test/samples/testbed/orders/AvailableAlgoParams.java b/test/samples/testbed/orders/AvailableAlgoParams.java new file mode 100644 index 0000000..1c93966 --- /dev/null +++ b/test/samples/testbed/orders/AvailableAlgoParams.java @@ -0,0 +1,312 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.testbed.orders; + +import java.util.ArrayList; + +import com.ib.client.Order; +import com.ib.client.TagValue; + +public class AvailableAlgoParams { + + //! [scale_params] + public static void FillScaleParams (Order baseOrder, int scaleInitLevelSize, int scaleSubsLevelSize, boolean scaleRandomPercent, + double scalePriceIncrement, double scalePriceAdjustValue, int scalePriceAdjustInterval, double scaleProfitOffset, + boolean scaleAutoReset, int scaleInitPosition, int scaleInitFillQty) { + + baseOrder.scaleInitLevelSize(scaleInitLevelSize); //Initial Component Size + baseOrder.scaleSubsLevelSize(scaleSubsLevelSize); //Subsequent Comp. Size + baseOrder.scaleRandomPercent(scaleRandomPercent); //Randomize size by +/-55% + baseOrder.scalePriceIncrement(scalePriceIncrement); //Price Increment + + /*Auto Price adjustment*/ + baseOrder.scalePriceAdjustValue(scalePriceAdjustValue); //starting price by + baseOrder.scalePriceAdjustInterval(scalePriceAdjustInterval); // in seconds + + /*Profit Orders*/ + baseOrder.scaleProfitOffset(scaleProfitOffset); //Create profit taking order Profit Offset + baseOrder.scaleAutoReset(scaleAutoReset); //Restore size after taking profit + baseOrder.scaleInitPosition(scaleInitPosition); //Initial Position + baseOrder.scaleInitFillQty(scaleInitFillQty); //Filled initial Component Size + + } + //! [scale_params] + + //! [arrivalpx_params] + public static void FillArrivalPriceParams(Order baseOrder, double maxPctVol, String riskAversion, String startTime, + String endTime, boolean forceCompletion, boolean allowPastTime, double monetaryValue) { + + baseOrder.algoStrategy("ArrivalPx"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("maxPctVol", String.valueOf(maxPctVol))); + baseOrder.algoParams().add(new TagValue("riskAversion", riskAversion)); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("forceCompletion", forceCompletion ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("allowPastEndTime", allowPastTime ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + + } + //! [arrivalpx_params] + + //! [darkice_params] + public static void FillDarkIceParams(Order baseOrder, int displaySize, String startTime, String endTime, + boolean allowPastEndTime, double monetaryValue) { + + baseOrder.algoStrategy("DarkIce"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("displaySize", String.valueOf(displaySize))); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("allowPastEndTime", allowPastEndTime ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + + } + //! [darkice_params] + + //! [pctvol_params] + public static void FillPctVolParams(Order baseOrder, double pctVol, String startTime, String endTime, boolean noTakeLiq, double monetaryValue) { + + baseOrder.algoStrategy("PctVol"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("pctVol", String.valueOf(pctVol))); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("noTakeLiq", noTakeLiq ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + } + //! [pctvol_params] + + //! [twap_params] + public static void FillTwapParams(Order baseOrder, String strategyType, String startTime, String endTime, + boolean allowPastEndTime, double monetaryValue) { + + baseOrder.algoStrategy("Twap"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("strategyType", strategyType)); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("allowPastEndTime", allowPastEndTime ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + + } + //! [twap_params] + + //! [vwap_params] + public static void FillVwapParams(Order baseOrder, double maxPctVol, String startTime, String endTime, + boolean allowPastEndTime, boolean noTakeLiq, boolean speedUp, double monetaryValue) { + + baseOrder.algoStrategy("Vwap"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("maxPctVol", String.valueOf(maxPctVol))); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("allowPastEndTime", allowPastEndTime ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("noTakeLiq", noTakeLiq ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("speedUp", speedUp ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + + } + //! [vwap_params] + + //! [ad_params] + public static void FillAccumulateDistributeParams(Order baseOrder, int componentSize, int timeBetweenOrders, boolean randomizeTime20, boolean randomizeSize55, + int giveUp, boolean catchUp, boolean waitForFill, String startTime, String endTime) { + + baseOrder.algoStrategy("AD"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("componentSize", String.valueOf(componentSize))); + baseOrder.algoParams().add(new TagValue("timeBetweenOrders", String.valueOf(timeBetweenOrders))); + baseOrder.algoParams().add(new TagValue("randomizeTime20", randomizeTime20 ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("randomizeSize55", randomizeSize55 ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("giveUp", String.valueOf(giveUp))); + baseOrder.algoParams().add(new TagValue("catchUp", catchUp ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("waitForFill", waitForFill ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("activeTimeStart", startTime)); + baseOrder.algoParams().add(new TagValue("activeTimeEnd", endTime)); + + } + //! [ad_params] + + //! [balanceimpactrisk_params] + public static void FillBalanceImpactRiskParams(Order baseOrder, double maxPctVol, String riskAversion, boolean forceCompletion) { + + baseOrder.algoStrategy("BalanceImpactRisk"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("maxPctVol", String.valueOf(maxPctVol))); + baseOrder.algoParams().add(new TagValue("riskAversion", riskAversion)); + baseOrder.algoParams().add(new TagValue("forceCompletion", forceCompletion ? "1" : "0")); + + } + //! [balanceimpactrisk_params] + + //! [minimpact_params] + public static void FillMinImpactParams(Order baseOrder, double maxPctVol) { + + baseOrder.algoStrategy("BalanceImpactRisk"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("maxPctVol", String.valueOf(maxPctVol))); + + } + //! [minimpact_params] + + //! [adaptive_params] + public static void FillAdaptiveParams(Order baseOrder, String priority) { + + baseOrder.algoStrategy("Adaptive"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("adaptivePriority", priority)); + + } + //! [adaptive_params] + + //! [closepx_params] + public static void FillClosePriceParams(Order baseOrder, double maxPctVol, String riskAversion, String startTime, + boolean forceCompletion, double monetaryValue){ + + baseOrder.algoStrategy("ClosePx"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("maxPctVol", String.valueOf(maxPctVol))); + baseOrder.algoParams().add(new TagValue("riskAversion", riskAversion)); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("forceCompletion", forceCompletion ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + } + //! [closepx_params] + + //! [pctvolpx_params] + public static void FillPriceVariantPctVolParams(Order baseOrder, double pctVol, double deltaPctVol, double minPctVol4Px, + double maxPctVol4Px, String startTime, String endTime, boolean noTakeLiq, double monetaryValue){ + + baseOrder.algoStrategy("PctVolPx"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("pctVol", String.valueOf(pctVol))); + baseOrder.algoParams().add(new TagValue("deltaPctVol", String.valueOf(deltaPctVol))); + baseOrder.algoParams().add(new TagValue("minPctVol4Px", String.valueOf(minPctVol4Px))); + baseOrder.algoParams().add(new TagValue("maxPctVol4Px", String.valueOf(maxPctVol4Px))); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("noTakeLiq", noTakeLiq ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + } + //! [pctvolpx_params] + + //! [pctvolsz_params] + public static void FillSizeVariantPctVolParams(Order baseOrder, double startPctVol, double endPctVol, + String startTime, String endTime, boolean noTakeLiq, double monetaryValue){ + + baseOrder.algoStrategy("PctVolSz"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("startPctVol", String.valueOf(startPctVol))); + baseOrder.algoParams().add(new TagValue("endPctVol", String.valueOf(endPctVol))); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("noTakeLiq", noTakeLiq ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + } + //! [pctvolsz_params] + + //! [pctvoltm_params] + public static void FillTimeVariantPctVolParams(Order baseOrder, double startPctVol, double endPctVol, + String startTime, String endTime, boolean noTakeLiq, double monetaryValue){ + + baseOrder.algoStrategy("PctVolTm"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("startPctVol", String.valueOf(startPctVol))); + baseOrder.algoParams().add(new TagValue("endPctVol", String.valueOf(endPctVol))); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("noTakeLiq", noTakeLiq ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + } + //! [pctvoltm_params] + + //! [csfb_params] + public static void FillCSFBParams(Order baseOrder, double startPctVol, double endPctVol, + String startTime, String endTime, boolean noTakeLiq, double monetaryValue){ + + // must be direct-routed to "CSFB" + + baseOrder.algoStrategy("PctVolTm"); + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("startPctVol", String.valueOf(startPctVol))); + baseOrder.algoParams().add(new TagValue("endPctVol", String.valueOf(endPctVol))); + baseOrder.algoParams().add(new TagValue("startTime", startTime)); + baseOrder.algoParams().add(new TagValue("endTime", endTime)); + baseOrder.algoParams().add(new TagValue("noTakeLiq", noTakeLiq ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("monetaryValue", String.valueOf(monetaryValue))); + } + //! [csfb_params] + + //! [jefferies_vwap_params] + public static void FillJefferiesVWAPParams(Order baseOrder, String startTime, String endTime, double relativeLimit, + double maxVolumeRate, String excludeAuctions, double triggerPrice, double wowPrice, int minFillSize, double wowOrderPct, + String wowMode, boolean isBuyBack, String wowReference) { + + // must be direct-routed to "JEFFALGO" + + baseOrder.algoStrategy("VWAP"); + + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("StartTime", startTime)); + baseOrder.algoParams().add(new TagValue("EndTime", endTime)); + baseOrder.algoParams().add(new TagValue("RelativeLimit", String.valueOf(relativeLimit))); + baseOrder.algoParams().add(new TagValue("MaxVolumeRate", String.valueOf(maxVolumeRate))); + baseOrder.algoParams().add(new TagValue("ExcludeAuctions", excludeAuctions)); + baseOrder.algoParams().add(new TagValue("TriggerPrice", String.valueOf(triggerPrice))); + baseOrder.algoParams().add(new TagValue("WowPrice", String.valueOf(wowPrice))); + baseOrder.algoParams().add(new TagValue("MinFillSize", String.valueOf(minFillSize))); + baseOrder.algoParams().add(new TagValue("WowOrderPct", String.valueOf(wowOrderPct))); + baseOrder.algoParams().add(new TagValue("WowMode", wowMode)); + baseOrder.algoParams().add(new TagValue("IsBuyBack", isBuyBack ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("WowReference", wowReference)); + + } + //! [jefferies_vwap_params] + + //! [csfb_inline_params] + public static void FillCSFBInlineParams(Order baseOrder, String startTime, String endTime, String execStyle, int minPercent, + int maxPercent, int displaySize, String auction, boolean blockFinder, double blockPrice, + int minBlockSize, int maxBlockSize, double iWouldPrice) { + + // must be direct-routed to "CSFBALGO" + + baseOrder.algoStrategy("INLINE"); + + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("StartTime", startTime)); + baseOrder.algoParams().add(new TagValue("EndTime", endTime)); + baseOrder.algoParams().add(new TagValue("ExecStyle", execStyle)); + baseOrder.algoParams().add(new TagValue("MinPercent", String.valueOf(minPercent))); + baseOrder.algoParams().add(new TagValue("MaxPercent", String.valueOf(maxPercent))); + baseOrder.algoParams().add(new TagValue("DisplaySize", String.valueOf(displaySize))); + baseOrder.algoParams().add(new TagValue("Auction", auction)); + baseOrder.algoParams().add(new TagValue("BlockFinder", blockFinder ? "1" : "0")); + baseOrder.algoParams().add(new TagValue("BlockPrice", String.valueOf(blockPrice))); + baseOrder.algoParams().add(new TagValue("MinBlockSize", String.valueOf(minBlockSize))); + baseOrder.algoParams().add(new TagValue("MaxBlockSize", String.valueOf(maxBlockSize))); + baseOrder.algoParams().add(new TagValue("IWouldPrice", String.valueOf(iWouldPrice))); + + } + //! [csfb_inline_params] + + //! [qbalgo_strobe_params] + public static void FillQBAlgoInlineParams(Order baseOrder, String startTime, String endTime, double duration, String benchmark, + double percentVolume, boolean noCleanUp) { + + baseOrder.algoStrategy("STROBE"); + + baseOrder.algoParams(new ArrayList<>()); + baseOrder.algoParams().add(new TagValue("StartTime", startTime)); + baseOrder.algoParams().add(new TagValue("EndTime", endTime)); + //This example uses endTime instead of duration + //baseOrder.algoParams().add(new TagValue("Duration", String.valueOf(duration))); + baseOrder.algoParams().add(new TagValue("Benchmark", benchmark)); + baseOrder.algoParams().add(new TagValue("PercentVolume", String.valueOf(percentVolume))); + baseOrder.algoParams().add(new TagValue("NoCleanUp", noCleanUp ? "1" : "0")); + + } + //! [qbalgo_strobe_params] + +} diff --git a/test/samples/testbed/orders/OrderSamples.java b/test/samples/testbed/orders/OrderSamples.java new file mode 100644 index 0000000..475a89a --- /dev/null +++ b/test/samples/testbed/orders/OrderSamples.java @@ -0,0 +1,728 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.testbed.orders; + +import java.util.ArrayList; +import java.util.List; +import com.ib.client.VolumeCondition; +import com.ib.client.TimeCondition; +import com.ib.client.PercentChangeCondition; +import com.ib.client.MarginCondition; +import com.ib.client.ExecutionCondition; +import com.ib.client.PriceCondition; +import com.ib.client.Order; +import com.ib.client.OrderComboLeg; +import com.ib.client.OrderCondition; +import com.ib.client.OrderConditionType; +import com.ib.client.OrderType; +import com.ib.client.TagValue; + +public class OrderSamples { + + public static Order AtAuction(String action, double quantity, double price) { + //! [auction] + Order order = new Order(); + order.action(action); + order.tif("AUC"); + order.orderType("MTL"); + order.totalQuantity(quantity); + order.lmtPrice(price); + //! [auction] + return order; + } + + public static Order Discretionary(String action, double quantity, double price, double discretionaryAmt) { + //! [discretionary] + Order order = new Order(); + order.action(action); + order.orderType("LMT"); + order.totalQuantity(quantity); + order.lmtPrice(price); + order.discretionaryAmt(discretionaryAmt); + //! [discretionary] + return order; + } + + public static Order MarketOrder(String action, double quantity) { + //! [market] + Order order = new Order(); + order.action(action); + order.orderType("MKT"); + order.totalQuantity(quantity); + //! [market] + return order; + } + + public static Order MarketIfTouched(String action, double quantity, double price) { + //! [market_if_touched] + Order order = new Order(); + order.action(action); + order.orderType("MIT"); + order.totalQuantity(quantity); + order.auxPrice(price); + //! [market_if_touched] + return order; + } + + public static Order MarketOnClose(String action, double quantity) { + //! [market_on_close] + Order order = new Order(); + order.action(action); + order.orderType("MOC"); + order.totalQuantity(quantity); + //! [market_on_close] + return order; + } + + public static Order MarketOnOpen(String action, double quantity) { + //! [market_on_open] + Order order = new Order(); + order.action(action); + order.orderType("MKT"); + order.totalQuantity(quantity); + order.tif("OPG"); + //! [market_on_open] + return order; + } + + public static Order MidpointMatch(String action, double quantity) { + //! [midpoint_match] + Order order = new Order(); + order.action(action); + order.orderType("MKT"); + order.totalQuantity(quantity); + //! [midpoint_match] + return order; + } + + public static Order Midprice(String action, double quantity, double priceCap) { + //! [midprice] + Order order = new Order(); + order.action(action); + order.orderType("MIDPRICE"); + order.totalQuantity(quantity); + order.lmtPrice(priceCap); // optional + //! [midprice] + return order; + } + + public static Order PeggedToMarket(String action, double quantity, double marketOffset) { + //! [pegged_market] + Order order = new Order(); + order.action(action); + order.orderType("PEG MKT"); + order.totalQuantity(100); + order.auxPrice(marketOffset);//Offset price + //! [pegged_market] + return order; + } + + public static Order PeggedToStock(String action, double quantity, double delta, double stockReferencePrice, double startingPrice) { + //! [pegged_stock] + Order order = new Order(); + order.action(action); + order.orderType("PEG STK"); + order.totalQuantity(quantity); + order.delta(delta); + order.stockRefPrice(stockReferencePrice); + order.startingPrice(startingPrice); + //! [pegged_stock] + return order; + } + + public static Order RelativePeggedToPrimary(String action, double quantity, double priceCap, double offsetAmount) { + //! [relative_pegged_primary] + Order order = new Order(); + order.action(action); + order.orderType("REL"); + order.totalQuantity(quantity); + order.lmtPrice(priceCap); + order.auxPrice(offsetAmount); + //! [relative_pegged_primary] + return order; + } + + public static Order SweepToFill(String action, double quantity, double price) { + //! [sweep_to_fill] + Order order = new Order(); + order.action(action); + order.orderType("LMT"); + order.totalQuantity(quantity); + order.lmtPrice(price); + order.sweepToFill(true); + //! [sweep_to_fill] + return order; + } + + public static Order AuctionLimit(String action, double quantity, double price, int auctionStrategy) { + //! [auction_limit] + Order order = new Order(); + order.action(action); + order.orderType("LMT"); + order.totalQuantity(quantity); + order.lmtPrice(price); + order.auctionStrategy(auctionStrategy); + //! [auction_limit] + return order; + } + + public static Order AuctionPeggedToStock(String action, double quantity, double startingPrice, double delta) { + //! [auction_pegged_stock] + Order order = new Order(); + order.action(action); + order.orderType("PEG STK"); + order.totalQuantity(quantity); + order.delta(delta); + order.startingPrice(startingPrice); + //! [auction_pegged_stock] + return order; + } + + public static Order AuctionRelative(String action, double quantity, double offset) { + //! [auction_relative] + Order order = new Order(); + order.action(action); + order.orderType("REL"); + order.totalQuantity(quantity); + order.auxPrice(offset); + //! [auction_relative] + return order; + } + + public static Order Block(String action, double quantity, double price) { + // ! [block] + Order order = new Order(); + order.action(action); + order.orderType("LMT"); + order.totalQuantity(quantity);//Large volumes! + order.lmtPrice(price); + order.blockOrder(true); + // ! [block] + return order; + } + + public static Order BoxTop(String action, double quantity) { + // ! [boxtop] + Order order = new Order(); + order.action(action); + order.orderType("BOX TOP"); + order.totalQuantity(quantity); + // ! [boxtop] + return order; + } + + public static Order LimitOrder(String action, double quantity, double limitPrice) { + // ! [limitorder] + Order order = new Order(); + order.action(action); + order.orderType("LMT"); + order.totalQuantity(quantity); + order.lmtPrice(limitPrice); + // ! [limitorder] + return order; + } + + // Forex orders can be placed in denomination of second currency in pair using cashQty field + // Requires TWS or IBG 963+ + // https://www.interactivebrokers.com/en/index.php?f=23876#963-02 + + public static Order LimitOrderWithCashQty(String action, double quantity, double limitPrice, double cashQty) { + // ! [limitorderwithcashqty] + Order order = new Order(); + order.action(action); + order.orderType("LMT"); + order.totalQuantity(quantity); + order.lmtPrice(limitPrice); + order.cashQty(cashQty); + // ! [limitorderwithcashqty] + return order; + } + + + public static Order LimitIfTouched(String action, double quantity, double limitPrice, double triggerPrice) { + // ! [limitiftouched] + Order order = new Order(); + order.action(action); + order.orderType("LIT"); + order.totalQuantity(quantity); + order.lmtPrice(limitPrice); + order.auxPrice(triggerPrice); + // ! [limitiftouched] + return order; + } + + public static Order LimitOnClose(String action, double quantity, double limitPrice) { + // ! [limitonclose] + Order order = new Order(); + order.action(action); + order.orderType("LOC"); + order.totalQuantity(quantity); + order.lmtPrice(limitPrice); + // ! [limitonclose] + return order; + } + + public static Order LimitOnOpen(String action, double quantity, double limitPrice) { + // ! [limitonopen] + Order order = new Order(); + order.action(action); + order.tif("OPG"); + order.orderType("LOC"); + order.totalQuantity(quantity); + order.lmtPrice(limitPrice); + // ! [limitonopen] + return order; + } + + public static Order PassiveRelative(String action, double quantity, double offset) { + // ! [passive_relative] + Order order = new Order(); + order.action(action); + order.orderType("PASSV REL"); + order.totalQuantity(quantity); + order.auxPrice(offset); + // ! [passive_relative] + return order; + } + + public static Order PeggedToMidpoint(String action, double quantity, double offset, double limitPrice) { + // ! [pegged_midpoint] + Order order = new Order(); + order.action(action); + order.orderType("PEG MID"); + order.totalQuantity(quantity); + order.auxPrice(offset); + order.lmtPrice(limitPrice); + // ! [pegged_midpoint] + return order; + } + + //! [bracket] + public static List BracketOrder(int parentOrderId, String action, double quantity, double limitPrice, double takeProfitLimitPrice, double stopLossPrice) { + //This will be our main or "parent" order + Order parent = new Order(); + parent.orderId(parentOrderId); + parent.action(action); + parent.orderType("LMT"); + parent.totalQuantity(quantity); + parent.lmtPrice(limitPrice); + //The parent and children orders will need this attribute set to false to prevent accidental executions. + //The LAST CHILD will have it set to true. + parent.transmit(false); + + Order takeProfit = new Order(); + takeProfit.orderId(parent.orderId() + 1); + takeProfit.action(action.equals("BUY") ? "SELL" : "BUY"); + takeProfit.orderType("LMT"); + takeProfit.totalQuantity(quantity); + takeProfit.lmtPrice(takeProfitLimitPrice); + takeProfit.parentId(parentOrderId); + takeProfit.transmit(false); + + Order stopLoss = new Order(); + stopLoss.orderId(parent.orderId() + 2); + stopLoss.action(action.equals("BUY") ? "SELL" : "BUY"); + stopLoss.orderType("STP"); + //Stop trigger price + stopLoss.auxPrice(stopLossPrice); + stopLoss.totalQuantity(quantity); + stopLoss.parentId(parentOrderId); + //In this case, the low side order will be the last child being sent. Therefore, it needs to set this attribute to true + //to activate all its predecessors + stopLoss.transmit(true); + + List bracketOrder = new ArrayList<>(); + bracketOrder.add(parent); + bracketOrder.add(takeProfit); + bracketOrder.add(stopLoss); + + return bracketOrder; + } + //! [bracket] + + public static Order MarketToLimit(String action, double quantity) { + // ! [markettolimit] + Order order = new Order(); + order.action(action); + order.orderType("MTL"); + order.totalQuantity(quantity); + // ! [markettolimit] + return order; + } + + public static Order MarketWithProtection(String action, double quantity) { + // ! [marketwithprotection] + Order order = new Order(); + order.action(action); + order.orderType("MKT PRT"); + order.totalQuantity(quantity); + // ! [marketwithprotection] + return order; + } + + public static Order Stop(String action, double quantity, double stopPrice) { + // ! [stop] + Order order = new Order(); + order.action(action); + order.orderType("STP"); + order.auxPrice(stopPrice); + order.totalQuantity(quantity); + // ! [stop] + return order; + } + + public static Order StopLimit(String action, double quantity, double limitPrice, double stopPrice) { + // ! [stoplimit] + Order order = new Order(); + order.action(action); + order.orderType("STP LMT"); + order.lmtPrice(limitPrice); + order.auxPrice(stopPrice); + order.totalQuantity(quantity); + // ! [stoplimit] + return order; + } + + public static Order StopWithProtection(String action, double quantity, double stopPrice) { + // ! [stopwithprotection] + Order order = new Order(); + order.action(action); + order.orderType("STP PRT"); + order.auxPrice(stopPrice); + order.totalQuantity(quantity); + // ! [stopwithprotection] + return order; + } + + public static Order TrailingStop(String action, double quantity, double trailingPercent, double trailStopPrice) { + // ! [trailingstop] + Order order = new Order(); + order.action(action); + order.orderType("TRAIL"); + order.trailingPercent(trailingPercent); + order.trailStopPrice(trailStopPrice); + order.totalQuantity(quantity); + // ! [trailingstop] + return order; + } + + public static Order TrailingStopLimit(String action, double quantity, double lmtPriceOffset, double trailingAmount, double trailStopPrice) { + // ! [trailingstoplimit] + Order order = new Order(); + order.action(action); + order.orderType("TRAIL LIMIT"); + order.lmtPriceOffset(lmtPriceOffset); + order.auxPrice(trailingAmount); + order.trailStopPrice(trailStopPrice); + order.totalQuantity(quantity); + // ! [trailingstoplimit] + return order; + } + + public static Order ComboLimitOrder(String action, double quantity, boolean nonGuaranteed, double limitPrice) { + // ! [combolimit] + Order order = new Order(); + order.action(action); + order.orderType("LMT"); + order.lmtPrice(limitPrice); + order.totalQuantity(quantity); + if (nonGuaranteed) + { + order.smartComboRoutingParams().add(new TagValue("NonGuaranteed", "1")); + } + // ! [combolimit] + return order; + } + + public static Order ComboMarketOrder(String action, double quantity, boolean nonGuaranteed) { + // ! [combomarket] + Order order = new Order(); + order.action(action); + order.orderType("MKT"); + order.totalQuantity(quantity); + if (nonGuaranteed) + { + order.smartComboRoutingParams().add(new TagValue("NonGuaranteed", "1")); + } + // ! [combomarket] + return order; + } + + public static Order LimitOrderForComboWithLegPrices(String action, double quantity, boolean nonGuaranteed, double[] legPrices) { + // ! [limitordercombolegprices] + Order order = new Order(); + order.action(action); + order.orderType("LMT"); + order.totalQuantity(quantity); + order.orderComboLegs(new ArrayList<>()); + + for(double price : legPrices) { + OrderComboLeg comboLeg = new OrderComboLeg(); + comboLeg.price(5.0); + order.orderComboLegs().add(comboLeg); + } + + if (nonGuaranteed) + { + order.smartComboRoutingParams().add(new TagValue("NonGuaranteed", "1")); + } + // ! [limitordercombolegprices] + return order; + } + + public static Order RelativeLimitCombo(String action, double quantity, boolean nonGuaranteed, double limitPrice) { + // ! [relativelimitcombo] + Order order = new Order(); + order.action(action); + order.orderType("REL + LMT"); + order.totalQuantity(quantity); + order.lmtPrice(limitPrice); + + if (nonGuaranteed) + { + order.smartComboRoutingParams().add(new TagValue("NonGuaranteed", "1")); + } + // ! [relativelimitcombo] + return order; + } + + public static Order RelativeMarketCombo(String action, double quantity, boolean nonGuaranteed) { + // ! [relativemarketcombo] + Order order = new Order(); + order.action(action); + order.orderType("REL + MKT"); + order.totalQuantity(quantity); + if (nonGuaranteed) + { + order.smartComboRoutingParams().add(new TagValue("NonGuaranteed", "1")); + } + // ! [relativemarketcombo] + return order; + } + + // ! [oca] + public static List OneCancelsAll(String ocaGroup, List ocaOrders, int ocaType) { + + for (Order o : ocaOrders) { + o.ocaGroup(ocaGroup); + o.ocaType(ocaType); + } + return ocaOrders; + } + // ! [oca] + + public static Order Volatility(String action, double quantity, double volatilityPercent, int volatilityType) { + // ! [volatility] + Order order = new Order(); + order.action(action); + order.orderType("VOL"); + order.volatility(volatilityPercent);//Expressed in percentage (40%) + order.volatilityType(volatilityType);// 1=daily, 2=annual + order.totalQuantity(quantity); + // ! [volatility] + return order; + } + + //! [fhedge] + public static Order MarketFHedge(int parentOrderId, String action) { + //FX Hedge orders can only have a quantity of 0 + Order order = MarketOrder(action, 0); + order.parentId(parentOrderId); + order.hedgeType("F"); + return order; + } + //! [fhedge] + + public static Order PeggedToBenchmark(String action, double quantity, double startingPrice, boolean peggedChangeAmountDecrease, double peggedChangeAmount, double referenceChangeAmount, int referenceConId, String referenceExchange, double stockReferencePrice, + double referenceContractLowerRange, double referenceContractUpperRange) { + //! [pegged_benchmark] + Order order = new Order(); + order.orderType("PEG BENCH"); + //BUY or SELL + order.action(action); + order.totalQuantity(quantity); + //Beginning with price... + order.startingPrice(startingPrice); + //increase/decrease price... + order.isPeggedChangeAmountDecrease(peggedChangeAmountDecrease); + //by... (and likewise for price moving in opposite direction) + order.peggedChangeAmount(peggedChangeAmount); + //whenever there is a price change of... + order.referenceChangeAmount(referenceChangeAmount); + //in the reference contract... + order.referenceContractId(referenceConId); + //being traded at... + order.referenceExchangeId(referenceExchange); + //starting reference price is... + order.stockRefPrice(stockReferencePrice); + //Keep order active as long as reference contract trades between... + order.stockRangeLower(referenceContractLowerRange); + //and... + order.stockRangeUpper(referenceContractUpperRange); + //! [pegged_benchmark] + return order; + } + + public static Order AttachAdjustableToStop(Order parent, double attachedOrderStopPrice, double triggerPrice, double adjustStopPrice) { + //! [adjustable_stop] + Order order = new Order(); + //Attached order is a conventional STP order in opposite direction + order.action("BUY".equals(parent.getAction()) ? "SELL" : "BUY"); + order.totalQuantity(parent.totalQuantity()); + order.auxPrice(attachedOrderStopPrice); + order.parentId(parent.orderId()); + //When trigger price is penetrated + order.triggerPrice(triggerPrice); + //The parent order will be turned into a STP order + order.adjustedOrderType(OrderType.STP); + //With the given STP price + order.adjustedStopPrice(adjustStopPrice); + //! [adjustable_stop] + return order; + } + + public static Order AttachAdjustableToStopLimit(Order parent, double attachedOrderStopPrice, double triggerPrice, double adjustStopPrice, double adjustedStopLimitPrice) { + //! [adjustable_stop_limit] + Order order = new Order(); + //Attached order is a conventional STP order + order.action("BUY".equals(parent.getAction()) ? "SELL" : "BUY"); + order.totalQuantity(parent.totalQuantity()); + order.auxPrice(attachedOrderStopPrice); + order.parentId(parent.orderId()); + //When trigger price is penetrated + order.triggerPrice(triggerPrice); + //The parent order will be turned into a STP LMT order + order.adjustedOrderType(OrderType.STP_LMT); + //With the given stop price + order.adjustedStopPrice(adjustStopPrice); + //And the given limit price + order.adjustedStopLimitPrice(adjustedStopLimitPrice); + //! [adjustable_stop_limit] + return order; + } + + public static Order AttachAdjustableToTrail(Order parent, double attachedOrderStopPrice, double triggerPrice, double adjustStopPrice, double adjustedTrailAmount, int trailUnit) { + //! [adjustable_trail] + Order order = new Order(); + //Attached order is a conventional STP order + order.action("BUY".equals(parent.getAction()) ? "SELL" : "BUY"); + order.totalQuantity(parent.totalQuantity()); + order.auxPrice(attachedOrderStopPrice); + order.parentId(parent.orderId()); + //When trigger price is penetrated + order.triggerPrice(triggerPrice); + //The parent order will be turned into a TRAIL order + order.adjustedOrderType(OrderType.TRAIL); + //With a stop price of... + order.adjustedStopPrice(adjustStopPrice); + //trailing by and amount (0) or a percent (1)... + order.adjustableTrailingUnit(trailUnit); + //of... + order.adjustedTrailingAmount(adjustedTrailAmount); + //! [adjustable_trail] + return order; + } + + public static PriceCondition PriceCondition(int conId, String exchange, double price, boolean isMore, boolean isConjunction) { + //! [price_condition] + //Conditions have to be created via the OrderCondition.Create + PriceCondition priceCondition = (PriceCondition)OrderCondition.create(OrderConditionType.Price); + //When this contract... + priceCondition.conId(conId); + //traded on this exchange + priceCondition.exchange(exchange); + //has a price above/below + priceCondition.isMore(isMore); + //this quantity + priceCondition.price(price); + //AND | OR next condition (will be ignored if no more conditions are added) + priceCondition.conjunctionConnection(isConjunction); + //! [price_condition] + return priceCondition; + } + + public static ExecutionCondition ExecutionCondition(String symbol, String secType, String exchange, boolean isConjunction) { + //! [execution_condition] + ExecutionCondition execCondition = (ExecutionCondition)OrderCondition.create(OrderConditionType.Execution); + //When an execution on symbol + execCondition.symbol(symbol); + //at exchange + execCondition.exchange(exchange); + //for this secType + execCondition.secType(secType); + //AND | OR next condition (will be ignored if no more conditions are added) + execCondition.conjunctionConnection(isConjunction); + //! [execution_condition] + return execCondition; + } + + public static MarginCondition MarginCondition(int percent, boolean isMore, boolean isConjunction) { + //! [margin_condition] + MarginCondition marginCondition = (MarginCondition)OrderCondition.create(OrderConditionType.Margin); + //If margin is above/below + marginCondition.isMore(isMore); + //given percent + marginCondition.percent(percent); + //AND | OR next condition (will be ignored if no more conditions are added) + marginCondition.conjunctionConnection(isConjunction); + //! [margin_condition] + return marginCondition; + } + + public static PercentChangeCondition PercentageChangeCondition(double pctChange, int conId, String exchange, boolean isMore, boolean isConjunction) { + //! [percentage_condition] + PercentChangeCondition pctChangeCondition = (PercentChangeCondition)OrderCondition.create(OrderConditionType.PercentChange); + //If there is a price percent change measured against last close price above or below... + pctChangeCondition.isMore(isMore); + //this amount... + pctChangeCondition.changePercent(pctChange); + //on this contract + pctChangeCondition.conId(conId); + //when traded on this exchange... + pctChangeCondition.exchange(exchange); + //AND | OR next condition (will be ignored if no more conditions are added) + pctChangeCondition.conjunctionConnection(isConjunction); + //! [percentage_condition] + return pctChangeCondition; + } + + public static TimeCondition TimeCondition(String time, boolean isMore, boolean isConjunction) { + //! [time_condition] + TimeCondition timeCondition = (TimeCondition)OrderCondition.create(OrderConditionType.Time); + //Before or after... + timeCondition.isMore(isMore); + //this time... + timeCondition.time(time); + //AND | OR next condition (will be ignored if no more conditions are added) + timeCondition.conjunctionConnection(isConjunction); + //! [time_condition] + return timeCondition; + } + + public static VolumeCondition VolumeCondition(int conId, String exchange, boolean isMore, int volume, boolean isConjunction) { + //! [volume_condition] + VolumeCondition volCon = (VolumeCondition)OrderCondition.create(OrderConditionType.Volume); + //Whenever contract... + volCon.conId(conId); + //When traded at + volCon.exchange(exchange); + //reaches a volume higher/lower + volCon.isMore(isMore); + //than this... + volCon.volume(volume); + //AND | OR next condition (will be ignored if no more conditions are added) + volCon.conjunctionConnection(isConjunction); + //! [volume_condition] + return volCon; + } + + public static Order WhatIfLimitOrder(String action, double quantity, double limitPrice) { + // ! [whatiflimitorder] + Order order = LimitOrder(action, quantity, limitPrice); + order.whatIf(true); + // ! [whatiflimitorder] + return order; + } + +} \ No newline at end of file diff --git a/test/samples/testbed/scanner/ScannerSubscriptionSamples.java b/test/samples/testbed/scanner/ScannerSubscriptionSamples.java new file mode 100644 index 0000000..02d1530 --- /dev/null +++ b/test/samples/testbed/scanner/ScannerSubscriptionSamples.java @@ -0,0 +1,75 @@ +/* Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms + * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ + +package samples.testbed.scanner; + +import com.ib.client.ScannerSubscription; + +public class ScannerSubscriptionSamples { + + public static ScannerSubscription HotUSStkByVolume() { + + //! [hotusvolume] + //Hot US stocks by volume + ScannerSubscription scanSub = new ScannerSubscription(); + scanSub.instrument("STK"); + scanSub.locationCode("STK.US.MAJOR"); + scanSub.scanCode("HOT_BY_VOLUME"); + //! [hotusvolume] + return scanSub; + + } + + public static ScannerSubscription TopPercentGainersIbis() { + + //! [toppercentgaineribis] + //Top % gainers at IBIS + ScannerSubscription scanSub = new ScannerSubscription(); + scanSub.instrument("STOCK.EU"); + scanSub.locationCode("STK.EU.IBIS"); + scanSub.scanCode("TOP_PERC_GAIN"); + //! [toppercentgaineribis] + return scanSub; + + } + + public static ScannerSubscription MostActiveFutSoffex() + { + //! [mostactivefutsoffex] + //Most active futures at SOFFEX + ScannerSubscription scanSub = new ScannerSubscription(); + scanSub.instrument("FUT.EU"); + scanSub.locationCode("FUT.EU.SOFFEX"); + scanSub.scanCode("MOST_ACTIVE"); + //! [mostactivefutsoffex] + return scanSub; + } + + public static ScannerSubscription HighOptVolumePCRatioUSIndexes() { + + //! [highoptvolume] + //High option volume P/C ratio US indexes + ScannerSubscription scanSub = new ScannerSubscription(); + scanSub.instrument("IND.US"); + scanSub.locationCode("IND.US"); + scanSub.scanCode("HIGH_OPT_VOLUME_PUT_CALL_RATIO"); + //! [highoptvolume] + return scanSub; + + } + + public static ScannerSubscription ComplexOrdersAndTrades() { + + //! [combolatesttrade] + //Complex orders and trades scan, latest trades + ScannerSubscription scanSub = new ScannerSubscription(); + scanSub.instrument("NATCOMB"); + scanSub.locationCode("NATCOMB.OPT.US"); + scanSub.scanCode("COMBO_LATEST_TRADE"); + //! [combolatesttrade] + return scanSub; + + } + + +}