✅ Getting All Open Positions and Pending Orders
Request: retrieve complete information about all currently open positions and pending orders. Returns detailed data including prices, volumes, profits, timestamps, and more.
API Information:
- SDK wrapper:
MT5Account.openedOrders(...) (from package io.metarpc.mt5)
- gRPC service:
mt5_term_api.AccountHelper
- Proto definition:
OpenedOrders (defined in mt5-term-api-account-helper.proto)
RPC
- Service:
mt5_term_api.AccountHelper
- Method:
OpenedOrders(OpenedOrdersRequest) → OpenedOrdersReply
- Low‑level client (generated):
AccountHelperGrpc.AccountHelperBlockingStub.openedOrders(request)
- SDK wrapper (high-level):
package io.metarpc.mt5;
public class MT5Account {
/**
* Gets complete details for all currently open positions and pending orders.
* Returns comprehensive information including symbols, volumes, prices, profits, and timestamps.
* Use this to retrieve the full state of all active trading operations with sorting options.
*
* @param sortType Sort order for results (by symbol, open time, profit, etc.)
* @return Complete list of open positions and pending orders with all details
* @throws ApiExceptionMT5 if the call fails or connection is lost
*/
public Mt5TermApiAccountHelper.OpenedOrdersReply openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE sortType) throws ApiExceptionMT5;
}
Request message: OpenedOrdersRequest { inputSortMode: BMT5_ENUM_OPENED_ORDER_SORT_TYPE }
Reply message: OpenedOrdersReply { data: OpenedOrdersData } or { error: Error }
| Parameter |
Type |
Required |
Description |
sortType |
BMT5_ENUM_OPENED_ORDER_SORT_TYPE |
✅ |
Sort order for results (see enum below) |
⬆️ Output - OpenedOrdersData
| Field |
Type |
Description |
opened_orders |
List<OpenedOrderInfo> |
List of pending orders |
position_infos |
List<PositionInfo> |
List of open positions |
PositionInfo Fields
| Field |
Type |
Description |
index |
int |
Index in result array |
ticket |
long |
Unique position ticket number |
open_time |
Timestamp |
Position open time |
volume |
double |
Position volume (lots) |
price_open |
double |
Open price |
stop_loss |
double |
Stop Loss price (0 if not set) |
take_profit |
double |
Take Profit price (0 if not set) |
price_current |
double |
Current market price |
swap |
double |
Accumulated swap |
profit |
double |
Current profit/loss |
last_update_time |
Timestamp |
Last update timestamp |
type |
enum |
Position type (BUY/SELL) |
magic_number |
long |
Expert Advisor ID |
identifier |
long |
Position identifier |
reason |
enum |
Position open reason (CLIENT/MOBILE/WEB/EXPERT) |
symbol |
String |
Trading symbol |
comment |
String |
Position comment |
external_id |
String |
External system ID |
position_commission |
double |
Commission charged |
account_login |
long |
Account number |
OpenedOrderInfo Fields
| Field |
Type |
Description |
index |
int |
Index in result array |
ticket |
long |
Unique order ticket number |
price_current |
double |
Current market price |
price_open |
double |
Order price |
stop_limit |
double |
Stop Limit price (for STOP_LIMIT orders) |
stop_loss |
double |
Stop Loss price |
take_profit |
double |
Take Profit price |
volume_current |
double |
Current volume |
volume_initial |
double |
Initial volume |
magic_number |
long |
Expert Advisor ID |
reason |
int |
Order placement reason |
type |
enum |
Order type (BUY_LIMIT, SELL_STOP, etc.) |
state |
enum |
Order state |
time_expiration |
Timestamp |
Order expiration time |
time_setup |
Timestamp |
Order setup time |
time_done |
Timestamp |
Order execution/cancellation time |
type_filling |
enum |
Filling type (FOK, IOC, Return) |
type_time |
enum |
Time in force type |
position_id |
long |
Position ID |
position_by_id |
long |
Opposite position ID (for close by) |
symbol |
String |
Trading symbol |
external_id |
String |
External system ID |
comment |
String |
Order comment |
account_login |
long |
Account number |
BMT5_ENUM_OPENED_ORDER_SORT_TYPE
| Enum Value |
Value |
Description |
BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_ASC |
0 |
Sort by open time (oldest first) |
BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_DESC |
1 |
Sort by open time (newest first) |
BMT5_OPENED_ORDER_SORT_BY_ORDER_TICKET_ID_ASC |
2 |
Sort by ticket ID (ascending) |
BMT5_OPENED_ORDER_SORT_BY_ORDER_TICKET_ID_DESC |
3 |
Sort by ticket ID (descending) |
BMT5_ENUM_POSITION_TYPE
| Enum Value |
Value |
Description |
BMT5_POSITION_TYPE_BUY |
0 |
Long position |
BMT5_POSITION_TYPE_SELL |
1 |
Short position |
BMT5_ENUM_POSITION_REASON
| Enum Value |
Value |
Description |
BMT5_POSITION_REASON_CLIENT |
0 |
Opened from desktop terminal |
BMT5_POSITION_REASON_MOBILE |
1 |
Opened from mobile app |
BMT5_POSITION_REASON_WEB |
2 |
Opened from web terminal |
BMT5_POSITION_REASON_EXPERT |
3 |
Opened by Expert Advisor |
ORDER_REASON_SL |
4 |
Closed by Stop Loss |
ORDER_REASON_TP |
5 |
Closed by Take Profit |
ORDER_REASON_SO |
6 |
Closed by Stop Out (margin call) |
💬 Just the essentials
- What it is. Comprehensive RPC returning ALL open positions and pending orders with full details.
- Why you need it. Essential for portfolio monitoring, risk management, and trading decisions.
- Performance. More expensive than
positionsTotal() - fetches complete data for all positions.
- Two lists. Returns both positions (actively in market) and pending orders (not yet executed).
🎯 Purpose
Use this method when you need to:
- Display all active trades in UI/dashboard.
- Calculate total exposure and risk.
- Monitor profit/loss across all positions.
- Check for positions on specific symbols.
- Implement automated risk management.
- Close or modify existing positions.
🧩 Notes & Tips
- The method returns two separate lists: positions and pending orders.
- Use
positionsTotal() first to check if positions exist before calling this.
- Profit and swap are in account currency.
- Timestamps are protobuf
Timestamp - convert using .getSeconds() for Unix time.
- The method uses automatic reconnection via
executeWithReconnect().
- Empty lists returned if no positions/orders exist.
🔗 Usage Examples
1) Get all open positions
import io.metarpc.mt5.MT5Account;
import io.metarpc.mt5.exceptions.ApiExceptionMT5;
import mt5_term_api.Mt5TermApiAccountHelper;
public class Example {
public static void main(String[] args) {
MT5Account account = new MT5Account(12345678, "password");
try {
account.connect("demo.mt5server.com", 443, "EURUSD");
// Get all opened orders and positions
var reply = account.openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_DESC
);
var data = reply.getData();
System.out.printf("Open positions: %d%n", data.getPositionInfosCount());
System.out.printf("Pending orders: %d%n", data.getOpenedOrdersCount());
// Display positions
for (var position : data.getPositionInfosList()) {
System.out.printf("Ticket #%d: %s %.2f lots @ %.5f, P/L: %.2f%n",
position.getTicket(),
position.getSymbol(),
position.getVolume(),
position.getPriceOpen(),
position.getProfit()
);
}
} catch (ApiExceptionMT5 e) {
System.err.println("Error: " + e.getMessage());
} finally {
account.close();
}
}
}
2) Calculate total profit/loss
public class ProfitCalculator {
/**
* Calculate total P/L across all positions
*/
public static double getTotalProfit(MT5Account account) throws ApiExceptionMT5 {
var reply = account.openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_ASC
);
double totalProfit = 0.0;
double totalSwap = 0.0;
for (var position : reply.getData().getPositionInfosList()) {
totalProfit += position.getProfit();
totalSwap += position.getSwap();
}
double netProfit = totalProfit + totalSwap;
System.out.printf("Gross P/L: %.2f%n", totalProfit);
System.out.printf("Swap: %.2f%n", totalSwap);
System.out.printf("Net P/L: %.2f%n", netProfit);
return netProfit;
}
}
// Usage
double totalPL = ProfitCalculator.getTotalProfit(account);
3) Find positions by symbol
public class PositionFinder {
/**
* Find all positions for specific symbol
*/
public static java.util.List<Mt5TermApiAccountHelper.PositionInfo> findBySymbol(
MT5Account account,
String symbol) throws ApiExceptionMT5 {
var reply = account.openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_DESC
);
return reply.getData().getPositionInfosList().stream()
.filter(p -> p.getSymbol().equals(symbol))
.collect(java.util.stream.Collectors.toList());
}
}
// Usage
var eurusdPositions = PositionFinder.findBySymbol(account, "EURUSD");
System.out.printf("Found %d EURUSD positions%n", eurusdPositions.size());
for (var pos : eurusdPositions) {
String type = pos.getType() == Mt5TermApiAccountHelper.BMT5_ENUM_POSITION_TYPE.BMT5_POSITION_TYPE_BUY
? "BUY" : "SELL";
System.out.printf(" #%d %s %.2f lots, P/L: %.2f%n",
pos.getTicket(), type, pos.getVolume(), pos.getProfit());
}
4) Display positions table
public class PositionsTable {
public static void printTable(MT5Account account) throws ApiExceptionMT5 {
var reply = account.openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_DESC
);
var positions = reply.getData().getPositionInfosList();
if (positions.isEmpty()) {
System.out.println("No open positions");
return;
}
System.out.println("\n╔═══════════════════════════════════════════════════════════════════════╗");
System.out.println("║ OPEN POSITIONS ║");
System.out.println("╠═══════════════════════════════════════════════════════════════════════╣");
System.out.println("║ Ticket │ Symbol │ Type │ Volume │ Open │ Current │ P/L ║");
System.out.println("╠═══════════════════════════════════════════════════════════════════════╣");
double totalPL = 0.0;
for (var pos : positions) {
String type = pos.getType() == Mt5TermApiAccountHelper.BMT5_ENUM_POSITION_TYPE.BMT5_POSITION_TYPE_BUY
? "BUY " : "SELL";
System.out.printf("║ %-8d │ %-7s │ %s │ %6.2f │ %.5f │ %.5f │ %8.2f ║%n",
pos.getTicket(),
pos.getSymbol(),
type,
pos.getVolume(),
pos.getPriceOpen(),
pos.getPriceCurrent(),
pos.getProfit()
);
totalPL += pos.getProfit();
}
System.out.println("╠═══════════════════════════════════════════════════════════════════════╣");
System.out.printf("║ Total P/L: %54.2f ║%n", totalPL);
System.out.println("╚═══════════════════════════════════════════════════════════════════════╝");
}
}
// Usage
PositionsTable.printTable(account);
5) Check risk exposure
public class RiskCalculator {
public record RiskMetrics(
int totalPositions,
double totalVolume,
double totalProfit,
double largestLoss,
java.util.Map<String, Integer> symbolCounts
) {}
/**
* Calculate risk metrics
*/
public static RiskMetrics calculateRisk(MT5Account account) throws ApiExceptionMT5 {
var reply = account.openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_ASC
);
var positions = reply.getData().getPositionInfosList();
double totalVolume = 0.0;
double totalProfit = 0.0;
double largestLoss = 0.0;
java.util.Map<String, Integer> symbolCounts = new java.util.HashMap<>();
for (var pos : positions) {
totalVolume += pos.getVolume();
totalProfit += pos.getProfit();
if (pos.getProfit() < largestLoss) {
largestLoss = pos.getProfit();
}
symbolCounts.merge(pos.getSymbol(), 1, Integer::sum);
}
return new RiskMetrics(
positions.size(),
totalVolume,
totalProfit,
largestLoss,
symbolCounts
);
}
/**
* Print risk report
*/
public static void printRiskReport(RiskMetrics metrics) {
System.out.println("\n=== RISK ANALYSIS ===");
System.out.printf("Total positions: %d%n", metrics.totalPositions());
System.out.printf("Total volume: %.2f lots%n", metrics.totalVolume());
System.out.printf("Total P/L: %.2f%n", metrics.totalProfit());
System.out.printf("Largest loss: %.2f%n", metrics.largestLoss());
System.out.println("\nPositions by symbol:");
metrics.symbolCounts().forEach((symbol, count) ->
System.out.printf(" %s: %d position(s)%n", symbol, count)
);
}
}
// Usage
var risk = RiskCalculator.calculateRisk(account);
RiskCalculator.printRiskReport(risk);
6) Monitor positions in real-time
public class PositionMonitor {
/**
* Monitor positions and alert on changes
*/
public static void monitor(MT5Account account, int durationSeconds)
throws InterruptedException {
System.out.println("Monitoring positions...");
System.out.println("═".repeat(70));
long startTime = System.currentTimeMillis();
long endTime = startTime + (durationSeconds * 1000L);
java.util.Set<Long> lastTickets = new java.util.HashSet<>();
while (System.currentTimeMillis() < endTime) {
try {
var reply = account.openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_DESC
);
java.util.Set<Long> currentTickets = reply.getData().getPositionInfosList()
.stream()
.map(Mt5TermApiAccountHelper.PositionInfo::getTicket)
.collect(java.util.stream.Collectors.toSet());
// Check for new positions
for (long ticket : currentTickets) {
if (!lastTickets.contains(ticket)) {
System.out.printf("[%s] 🆕 New position opened: #%d%n",
java.time.LocalTime.now(), ticket);
}
}
// Check for closed positions
for (long ticket : lastTickets) {
if (!currentTickets.contains(ticket)) {
System.out.printf("[%s] ❌ Position closed: #%d%n",
java.time.LocalTime.now(), ticket);
}
}
lastTickets = currentTickets;
Thread.sleep(2000);
} catch (ApiExceptionMT5 e) {
System.err.println("Error: " + e.getMessage());
Thread.sleep(2000);
}
}
System.out.println("═".repeat(70));
System.out.println("Monitoring stopped");
}
}
// Usage
PositionMonitor.monitor(account, 60);
7) Export positions to CSV
public class PositionExporter {
/**
* Export all positions to CSV file
*/
public static void exportToCSV(MT5Account account, String filename)
throws Exception {
var reply = account.openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_ASC
);
try (java.io.PrintWriter writer = new java.io.PrintWriter(filename)) {
// CSV header
writer.println("Ticket,Symbol,Type,Volume,OpenPrice,CurrentPrice,StopLoss,TakeProfit,Profit,Swap,OpenTime,Comment");
for (var pos : reply.getData().getPositionInfosList()) {
String type = pos.getType() == Mt5TermApiAccountHelper.BMT5_ENUM_POSITION_TYPE.BMT5_POSITION_TYPE_BUY
? "BUY" : "SELL";
long openTimeSec = pos.getOpenTime().getSeconds();
String openTime = java.time.Instant.ofEpochSecond(openTimeSec).toString();
writer.printf("%d,%s,%s,%.2f,%.5f,%.5f,%.5f,%.5f,%.2f,%.2f,%s,\"%s\"%n",
pos.getTicket(),
pos.getSymbol(),
type,
pos.getVolume(),
pos.getPriceOpen(),
pos.getPriceCurrent(),
pos.getStopLoss(),
pos.getTakeProfit(),
pos.getProfit(),
pos.getSwap(),
openTime,
pos.getComment()
);
}
}
System.out.printf("✅ Exported %d positions to %s%n",
reply.getData().getPositionInfosCount(), filename);
}
}
// Usage
PositionExporter.exportToCSV(account, "positions.csv");
8) Find positions without stop loss
public class StopLossChecker {
/**
* Find positions without stop loss
*/
public static void findUnprotectedPositions(MT5Account account)
throws ApiExceptionMT5 {
var reply = account.openedOrders(
Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_DESC
);
var unprotected = reply.getData().getPositionInfosList().stream()
.filter(p -> p.getStopLoss() == 0.0)
.collect(java.util.stream.Collectors.toList());
if (unprotected.isEmpty()) {
System.out.println("✅ All positions have stop loss");
return;
}
System.out.printf("⚠️ Found %d positions WITHOUT stop loss:%n", unprotected.size());
for (var pos : unprotected) {
String type = pos.getType() == Mt5TermApiAccountHelper.BMT5_ENUM_POSITION_TYPE.BMT5_POSITION_TYPE_BUY
? "BUY" : "SELL";
System.out.printf(" #%d %s %s %.2f lots @ %.5f (P/L: %.2f)%n",
pos.getTicket(),
pos.getSymbol(),
type,
pos.getVolume(),
pos.getPriceOpen(),
pos.getProfit()
);
}
}
}
// Usage
StopLossChecker.findUnprotectedPositions(account);
🔄 Low-level gRPC call (for reference)
import io.grpc.*;
import mt5_term_api.*;
// Create request
Mt5TermApiAccountHelper.OpenedOrdersRequest request =
Mt5TermApiAccountHelper.OpenedOrdersRequest.newBuilder()
.setInputSortMode(Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE
.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_DESC)
.build();
// Add metadata headers
Metadata headers = new Metadata();
Metadata.Key<String> idKey = Metadata.Key.of("id", Metadata.ASCII_STRING_MARSHALLER);
headers.put(idKey, instanceId.toString());
// Call service
Mt5TermApiAccountHelper.OpenedOrdersReply reply = accountClient
.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers))
.openedOrders(request);
// Check for errors
if (reply.hasError()) {
throw new ApiExceptionMT5(reply.getError());
}
// Use data
var data = reply.getData();
var positions = data.getPositionInfosList();
var orders = data.getOpenedOrdersList();