add order and order test classes

This commit is contained in:
2018-09-20 16:51:20 -07:00
parent b9cac77bcd
commit aef74dfa59
22 changed files with 2168 additions and 0 deletions

View File

@ -0,0 +1,26 @@
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;
}

View File

@ -0,0 +1,248 @@
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 OANDAs proprietary or partner trading
* platforms, their transaction history or their account
* statements. OANDA platforms always assume that an Orders
* trigger condition is set to the default value when indicating
* the distance from an Orders 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 Trades 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
* Trades 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 Trades 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 OANDAs
* proprietary or partner trading platforms, their transaction
* history or their account statements. OANDA platforms always
* assume that an Orders trigger condition is set to the default
* value when indicating the distance from an Orders 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 Trades 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 Trades 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 Trades 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;
}
}

View File

@ -0,0 +1,272 @@
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 Orders
* 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 OANDAs proprietary or partner trading
* platforms, their transaction history or their account
* statements. OANDA platforms always assume that an Orders
* trigger condition is set to the default value when indicating
* the distance from an Orders 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 Trades 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
* Trades 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 Trades 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
* Orders 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
* Orders 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 OANDAs
* proprietary or partner trading platforms, their transaction
* history or their account statements. OANDA platforms always
* assume that an Orders trigger condition is set to the default
* value when indicating the distance from an Orders 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 Trades 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 Trades 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 Trades 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;
}
}

View File

@ -0,0 +1,177 @@
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 Trades 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
* Trades 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 Trades 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 Trades 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 Trades 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 Trades 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;
}
}

View File

@ -0,0 +1,33 @@
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
};

View File

@ -0,0 +1,66 @@
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;
/**
* Base class for order requests to send to the OANDA API.
*/
public class OrderRequest {
/**
* 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;
}
/**
* Return all properties of the request. Subclasses should
* override to add their own properties to the parent class'.
*/
// public Map<String, Object> getOrderParams() {
// Map<String, Object> params = new HashMap<>();
// params.put("type", orderType.toString());
// return params;
// }
/**
* 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;
}
}

View File

@ -0,0 +1,59 @@
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 OANDAs proprietary or partner trading
* platforms, their transaction history or their account
* statements. OANDA platforms always assume that an Orders trigger
* condition is set to the default value when indicating the distance
* from an Orders 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
}

View File

@ -0,0 +1,17 @@
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
};

View File

@ -0,0 +1,57 @@
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 Trades
* 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 Trades
* 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;
}

View File

@ -0,0 +1,185 @@
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 Accounts
* current price to use as the StopLoss Order price. If the Trade
* is short the Instruments 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 OANDAs proprietary or partner trading
* platforms, their transaction history or their account
* statements. OANDA platforms always assume that an Orders
* trigger condition is set to the default value when indicating
* the distance from an Orders 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 Accounts current price to use as the Stop Loss Order
* price. If the Trade is short the Instruments 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 OANDAs
* proprietary or partner trading platforms, their transaction
* history or their account statements. OANDA platforms always
* assume that an Orders trigger condition is set to the default
* value when indicating the distance from an Orders 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;
}
}

View File

@ -0,0 +1,264 @@
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 OANDAs proprietary or partner trading
* platforms, their transaction history or their account
* statements. OANDA platforms always assume that an Orders
* trigger condition is set to the default value when indicating
* the distance from an Orders 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 Trades 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
* Trades 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 Trades 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 OANDAs
* proprietary or partner trading platforms, their transaction
* history or their account statements. OANDA platforms always
* assume that an Orders trigger condition is set to the default
* value when indicating the distance from an Orders 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 Trades 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 Trades 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 Trades 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;
}
}

View File

@ -0,0 +1,40 @@
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
* Trades 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;
}

View File

@ -0,0 +1,170 @@
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 OANDAs proprietary or partner trading
* platforms, their transaction history or their account
* statements. OANDA platforms always assume that an Orders
* trigger condition is set to the default value when indicating
* the distance from an Orders 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 OANDAs
* proprietary or partner trading platforms, their transaction
* history or their account statements. OANDA platforms always
* assume that an Orders trigger condition is set to the default
* value when indicating the distance from an Orders 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;
}
}

View File

@ -0,0 +1,35 @@
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
};

View File

@ -0,0 +1,41 @@
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 Trades 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 Trades 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;
}

View File

@ -0,0 +1,166 @@
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 OANDAs proprietary or partner trading
* platforms, their transaction history or their account
* statements. OANDA platforms always assume that an Orders
* trigger condition is set to the default value when indicating
* the distance from an Orders 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 OANDAs
* proprietary or partner trading platforms, their transaction
* history or their account statements. OANDA platforms always
* assume that an Orders trigger condition is set to the default
* value when indicating the distance from an Orders 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;
}
}

View File

@ -0,0 +1,64 @@
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);
}
}

View File

@ -0,0 +1,42 @@
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);
}
}

View File

@ -0,0 +1,53 @@
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);
}
}

View File

@ -0,0 +1,46 @@
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);
}
}

View File

@ -0,0 +1,54 @@
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);
}
}

View File

@ -0,0 +1,53 @@
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);
}
}