Use OANDA order classes instead of our own
This commit is contained in:
@ -26,6 +26,7 @@ dependencies {
|
|||||||
implementation 'commons-cli:commons-cli:1.4'
|
implementation 'commons-cli:commons-cli:1.4'
|
||||||
implementation 'joda-time:joda-time:2.9.9'
|
implementation 'joda-time:joda-time:2.9.9'
|
||||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.9.5'
|
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.9.5'
|
||||||
|
implementation 'com.oanda.v20:v20:3.0.25'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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 {
|
public class DebugTradingManager implements TradingManager {
|
||||||
static final Logger log = LoggerFactory.getLogger("DebugTradingManager");
|
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.
|
* Place an order request.
|
||||||
|
|||||||
@ -2,18 +2,20 @@ import java.util.Arrays;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.espertech.esper.client.Configuration;
|
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.EPServiceProvider;
|
||||||
import com.espertech.esper.client.EPServiceProviderManager;
|
import com.espertech.esper.client.EPServiceProviderManager;
|
||||||
import com.espertech.esper.client.EPStatement;
|
import com.espertech.esper.client.EPStatement;
|
||||||
import com.espertech.esper.client.StatementAwareUpdateListener;
|
import com.espertech.esper.client.StatementAwareUpdateListener;
|
||||||
import com.espertech.esper.client.UpdateListener;
|
import com.espertech.esper.client.UpdateListener;
|
||||||
|
import com.espertech.esper.client.soda.EPStatementObjectModel;
|
||||||
import com.espertech.esper.client.time.CurrentTimeEvent;
|
import com.espertech.esper.client.time.CurrentTimeEvent;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ats.orders.MarketOrderRequest;
|
|
||||||
import ats.plugin.OHLCEvent;
|
import ats.plugin.OHLCEvent;
|
||||||
import ats.plugin.OHLCPlugInViewFactory;
|
import ats.plugin.OHLCPlugInViewFactory;
|
||||||
|
|
||||||
@ -26,6 +28,7 @@ public class EsperProcessor implements TickProcessor {
|
|||||||
|
|
||||||
public EsperProcessor(String epl, TradingManager trader) {
|
public EsperProcessor(String epl, TradingManager trader) {
|
||||||
this.trader = trader;
|
this.trader = trader;
|
||||||
|
trader.setProcessor(this);
|
||||||
Configuration config = new Configuration();
|
Configuration config = new Configuration();
|
||||||
|
|
||||||
// disable esper's internal clock. we use tick data for our
|
// disable esper's internal clock. we use tick data for our
|
||||||
@ -196,6 +199,39 @@ public class EsperProcessor implements TickProcessor {
|
|||||||
return statement;
|
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.
|
* Send a single TickEvent to Esper.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,16 +1,28 @@
|
|||||||
import java.io.BufferedReader;
|
import java.math.BigDecimal;
|
||||||
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 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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ats.orders.OrderRequest;
|
import ats.orders.OrderReply;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OANDATradingManager manages orders via the OANDA API.
|
* OANDATradingManager manages orders via the OANDA API.
|
||||||
@ -18,6 +30,7 @@ import ats.orders.OrderRequest;
|
|||||||
public class OANDATradingManager implements TradingManager {
|
public class OANDATradingManager implements TradingManager {
|
||||||
static final Logger log = LoggerFactory.getLogger("OANDATradingManager");
|
static final Logger log = LoggerFactory.getLogger("OANDATradingManager");
|
||||||
private Config config;
|
private Config config;
|
||||||
|
private EsperProcessor processor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,73 +40,82 @@ public class OANDATradingManager implements TradingManager {
|
|||||||
public OANDATradingManager(Config config) {
|
public OANDATradingManager(Config config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place an order request.
|
* Set the Esper processor for this trading manager.
|
||||||
*/
|
*/
|
||||||
@Override
|
public void setProcessor(EsperProcessor processor) {
|
||||||
public void placeOrder(OrderRequest order) {
|
this.processor = processor;
|
||||||
log.info("Placing order: {}", order);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place an order request to open a new position.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public OrderReply openPosition(String instrument, BigDecimal requestUnits) {
|
||||||
try {
|
try {
|
||||||
String orderJSON = order.toJSON();
|
MarketOrderRequest orderRequest = new MarketOrderRequest();
|
||||||
byte[] postData = orderJSON.getBytes(StandardCharsets.UTF_8);
|
orderRequest.setInstrument(instrument);
|
||||||
int postDataLength = postData.length;
|
orderRequest.setUnits(requestUnits);
|
||||||
|
|
||||||
URL url = new URL(orderURL());
|
OrderCreateRequest createRequest = new OrderCreateRequest(new AccountID(config.accountID()));
|
||||||
|
createRequest.setOrder(orderRequest);
|
||||||
|
|
||||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
OrderCreateResponse response = getContext().order.create(createRequest);
|
||||||
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);
|
|
||||||
|
|
||||||
try (DataOutputStream dos = new DataOutputStream(conn.getOutputStream())) {
|
Gson gson = new GsonBuilder()
|
||||||
dos.write(postData);
|
.setPrettyPrinting()
|
||||||
dos.flush();
|
.registerTypeAdapter(Order.class, new OrderAdapter())
|
||||||
dos.close();
|
.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.info(response.toString());
|
||||||
log.debug("Params: " + new String(postData));
|
|
||||||
log.debug("Response code: " + responseCode);
|
|
||||||
|
|
||||||
// read response
|
processor.executeQuery(orderReply.toEPL());
|
||||||
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();
|
|
||||||
|
|
||||||
log.info("Response: " + response);
|
return orderReply;
|
||||||
log.info("Finished placing order.");
|
} catch (RequestException | ExecuteException e) {
|
||||||
} catch (IOException e) {
|
log.warn("Error opening position", e);
|
||||||
log.warn("Error sending order", 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";
|
String type = config.isLiveAccount() ? "fxlive" : "fxpractice";
|
||||||
return String.format("https://api-%s.oanda.com/v3/accounts/%s/orders",
|
String url = String.format("https://api-%s.oanda.com/", type);
|
||||||
type, config.accountID());
|
return new Context(url, config.accessToken());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import ats.orders.OrderRequest;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import ats.orders.OrderReply;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TradingManager describes the interface with a trading system.
|
* TradingManager describes the interface with a trading system.
|
||||||
@ -6,8 +8,23 @@ import ats.orders.OrderRequest;
|
|||||||
interface TradingManager {
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/transaction-df/#ClientExtensions">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-df/#LimitOrderRequest">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-df/#MarketIfTouchedOrderRequest">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,177 +0,0 @@
|
|||||||
package ats.orders;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new market order request to send to the OANDA API.
|
|
||||||
*
|
|
||||||
* @see <a href="https://developer.oanda.com/rest-live-v20/order-df/#MarketOrderRequest">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
package ats.orders;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specification of how Positions in the Account are modified when the
|
|
||||||
* Order is filled.
|
|
||||||
*
|
|
||||||
* @see <a href="https://developer.oanda.com/rest-live-v20/order-df/#OrderPositionFill">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
};
|
|
||||||
66
src/main/java/ats/orders/OrderReply.java
Normal file
66
src/main/java/ats/orders/OrderReply.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-ep/">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
public String toJSON() throws JsonProcessingException {
|
|
||||||
Map<String, Object> 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-df/#OrderPositionFill">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package ats.orders;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Order type.
|
|
||||||
*
|
|
||||||
* @see <a href="https://developer.oanda.com/rest-live-v20/order-df/#OrderType">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
public enum OrderType {
|
|
||||||
MARKET,
|
|
||||||
LIMIT,
|
|
||||||
STOP,
|
|
||||||
MARKET_IF_TOUCHED,
|
|
||||||
TAKE_PROFIT,
|
|
||||||
STOP_LOSS,
|
|
||||||
TRAILING_STOP_LOSS,
|
|
||||||
FIXED_PRICE
|
|
||||||
};
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/transaction-df/#StopLossDetails">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-df/#StopLossOrderRequest">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-df/#StopOrderRequest">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/transaction-df/#TakeProfitDetails">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-df/#MarketIfTouchedOrderRequest">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-df/#TimeInForce">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
};
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/transaction-df/#TrailingStopLossDetails">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@ -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 <a href="https://developer.oanda.com/rest-live-v20/order-df/#TrailingStopLossOrderRequest">OANDA API docs</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user