JavaScript bindings for OANDA's v20 REST API enabling programmatic forex and CFD trading operations.
Operations for managing open trades including listing all trades, retrieving trade details, closing trades partially or fully, updating client extensions, and managing dependent orders (take-profit, stop-loss, trailing-stop-loss).
All trade operations are accessed via ctx.trade where ctx is a Context instance.
Get a list of Trades for an Account.
/**
* Get list of Trades for Account
* @param accountID - Account identifier
* @param queryParams - Query parameters object
* - ids: string (comma-separated list of Trade IDs, optional)
* - state: string (trade state filter: OPEN, CLOSED, CLOSE_WHEN_TRADEABLE, ALL, optional)
* - instrument: string (instrument filter, optional)
* - count: number (maximum trades to return, optional, default 50)
* - beforeID: string (trades before this ID, optional)
* @param responseHandler - Callback receiving Response object
* Response body contains: { trades: Trade[], lastTransactionID: string }
*/
list(accountID, queryParams, responseHandler);Usage Example:
// List all trades
ctx.trade.list('001-001-1234567-001', {}, response => {
if (response.isSuccess()) {
response.body.trades.forEach(trade => {
console.log(`Trade ${trade.id}: ${trade.instrument} ${trade.currentUnits} units`);
console.log(` Unrealized P/L: ${trade.unrealizedPL}`);
});
}
});
// List open trades for EUR_USD
ctx.trade.list('001-001-1234567-001', {
state: 'OPEN',
instrument: 'EUR_USD'
}, response => {
if (response.isSuccess()) {
console.log('Open EUR_USD trades:', response.body.trades);
}
});Get a list of all open Trades for an Account.
/**
* Get list of open Trades
* @param accountID - Account identifier
* @param responseHandler - Callback receiving Response object
* Response body contains: { trades: Trade[], lastTransactionID: string }
*/
listOpen(accountID, responseHandler);Usage Example:
ctx.trade.listOpen('001-001-1234567-001', response => {
if (response.isSuccess()) {
const trades = response.body.trades;
console.log(`${trades.length} open trades`);
trades.forEach(trade => {
console.log(`${trade.instrument}: ${trade.currentUnits} units @ ${trade.price}`);
console.log(` Unrealized P/L: ${trade.unrealizedPL}`);
if (trade.stopLossOrder) {
console.log(` Stop Loss: ${trade.stopLossOrder.price}`);
}
if (trade.takeProfitOrder) {
console.log(` Take Profit: ${trade.takeProfitOrder.price}`);
}
});
}
});Get the details of a specific Trade.
/**
* Get details of specific Trade
* @param accountID - Account identifier
* @param tradeSpecifier - Trade ID or client Trade ID
* @param responseHandler - Callback receiving Response object
* Response body contains: { trade: Trade, lastTransactionID: string }
*/
get(accountID, tradeSpecifier, responseHandler);Usage Example:
ctx.trade.get('001-001-1234567-001', '5678', response => {
if (response.isSuccess()) {
const trade = response.body.trade;
console.log(`Trade ${trade.id}:`);
console.log(` Instrument: ${trade.instrument}`);
console.log(` Current Units: ${trade.currentUnits}`);
console.log(` Open Price: ${trade.price}`);
console.log(` Open Time: ${trade.openTime}`);
console.log(` Unrealized P/L: ${trade.unrealizedPL}`);
console.log(` Realized P/L: ${trade.realizedPL}`);
console.log(` Margin Used: ${trade.marginUsed}`);
}
});Close (partially or fully) a specific open Trade.
/**
* Close a Trade
* @param accountID - Account identifier
* @param tradeSpecifier - Trade ID or client Trade ID
* @param bodyParams - Body parameters object
* - units: string (portion to close, or "ALL" for full close, optional, default "ALL")
* @param responseHandler - Callback receiving Response object
* Response body contains: {
* orderCreateTransaction: MarketOrderTransaction,
* orderFillTransaction: OrderFillTransaction,
* orderCancelTransaction?: OrderCancelTransaction,
* relatedTransactionIDs: string[],
* lastTransactionID: string
* }
*/
close(accountID, tradeSpecifier, bodyParams, responseHandler);Usage Example:
// Close entire trade
ctx.trade.close('001-001-1234567-001', '5678', {
units: 'ALL'
}, response => {
if (response.isSuccess()) {
const fill = response.body.orderFillTransaction;
console.log('Trade closed');
console.log(` Price: ${fill.price}`);
console.log(` P/L: ${fill.pl}`);
}
});
// Close partial position (50 units)
ctx.trade.close('001-001-1234567-001', '5678', {
units: '50'
}, response => {
if (response.isSuccess()) {
console.log('Partial close executed');
console.log('Fill:', response.body.orderFillTransaction);
}
});Update the client extensions for a Trade.
/**
* Update client extensions for Trade
* @param accountID - Account identifier
* @param tradeSpecifier - Trade ID or client Trade ID
* @param bodyParams - Body parameters object
* - clientExtensions: ClientExtensions (required)
* @param responseHandler - Callback receiving Response object
* Response body contains: {
* tradeClientExtensionsModifyTransaction: TradeClientExtensionsModifyTransaction,
* relatedTransactionIDs: string[],
* lastTransactionID: string
* }
*/
setClientExtensions(accountID, tradeSpecifier, bodyParams, responseHandler);Usage Example:
ctx.trade.setClientExtensions('001-001-1234567-001', '5678', {
clientExtensions: {
id: 'my-trade-123',
tag: 'breakout-long',
comment: 'EUR/USD breakout entry'
}
}, response => {
if (response.isSuccess()) {
console.log('Client extensions updated');
}
});Create, replace, or cancel dependent orders for a Trade (take-profit, stop-loss, trailing-stop-loss).
/**
* Create/modify/cancel dependent orders for Trade
* @param accountID - Account identifier
* @param tradeSpecifier - Trade ID or client Trade ID
* @param bodyParams - Body parameters object
* - takeProfit: TakeProfitDetails (optional - to create/modify take profit)
* - stopLoss: StopLossDetails (optional - to create/modify stop loss)
* - trailingStopLoss: TrailingStopLossDetails (optional - to create/modify trailing stop loss)
* To cancel a dependent order, omit it from the request or set to null
* @param responseHandler - Callback receiving Response object
* Response body contains transaction details for created/cancelled dependent orders
*/
setDependentOrders(accountID, tradeSpecifier, bodyParams, responseHandler);Usage Example:
// Add stop loss and take profit to a trade
ctx.trade.setDependentOrders('001-001-1234567-001', '5678', {
stopLoss: {
price: '1.0950',
timeInForce: 'GTC'
},
takeProfit: {
price: '1.1150',
timeInForce: 'GTC'
}
}, response => {
if (response.isSuccess()) {
console.log('Dependent orders created');
if (response.body.stopLossOrderTransaction) {
console.log('Stop Loss:', response.body.stopLossOrderTransaction);
}
if (response.body.takeProfitOrderTransaction) {
console.log('Take Profit:', response.body.takeProfitOrderTransaction);
}
}
});
// Add trailing stop loss
ctx.trade.setDependentOrders('001-001-1234567-001', '5678', {
trailingStopLoss: {
distance: '0.0050', // 50 pips
timeInForce: 'GTC'
}
}, response => {
if (response.isSuccess()) {
console.log('Trailing stop loss created');
}
});
// Update stop loss (replace existing)
ctx.trade.setDependentOrders('001-001-1234567-001', '5678', {
stopLoss: {
price: '1.0975', // New stop loss price
timeInForce: 'GTC'
}
}, response => {
if (response.isSuccess()) {
console.log('Stop loss updated');
}
});Full representation of a Trade.
interface Trade {
// Identification
id: string;
instrument: string;
clientExtensions?: ClientExtensions;
// Opening details
price: string;
openTime: string;
initialUnits: string;
initialMarginRequired: string;
// Current state
state: string; // OPEN, CLOSED, CLOSE_WHEN_TRADEABLE
currentUnits: string;
// Financial summary
realizedPL: string;
unrealizedPL: string;
marginUsed: string;
financing: string;
// Closing details (if closed)
averageClosePrice?: string;
closingTransactionIDs?: string[];
closeTime?: string;
// Dependent orders
takeProfitOrder?: TakeProfitOrder;
stopLossOrder?: StopLossOrder;
trailingStopLossOrder?: TrailingStopLossOrder;
}Summary of a Trade (subset of full Trade without dependent orders).
interface TradeSummary {
id: string;
instrument: string;
price: string;
openTime: string;
state: string;
initialUnits: string;
initialMarginRequired: string;
currentUnits: string;
realizedPL: string;
unrealizedPL: string;
marginUsed: string;
averageClosePrice?: string;
closingTransactionIDs?: string[];
financing: string;
closeTime?: string;
clientExtensions?: ClientExtensions;
}Calculated price-dependent state of a Trade.
interface CalculatedTradeState {
id: string;
unrealizedPL: string;
marginUsed: string;
}Dependent orders that can be attached to trades:
interface TakeProfitOrder {
id: string;
type: 'TAKE_PROFIT';
tradeID: string;
clientTradeID?: string;
price: string;
timeInForce: string;
gtdTime?: string;
triggerCondition: string;
state: string;
createTime: string;
clientExtensions?: ClientExtensions;
fillingTransactionID?: string;
filledTime?: string;
cancellingTransactionID?: string;
cancelledTime?: string;
replacesOrderID?: string;
replacedByOrderID?: string;
}
interface StopLossOrder {
id: string;
type: 'STOP_LOSS';
tradeID: string;
clientTradeID?: string;
price?: string;
distance?: string;
timeInForce: string;
gtdTime?: string;
triggerCondition: string;
guaranteed?: boolean;
state: string;
createTime: string;
clientExtensions?: ClientExtensions;
fillingTransactionID?: string;
filledTime?: string;
cancellingTransactionID?: string;
cancelledTime?: string;
replacesOrderID?: string;
replacedByOrderID?: string;
}
interface TrailingStopLossOrder {
id: string;
type: 'TRAILING_STOP_LOSS';
tradeID: string;
clientTradeID?: string;
distance: string;
timeInForce: string;
gtdTime?: string;
triggerCondition: string;
trailingStopValue?: string;
state: string;
createTime: string;
clientExtensions?: ClientExtensions;
fillingTransactionID?: string;
filledTime?: string;
cancellingTransactionID?: string;
cancelledTime?: string;
replacesOrderID?: string;
replacedByOrderID?: string;
}Details for creating dependent orders:
interface TakeProfitDetails {
price: string;
timeInForce?: string; // GTC, GTD, GFD
gtdTime?: string;
clientExtensions?: ClientExtensions;
}
interface StopLossDetails {
price?: string; // Either price or distance must be specified
distance?: string;
timeInForce?: string;
gtdTime?: string;
clientExtensions?: ClientExtensions;
guaranteed?: boolean;
}
interface TrailingStopLossDetails {
distance: string; // Trailing distance from current price
timeInForce?: string;
gtdTime?: string;
clientExtensions?: ClientExtensions;
}Details about trade opening and closing:
interface TradeOpen {
tradeID: string;
units: string;
price: string;
guaranteedExecutionFee?: string;
clientExtensions?: ClientExtensions;
halfSpreadCost: string;
initialMarginRequired: string;
}
interface TradeReduce {
tradeID: string;
units: string;
price: string;
realizedPL: string;
financing: string;
guaranteedExecutionFee?: string;
halfSpreadCost: string;
}Install with Tessl CLI
npx tessl i tessl/npm-oanda--v20