Position tracking and management operations for viewing all positions by instrument, listing open positions, retrieving position details with separate long/short side information, and closing positions.
All position operations are accessed via ctx.position where ctx is a Context instance.
Get a list of all Positions for an Account.
/**
* Get list of all Positions for Account
* @param accountID - Account identifier
* @param responseHandler - Callback receiving Response object
* Response body contains: { positions: Position[], lastTransactionID: string }
*/
list(accountID, responseHandler);Usage Example:
ctx.position.list('001-001-1234567-001', response => {
if (response.isSuccess()) {
response.body.positions.forEach(position => {
console.log(`${position.instrument}:`);
console.log(` Long: ${position.long.units} units, P/L: ${position.long.pl}`);
console.log(` Short: ${position.short.units} units, P/L: ${position.short.pl}`);
console.log(` Total Unrealized P/L: ${position.unrealizedPL}`);
});
}
});Get a list of all open Positions for an Account (positions with non-zero units).
/**
* Get list of open Positions
* @param accountID - Account identifier
* @param responseHandler - Callback receiving Response object
* Response body contains: { positions: Position[], lastTransactionID: string }
*/
listOpen(accountID, responseHandler);Usage Example:
ctx.position.listOpen('001-001-1234567-001', response => {
if (response.isSuccess()) {
const positions = response.body.positions;
console.log(`${positions.length} open positions`);
positions.forEach(position => {
const longUnits = parseFloat(position.long.units);
const shortUnits = parseFloat(position.short.units);
const netUnits = longUnits + shortUnits;
console.log(`${position.instrument}: ${netUnits} units (${netUnits > 0 ? 'LONG' : 'SHORT'})`);
console.log(` Unrealized P/L: ${position.unrealizedPL}`);
console.log(` Margin Used: ${position.marginUsed}`);
});
}
});Get the details of a single Position for a specific instrument.
/**
* Get details of specific Position
* @param accountID - Account identifier
* @param instrument - Instrument name (e.g., "EUR_USD")
* @param responseHandler - Callback receiving Response object
* Response body contains: { position: Position, lastTransactionID: string }
*/
get(accountID, instrument, responseHandler);Usage Example:
ctx.position.get('001-001-1234567-001', 'EUR_USD', response => {
if (response.isSuccess()) {
const position = response.body.position;
console.log(`Position for ${position.instrument}:`);
if (parseFloat(position.long.units) !== 0) {
console.log('Long Side:');
console.log(` Units: ${position.long.units}`);
console.log(` Average Price: ${position.long.averagePrice}`);
console.log(` Unrealized P/L: ${position.long.unrealizedPL}`);
console.log(` Trade IDs: ${position.long.tradeIDs.join(', ')}`);
}
if (parseFloat(position.short.units) !== 0) {
console.log('Short Side:');
console.log(` Units: ${position.short.units}`);
console.log(` Average Price: ${position.short.averagePrice}`);
console.log(` Unrealized P/L: ${position.short.unrealizedPL}`);
console.log(` Trade IDs: ${position.short.tradeIDs.join(', ')}`);
}
console.log(`Total Unrealized P/L: ${position.unrealizedPL}`);
console.log(`Margin Used: ${position.marginUsed}`);
}
});Close a Position by closing all open Trades for the specified instrument.
/**
* Close a Position
* @param accountID - Account identifier
* @param instrument - Instrument name (e.g., "EUR_USD")
* @param bodyParams - Body parameters object
* - longUnits: string (units to close on long side, "ALL" or "NONE", optional)
* - longClientExtensions: ClientExtensions (optional)
* - shortUnits: string (units to close on short side, "ALL" or "NONE", optional)
* - shortClientExtensions: ClientExtensions (optional)
* @param responseHandler - Callback receiving Response object
* Response body contains: {
* longOrderCreateTransaction?: MarketOrderTransaction,
* longOrderFillTransaction?: OrderFillTransaction,
* longOrderCancelTransaction?: OrderCancelTransaction,
* shortOrderCreateTransaction?: MarketOrderTransaction,
* shortOrderFillTransaction?: OrderFillTransaction,
* shortOrderCancelTransaction?: OrderCancelTransaction,
* relatedTransactionIDs: string[],
* lastTransactionID: string
* }
*/
close(accountID, instrument, bodyParams, responseHandler);Usage Example:
// Close entire position (both long and short sides)
ctx.position.close('001-001-1234567-001', 'EUR_USD', {
longUnits: 'ALL',
shortUnits: 'ALL'
}, response => {
if (response.isSuccess()) {
console.log('Position closed');
if (response.body.longOrderFillTransaction) {
const longFill = response.body.longOrderFillTransaction;
console.log(`Long side closed: ${longFill.units} units @ ${longFill.price}`);
console.log(` P/L: ${longFill.pl}`);
}
if (response.body.shortOrderFillTransaction) {
const shortFill = response.body.shortOrderFillTransaction;
console.log(`Short side closed: ${shortFill.units} units @ ${shortFill.price}`);
console.log(` P/L: ${shortFill.pl}`);
}
}
});
// Close only long side
ctx.position.close('001-001-1234567-001', 'EUR_USD', {
longUnits: 'ALL',
shortUnits: 'NONE'
}, response => {
if (response.isSuccess()) {
console.log('Long position closed');
}
});
// Close only short side with client extensions
ctx.position.close('001-001-1234567-001', 'EUR_USD', {
longUnits: 'NONE',
shortUnits: 'ALL',
shortClientExtensions: {
comment: 'Closing short position'
}
}, response => {
if (response.isSuccess()) {
console.log('Short position closed');
}
});Representation of a Position for a single instrument.
interface Position {
// Identification
instrument: string;
// Financial summary over account lifetime
pl: string; // Total realized P/L
resettablePL: string;
financing: string;
commission: string;
guaranteedExecutionFees: string;
// Current state
unrealizedPL: string;
marginUsed: string;
// Long and short sides
long: PositionSide;
short: PositionSide;
}One side (long or short) of a Position.
interface PositionSide {
// Position details
units: string; // Number of units (0 if no position on this side)
averagePrice?: string; // Volume-weighted average price (if units != 0)
// Trade references
tradeIDs: string[]; // Trade IDs contributing to this position side
// Financial summary
pl: string; // Total realized P/L for this side
unrealizedPL: string; // Current unrealized P/L
resettablePL: string;
financing: string;
guaranteedExecutionFees: string;
}Calculated price-dependent state of a Position.
interface CalculatedPositionState {
instrument: string;
netUnrealizedPL: string;
longUnrealizedPL: string;
shortUnrealizedPL: string;
marginUsed: string;
}In OANDA's v20 API, positions are tracked separately for long and short sides:
An account can have simultaneous long and short positions in the same instrument (hedging).
The net position is calculated as: long.units + short.units
When closing a position, you can:
Closing a position creates Market Orders for each side being closed, which immediately close all contributing trades on that side.