diff --git a/build.gradle b/build.gradle
index edd2305..3c33742 100644
--- a/build.gradle
+++ b/build.gradle
@@ -26,6 +26,7 @@ dependencies {
implementation 'commons-cli:commons-cli:1.4'
implementation 'joda-time:joda-time:2.9.9'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.9.5'
+ implementation 'com.oanda.v20:v20:3.0.25'
}
repositories {
diff --git a/src/main/java/DebugTradingManager.java b/src/main/java/DebugTradingManager.java
index 60b0549..e9124f9 100644
--- a/src/main/java/DebugTradingManager.java
+++ b/src/main/java/DebugTradingManager.java
@@ -1,7 +1,10 @@
+import java.math.BigDecimal;
+
+import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import ats.orders.OrderRequest;
+import ats.orders.OrderReply;
/**
@@ -9,6 +12,19 @@ import ats.orders.OrderRequest;
*/
public class DebugTradingManager implements TradingManager {
static final Logger log = LoggerFactory.getLogger("DebugTradingManager");
+ static int orderID = 1;
+ private EsperProcessor processor;
+
+
+ public DebugTradingManager() {
+ }
+
+ /**
+ * Set the Esper processor for this trading manager.
+ */
+ public void setProcessor(EsperProcessor processor) {
+ this.processor = processor;
+ }
/**
* Place an order request.
diff --git a/src/main/java/EsperProcessor.java b/src/main/java/EsperProcessor.java
index 5a2c186..96db03e 100644
--- a/src/main/java/EsperProcessor.java
+++ b/src/main/java/EsperProcessor.java
@@ -2,18 +2,20 @@ import java.util.Arrays;
import java.util.stream.Collectors;
import com.espertech.esper.client.Configuration;
+import com.espertech.esper.client.EPOnDemandPreparedQueryParameterized;
+import com.espertech.esper.client.EPOnDemandQueryResult;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
import com.espertech.esper.client.EPStatement;
import com.espertech.esper.client.StatementAwareUpdateListener;
import com.espertech.esper.client.UpdateListener;
+import com.espertech.esper.client.soda.EPStatementObjectModel;
import com.espertech.esper.client.time.CurrentTimeEvent;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import ats.orders.MarketOrderRequest;
import ats.plugin.OHLCEvent;
import ats.plugin.OHLCPlugInViewFactory;
@@ -26,6 +28,7 @@ public class EsperProcessor implements TickProcessor {
public EsperProcessor(String epl, TradingManager trader) {
this.trader = trader;
+ trader.setProcessor(this);
Configuration config = new Configuration();
// disable esper's internal clock. we use tick data for our
@@ -196,6 +199,39 @@ public class EsperProcessor implements TickProcessor {
return statement;
}
+ /**
+ * Add a single fire and forget EPL statement to the Esper engine.
+ */
+ public void executeQuery(String query) {
+ // EPStatement statement = engine.getEPAdministrator().create(query);
+ // log.debug("Adding query: {}", statement.getText());
+
+ EPOnDemandQueryResult result = engine.getEPRuntime().executeQuery(query);
+ log.info(result.toString());
+ }
+
+ /**
+ * Add a single fire and forget EPL statement to the Esper engine.
+ */
+ public void executeQuery(EPStatementObjectModel query) {
+ // EPStatement statement = engine.getEPAdministrator().create(query);
+ // log.debug("Adding query: {}", statement.getText());
+
+ EPOnDemandQueryResult result = engine.getEPRuntime().executeQuery(query);
+ log.info(result.toString());
+ }
+
+ /**
+ * Add a single fire and forget EPL statement to the Esper engine.
+ */
+ public void executeQuery(EPOnDemandPreparedQueryParameterized query) {
+ // EPStatement statement = engine.getEPAdministrator().create(query);
+ // log.debug("Adding query: {}", statement.getText());
+
+ EPOnDemandQueryResult result = engine.getEPRuntime().executeQuery(query);
+ log.info(result.toString());
+ }
+
/**
* Send a single TickEvent to Esper.
*/
diff --git a/src/main/java/OANDATradingManager.java b/src/main/java/OANDATradingManager.java
index a1f318a..53d325c 100644
--- a/src/main/java/OANDATradingManager.java
+++ b/src/main/java/OANDATradingManager.java
@@ -1,16 +1,28 @@
-import java.io.BufferedReader;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
+import java.math.BigDecimal;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.oanda.v20.Context;
+import com.oanda.v20.ExecuteException;
+import com.oanda.v20.RequestException;
+import com.oanda.v20.account.AccountID;
+import com.oanda.v20.order.MarketOrderRequest;
+import com.oanda.v20.order.Order;
+import com.oanda.v20.order.OrderAdapter;
+import com.oanda.v20.order.OrderCreateRequest;
+import com.oanda.v20.order.OrderCreateResponse;
+import com.oanda.v20.transaction.OrderCancelReason;
+import com.oanda.v20.transaction.OrderCancelTransaction;
+import com.oanda.v20.transaction.OrderFillTransaction;
+import com.oanda.v20.transaction.Transaction;
+import com.oanda.v20.transaction.TransactionAdapter;
+
+import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import ats.orders.OrderRequest;
+import ats.orders.OrderReply;
+
/**
* OANDATradingManager manages orders via the OANDA API.
@@ -18,6 +30,7 @@ import ats.orders.OrderRequest;
public class OANDATradingManager implements TradingManager {
static final Logger log = LoggerFactory.getLogger("OANDATradingManager");
private Config config;
+ private EsperProcessor processor;
/**
@@ -27,73 +40,82 @@ public class OANDATradingManager implements TradingManager {
public OANDATradingManager(Config config) {
this.config = config;
}
-
+
/**
- * Place an order request.
+ * Set the Esper processor for this trading manager.
*/
- @Override
- public void placeOrder(OrderRequest order) {
- log.info("Placing order: {}", order);
+ public void setProcessor(EsperProcessor processor) {
+ this.processor = processor;
+ }
+ /**
+ * Place an order request to open a new position.
+ */
+ @Override
+ public OrderReply openPosition(String instrument, BigDecimal requestUnits) {
try {
- String orderJSON = order.toJSON();
- byte[] postData = orderJSON.getBytes(StandardCharsets.UTF_8);
- int postDataLength = postData.length;
+ MarketOrderRequest orderRequest = new MarketOrderRequest();
+ orderRequest.setInstrument(instrument);
+ orderRequest.setUnits(requestUnits);
- URL url = new URL(orderURL());
+ OrderCreateRequest createRequest = new OrderCreateRequest(new AccountID(config.accountID()));
+ createRequest.setOrder(orderRequest);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setDoOutput(true);
- conn.setInstanceFollowRedirects(false);
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Content-Type", "application/json");
- conn.setRequestProperty("charset", "utf-8");
- conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
- conn.setRequestProperty("Authorization", "Bearer " + config.accessToken());
- conn.setUseCaches(false);
+ OrderCreateResponse response = getContext().order.create(createRequest);
- try (DataOutputStream dos = new DataOutputStream(conn.getOutputStream())) {
- dos.write(postData);
- dos.flush();
- dos.close();
+ Gson gson = new GsonBuilder()
+ .setPrettyPrinting()
+ .registerTypeAdapter(Order.class, new OrderAdapter())
+ .registerTypeAdapter(Transaction.class, new TransactionAdapter())
+ .create();
+
+ // log.info(gson.toJson(response));
+
+ // Transaction create = response.getOrderCreateTransaction();
+ // log.info(create.toString());
+
+ OrderFillTransaction fill = response.getOrderFillTransaction();
+ // log.info(fill.toString());
+
+ if (fill == null) {
+ OrderCancelTransaction cancel = response.getOrderCancelTransaction();
+ OrderCancelReason reason = cancel.getReason();
+ log.warn("Open position order cancelled. Reason: " + reason.toString());
+ log.info(cancel.toString());
+ return null;
}
- int responseCode = conn.getResponseCode();
+ String orderID = fill.getOrderID().toString();
+ DateTime time = DateTime.parse(fill.getTime().toString());
+ BigDecimal price = fill.getTradeOpened().getPrice().bigDecimalValue();
+ BigDecimal actualUnits = fill.getTradeOpened().getUnits().bigDecimalValue();
+ OrderReply orderReply = new OrderReply(orderID, time, instrument, price, actualUnits);
- log.debug("Sending request to " + url);
- log.debug("Params: " + new String(postData));
- log.debug("Response code: " + responseCode);
+ // log.info(response.toString());
- // read response
- InputStream is;
- if (responseCode < 400) {
- log.debug("Reading input stream");
- is = conn.getInputStream();
- } else {
- log.debug("Reading error stream");
- is = conn.getErrorStream();
- }
- BufferedReader in = new BufferedReader(new InputStreamReader(is));
- String inputLine;
- StringBuffer response = new StringBuffer();
- while ((inputLine = in.readLine()) != null) {
- response.append(inputLine);
- }
- in.close();
+ processor.executeQuery(orderReply.toEPL());
- log.info("Response: " + response);
- log.info("Finished placing order.");
- } catch (IOException e) {
- log.warn("Error sending order", e);
+ return orderReply;
+ } catch (RequestException | ExecuteException e) {
+ log.warn("Error opening position", e);
+ return null;
}
}
/**
- * Return the OANDA API endpoint for placing orders.
+ * Place an order request to close an existing position.
*/
- private String orderURL() {
+ @Override
+ public void closePosition(String orderID) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Return the OANDA context.
+ */
+ private Context getContext() {
String type = config.isLiveAccount() ? "fxlive" : "fxpractice";
- return String.format("https://api-%s.oanda.com/v3/accounts/%s/orders",
- type, config.accountID());
+ String url = String.format("https://api-%s.oanda.com/", type);
+ return new Context(url, config.accessToken());
}
}
diff --git a/src/main/java/TradingManager.java b/src/main/java/TradingManager.java
index bd891e2..68850bf 100644
--- a/src/main/java/TradingManager.java
+++ b/src/main/java/TradingManager.java
@@ -1,4 +1,6 @@
-import ats.orders.OrderRequest;
+import java.math.BigDecimal;
+
+import ats.orders.OrderReply;
/**
* TradingManager describes the interface with a trading system.
@@ -6,8 +8,23 @@ import ats.orders.OrderRequest;
interface TradingManager {
/**
- * Place an order request.
+ * Set the Esper processor for this trading manager.
*/
- public void placeOrder(OrderRequest order);
+ public void setProcessor(EsperProcessor processor);
+ /**
+ * Place an order request to open a new position.
+ */
+ public OrderReply openPosition(String instrument, BigDecimal units);
+
+ /**
+ * Place an order request to close an existing position.
+ */
+ public void closePosition(String orderID);
+
+ /**
+ * Place an order request. Lower level than openPosition() and
+ * closePosition().
+ */
+ // public void placeOrder(OrderRequest order);
}
diff --git a/src/main/java/ats/orders/ClientExtensions.java b/src/main/java/ats/orders/ClientExtensions.java
deleted file mode 100644
index a3d4232..0000000
--- a/src/main/java/ats/orders/ClientExtensions.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package ats.orders;
-
-/**
- * A ClientExtensions object allows a client to attach a clientID, tag
- * and comment to Orders and Trades in their Account. Do not set,
- * modify, or delete this field if your account is associated with
- * MT4.
- *
- * @see OANDA API docs
- */
-public class ClientExtensions {
- /**
- * The Client ID of the Order/Trade
- */
- public String id;
-
- /**
- * A tag associated with the Order/Trade
- */
- public String tag;
-
- /**
- * A comment associated with the Order/Trade
- */
- public String comment;
-}
diff --git a/src/main/java/ats/orders/LimitOrderRequest.java b/src/main/java/ats/orders/LimitOrderRequest.java
deleted file mode 100644
index 4812ce8..0000000
--- a/src/main/java/ats/orders/LimitOrderRequest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-package ats.orders;
-
-import com.oanda.v20.order.OrderTriggerCondition;
-
-import org.joda.time.DateTime;
-
-/**
- * Create a new limit order request to send to the OANDA API.
- *
- * @see OANDA API docs
- */
-public class LimitOrderRequest extends OrderRequest {
-
- /**
- * Instrument to open the order on. Example: "EUR_USD"
- */
- public String instrument;
-
- /**
- * The quantity requested to be filled by the Order. A
- * posititive number of units results in a long Order, and a
- * negative number of units results in a short Order.
- */
- public int units;
-
- /**
- * The price threshold specified for the Limit Order. The Limit
- * Order will only be filled by a market price that is equal to or
- * better than this price.
- */
- public String price;
-
- /**
- * The time-in-force requested for the Order.
- */
- public TimeInForce timeInForce;
-
- /**
- * The date/time when the Limit Order will be cancelled if its
- * timeInForce is “GTD”.
- */
- public DateTime gtdTime;
-
- /**
- * Specification of how Positions in the Account are modified when
- * the Order is filled.
- */
- public OrderPositionFill positionFill;
-
- /**
- * Specification of which price component should be used when
- * determining if an Order should be triggered and filled. This
- * allows Orders to be triggered based on the bid, ask, mid,
- * default (ask for buy, bid for sell) or inverse (ask for sell,
- * bid for buy) price depending on the desired behaviour. Orders
- * are always filled using their default price component. This
- * feature is only provided through the REST API. Clients who
- * choose to specify a non-default trigger condition will not see
- * it reflected in any of OANDA’s proprietary or partner trading
- * platforms, their transaction history or their account
- * statements. OANDA platforms always assume that an Order’s
- * trigger condition is set to the default value when indicating
- * the distance from an Order’s trigger price, and will always
- * provide the default trigger condition when creating or
- * modifying an Order. A special restriction applies when creating
- * a guaranteed Stop Loss Order. In this case the TriggerCondition
- * value must either be “DEFAULT”, or the “natural” trigger side
- * “DEFAULT” results in. So for a String top Loss Order for a long
- * trade valid values are “DEFAULT” and “BID”, and for short
- * trades “DEFAULT” and “ASK” are valid.
- */
- public OrderTriggerCondition triggerCondition;
-
- /**
- * The client extensions to add to the Order. Do not set, modify,
- * or delete clientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions clientExtensions;
-
- /**
- * TakeProfitDetails specifies the details of a Take Profit Order
- * to be created on behalf of a client. This may happen when an
- * Order is filled that opens a Trade requiring a Take Profit, or
- * when a Trade’s dependent Take Profit Order is modified directly
- * through the Trade.
- */
- public TakeProfitDetails takeProfitOnFill;
-
- /**
- * StopLossDetails specifies the details of a Stop Loss Order to
- * be created on behalf of a client. This may happen when an Order
- * is filled that opens a Trade requiring a Stop Loss, or when a
- * Trade’s dependent Stop Loss Order is modified directly through
- * the Trade.
- */
- public StopLossDetails stopLossOnFill;
-
- /**
- * TrailingStopLossDetails specifies the details of a Trailing
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a
- * Trailing Stop Loss, or when a Trade’s dependent Trailing Stop
- * Loss Order is modified directly through the Trade.
- */
- public TrailingStopLossDetails trailingStopLossOnFill;
-
- /**
- * Client Extensions to add to the Trade created when the Order is
- * filled (if such a Trade is created). Do not set, modify, or
- * delete tradeClientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions tradeClientExtensions;
-
-
-
- /**
- * Create a new limit order request to send to the OANDA API.
- *
- * @param instrument Instrument to open the order on.
- * Example: "EUR_USD"
- *
- * @param units The quantity requested to be filled by the
- * Order. A posititive number of units results in a long Order,
- * and a negative number of units results in a short Order.
- *
- * @param price The price threshold specified for the Limit
- * Order. The Limit Order will only be filled by a market price
- * that is equal to or better than this price.
- */
- public LimitOrderRequest(String instrument, int units, String price)
- {
- this(instrument, units, price, null, null, null,
- null, null, null, null, null, null);
- }
-
- /**
- * Create a new limit order request to send to the OANDA API.
- *
- * @param instrument Instrument to open the order on.
- * Example: "EUR_USD"
- *
- * @param units The quantity requested to be filled by the
- * Order. A posititive number of units results in a long Order,
- * and a negative number of units results in a short Order.
- *
- * @param price The price threshold specified for the Limit
- * Order. The Limit Order will only be filled by a market price
- * that is equal to or better than this price.
- *
- * @param timeInForce The time-in-force requested for the Limit
- * Order. The default is TimeInForce.GTC.
- *
- * @param gtdTime The date when the Limit Order will be cancelled
- * on if timeInForce is GTD.
- *
- * @param positionFill Specification of how Positions in the Account
- * are modified when the Order is filled. The default is
- * OrderPositionFill.DEFAULT.
- *
- * @param triggerCondition Specification of which price component
- * should be used when determining if an Order should be triggered
- * and filled. This allows Orders to be triggered based on the
- * bid, ask, mid, default (ask for buy, bid for sell) or inverse
- * (ask for sell, bid for buy) price depending on the desired
- * behaviour. Orders are always filled using their default price
- * component. This feature is only provided through the REST
- * API. Clients who choose to specify a non-default trigger
- * condition will not see it reflected in any of OANDA’s
- * proprietary or partner trading platforms, their transaction
- * history or their account statements. OANDA platforms always
- * assume that an Order’s trigger condition is set to the default
- * value when indicating the distance from an Order’s trigger
- * price, and will always provide the default trigger condition
- * when creating or modifying an Order. A special restriction
- * applies when creating a guaranteed Stop Loss Order. In this
- * case the TriggerCondition value must either be “DEFAULT”, or
- * the “natural” trigger side “DEFAULT” results in. So for a Stop
- * Loss Order for a long trade valid values are “DEFAULT” and
- * “BID”, and for short trades “DEFAULT” and “ASK” are valid.
- * The default is OrderTriggerCondition.DEFAULT.
- *
- * @param clientExtensions The client extensions to add to the
- * Order. Do not set, modify, or delete clientExtensions if your
- * account is associated with MT4.
- *
- * @param takeProfitOnFill TakeProfitDetails specifies the details of
- * a Take Profit Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a Take
- * Profit, or when a Trade’s dependent Take Profit Order is modified
- * directly through the Trade.
- *
- * @param stopLossOnFill StopLossDetails specifies the details of a
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a Stop
- * Loss, or when a Trade’s dependent Stop Loss Order is modified
- * directly through the Trade.
- *
- * @param trailingStopLossOnFill TrailingStopLossDetails specifies the
- * details of a Trailing Stop Loss Order to be created on behalf of a
- * client. This may happen when an Order is filled that opens a Trade
- * requiring a Trailing Stop Loss, or when a Trade’s dependent
- * Trailing Stop Loss Order is modified directly through the Trade.
- *
- * @param tradeClientExtensions Client Extensions to add to the Trade
- * created when the Order is filled (if such a Trade is created). Do
- * not set, modify, or delete tradeClientExtensions if your account is
- * associated with MT4.
- */
- public LimitOrderRequest(String instrument,
- int units,
- String price,
- TimeInForce timeInForce,
- DateTime gtdTime,
- OrderPositionFill positionFill,
- OrderTriggerCondition triggerCondition,
- ClientExtensions clientExtensions,
- TakeProfitDetails takeProfitOnFill,
- StopLossDetails stopLossOnFill,
- TrailingStopLossDetails trailingStopLossOnFill,
- ClientExtensions tradeClientExtensions)
- {
- super(OrderType.LIMIT);
-
- this.instrument = instrument;
- this.units = units;
- this.price = price;
- this.timeInForce = timeInForce;
- this.gtdTime = gtdTime;
- this.positionFill = positionFill;
- this.triggerCondition = triggerCondition;
- this.clientExtensions = clientExtensions;
- this.takeProfitOnFill = takeProfitOnFill;
- this.stopLossOnFill = stopLossOnFill;
- this.trailingStopLossOnFill = trailingStopLossOnFill;
- this.tradeClientExtensions = tradeClientExtensions;
-
- if (this.timeInForce == null)
- this.timeInForce = TimeInForce.GTC;
-
- if (this.positionFill == null)
- this.positionFill = OrderPositionFill.DEFAULT;
-
- if (this.triggerCondition == null)
- this.triggerCondition = OrderTriggerCondition.DEFAULT;
- }
-}
diff --git a/src/main/java/ats/orders/MarketIfTouchedOrderRequest.java b/src/main/java/ats/orders/MarketIfTouchedOrderRequest.java
deleted file mode 100644
index 9d1f020..0000000
--- a/src/main/java/ats/orders/MarketIfTouchedOrderRequest.java
+++ /dev/null
@@ -1,272 +0,0 @@
-package ats.orders;
-
-import com.oanda.v20.order.OrderTriggerCondition;
-
-import org.joda.time.DateTime;
-
-/**
- * Create a new market-if-touched order request to send to the OANDA API.
- *
- * @see OANDA API docs
- */
-public class MarketIfTouchedOrderRequest extends OrderRequest {
-
- /**
- * Instrument to open the order on. Example: "EUR_USD"
- */
- public String instrument;
-
- /**
- * The quantity requested to be filled by the order. A posititive
- * number of units results in a long Order, and a negative number
- * of units results in a short Order.
- */
- public int units;
-
- /**
- * The price threshold specified for the MarketIfTouched
- * Order. The MarketIfTouched Order will only be filled by a
- * market price that crosses this price from the direction of the
- * market price at the time when the Order was created (the
- * initialMarketPrice). Depending on the value of the Order’s
- * price and initialMarketPrice, the MarketIfTouchedOrder will
- * behave like a Limit or a Stop Order.
- */
- public String price;
-
- /**
- * The worst market price that may be used to fill this
- * MarketIfTouched Order.
- */
- public String priceBound;
-
- /**
- * The time-in-force requested for the order. The default is
- * TimeInForce.GTC.
- */
- public TimeInForce timeInForce;
-
- /**
- * The date/time when the order will be cancelled if its
- * timeInForce is “GTD”.
- */
- public DateTime gtdTime;
-
- /**
- * Specification of how Positions in the Account are modified when
- * the Order is filled.
- */
- public OrderPositionFill positionFill;
-
- /**
- * Specification of which price component should be used when
- * determining if an Order should be triggered and filled. This
- * allows Orders to be triggered based on the bid, ask, mid,
- * default (ask for buy, bid for sell) or inverse (ask for sell,
- * bid for buy) price depending on the desired behaviour. Orders
- * are always filled using their default price component. This
- * feature is only provided through the REST API. Clients who
- * choose to specify a non-default trigger condition will not see
- * it reflected in any of OANDA’s proprietary or partner trading
- * platforms, their transaction history or their account
- * statements. OANDA platforms always assume that an Order’s
- * trigger condition is set to the default value when indicating
- * the distance from an Order’s trigger price, and will always
- * provide the default trigger condition when creating or
- * modifying an Order. A special restriction applies when creating
- * a guaranteed Stop Loss Order. In this case the TriggerCondition
- * value must either be “DEFAULT”, or the “natural” trigger side
- * “DEFAULT” results in. So for a String top Loss Order for a long
- * trade valid values are “DEFAULT” and “BID”, and for short
- * trades “DEFAULT” and “ASK” are valid.
- */
- public OrderTriggerCondition triggerCondition;
-
- /**
- * The client extensions to add to the Order. Do not set, modify,
- * or delete clientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions clientExtensions;
-
- /**
- * TakeProfitDetails specifies the details of a Take Profit Order
- * to be created on behalf of a client. This may happen when an
- * Order is filled that opens a Trade requiring a Take Profit, or
- * when a Trade’s dependent Take Profit Order is modified directly
- * through the Trade.
- */
- public TakeProfitDetails takeProfitOnFill;
-
- /**
- * StopLossDetails specifies the details of a Stop Loss Order to
- * be created on behalf of a client. This may happen when an Order
- * is filled that opens a Trade requiring a Stop Loss, or when a
- * Trade’s dependent Stop Loss Order is modified directly through
- * the Trade.
- */
- public StopLossDetails stopLossOnFill;
-
- /**
- * TrailingStopLossDetails specifies the details of a Trailing
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a
- * Trailing Stop Loss, or when a Trade’s dependent Trailing Stop
- * Loss Order is modified directly through the Trade.
- */
- public TrailingStopLossDetails trailingStopLossOnFill;
-
- /**
- * Client Extensions to add to the Trade created when the Order is
- * filled (if such a Trade is created). Do not set, modify, or
- * delete tradeClientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions tradeClientExtensions;
-
-
-
- /**
- * Create a new stop order request to send to the OANDA API.
- *
- * @param instrument Instrument to open the order on.
- * Example: "EUR_USD"
- *
- * @param units The quantity requested to be filled by the
- * Order. A posititive number of units results in a long Order,
- * and a negative number of units results in a short Order.
- *
- * @param price The price threshold specified for the
- * MarketIfTouched Order. The MarketIfTouched Order will only be
- * filled by a market price that crosses this price from the
- * direction of the market price at the time when the Order was
- * created (the initialMarketPrice). Depending on the value of the
- * Order’s price and initialMarketPrice, the MarketIfTouchedOrder
- * will behave like a Limit or a Stop Order.
- */
- public MarketIfTouchedOrderRequest(String instrument, int units, String price)
- {
- this(instrument, units, price, null, null, null,
- null, null, null, null, null, null, null);
- }
-
- /**
- * Create a new stop order request to send to the OANDA API.
- *
- * @param instrument Instrument to open the order on.
- * Example: "EUR_USD"
- *
- * @param units The quantity requested to be filled by the
- * Order. A posititive number of units results in a long Order,
- * and a negative number of units results in a short Order.
- *
- * @param price The price threshold specified for the
- * MarketIfTouched Order. The MarketIfTouched Order will only be
- * filled by a market price that crosses this price from the
- * direction of the market price at the time when the Order was
- * created (the initialMarketPrice). Depending on the value of the
- * Order’s price and initialMarketPrice, the MarketIfTouchedOrder
- * will behave like a Limit or a Stop Order.
- *
- * @param priceBound The worst market price that may be used to
- * fill this MarketIfTouched Order.
- *
- * @param timeInForce The time-in-force requested for the Order.
- * The default is TimeInForce.GTC.
- *
- * @param gtdTime The date when the Order will be cancelled on if
- * timeInForce is GTD.
- *
- * @param positionFill Specification of how Positions in the Account
- * are modified when the Order is filled. The default is
- * OrderPositionFill.DEFAULT.
- *
- * @param triggerCondition Specification of which price component
- * should be used when determining if an Order should be triggered
- * and filled. This allows Orders to be triggered based on the
- * bid, ask, mid, default (ask for buy, bid for sell) or inverse
- * (ask for sell, bid for buy) price depending on the desired
- * behaviour. Orders are always filled using their default price
- * component. This feature is only provided through the REST
- * API. Clients who choose to specify a non-default trigger
- * condition will not see it reflected in any of OANDA’s
- * proprietary or partner trading platforms, their transaction
- * history or their account statements. OANDA platforms always
- * assume that an Order’s trigger condition is set to the default
- * value when indicating the distance from an Order’s trigger
- * price, and will always provide the default trigger condition
- * when creating or modifying an Order. A special restriction
- * applies when creating a guaranteed Stop Loss Order. In this
- * case the TriggerCondition value must either be “DEFAULT”, or
- * the “natural” trigger side “DEFAULT” results in. So for a Stop
- * Loss Order for a long trade valid values are “DEFAULT” and
- * “BID”, and for short trades “DEFAULT” and “ASK” are valid.
- * The default is OrderTriggerCondition.DEFAULT.
- *
- * @param clientExtensions The client extensions to add to the
- * Order. Do not set, modify, or delete clientExtensions if your
- * account is associated with MT4.
- *
- * @param takeProfitOnFill TakeProfitDetails specifies the details of
- * a Take Profit Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a Take
- * Profit, or when a Trade’s dependent Take Profit Order is modified
- * directly through the Trade.
- *
- * @param stopLossOnFill StopLossDetails specifies the details of a
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a Stop
- * Loss, or when a Trade’s dependent Stop Loss Order is modified
- * directly through the Trade.
- *
- * @param trailingStopLossOnFill TrailingStopLossDetails specifies the
- * details of a Trailing Stop Loss Order to be created on behalf of a
- * client. This may happen when an Order is filled that opens a Trade
- * requiring a Trailing Stop Loss, or when a Trade’s dependent
- * Trailing Stop Loss Order is modified directly through the Trade.
- *
- * @param tradeClientExtensions Client Extensions to add to the Trade
- * created when the Order is filled (if such a Trade is created). Do
- * not set, modify, or delete tradeClientExtensions if your account is
- * associated with MT4.
- */
- public MarketIfTouchedOrderRequest(String instrument,
- int units,
- String price,
- String priceBound,
- TimeInForce timeInForce,
- DateTime gtdTime,
- OrderPositionFill positionFill,
- OrderTriggerCondition triggerCondition,
- ClientExtensions clientExtensions,
- TakeProfitDetails takeProfitOnFill,
- StopLossDetails stopLossOnFill,
- TrailingStopLossDetails trailingStopLossOnFill,
- ClientExtensions tradeClientExtensions)
- {
- super(OrderType.MARKET_IF_TOUCHED);
-
- this.instrument = instrument;
- this.units = units;
- this.price = price;
- this.priceBound = priceBound;
- this.timeInForce = timeInForce;
- this.gtdTime = gtdTime;
- this.positionFill = positionFill;
- this.triggerCondition = triggerCondition;
- this.clientExtensions = clientExtensions;
- this.takeProfitOnFill = takeProfitOnFill;
- this.stopLossOnFill = stopLossOnFill;
- this.trailingStopLossOnFill = trailingStopLossOnFill;
- this.tradeClientExtensions = tradeClientExtensions;
-
- if (this.timeInForce == null)
- this.timeInForce = TimeInForce.GTC;
-
- if (this.positionFill == null)
- this.positionFill = OrderPositionFill.DEFAULT;
-
- if (this.triggerCondition == null)
- this.triggerCondition = OrderTriggerCondition.DEFAULT;
- }
-}
diff --git a/src/main/java/ats/orders/MarketOrderRequest.java b/src/main/java/ats/orders/MarketOrderRequest.java
deleted file mode 100644
index daff38a..0000000
--- a/src/main/java/ats/orders/MarketOrderRequest.java
+++ /dev/null
@@ -1,177 +0,0 @@
-package ats.orders;
-
-/**
- * Create a new market order request to send to the OANDA API.
- *
- * @see OANDA API docs
- */
-public class MarketOrderRequest extends OrderRequest {
-
- /**
- * Instrument to open the order on. Example: "EUR_USD"
- */
- public String instrument;
-
- /**
- * The quantity requested to be filled by the Market Order. A
- * posititive number of units results in a long Order, and a
- * negative number of units results in a short Order.
- */
- public int units;
-
- /**
- * The time-in-force requested for the Market Order. Restricted to
- * FOK or IOC for a MarketOrder.
- */
- public TimeInForce timeInForce;
-
- /**
- * The worst price that the client is willing to have the Market
- * Order filled at.
- */
- public String priceBound;
-
- /**
- * Specification of how Positions in the Account are modified when
- * the Order is filled.
- */
- public OrderPositionFill positionFill;
-
- /**
- * The client extensions to add to the Order. Do not set, modify,
- * or delete clientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions clientExtensions;
-
- /**
- * TakeProfitDetails specifies the details of a Take Profit Order
- * to be created on behalf of a client. This may happen when an
- * Order is filled that opens a Trade requiring a Take Profit, or
- * when a Trade’s dependent Take Profit Order is modified directly
- * through the Trade.
- */
- public TakeProfitDetails takeProfitOnFill;
-
- /**
- * StopLossDetails specifies the details of a Stop Loss Order to
- * be created on behalf of a client. This may happen when an Order
- * is filled that opens a Trade requiring a Stop Loss, or when a
- * Trade’s dependent Stop Loss Order is modified directly through
- * the Trade.
- */
- public StopLossDetails stopLossOnFill;
-
- /**
- * TrailingStopLossDetails specifies the details of a Trailing
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a
- * Trailing Stop Loss, or when a Trade’s dependent Trailing Stop
- * Loss Order is modified directly through the Trade.
- */
- public TrailingStopLossDetails trailingStopLossOnFill;
-
- /**
- * Client Extensions to add to the Trade created when the Order is
- * filled (if such a Trade is created). Do not set, modify, or
- * delete tradeClientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions tradeClientExtensions;
-
-
- /**
- * Create a new market order request to send to the OANDA API.
- * Use empty or default values for any unspecified properties.
- *
- * @param instrument Instrument to open the order on.
- * Example: "EUR_USD"
- *
- * @param units The quantity requested to be filled by the Market
- * Order. A posititive number of units results in a long Order, and a
- * negative number of units results in a short Order.
- */
- public MarketOrderRequest(String instrument, int units)
- {
- this(instrument, units, null, null, null, null, null, null, null, null);
- }
-
- /**
- * Create a new market order request to send to the OANDA API.
- *
- * @param instrument Instrument to open the order on.
- * Example: "EUR_USD"
- *
- * @param units The quantity requested to be filled by the Market
- * Order. A posititive number of units results in a long Order, and a
- * negative number of units results in a short Order.
- *
- * @param timeInForce The time-in-force requested for the Market
- * Order. Restricted to FOK or IOC for a MarketOrder. The default is
- * TimeInForce.FOK.
- *
- * @param priceBound The worst price that the client is willing to
- * have the Market Order filled at.
- *
- * @param positionFill Specification of how Positions in the Account
- * are modified when the Order is filled. The default is
- * OrderPositionFill.DEFAULT.
- *
- * @param clientExtensions The client extensions to add to the
- * Order. Do not set, modify, or delete clientExtensions if your
- * account is associated with MT4.
- *
- * @param takeProfitOnFill TakeProfitDetails specifies the details of
- * a Take Profit Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a Take
- * Profit, or when a Trade’s dependent Take Profit Order is modified
- * directly through the Trade.
- *
- * @param stopLossOnFill StopLossDetails specifies the details of a
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a Stop
- * Loss, or when a Trade’s dependent Stop Loss Order is modified
- * directly through the Trade.
- *
- * @param trailingStopLossOnFill TrailingStopLossDetails specifies the
- * details of a Trailing Stop Loss Order to be created on behalf of a
- * client. This may happen when an Order is filled that opens a Trade
- * requiring a Trailing Stop Loss, or when a Trade’s dependent
- * Trailing Stop Loss Order is modified directly through the Trade.
- *
- * @param tradeClientExtensions Client Extensions to add to the Trade
- * created when the Order is filled (if such a Trade is created). Do
- * not set, modify, or delete tradeClientExtensions if your account is
- * associated with MT4.
- */
- public MarketOrderRequest(String instrument,
- int units,
- TimeInForce timeInForce,
- String priceBound,
- OrderPositionFill positionFill,
- ClientExtensions clientExtensions,
- TakeProfitDetails takeProfitOnFill,
- StopLossDetails stopLossOnFill,
- TrailingStopLossDetails trailingStopLossOnFill,
- ClientExtensions tradeClientExtensions)
- {
- super(OrderType.MARKET);
-
- this.instrument = instrument;
- this.units = units;
- this.timeInForce = timeInForce;
- this.priceBound = priceBound;
- this.positionFill = positionFill;
- this.clientExtensions = clientExtensions;
- this.takeProfitOnFill = takeProfitOnFill;
- this.stopLossOnFill = stopLossOnFill;
- this.trailingStopLossOnFill = trailingStopLossOnFill;
- this.tradeClientExtensions = tradeClientExtensions;
-
- if (this.timeInForce == null)
- this.timeInForce = TimeInForce.FOK;
-
- if (this.positionFill == null)
- this.positionFill = OrderPositionFill.DEFAULT;
- }
-}
diff --git a/src/main/java/ats/orders/OrderPositionFill.java b/src/main/java/ats/orders/OrderPositionFill.java
deleted file mode 100644
index b2b64bd..0000000
--- a/src/main/java/ats/orders/OrderPositionFill.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package ats.orders;
-
-/**
- * Specification of how Positions in the Account are modified when the
- * Order is filled.
- *
- * @see OANDA API docs
- */
-public enum OrderPositionFill {
- /**
- * When the Order is filled, only allow Positions to be opened
- * or extended.
- */
- OPEN_ONLY,
-
- /**
- * When the Order is filled, always fully reduce an existing
- * Position before opening a new Position.
- */
- REDUCE_FIRST,
-
- /**
- * When the Order is filled, only reduce an existing Position.
- */
- REDUCE_ONLY,
-
- /**
- * When the Order is filled, use REDUCE_FIRST behaviour for
- * non-client hedging Accounts, and OPEN_ONLY behaviour for
- * client hedging Accounts.
- */
- DEFAULT
-};
diff --git a/src/main/java/ats/orders/OrderReply.java b/src/main/java/ats/orders/OrderReply.java
new file mode 100644
index 0000000..8b48fd4
--- /dev/null
+++ b/src/main/java/ats/orders/OrderReply.java
@@ -0,0 +1,66 @@
+package ats.orders;
+
+import java.math.BigDecimal;
+
+import com.espertech.esper.client.EPOnDemandPreparedQueryParameterized;
+import com.espertech.esper.client.soda.ConstantExpression;
+import com.espertech.esper.client.soda.EPStatementObjectModel;
+import com.espertech.esper.client.soda.FireAndForgetInsert;
+import com.espertech.esper.client.soda.FromClause;
+import com.espertech.esper.client.soda.InsertIntoClause;
+import com.espertech.esper.client.soda.SelectClause;
+import com.espertech.esper.core.service.EPPreparedStatementImpl;
+
+import org.joda.time.DateTime;
+
+/**
+ * TODO
+ */
+public class OrderReply {
+ private String orderID;
+ private DateTime time;
+ private String instrument;
+ private BigDecimal price;
+ private BigDecimal units;
+
+
+ public OrderReply(String orderID, DateTime time, String instrument,
+ BigDecimal price, BigDecimal actualUnits)
+ {
+ this.orderID = orderID;
+ this.time = time;
+ this.instrument = instrument;
+ this.price = price;
+ this.units = actualUnits;
+ }
+
+ /**
+ * Return an epl insert statement to add this to the Esper order
+ * table.
+ */
+ public EPOnDemandPreparedQueryParameterized toEPL() {
+ EPStatementObjectModel model = new EPStatementObjectModel();
+ model.setFireAndForgetClause(new FireAndForgetInsert());
+ model.insertInto(InsertIntoClause.create("OrderTable", "id", "time", "instrument", "price", "units", "open", "stopBarCount"));
+
+ SelectClause select = SelectClause.create();
+ select.add(new ConstantExpression(orderID));
+ select.add(new ConstantExpression(time));
+ select.add(new ConstantExpression(instrument));
+ select.add(new ConstantExpression(price));
+ select.add(new ConstantExpression(units));
+ select.add(new ConstantExpression(true)); // open
+ select.add(new ConstantExpression(0)); // stopBarCount
+ model.setSelectClause(select);
+
+ model.setFromClause(FromClause.create());
+
+ return new EPPreparedStatementImpl(model, null, null);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("OrderReply[id=%s, time=%s, instr=%s, units=%d, price=%s]",
+ orderID, time, instrument, units, price);
+ }
+}
diff --git a/src/main/java/ats/orders/OrderRequest.java b/src/main/java/ats/orders/OrderRequest.java
deleted file mode 100644
index 3bb4943..0000000
--- a/src/main/java/ats/orders/OrderRequest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package ats.orders;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Base class for order requests to send to the OANDA API.
- */
-public class OrderRequest {
- final Logger log = LoggerFactory.getLogger(OrderRequest.class);
-
- /**
- * The type of the Order to Create.
- */
- public OrderType type;
-
-
- /**
- * Create an order. Subclasses only will call this. Not for user
- * code.
- */
- public OrderRequest(OrderType orderType)
- {
- this.type = orderType;
- }
-
- /**
- * Create a JSON representation of the order suitable for sending
- * to the OANDA API.
- *
- * @see OANDA API docs
- */
- public String toJSON() throws JsonProcessingException {
- Map order = new HashMap<>();
- order.put("order", this);
- return getJSONMapper().writeValueAsString(order);
- }
-
- /**
- * Return a new JSON object mapper suitable for serializing orders
- * for the OANDA api.
- */
- public static ObjectMapper getJSONMapper() {
- ObjectMapper mapper = new ObjectMapper();
- mapper.registerModule(new JodaModule());
- mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
- mapper.setSerializationInclusion(Include.NON_NULL);
- return mapper;
- }
-
- /**
- * Return a better description of the order.
- */
- @Override
- public String toString() {
- try {
- return toJSON();
- } catch (JsonProcessingException e) {
- log.warn("Error converting to JSON", e);
- return super.toString();
- }
- }
-}
diff --git a/src/main/java/ats/orders/OrderTriggerCondition.java b/src/main/java/ats/orders/OrderTriggerCondition.java
deleted file mode 100644
index 7d5f2f7..0000000
--- a/src/main/java/ats/orders/OrderTriggerCondition.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package ats.orders;
-
-/**
- * Specification of which price component should be used when
- * determining if an Order should be triggered and filled. This allows
- * Orders to be triggered based on the bid, ask, mid, default (ask for
- * buy, bid for sell) or inverse (ask for sell, bid for buy) price
- * depending on the desired behaviour. Orders are always filled using
- * their default price component.
- *
- * This feature is only provided through the REST API. Clients who
- * choose to specify a non-default trigger condition will not see it
- * reflected in any of OANDA’s proprietary or partner trading
- * platforms, their transaction history or their account
- * statements. OANDA platforms always assume that an Order’s trigger
- * condition is set to the default value when indicating the distance
- * from an Order’s trigger price, and will always provide the default
- * trigger condition when creating or modifying an Order.
- *
- * A special restriction applies when creating a guaranteed Stop Loss
- * Order. In this case the TriggerCondition value must either be
- * “DEFAULT”, or the “natural” trigger side “DEFAULT” results in. So
- * for a Stop Loss Order for a long trade valid values are “DEFAULT”
- * and “BID”, and for short trades “DEFAULT” and “ASK” are valid.
- *
- * @see OANDA API docs
- */
-public enum OrderTriggerCondition {
-
- /**
- * Trigger an Order the “natural” way: compare its price to the
- * ask for long Orders and bid for short Orders.
- */
- DEFAULT,
-
- /**
- * Trigger an Order the opposite of the “natural” way: compare its
- * price the bid for long Orders and ask for short Orders.
- */
- INVERSE,
-
- /**
- * Trigger an Order by comparing its price to the bid regardless
- * of whether it is long or short.
- */
- BID,
-
- /**
- * Trigger an Order by comparing its price to the ask regardless
- * of whether it is long or short.
- */
- ASK,
-
- /**
- * Trigger an Order by comparing its price to the midpoint
- * regardless of whether it is long or short.
- */
- MID
-}
diff --git a/src/main/java/ats/orders/OrderType.java b/src/main/java/ats/orders/OrderType.java
deleted file mode 100644
index 00cf278..0000000
--- a/src/main/java/ats/orders/OrderType.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package ats.orders;
-
-/**
- * Order type.
- *
- * @see OANDA API docs
- */
-public enum OrderType {
- MARKET,
- LIMIT,
- STOP,
- MARKET_IF_TOUCHED,
- TAKE_PROFIT,
- STOP_LOSS,
- TRAILING_STOP_LOSS,
- FIXED_PRICE
-};
diff --git a/src/main/java/ats/orders/StopLossDetails.java b/src/main/java/ats/orders/StopLossDetails.java
deleted file mode 100644
index 1ef57d2..0000000
--- a/src/main/java/ats/orders/StopLossDetails.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package ats.orders;
-
-import java.math.BigDecimal;
-
-import org.joda.time.DateTime;
-
-/**
- * StopLossDetails specifies the details of a Stop Loss Order to be
- * created on behalf of a client. This may happen when an Order is
- * filled that opens a Trade requiring a Stop Loss, or when a Trade’s
- * dependent Stop Loss Order is modified directly through the Trade.
- *
- * @see OANDA API docs
- */
-public class StopLossDetails {
-
- /**
- * The price that the Stop Loss Order will be triggered
- * at. Only one of the price and distance fields may be
- * specified.
- */
- public String price;
-
- /**
- * Specifies the distance (in price units) from the Trade’s
- * open price to use as the Stop Loss Order price. Only one of
- * the distance and price fields may be specified.
- */
- public BigDecimal distance;
-
- /**
- * The time in force for the created Stop Loss Order. This may
- * only be GTC, GTD or GFD. The default is GTC.
- */
- public TimeInForce timeInForce = TimeInForce.GTC;
-
- /**
- * The date when the Stop Loss Order will be cancelled on if
- * timeInForce is GTD.
- */
- public DateTime gtdTime;
-
- /**
- * The Client Extensions to add to the Stop Loss Order when
- * created.
- */
- public ClientExtensions clientExtensions;
-
- /**
- * Flag indicating that the price for the Stop Loss Order is
- * guaranteed. The default value depends on the
- * GuaranteedStopLossOrderMode of the account, if it is
- * REQUIRED, the default will be true, for DISABLED or ENABLED
- * the default is false.
- */
- public boolean guaranteed;
-}
diff --git a/src/main/java/ats/orders/StopLossOrderRequest.java b/src/main/java/ats/orders/StopLossOrderRequest.java
deleted file mode 100644
index c95253f..0000000
--- a/src/main/java/ats/orders/StopLossOrderRequest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package ats.orders;
-
-import com.oanda.v20.order.OrderTriggerCondition;
-
-import org.joda.time.DateTime;
-
-/**
- * Create a new stop loss order request to send to the OANDA API.
- *
- * @see OANDA API docs
- */
-public class StopLossOrderRequest extends OrderRequest {
-
- /**
- * The ID of the Trade to close when the price threshold is
- * breached.
- */
- public String tradeID;
-
- /**
- * The client ID of the Trade to be closed when the price
- * threshold is breached.
- */
- public String clientTradeID;
-
- /**
- * The price threshold specified for the Stop Loss Order. If the
- * guaranteed flag is false, the associated Trade will be closed
- * by a market price that is equal to or worse than this
- * threshold. If the flag is true the associated Trade will be
- * closed at this price.
- */
- public String price;
-
- /**
- * Specifies the distance (in price units) from the Account’s
- * current price to use as the StopLoss Order price. If the Trade
- * is short the Instrument’s bid price is used, and for long
- * Trades the ask is used.
- */
- public String distance;
-
- /**
- * The time-in-force requested for the StopLoss Order. Restricted
- * to “GTC”, “GFD” and “GTD” for StopLoss Orders. The default
- * is TimeInForce.GTC.
- */
- public TimeInForce timeInForce;
-
- /**
- * The date/time when the order will be cancelled if its
- * timeInForce is “GTD”.
- */
- public DateTime gtdTime;
-
- /**
- * Specification of which price component should be used when
- * determining if an Order should be triggered and filled. This
- * allows Orders to be triggered based on the bid, ask, mid,
- * default (ask for buy, bid for sell) or inverse (ask for sell,
- * bid for buy) price depending on the desired behaviour. Orders
- * are always filled using their default price component. This
- * feature is only provided through the REST API. Clients who
- * choose to specify a non-default trigger condition will not see
- * it reflected in any of OANDA’s proprietary or partner trading
- * platforms, their transaction history or their account
- * statements. OANDA platforms always assume that an Order’s
- * trigger condition is set to the default value when indicating
- * the distance from an Order’s trigger price, and will always
- * provide the default trigger condition when creating or
- * modifying an Order. A special restriction applies when creating
- * a guaranteed Stop Loss Order. In this case the TriggerCondition
- * value must either be “DEFAULT”, or the “natural” trigger side
- * “DEFAULT” results in. So for a Stop Loss Order for a long trade
- * valid values are “DEFAULT” and “BID”, and for short trades
- * “DEFAULT” and “ASK” are valid. The default is
- * OrderTriggerCondition.DEFAULT.
- */
- public OrderTriggerCondition triggerCondition;
-
- /**
- * The client extensions to add to the Order. Do not set, modify,
- * or delete clientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions clientExtensions;
-
-
-
- /**
- * Create a new stop loss order request to send to the OANDA API.
- *
- * @param tradeID The ID of the Trade to close when the price
- * threshold is breached.
- *
- * @param clientTradeID The client ID of the Trade to be closed
- * when the price threshold is breached.
- *
- * @param price The price threshold specified for the TakeProfit
- * Order. The associated Trade will be closed by a market price
- * that is equal to or better than this threshold.
- */
- public StopLossOrderRequest(String tradeID, String clientTradeID, String price)
- {
- this(tradeID, clientTradeID, price, null, null, null, null, null);
- }
-
- /**
- * Create a new stop loss order request to send to the OANDA API.
- *
- * @param tradeID The ID of the Trade to close when the price
- * threshold is breached.
- *
- * @param clientTradeID The client ID of the Trade to be closed
- * when the price threshold is breached.
- *
- * @param price The price threshold specified for the TakeProfit
- * Order. The associated Trade will be closed by a market price
- * that is equal to or better than this threshold.
- *
- * @param distance Specifies the distance (in price units) from
- * the Account’s current price to use as the Stop Loss Order
- * price. If the Trade is short the Instrument’s bid price is
- * used, and for long Trades the ask is used.
- *
- * @param timeInForce The time-in-force requested for the Order.
- * Restricted to “GTC”, “GFD” and “GTD” for StopLoss Orders.
- * The default is TimeInForce.GTC.
- *
- * @param gtdTime The date when the Order will be cancelled on if
- * timeInForce is GTD.
- *
- * @param triggerCondition Specification of which price component
- * should be used when determining if an Order should be triggered
- * and filled. This allows Orders to be triggered based on the
- * bid, ask, mid, default (ask for buy, bid for sell) or inverse
- * (ask for sell, bid for buy) price depending on the desired
- * behaviour. Orders are always filled using their default price
- * component. This feature is only provided through the REST
- * API. Clients who choose to specify a non-default trigger
- * condition will not see it reflected in any of OANDA’s
- * proprietary or partner trading platforms, their transaction
- * history or their account statements. OANDA platforms always
- * assume that an Order’s trigger condition is set to the default
- * value when indicating the distance from an Order’s trigger
- * price, and will always provide the default trigger condition
- * when creating or modifying an Order. A special restriction
- * applies when creating a guaranteed Stop Loss Order. In this
- * case the TriggerCondition value must either be “DEFAULT”, or
- * the “natural” trigger side “DEFAULT” results in. So for a Stop
- * Loss Order for a long trade valid values are “DEFAULT” and
- * “BID”, and for short trades “DEFAULT” and “ASK” are valid.
- * The default is OrderTriggerCondition.DEFAULT.
- *
- * @param clientExtensions The client extensions to add to the
- * Order. Do not set, modify, or delete clientExtensions if your
- * account is associated with MT4.
- */
- public StopLossOrderRequest(String tradeID,
- String clientTradeID,
- String price,
- String distance,
- TimeInForce timeInForce,
- DateTime gtdTime,
- OrderTriggerCondition triggerCondition,
- ClientExtensions clientExtensions)
- {
- super(OrderType.STOP_LOSS);
-
- this.tradeID = tradeID;
- this.clientTradeID = clientTradeID;
- this.price = price;
- this.distance = distance;
- this.timeInForce = timeInForce;
- this.gtdTime = gtdTime;
- this.triggerCondition = triggerCondition;
- this.clientExtensions = clientExtensions;
-
- if (this.timeInForce == null)
- this.timeInForce = TimeInForce.GTC;
-
- if (this.triggerCondition == null)
- this.triggerCondition = OrderTriggerCondition.DEFAULT;
- }
-}
diff --git a/src/main/java/ats/orders/StopOrderRequest.java b/src/main/java/ats/orders/StopOrderRequest.java
deleted file mode 100644
index ac0aea4..0000000
--- a/src/main/java/ats/orders/StopOrderRequest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-package ats.orders;
-
-import com.oanda.v20.order.OrderTriggerCondition;
-
-import org.joda.time.DateTime;
-
-/**
- * Create a new stop order request to send to the OANDA API.
- *
- * @see OANDA API docs
- */
-public class StopOrderRequest extends OrderRequest {
-
- /**
- * Instrument to open the order on. Example: "EUR_USD"
- */
- public String instrument;
-
- /**
- * The quantity requested to be filled by the order. A
- * posititive number of units results in a long Order, and a
- * negative number of units results in a short Order.
- */
- public int units;
-
- /**
- * The price threshold specified for the order. The order will
- * only be filled by a market price that is equal to or worse than
- * this price.
- */
- public String price;
-
- /**
- * The worst market price that may be used to fill this Stop
- * Order. If the market gaps and crosses through both the price
- * and the priceBound, the Stop Order will be cancelled instead of
- * being filled.
- */
- public String priceBound;
-
- /**
- * The time-in-force requested for the order. The default is
- * TimeInForce.GTC.
- */
- public TimeInForce timeInForce;
-
- /**
- * The date/time when the order will be cancelled if its
- * timeInForce is “GTD”.
- */
- public DateTime gtdTime;
-
- /**
- * Specification of how Positions in the Account are modified when
- * the Order is filled.
- */
- public OrderPositionFill positionFill;
-
- /**
- * Specification of which price component should be used when
- * determining if an Order should be triggered and filled. This
- * allows Orders to be triggered based on the bid, ask, mid,
- * default (ask for buy, bid for sell) or inverse (ask for sell,
- * bid for buy) price depending on the desired behaviour. Orders
- * are always filled using their default price component. This
- * feature is only provided through the REST API. Clients who
- * choose to specify a non-default trigger condition will not see
- * it reflected in any of OANDA’s proprietary or partner trading
- * platforms, their transaction history or their account
- * statements. OANDA platforms always assume that an Order’s
- * trigger condition is set to the default value when indicating
- * the distance from an Order’s trigger price, and will always
- * provide the default trigger condition when creating or
- * modifying an Order. A special restriction applies when creating
- * a guaranteed Stop Loss Order. In this case the TriggerCondition
- * value must either be “DEFAULT”, or the “natural” trigger side
- * “DEFAULT” results in. So for a String top Loss Order for a long
- * trade valid values are “DEFAULT” and “BID”, and for short
- * trades “DEFAULT” and “ASK” are valid.
- */
- public OrderTriggerCondition triggerCondition;
-
- /**
- * The client extensions to add to the Order. Do not set, modify,
- * or delete clientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions clientExtensions;
-
- /**
- * TakeProfitDetails specifies the details of a Take Profit Order
- * to be created on behalf of a client. This may happen when an
- * Order is filled that opens a Trade requiring a Take Profit, or
- * when a Trade’s dependent Take Profit Order is modified directly
- * through the Trade.
- */
- public TakeProfitDetails takeProfitOnFill;
-
- /**
- * StopLossDetails specifies the details of a Stop Loss Order to
- * be created on behalf of a client. This may happen when an Order
- * is filled that opens a Trade requiring a Stop Loss, or when a
- * Trade’s dependent Stop Loss Order is modified directly through
- * the Trade.
- */
- public StopLossDetails stopLossOnFill;
-
- /**
- * TrailingStopLossDetails specifies the details of a Trailing
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a
- * Trailing Stop Loss, or when a Trade’s dependent Trailing Stop
- * Loss Order is modified directly through the Trade.
- */
- public TrailingStopLossDetails trailingStopLossOnFill;
-
- /**
- * Client Extensions to add to the Trade created when the Order is
- * filled (if such a Trade is created). Do not set, modify, or
- * delete tradeClientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions tradeClientExtensions;
-
-
-
- /**
- * Create a new stop order request to send to the OANDA API.
- *
- * @param instrument Instrument to open the order on.
- * Example: "EUR_USD"
- *
- * @param units The quantity requested to be filled by the
- * Order. A posititive number of units results in a long Order,
- * and a negative number of units results in a short Order.
- *
- * @param price The price threshold specified for the order. The
- * order will only be filled by a market price that is equal to or
- * worse than this price.
- */
- public StopOrderRequest(String instrument, int units, String price)
- {
- this(instrument, units, price, null, null, null,
- null, null, null, null, null, null, null);
- }
-
- /**
- * Create a new stop order request to send to the OANDA API.
- *
- * @param instrument Instrument to open the order on.
- * Example: "EUR_USD"
- *
- * @param units The quantity requested to be filled by the
- * Order. A posititive number of units results in a long Order,
- * and a negative number of units results in a short Order.
- *
- * @param price The price threshold specified for the Order. The
- * Order will only be filled by a market price that is equal to or
- * worse than this price.
- *
- * @param priceBound The worst market price that may be used to
- * fill this Stop Order. If the market gaps and crosses through
- * both the price and the priceBound, the Stop Order will be
- * cancelled instead of being filled.
- *
- * @param timeInForce The time-in-force requested for the Order.
- * The default is TimeInForce.GTC.
- *
- * @param gtdTime The date when the Order will be cancelled on if
- * timeInForce is GTD.
- *
- * @param positionFill Specification of how Positions in the Account
- * are modified when the Order is filled. The default is
- * OrderPositionFill.DEFAULT.
- *
- * @param triggerCondition Specification of which price component
- * should be used when determining if an Order should be triggered
- * and filled. This allows Orders to be triggered based on the
- * bid, ask, mid, default (ask for buy, bid for sell) or inverse
- * (ask for sell, bid for buy) price depending on the desired
- * behaviour. Orders are always filled using their default price
- * component. This feature is only provided through the REST
- * API. Clients who choose to specify a non-default trigger
- * condition will not see it reflected in any of OANDA’s
- * proprietary or partner trading platforms, their transaction
- * history or their account statements. OANDA platforms always
- * assume that an Order’s trigger condition is set to the default
- * value when indicating the distance from an Order’s trigger
- * price, and will always provide the default trigger condition
- * when creating or modifying an Order. A special restriction
- * applies when creating a guaranteed Stop Loss Order. In this
- * case the TriggerCondition value must either be “DEFAULT”, or
- * the “natural” trigger side “DEFAULT” results in. So for a Stop
- * Loss Order for a long trade valid values are “DEFAULT” and
- * “BID”, and for short trades “DEFAULT” and “ASK” are valid.
- * The default is OrderTriggerCondition.DEFAULT.
- *
- * @param clientExtensions The client extensions to add to the
- * Order. Do not set, modify, or delete clientExtensions if your
- * account is associated with MT4.
- *
- * @param takeProfitOnFill TakeProfitDetails specifies the details of
- * a Take Profit Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a Take
- * Profit, or when a Trade’s dependent Take Profit Order is modified
- * directly through the Trade.
- *
- * @param stopLossOnFill StopLossDetails specifies the details of a
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a Stop
- * Loss, or when a Trade’s dependent Stop Loss Order is modified
- * directly through the Trade.
- *
- * @param trailingStopLossOnFill TrailingStopLossDetails specifies the
- * details of a Trailing Stop Loss Order to be created on behalf of a
- * client. This may happen when an Order is filled that opens a Trade
- * requiring a Trailing Stop Loss, or when a Trade’s dependent
- * Trailing Stop Loss Order is modified directly through the Trade.
- *
- * @param tradeClientExtensions Client Extensions to add to the Trade
- * created when the Order is filled (if such a Trade is created). Do
- * not set, modify, or delete tradeClientExtensions if your account is
- * associated with MT4.
- */
- public StopOrderRequest(String instrument,
- int units,
- String price,
- String priceBound,
- TimeInForce timeInForce,
- DateTime gtdTime,
- OrderPositionFill positionFill,
- OrderTriggerCondition triggerCondition,
- ClientExtensions clientExtensions,
- TakeProfitDetails takeProfitOnFill,
- StopLossDetails stopLossOnFill,
- TrailingStopLossDetails trailingStopLossOnFill,
- ClientExtensions tradeClientExtensions)
- {
- super(OrderType.STOP);
-
- this.instrument = instrument;
- this.units = units;
- this.price = price;
- this.priceBound = priceBound;
- this.timeInForce = timeInForce;
- this.gtdTime = gtdTime;
- this.positionFill = positionFill;
- this.triggerCondition = triggerCondition;
- this.clientExtensions = clientExtensions;
- this.takeProfitOnFill = takeProfitOnFill;
- this.stopLossOnFill = stopLossOnFill;
- this.trailingStopLossOnFill = trailingStopLossOnFill;
- this.tradeClientExtensions = tradeClientExtensions;
-
- if (this.timeInForce == null)
- this.timeInForce = TimeInForce.GTC;
-
- if (this.positionFill == null)
- this.positionFill = OrderPositionFill.DEFAULT;
-
- if (this.triggerCondition == null)
- this.triggerCondition = OrderTriggerCondition.DEFAULT;
- }
-}
diff --git a/src/main/java/ats/orders/TakeProfitDetails.java b/src/main/java/ats/orders/TakeProfitDetails.java
deleted file mode 100644
index 3cf2708..0000000
--- a/src/main/java/ats/orders/TakeProfitDetails.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package ats.orders;
-
-import org.joda.time.DateTime;
-
-/**
- * TakeProfitDetails specifies the details of a Take Profit Order to
- * be created on behalf of a client. This may happen when an Order is
- * filled that opens a Trade requiring a Take Profit, or when a
- * Trade’s dependent Take Profit Order is modified directly through
- * the Trade.
- *
- * @see OANDA API docs
- */
-public class TakeProfitDetails {
-
- /**
- * The price that the Take Profit Order will be triggered
- * at. Only one of the price and distance fields may be
- * specified.
- */
- public String price;
-
- /**
- * The time in force for the created Take Profit Order. This
- * may only be GTC, GTD or GFD. Default is GTC.
- */
- public TimeInForce timeInForce = TimeInForce.GTC;
-
- /**
- * The date when the Take Profit Order will be cancelled on if
- * timeInForce is GTD.
- */
- public DateTime gtdTime;
-
- /**
- * The Client Extensions to add to the Take Profit Order when
- * created.
- */
- public ClientExtensions clientExtensions;
-}
diff --git a/src/main/java/ats/orders/TakeProfitOrderRequest.java b/src/main/java/ats/orders/TakeProfitOrderRequest.java
deleted file mode 100644
index d93cdb9..0000000
--- a/src/main/java/ats/orders/TakeProfitOrderRequest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package ats.orders;
-
-import com.oanda.v20.order.OrderTriggerCondition;
-
-import org.joda.time.DateTime;
-
-/**
- * Create a new market-if-touched order request to send to the OANDA API.
- *
- * @see OANDA API docs
- */
-public class TakeProfitOrderRequest extends OrderRequest {
-
- /**
- * The ID of the Trade to close when the price threshold is
- * breached.
- */
- public String tradeID;
-
- /**
- * The client ID of the Trade to be closed when the price
- * threshold is breached.
- */
- public String clientTradeID;
-
- /**
- * The price threshold specified for the TakeProfit Order. The
- * associated Trade will be closed by a market price that is equal
- * to or better than this threshold.
- */
- public String price;
-
- /**
- * The time-in-force requested for the TakeProfit
- * Order. Restricted to “GTC”, “GFD” and “GTD” for TakeProfit
- * Orders. The default is TimeInForce.GTC.
- */
- public TimeInForce timeInForce;
-
- /**
- * The date/time when the order will be cancelled if its
- * timeInForce is “GTD”.
- */
- public DateTime gtdTime;
-
- /**
- * Specification of which price component should be used when
- * determining if an Order should be triggered and filled. This
- * allows Orders to be triggered based on the bid, ask, mid,
- * default (ask for buy, bid for sell) or inverse (ask for sell,
- * bid for buy) price depending on the desired behaviour. Orders
- * are always filled using their default price component. This
- * feature is only provided through the REST API. Clients who
- * choose to specify a non-default trigger condition will not see
- * it reflected in any of OANDA’s proprietary or partner trading
- * platforms, their transaction history or their account
- * statements. OANDA platforms always assume that an Order’s
- * trigger condition is set to the default value when indicating
- * the distance from an Order’s trigger price, and will always
- * provide the default trigger condition when creating or
- * modifying an Order. A special restriction applies when creating
- * a guaranteed Stop Loss Order. In this case the TriggerCondition
- * value must either be “DEFAULT”, or the “natural” trigger side
- * “DEFAULT” results in. So for a Stop Loss Order for a long trade
- * valid values are “DEFAULT” and “BID”, and for short trades
- * “DEFAULT” and “ASK” are valid. The default is
- * OrderTriggerCondition.DEFAULT.
- */
- public OrderTriggerCondition triggerCondition;
-
- /**
- * The client extensions to add to the Order. Do not set, modify,
- * or delete clientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions clientExtensions;
-
-
-
- /**
- * Create a new take profit order request to send to the OANDA
- * API.
- *
- * @param tradeID The ID of the Trade to close when the price
- * threshold is breached.
- *
- * @param clientTradeID The client ID of the Trade to be closed
- * when the price threshold is breached.
- *
- * @param price The price threshold specified for the TakeProfit
- * Order. The associated Trade will be closed by a market price
- * that is equal to or better than this threshold.
- */
- public TakeProfitOrderRequest(String tradeID, String clientTradeID, String price)
- {
- this(tradeID, clientTradeID, price, null, null, null, null);
- }
-
- /**
- * Create a new take profit order request to send to the OANDA
- * API.
- *
- * @param tradeID The ID of the Trade to close when the price
- * threshold is breached.
- *
- * @param clientTradeID The client ID of the Trade to be closed
- * when the price threshold is breached.
- *
- * @param price The price threshold specified for the TakeProfit
- * Order. The associated Trade will be closed by a market price
- * that is equal to or better than this threshold.
- *
- * @param timeInForce The time-in-force requested for the Order.
- * Restricted to “GTC”, “GFD” and “GTD” for TakeProfit Orders.
- * The default is TimeInForce.GTC.
- *
- * @param gtdTime The date when the Order will be cancelled on if
- * timeInForce is GTD.
- *
- * @param triggerCondition Specification of which price component
- * should be used when determining if an Order should be triggered
- * and filled. This allows Orders to be triggered based on the
- * bid, ask, mid, default (ask for buy, bid for sell) or inverse
- * (ask for sell, bid for buy) price depending on the desired
- * behaviour. Orders are always filled using their default price
- * component. This feature is only provided through the REST
- * API. Clients who choose to specify a non-default trigger
- * condition will not see it reflected in any of OANDA’s
- * proprietary or partner trading platforms, their transaction
- * history or their account statements. OANDA platforms always
- * assume that an Order’s trigger condition is set to the default
- * value when indicating the distance from an Order’s trigger
- * price, and will always provide the default trigger condition
- * when creating or modifying an Order. A special restriction
- * applies when creating a guaranteed Stop Loss Order. In this
- * case the TriggerCondition value must either be “DEFAULT”, or
- * the “natural” trigger side “DEFAULT” results in. So for a Stop
- * Loss Order for a long trade valid values are “DEFAULT” and
- * “BID”, and for short trades “DEFAULT” and “ASK” are valid.
- * The default is OrderTriggerCondition.DEFAULT.
- *
- * @param clientExtensions The client extensions to add to the
- * Order. Do not set, modify, or delete clientExtensions if your
- * account is associated with MT4.
- */
- public TakeProfitOrderRequest(String tradeID,
- String clientTradeID,
- String price,
- TimeInForce timeInForce,
- DateTime gtdTime,
- OrderTriggerCondition triggerCondition,
- ClientExtensions clientExtensions)
- {
- super(OrderType.TAKE_PROFIT);
-
- this.tradeID = tradeID;
- this.clientTradeID = clientTradeID;
- this.price = price;
- this.timeInForce = timeInForce;
- this.gtdTime = gtdTime;
- this.triggerCondition = triggerCondition;
- this.clientExtensions = clientExtensions;
-
- if (this.timeInForce == null)
- this.timeInForce = TimeInForce.GTC;
-
- if (this.triggerCondition == null)
- this.triggerCondition = OrderTriggerCondition.DEFAULT;
- }
-}
diff --git a/src/main/java/ats/orders/TimeInForce.java b/src/main/java/ats/orders/TimeInForce.java
deleted file mode 100644
index 935dcf6..0000000
--- a/src/main/java/ats/orders/TimeInForce.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package ats.orders;
-
-/**
- * The time-in-force of an Order. TimeInForce describes how long
- * an Order should remain pending before being automatically
- * cancelled by the execution system.
- *
- * @see OANDA API docs
- */
-public enum TimeInForce {
- /**
- * The Order is “Good unTil Cancelled”
- */
- GTC,
-
- /**
- * The Order is “Good unTil Date” and will be cancelled at the provided time
- */
- GTD,
-
- /**
- * The Order is “Good For Day” and will be cancelled at 5pm New York time
- */
- GFD,
-
- /**
- * The Order must be immediately “Filled Or Killed”
- */
- FOK,
-
- /**
- * The Order must be “Immediatedly paritally filled Or Cancelled”
- */
- IOC
-};
diff --git a/src/main/java/ats/orders/TrailingStopLossDetails.java b/src/main/java/ats/orders/TrailingStopLossDetails.java
deleted file mode 100644
index 97f2421..0000000
--- a/src/main/java/ats/orders/TrailingStopLossDetails.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package ats.orders;
-
-import java.math.BigDecimal;
-
-import org.joda.time.DateTime;
-
-/**
- * TrailingStopLossDetails specifies the details of a Trailing
- * Stop Loss Order to be created on behalf of a client. This may
- * happen when an Order is filled that opens a Trade requiring a
- * Trailing Stop Loss, or when a Trade’s dependent Trailing Stop
- * Loss Order is modified directly through the Trade.
- *
- * @see OANDA API docs
- */
-public class TrailingStopLossDetails {
- /**
- * The distance (in price units) from the Trade’s fill price
- * that the Trailing Stop Loss Order will be triggered at.
- */
- public BigDecimal distance;
-
- /**
- * The time in force for the created Trailing Stop Loss
- * Order. This may only be GTC, GTD or GFD. The default is
- * GTC.
- */
- public TimeInForce timeInForce = TimeInForce.GTC;
-
- /**
- * The date when the Trailing Stop Loss Order will be
- * cancelled on if timeInForce is GTD.
- */
- public DateTime gtdTime;
-
- /**
- * The Client Extensions to add to the Trailing Stop Loss Order when
- * created.
- */
- public ClientExtensions clientExtensions;
-}
diff --git a/src/main/java/ats/orders/TrailingStopLossOrderRequest.java b/src/main/java/ats/orders/TrailingStopLossOrderRequest.java
deleted file mode 100644
index 0bbaf13..0000000
--- a/src/main/java/ats/orders/TrailingStopLossOrderRequest.java
+++ /dev/null
@@ -1,166 +0,0 @@
-package ats.orders;
-
-import com.oanda.v20.order.OrderTriggerCondition;
-
-import org.joda.time.DateTime;
-
-/**
- * Create a new trailing stop loss order request to send to the OANDA API.
- *
- * @see OANDA API docs
- */
-public class TrailingStopLossOrderRequest extends OrderRequest {
-
- /**
- * The ID of the Trade to close when the price threshold is
- * breached.
- */
- public String tradeID;
-
- /**
- * The client ID of the Trade to be closed when the price
- * threshold is breached.
- */
- public String clientTradeID;
-
- /**
- * The price distance (in price units) specified for the
- * TrailingStopLoss Order.
- */
- public String distance;
-
- /**
- * The time-in-force requested for the TrailingStopLoss
- * Order. Restricted to “GTC”, “GFD” and “GTD” for
- * TrailingStopLoss Orders. The default is TimeInForce.GTC.
- */
- public TimeInForce timeInForce;
-
- /**
- * The date/time when the order will be cancelled if its
- * timeInForce is “GTD”.
- */
- public DateTime gtdTime;
-
- /**
- * Specification of which price component should be used when
- * determining if an Order should be triggered and filled. This
- * allows Orders to be triggered based on the bid, ask, mid,
- * default (ask for buy, bid for sell) or inverse (ask for sell,
- * bid for buy) price depending on the desired behaviour. Orders
- * are always filled using their default price component. This
- * feature is only provided through the REST API. Clients who
- * choose to specify a non-default trigger condition will not see
- * it reflected in any of OANDA’s proprietary or partner trading
- * platforms, their transaction history or their account
- * statements. OANDA platforms always assume that an Order’s
- * trigger condition is set to the default value when indicating
- * the distance from an Order’s trigger price, and will always
- * provide the default trigger condition when creating or
- * modifying an Order. A special restriction applies when creating
- * a guaranteed Stop Loss Order. In this case the TriggerCondition
- * value must either be “DEFAULT”, or the “natural” trigger side
- * “DEFAULT” results in. So for a Stop Loss Order for a long trade
- * valid values are “DEFAULT” and “BID”, and for short trades
- * “DEFAULT” and “ASK” are valid. The default is
- * OrderTriggerCondition.DEFAULT.
- */
- public OrderTriggerCondition triggerCondition;
-
- /**
- * The client extensions to add to the Order. Do not set, modify,
- * or delete clientExtensions if your account is associated with
- * MT4.
- */
- public ClientExtensions clientExtensions;
-
-
-
- /**
- * Create a new stop loss order request to send to the OANDA API.
- *
- * @param tradeID The ID of the Trade to close when the price
- * threshold is breached.
- *
- * @param clientTradeID The client ID of the Trade to be closed
- * when the price threshold is breached.
- *
- * @param price The price threshold specified for the TakeProfit
- * Order. The associated Trade will be closed by a market price
- * that is equal to or better than this threshold.
- */
- public TrailingStopLossOrderRequest(String tradeID, String clientTradeID, String distance)
- {
- this(tradeID, clientTradeID, distance, null, null, null, null);
- }
-
- /**
- * Create a new stop loss order request to send to the OANDA API.
- *
- * @param tradeID The ID of the Trade to close when the price
- * threshold is breached.
- *
- * @param clientTradeID The client ID of the Trade to be closed
- * when the price threshold is breached.
- *
- * @param distance The price distance (in price units) specified
- * for the TrailingStopLoss Order.
- *
- * @param timeInForce The time-in-force requested for the Order.
- * Restricted to “GTC”, “GFD” and “GTD” for TrailingStopLoss Orders.
- * The default is TimeInForce.GTC.
- *
- * @param gtdTime The date when the Order will be cancelled on if
- * timeInForce is GTD.
- *
- * @param triggerCondition Specification of which price component
- * should be used when determining if an Order should be triggered
- * and filled. This allows Orders to be triggered based on the
- * bid, ask, mid, default (ask for buy, bid for sell) or inverse
- * (ask for sell, bid for buy) price depending on the desired
- * behaviour. Orders are always filled using their default price
- * component. This feature is only provided through the REST
- * API. Clients who choose to specify a non-default trigger
- * condition will not see it reflected in any of OANDA’s
- * proprietary or partner trading platforms, their transaction
- * history or their account statements. OANDA platforms always
- * assume that an Order’s trigger condition is set to the default
- * value when indicating the distance from an Order’s trigger
- * price, and will always provide the default trigger condition
- * when creating or modifying an Order. A special restriction
- * applies when creating a guaranteed Stop Loss Order. In this
- * case the TriggerCondition value must either be “DEFAULT”, or
- * the “natural” trigger side “DEFAULT” results in. So for a Stop
- * Loss Order for a long trade valid values are “DEFAULT” and
- * “BID”, and for short trades “DEFAULT” and “ASK” are valid.
- * The default is OrderTriggerCondition.DEFAULT.
- *
- * @param clientExtensions The client extensions to add to the
- * Order. Do not set, modify, or delete clientExtensions if your
- * account is associated with MT4.
- */
- public TrailingStopLossOrderRequest(String tradeID,
- String clientTradeID,
- String distance,
- TimeInForce timeInForce,
- DateTime gtdTime,
- OrderTriggerCondition triggerCondition,
- ClientExtensions clientExtensions)
- {
- super(OrderType.TRAILING_STOP_LOSS);
-
- this.tradeID = tradeID;
- this.clientTradeID = clientTradeID;
- this.distance = distance;
- this.timeInForce = timeInForce;
- this.gtdTime = gtdTime;
- this.triggerCondition = triggerCondition;
- this.clientExtensions = clientExtensions;
-
- if (this.timeInForce == null)
- this.timeInForce = TimeInForce.GTC;
-
- if (this.triggerCondition == null)
- this.triggerCondition = OrderTriggerCondition.DEFAULT;
- }
-}
diff --git a/src/test/java/ats/orders/MarketOrderRequestTest.java b/src/test/java/ats/orders/MarketOrderRequestTest.java
deleted file mode 100644
index 4b6e6f5..0000000
--- a/src/test/java/ats/orders/MarketOrderRequestTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package ats.orders;
-
-import java.math.BigDecimal;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-
-import org.joda.time.DateTime;
-import org.json.JSONException;
-import org.junit.Test;
-
-/**
- * MarketOrderRequestTest tests JSON format serialization of
- * MarketOrderRequest objects.
- */
-public class MarketOrderRequestTest extends OrderSerializationTestBase {
-
-
- /**
- * Test the simplest form, including default values.
- */
- @Test
- public void testToJSONSmall()
- throws JsonProcessingException, JSONException
- {
- MarketOrderRequest obj = new MarketOrderRequest("EUR_USD", 34);
-
- String expected = "{\"type\":\"MARKET\",\"instrument\":\"EUR_USD\",\"units\":34,\"timeInForce\":\"FOK\",\"positionFill\":\"DEFAULT\"}";
-
- doTest(obj, expected);
- }
-
- /**
- * Test a fully filled out object.
- */
- @Test
- public void testToJSONLarge()
- throws JsonProcessingException, JSONException
- {
- TakeProfitDetails tpd = new TakeProfitDetails();
- tpd.price = "66.2";
- tpd.timeInForce = TimeInForce.GTD;
- tpd.gtdTime = new DateTime("2010-10-10T14:15:16.000Z");
-
- StopLossDetails sld = new StopLossDetails();
- sld.distance = new BigDecimal("22.7");
- sld.timeInForce = TimeInForce.IOC;
- sld.gtdTime = new DateTime("2012-12-12T14:15:16.000Z");
- sld.guaranteed = true;
-
- TrailingStopLossDetails tsld = new TrailingStopLossDetails();
- tsld.distance = new BigDecimal("33.6");
- tsld.timeInForce = TimeInForce.IOC;
- tsld.gtdTime = new DateTime("2013-3-13T14:15:16.000Z");
-
- MarketOrderRequest obj =
- new MarketOrderRequest("EUR_USD", 34, TimeInForce.IOC,
- "99.44", OrderPositionFill.REDUCE_ONLY,
- null, tpd, sld, tsld, null);
-
- String expected = "{\"stopLossOnFill\":{\"distance\":22.7,\"timeInForce\":\"IOC\",\"gtdTime\":\"2012-12-12T14:15:16.000Z\",\"guaranteed\":true},\"takeProfitOnFill\":{\"price\":\"66.2\",\"timeInForce\":\"GTD\",\"gtdTime\":\"2010-10-10T14:15:16.000Z\"},\"instrument\":\"EUR_USD\",\"units\":34,\"priceBound\":\"99.44\",\"type\":\"MARKET\",\"timeInForce\":\"IOC\",\"positionFill\":\"REDUCE_ONLY\",\"trailingStopLossOnFill\":{\"distance\":33.6,\"timeInForce\":\"IOC\",\"gtdTime\":\"2013-03-13T14:15:16.000Z\"}}";
-
- doTest(obj, expected);
- }
-}
diff --git a/src/test/java/ats/orders/OrderSerializationTestBase.java b/src/test/java/ats/orders/OrderSerializationTestBase.java
deleted file mode 100644
index 8a80b37..0000000
--- a/src/test/java/ats/orders/OrderSerializationTestBase.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package ats.orders;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.json.JSONException;
-import org.skyscreamer.jsonassert.JSONAssert;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * OrderSerializationTestBase is a base class for testing JSON format
- * serialization of order types for sending to the OANDA api.
- */
-public class OrderSerializationTestBase {
- private static final Logger log = LoggerFactory.getLogger(OrderSerializationTestBase.class);
-
- /**
- * Test an object against its expected json representation.
- */
- protected void doTest(Object obj, String expected)
- throws JsonProcessingException, JSONException
- {
- doTest(obj, expected, false);
- }
-
- /**
- * Test an object against its expected json representation.
- *
- * @param verbose Log a little extra if true.
- */
- protected void doTest(Object obj, String expected, boolean verbose)
- throws JsonProcessingException, JSONException
- {
- ObjectMapper mapper = OrderRequest.getJSONMapper();
- String actual = mapper.writeValueAsString(obj);
-
- if (verbose) log.warn(actual);
-
- JSONAssert.assertEquals(expected, actual, true);
- }
-}
diff --git a/src/test/java/ats/orders/StopLossDetailsTest.java b/src/test/java/ats/orders/StopLossDetailsTest.java
deleted file mode 100644
index 72737c0..0000000
--- a/src/test/java/ats/orders/StopLossDetailsTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package ats.orders;
-
-import java.math.BigDecimal;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-
-import org.joda.time.DateTime;
-import org.json.JSONException;
-import org.junit.Test;
-
-/**
- * StopLossDetailsTest tests JSON format serialization of
- * StopLossDetails objects.
- */
-public class StopLossDetailsTest extends OrderSerializationTestBase {
-
-
- /**
- * Test the simplest form, including default values.
- */
- @Test
- public void testToJSONSmall()
- throws JsonProcessingException, JSONException
- {
- StopLossDetails obj = new StopLossDetails();
- obj.price = "12.34";
-
- String expected = "{\"price\":\"12.34\",\"timeInForce\":\"GTC\",\"guaranteed\":false}";
-
- doTest(obj, expected);
- }
-
- /**
- * Test a fully filled out object.
- */
- @Test
- public void testToJSONLarge()
- throws JsonProcessingException, JSONException
- {
- StopLossDetails obj = new StopLossDetails();
- obj.distance = new BigDecimal("12.34");
- obj.timeInForce = TimeInForce.GFD;
- obj.gtdTime = new DateTime("2000-09-17T18:02:52.957Z");
-
- obj.clientExtensions = new ClientExtensions();
- obj.clientExtensions.id = "my id";
- obj.clientExtensions.tag = "my tag";
- obj.clientExtensions.comment = "my comment";
-
- String expected = "{\"distance\":12.34,\"timeInForce\":\"GFD\",\"gtdTime\":\"2000-09-17T18:02:52.957Z\",\"clientExtensions\":{\"id\":\"my id\",\"tag\":\"my tag\",\"comment\":\"my comment\"},\"guaranteed\":false}";
- doTest(obj, expected);
- }
-}
diff --git a/src/test/java/ats/orders/TakeProfitDetailsTest.java b/src/test/java/ats/orders/TakeProfitDetailsTest.java
deleted file mode 100644
index 8a529a7..0000000
--- a/src/test/java/ats/orders/TakeProfitDetailsTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package ats.orders;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-
-import org.joda.time.DateTime;
-import org.json.JSONException;
-import org.junit.Test;
-
-/**
- * TakeProfitDetailsTest tests JSON format serialization of
- * TakeProfitDetails objects.
- */
-public class TakeProfitDetailsTest extends OrderSerializationTestBase {
-
-
- /**
- * Test the simplest form, including default values.
- */
- @Test
- public void testToJSONSmall() throws JsonProcessingException, JSONException {
- TakeProfitDetails obj = new TakeProfitDetails();
- obj.price = "12.34";
-
- String expected = "{\"price\":\"12.34\",\"timeInForce\":\"GTC\"}";
- doTest(obj, expected);
- }
-
- /**
- * Test a fully filled out object.
- */
- @Test
- public void testToJSONLarge() throws JsonProcessingException, JSONException {
- TakeProfitDetails obj = new TakeProfitDetails();
- obj.price = "12.34";
- obj.timeInForce = TimeInForce.GFD;
- obj.gtdTime = new DateTime("2000-09-17T18:02:52.957Z");
-
- obj.clientExtensions = new ClientExtensions();
- obj.clientExtensions.id = "my id";
- obj.clientExtensions.tag = "my tag";
- obj.clientExtensions.comment = "my comment";
-
- String expected = "{\"price\":\"12.34\",\"timeInForce\":\"GFD\",\"gtdTime\":\"2000-09-17T18:02:52.957Z\",\"clientExtensions\":{\"id\":\"my id\",\"tag\":\"my tag\",\"comment\":\"my comment\"}}";
- doTest(obj, expected);
- }
-}
diff --git a/src/test/java/ats/orders/TakeProfitOrderRequestTest.java b/src/test/java/ats/orders/TakeProfitOrderRequestTest.java
deleted file mode 100644
index fc4e8b2..0000000
--- a/src/test/java/ats/orders/TakeProfitOrderRequestTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package ats.orders;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.oanda.v20.order.OrderTriggerCondition;
-
-import org.joda.time.DateTime;
-import org.json.JSONException;
-import org.junit.Test;
-
-/**
- * TakeProfitOrderRequestTest tests JSON format serialization of
- * TakeProfitOrderRequest objects.
- */
-public class TakeProfitOrderRequestTest extends OrderSerializationTestBase {
-
-
- /**
- * Test the simplest form, including default values.
- */
- @Test
- public void testToJSONSmall()
- throws JsonProcessingException, JSONException
- {
- TakeProfitOrderRequest obj = new TakeProfitOrderRequest("12", "23", "45.67");
-
- String expected = "{\"type\":\"TAKE_PROFIT\",\"tradeID\":\"12\",\"clientTradeID\":\"23\",\"price\":\"45.67\",\"timeInForce\":\"GTC\",\"triggerCondition\":\"DEFAULT\"}";
-
- doTest(obj, expected);
- }
-
- /**
- * Test a fully filled out object.
- */
- @Test
- public void testToJSONLarge()
- throws JsonProcessingException, JSONException
- {
- ClientExtensions clientExtensions = new ClientExtensions();
- clientExtensions.id = "my id";
- clientExtensions.tag = "my tag";
- clientExtensions.comment = "my comment";
-
- TakeProfitOrderRequest obj = new TakeProfitOrderRequest("12", "23", "45.67",
- TimeInForce.IOC,
- new DateTime("2000-09-17T18:02:52.957Z"),
- OrderTriggerCondition.MID,
- clientExtensions);
-
-
- String expected = "{\"type\":\"TAKE_PROFIT\",\"tradeID\":\"12\",\"clientTradeID\":\"23\",\"price\":\"45.67\",\"timeInForce\":\"IOC\",\"gtdTime\":\"2000-09-17T18:02:52.957Z\",\"triggerCondition\":\"MID\",\"clientExtensions\":{\"id\":\"my id\",\"tag\":\"my tag\",\"comment\":\"my comment\"}}";
-
- doTest(obj, expected);
- }
-}
diff --git a/src/test/java/ats/orders/TrailingStopLossDetailsTest.java b/src/test/java/ats/orders/TrailingStopLossDetailsTest.java
deleted file mode 100644
index 194cbaa..0000000
--- a/src/test/java/ats/orders/TrailingStopLossDetailsTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package ats.orders;
-
-import java.math.BigDecimal;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-
-import org.joda.time.DateTime;
-import org.json.JSONException;
-import org.junit.Test;
-
-/**
- * TrailingStopLossDetailsTest tests JSON format serialization of
- * TrailingStopLossDetails objects.
- */
-public class TrailingStopLossDetailsTest extends OrderSerializationTestBase {
-
-
- /**
- * Test the simplest form, including default values.
- */
- @Test
- public void testToJSONSmall()
- throws JsonProcessingException, JSONException
- {
- TrailingStopLossDetails obj = new TrailingStopLossDetails();
- obj.distance = new BigDecimal("12.34");
-
- String expected = "{\"distance\":12.34,\"timeInForce\":\"GTC\"}";
-
- doTest(obj, expected);
- }
-
- /**
- * Test a fully filled out object.
- */
- @Test
- public void testToJSONLarge()
- throws JsonProcessingException, JSONException
- {
- TrailingStopLossDetails obj = new TrailingStopLossDetails();
- obj.distance = new BigDecimal("12.34");
- obj.timeInForce = TimeInForce.GFD;
- obj.gtdTime = new DateTime("2000-09-17T18:02:52.957Z");
-
- obj.clientExtensions = new ClientExtensions();
- obj.clientExtensions.id = "my id";
- obj.clientExtensions.tag = "my tag";
- obj.clientExtensions.comment = "my comment";
-
- String expected = "{\"distance\":12.34,\"timeInForce\":\"GFD\",\"gtdTime\":\"2000-09-17T18:02:52.957Z\",\"clientExtensions\":{\"id\":\"my id\",\"tag\":\"my tag\",\"comment\":\"my comment\"}}";
- doTest(obj, expected);
- }
-}