Skip to content

✅ Getting Total Number of Open Positions

Request: retrieve the count of currently open positions on the account. Returns a simple integer count without position details.

API Information:

  • SDK wrapper: MT5Account.positionsTotal() (from package io.metarpc.mt5)
  • gRPC service: mt5_term_api.TradeFunctions
  • Proto definition: PositionsTotal (defined in mt5-term-api-trade-functions.proto)

RPC

  • Service: mt5_term_api.TradeFunctions
  • Method: PositionsTotal(Empty) → PositionsTotalReply
  • Low‑level client (generated): TradeFunctionsGrpc.TradeFunctionsBlockingStub.positionsTotal(Empty)
  • SDK wrapper (high-level):
package io.metarpc.mt5;

public class MT5Account {
    /**
     * Gets the total count of currently open positions on the account.
     * Returns a simple count of all active positions regardless of symbol.
     * Use this for quick checks of position count before retrieving detailed position information.
     *
     * @return Total number of open positions
     * @throws ApiExceptionMT5 if the call fails or connection is lost
     */
    public Mt5TermApiTradeFunctions.PositionsTotalReply positionsTotal() throws ApiExceptionMT5;
}

Request message: Empty {} (no parameters)

Reply message: PositionsTotalReply { data: PositionsTotalData } or { error: Error }


🔽 Input

No parameters required. The method automatically uses connection metadata (instance ID).


⬆️ Output - PositionsTotalData

Field Type Description
total int Total number of currently open positions

Access the count using reply.getData().getTotal().


💬 Just the essentials

  • What it is. Simple RPC returning the count of open positions.
  • Why you need it. Quick check before fetching full position details, monitoring position count limits.
  • Performance. Very lightweight - just returns a count, no position data.
  • Use case. Often used with openedOrders() to iterate through positions.

🎯 Purpose

Use this method when you need to:

  • Check if there are any open positions before querying details.
  • Monitor position count for risk management.
  • Verify positions were closed successfully.
  • Check against broker position limits.
  • Display position count in UI dashboards.

🧩 Notes & Tips

  • Returns only open positions, not pending orders (use openedOrders() for both).
  • Count includes positions on all symbols.
  • The method uses automatic reconnection via executeWithReconnect().
  • If count is 0, calling openedOrders() will return empty list.
  • Does not count historical/closed positions.

🔗 Usage Examples

1) Basic position count

import io.metarpc.mt5.MT5Account;
import io.metarpc.mt5.exceptions.ApiExceptionMT5;
import mt5_term_api.Mt5TermApiTradeFunctions;

public class Example {
    public static void main(String[] args) {
        MT5Account account = new MT5Account(12345678, "password");

        try {
            account.connect("demo.mt5server.com", 443, "EURUSD");

            // Get position count
            Mt5TermApiTradeFunctions.PositionsTotalReply reply = account.positionsTotal();
            int total = reply.getData().getTotal();

            System.out.printf("Open positions: %d%n", total);

        } catch (ApiExceptionMT5 e) {
            System.err.println("Error: " + e.getMessage());
        } finally {
            account.close();
        }
    }
}

2) Check if any positions exist

// Quick check before querying details
var reply = account.positionsTotal();
int count = reply.getData().getTotal();

if (count == 0) {
    System.out.println("No open positions");
} else {
    System.out.printf("Found %d open positions%n", count);
    // Now fetch details
    var ordersReply = account.openedOrders(
        Mt5TermApiAccountHelper.BMT5_ENUM_OPENED_ORDER_SORT_TYPE.BMT5_OPENED_ORDER_SORT_BY_OPEN_TIME_DESC
    );
    // Process positions...
}

3) Wait for all positions to close

public class PositionWaiter {
    /**
     * Wait for all positions to close (with timeout)
     */
    public static boolean waitForAllClosed(
            MT5Account account,
            int timeoutSeconds) throws InterruptedException {

        System.out.println("Waiting for all positions to close...");

        long startTime = System.currentTimeMillis();
        long timeoutMillis = timeoutSeconds * 1000L;

        while (System.currentTimeMillis() - startTime < timeoutMillis) {
            try {
                var reply = account.positionsTotal();
                int count = reply.getData().getTotal();

                if (count == 0) {
                    System.out.println("✅ All positions closed");
                    return true;
                }

                System.out.printf("⏳ Waiting... (%d positions still open)%n", count);
                Thread.sleep(1000);

            } catch (ApiExceptionMT5 e) {
                System.err.println("Error: " + e.getMessage());
                Thread.sleep(1000);
            }
        }

        System.out.println("⚠️ Timeout - positions still open");
        return false;
    }
}

// Usage
if (PositionWaiter.waitForAllClosed(account, 30)) {
    System.out.println("Safe to disconnect");
}

4) Monitor position count

public class PositionMonitor {
    /**
     * Monitor position count in real-time
     */
    public static void monitor(MT5Account account, int durationSeconds)
            throws InterruptedException {

        System.out.printf("Monitoring positions for %d seconds...%n", durationSeconds);
        System.out.println("═".repeat(50));

        long startTime = System.currentTimeMillis();
        long endTime = startTime + (durationSeconds * 1000L);

        int lastCount = -1;

        while (System.currentTimeMillis() < endTime) {
            try {
                var reply = account.positionsTotal();
                int count = reply.getData().getTotal();

                if (count != lastCount) {
                    System.out.printf("[%s] Position count: %d%n",
                        java.time.LocalTime.now(),
                        count);
                    lastCount = count;
                }

                Thread.sleep(1000);

            } catch (ApiExceptionMT5 e) {
                System.err.println("Error: " + e.getMessage());
                Thread.sleep(1000);
            }
        }

        System.out.println("═".repeat(50));
        System.out.printf("Final count: %d%n", lastCount);
    }
}

// Usage
PositionMonitor.monitor(account, 60);

5) Check position limit

public class PositionLimitChecker {
    /**
     * Check if opening new position would exceed limit
     */
    public static boolean canOpenPosition(
            MT5Account account,
            int maxPositions) throws ApiExceptionMT5 {

        var reply = account.positionsTotal();
        int current = reply.getData().getTotal();

        boolean allowed = current < maxPositions;

        System.out.printf("Positions: %d/%d%n", current, maxPositions);

        if (!allowed) {
            System.out.println("⚠️ Position limit reached");
        } else {
            System.out.printf("✅ Can open %d more positions%n", maxPositions - current);
        }

        return allowed;
    }
}

// Usage - check against broker limit or personal limit
if (PositionLimitChecker.canOpenPosition(account, 10)) {
    // Safe to open new position
    System.out.println("Opening new position...");
}

6) Dashboard status display

public class TradingDashboard {
    public static void displayStatus(MT5Account account) {
        try {
            // Get position count
            var posReply = account.positionsTotal();
            int positions = posReply.getData().getTotal();

            // Get account summary
            var accReply = account.accountSummary();
            var accData = accReply.getData();

            System.out.println("╔═══════════════════════════════════════╗");
            System.out.println("║       TRADING DASHBOARD               ║");
            System.out.println("╠═══════════════════════════════════════╣");
            System.out.printf("║ Account:       %-22d ║%n", accData.getAccountLogin());
            System.out.printf("║ Balance:       %-15.2f %s    ║%n",
                accData.getAccountBalance(),
                accData.getAccountCurrency());
            System.out.printf("║ Equity:        %-15.2f %s    ║%n",
                accData.getAccountEquity(),
                accData.getAccountCurrency());
            System.out.printf("║ Open Positions: %-21d ║%n", positions);

            String status = positions == 0 ? "No active trades" :
                           positions == 1 ? "1 active trade" :
                           positions + " active trades";
            System.out.printf("║ Status:        %-22s ║%n", status);
            System.out.println("╚═══════════════════════════════════════╝");

        } catch (ApiExceptionMT5 e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

// Usage
TradingDashboard.displayStatus(account);

7) Compare position count over time

public class PositionTracker {
    public record PositionSnapshot(
        java.time.Instant timestamp,
        int count
    ) {}

    private final java.util.List<PositionSnapshot> snapshots = new java.util.ArrayList<>();

    /**
     * Take a snapshot of current position count
     */
    public void takeSnapshot(MT5Account account) throws ApiExceptionMT5 {
        var reply = account.positionsTotal();
        int count = reply.getData().getTotal();

        snapshots.add(new PositionSnapshot(
            java.time.Instant.now(),
            count
        ));
    }

    /**
     * Print position history
     */
    public void printHistory() {
        System.out.println("\n=== Position Count History ===");
        for (var snapshot : snapshots) {
            System.out.printf("[%s] %d positions%n",
                snapshot.timestamp(),
                snapshot.count());
        }

        if (snapshots.size() >= 2) {
            int first = snapshots.get(0).count();
            int last = snapshots.get(snapshots.size() - 1).count();
            int change = last - first;

            System.out.printf("%nChange: %+d positions%n", change);
        }
    }
}

// Usage
var tracker = new PositionTracker();

for (int i = 0; i < 5; i++) {
    tracker.takeSnapshot(account);
    Thread.sleep(5000);
}

tracker.printHistory();

8) Position count alert

public class PositionAlertSystem {
    /**
     * Alert when position count reaches threshold
     */
    public static void monitorWithAlert(
            MT5Account account,
            int warningThreshold,
            int durationSeconds) throws InterruptedException {

        System.out.printf("Monitoring positions (alert at %d)...%n", warningThreshold);

        long startTime = System.currentTimeMillis();
        long endTime = startTime + (durationSeconds * 1000L);

        boolean alerted = false;

        while (System.currentTimeMillis() < endTime) {
            try {
                var reply = account.positionsTotal();
                int count = reply.getData().getTotal();

                if (count >= warningThreshold && !alerted) {
                    System.out.printf("🚨 ALERT: %d positions (threshold: %d)%n",
                        count, warningThreshold);
                    alerted = true;
                } else if (count < warningThreshold && alerted) {
                    System.out.printf("✅ Position count back to normal: %d%n", count);
                    alerted = false;
                }

                Thread.sleep(2000);

            } catch (ApiExceptionMT5 e) {
                System.err.println("Error: " + e.getMessage());
                Thread.sleep(2000);
            }
        }
    }
}

// Usage - alert if 5 or more positions open
PositionAlertSystem.monitorWithAlert(account, 5, 60);

9) Pre-trade validation

public class TradeValidator {
    /**
     * Validate trading conditions before opening position
     */
    public static boolean validateBeforeTrade(
            MT5Account account,
            int maxPositions,
            double maxMarginUsage) throws ApiExceptionMT5 {

        System.out.println("Validating trading conditions...");

        // Check position count
        var posReply = account.positionsTotal();
        int positions = posReply.getData().getTotal();

        if (positions >= maxPositions) {
            System.out.printf("❌ Too many positions: %d/%d%n", positions, maxPositions);
            return false;
        }
        System.out.printf("✅ Position count OK: %d/%d%n", positions, maxPositions);

        // Check margin level
        var marginReply = account.accountInfoDouble(
            Mt5TermApiAccountInformation.AccountInfoDoublePropertyType.ACCOUNT_MARGIN_LEVEL
        );
        double marginLevel = marginReply.getData().getRequestedValue();

        if (marginLevel < maxMarginUsage) {
            System.out.printf("❌ Insufficient margin: %.2f%% < %.2f%%%n",
                marginLevel, maxMarginUsage);
            return false;
        }
        System.out.printf("✅ Margin level OK: %.2f%%%n", marginLevel);

        System.out.println("✅ All checks passed - ready to trade");
        return true;
    }
}

// Usage
if (TradeValidator.validateBeforeTrade(account, 5, 200.0)) {
    // Place order
    System.out.println("Placing order...");
}

🔄 Low-level gRPC call (for reference)

import io.grpc.*;
import mt5_term_api.*;
import com.google.protobuf.Empty;

// Create request (empty)
Empty request = Empty.newBuilder().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
Mt5TermApiTradeFunctions.PositionsTotalReply reply = tradeFunctionsClient
    .withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers))
    .positionsTotal(request);

// Check for errors
if (reply.hasError()) {
    throw new ApiExceptionMT5(reply.getError());
}

// Use data
int total = reply.getData().getTotal();