Skip to content

MT5Sugar - Complete API ReferenceΒΆ

High-level convenience methods for MetaTrader 5 trading automation in Go

MT5Sugar wraps MT5Service (and the underlying MT5Account) with convenient methods for:

  • 🎯 Risk-based position sizing (percentage risk, SL/TP as point distances)
  • πŸ“Š Symbol information (digits, point, volume limits, stop level)
  • πŸ”„ Bulk operations (close all positions, manage multiple trades)
  • πŸ“ˆ Historical analysis and statistics
  • βœ… Pre-trade validation and margin checking
  • πŸ“‰ Real-time P&L monitoring and position tracking
  • πŸ”Œ Simplified connection management

Note: The order methods (BuyMarket, BuyLimitWithSLTP, ModifyPositionSLTP, ...) send volumes and prices exactly as given (no rounding to Digits / VolumeStep). The helpers do round: CalculateSLTP and Buy/SellMarketWithPips round SL/TP prices to the symbol's Digits; CalculatePositionSize and GetMaxLotSize round the volume down to VolumeStep.


[01] πŸ”Œ CONNECTION MANAGEMENTΒΆ

Connect to MT5 terminal and check connection status

Method Description Documentation
QuickConnect() Connect using cluster name (RECOMMENDED); the server waits up to 120 s for the terminal to start and log in, the call has a 130 s deadline β†’ Docs
IsConnected() Check if connected to MT5 β†’ Docs
Ping() Verify connection is alive β†’ Docs

Helper methods:

  • GetService() - access underlying MT5Service
  • GetAccount() - access underlying MT5Account
  • Disconnect(deleteOnDisconnect ...bool) - stops the terminal on the server (true = deletes it instead; the server gets up to 30 s), returns the disconnect error (Disconnect failed: ...), then closes the gRPC connection; a second call is a no-op. Always call it when done - also when QuickConnect failed (the server may already have started the terminal), or the terminal keeps running on the server

[02] πŸ“Š SYMBOL OPERATIONSΒΆ

Working with symbols, prices, and market data

Method Description Documentation
GetBid() Current bid price for symbol β†’ Docs
GetAsk() Current ask price for symbol β†’ Docs
GetSpread() Current spread in points β†’ Docs
GetPriceInfo() Complete price snapshot (bid, ask, spread, time) β†’ Docs
WaitForPrice() Wait for valid price with timeout β†’ Docs

Data structures:

  • PriceInfo - complete price data structure (Time = broker server time, TimeUtc = the same moment in UTC; SpreadPips is in points despite its name: (Ask - Bid) / SYMBOL_POINT)

[03] πŸ’Ό POSITION MANAGEMENTΒΆ

Manage existing positions (modify, close, track)

Method Description Documentation
ClosePosition() Close position completely by ticket β†’ Docs
ClosePositionPartial() Partial close with volume β†’ Docs
CloseAllPositions() Close ALL open positions (pending orders untouched); returns the closed count and an error naming every position that was not closed β†’ Docs
ModifyPositionSLTP() Modify both SL and TP β†’ Docs

Also available (no separate page): CloseAllBySymbol(symbol) - close all positions of one symbol, ModifyPositionSL(ticket, sl), ModifyPositionTP(ticket, tp).


[04] πŸ’Ή TRADING OPERATIONSΒΆ

Place market and pending orders

Market Orders (Instant Execution)ΒΆ

Method Description Documentation
BuyMarket() Simple BUY at market price β†’ Docs
SellMarket() Simple SELL at market price β†’ Docs
BuyMarketWithSLTP() BUY with SL/TP prices β†’ Docs
SellMarketWithSLTP() SELL with SL/TP prices β†’ Docs

Pending Orders (Limit/Stop)ΒΆ

Method Description Documentation
BuyLimit() Buy Limit (buy below current price) β†’ Docs
SellLimit() Sell Limit (sell above current price) β†’ Docs
BuyStop() Buy Stop (buy above current price) β†’ Docs
SellStop() Sell Stop (sell below current price) β†’ Docs
BuyLimitWithSLTP() Buy Limit with SL/TP β†’ Docs
SellLimitWithSLTP() Sell Limit with SL/TP β†’ Docs

[05] 🏦 ACCOUNT INFORMATION¢

Quick access to account balance and margin metrics

Method Description Documentation
GetBalance() Account balance (realized profit only) β†’ Docs
GetEquity() Current equity (balance + floating P/L) β†’ Docs
GetMargin() Used margin β†’ Docs
GetFreeMargin() Available margin for new positions β†’ Docs
GetMarginLevel() Margin level % (Equity/Margin Γ— 100) β†’ Docs
GetProfit() Total floating profit/loss β†’ Docs

[06] πŸ“ POSITION INFORMATIONΒΆ

Query and analyze open positions

Method Description Documentation
GetOpenPositions() Get ALL open positions β†’ Docs
GetPositionByTicket() Get specific position by ticket β†’ Docs
GetPositionsBySymbol() Get positions for specific symbol β†’ Docs
HasOpenPosition() Check if symbol has open positions β†’ Docs
CountOpenPositions() Total number of open positions β†’ Docs

Also available (no separate page): GetTotalProfit() - floating P/L of all open positions, GetProfitBySymbol(symbol) - floating P/L of one symbol.


[07] πŸ“œ HISTORY & STATISTICSΒΆ

Retrieve trading history and performance analytics

Method Description Documentation
GetDealsToday() Closed positions opened today (local midnight to now) β†’ Docs
GetDealsYesterday() Closed positions opened yesterday (whole previous local day) β†’ Docs
GetDealsThisWeek() Closed positions opened this week (local Monday 00:00 to now) β†’ Docs
GetDealsThisMonth() Closed positions opened this month (the 1st, 00:00 local, to now) β†’ Docs
GetDealsDateRange() Closed positions opened in a custom range (real moments, sent as UTC) β†’ Docs
GetProfitToday() Sum of Profit of today's closed positions (no commission/swap/fee) β†’ Docs
GetProfitThisWeek() Sum of Profit of this week's closed positions β†’ Docs
GetProfitThisMonth() Sum of Profit of this month's closed positions β†’ Docs

"Deals" here are closed positions from PositionsHistory (one entry per closed position; a position closed in parts has one entry per partial close), selected by their open time: a position opened yesterday and closed today is not in GetDealsToday(). The day/week/month boundaries are the local calendar of the computer running the program, sent to the server in the request's UTC fields, so the broker's time zone does not shift them. All pages are read (cursor paging, 1000 per page), so long ranges are complete. Timeouts (for all pages together): 15 s for today/yesterday/week (and GetDailyStats), 30 s for month and custom range.


[08] πŸ” SYMBOL INFORMATIONΒΆ

Symbol properties and trading conditions

Method Description Documentation
GetSymbolInfo() Complete symbol information (exact name match; 10 s) β†’ Docs
GetAllSymbols() List of all available symbols (reads all pages of 1000; 60 s) β†’ Docs
IsSymbolAvailable() Check if symbol exists and is synchronized (trade mode and sessions not checked) β†’ Docs
GetMinStopLevel() Minimum distance for SL/TP in points β†’ Docs
GetSymbolDigits() Decimal precision for symbol β†’ Docs

Data structures:

  • SymbolInfo - complete symbol data structure

[09] βš–οΈ RISK MANAGEMENTΒΆ

Position sizing, margin calculations, and pre-trade validation

Method Description Documentation
CalculatePositionSize() PRIMARY METHOD - auto-calculate lot size by risk % (SL distance in points; point value from the tick value, in the account currency); a size below the minimum volume is an error, never raised to it β†’ Docs
GetMaxLotSize() Maximum tradeable volume based on free margin (error if not even the minimum lot fits) β†’ Docs
CanOpenPosition() Comprehensive validation before trading β†’ Docs
CalculateRequiredMargin() Margin needed for specific position size β†’ Docs

The margin in all four methods is calculated for a BUY at the current ASK (they have no direction parameter; a SELL's margin may differ slightly).

Example:

// Auto-calculate lot size to risk 2% with a 500-point SL (= 50 pips on 5-digit EURUSD)
lotSize, _ := sugar.CalculatePositionSize("EURUSD", 2.0, 500)


[10] 🎯 TRADING HELPERS¢

Distance-based trading - SL/TP as distances in POINTS (despite the ...Pips names)

Method Description Documentation
CalculateSLTP() Convert point distances to SL/TP prices β†’ Docs
BuyMarketWithPips() MOST USED - BUY with SL/TP as point distances ⭐ β†’ Docs
SellMarketWithPips() MOST USED - SELL with SL/TP as point distances ⭐ β†’ Docs

Example:

// Buy EURUSD: 500-point SL, 1000-point TP (1:2 R:R)
// Ask 1.08500 -> SL 1.08000, TP 1.09500
ticket, _ := sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000)

CalculateSLTP accepts only "BUY" or "SELL" as direction (anything else is an error).


[11] πŸ’° ACCOUNT INFORMATION (Advanced)ΒΆ

Complete account snapshot and daily statistics

Method Description Documentation
GetAccountInfo() Complete account snapshot (one call; any failed value is returned as an error, never as 0) β†’ Docs
GetDailyStats() Today's trading statistics (win rate, profit, etc.) β†’ Docs

Data structures:

  • AccountInfo - complete account data (login, balance, equity, margin, etc.) β†’ Docs
  • DailyStats - daily performance metrics (win rate, total deals, best/worst trades) β†’ Docs

🎯 Common Use Cases¢

1. Simple market orderΒΆ

// Buy 0.10 lots EURUSD at market price
ticket, err := sugar.BuyMarket("EURUSD", 0.1)
if err != nil {
    log.Fatalf("Trade failed: %v", err)
}
fmt.Printf("Position opened: #%d\n", ticket)

2. Market order with SL/TP distances (intuitive!)ΒΆ

// Buy EURUSD: 500-point SL, 1000-point TP
ticket, _ := sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000)
fmt.Printf("βœ… BUY #%d opened (1:2 R:R)\n", ticket)

3. Risk-based position sizingΒΆ

symbol := "EURUSD"
riskPercent := 2.0      // Risk 2% of balance
stopLossPips := 500.0   // 500-point stop loss (= 50 pips on 5-digit EURUSD)

// Calculate lot size automatically
lotSize, _ := sugar.CalculatePositionSize(symbol, riskPercent, stopLossPips)

// Validate before trading
canOpen, reason, _ := sugar.CanOpenPosition(symbol, lotSize)
if !canOpen {
    fmt.Printf("Cannot trade: %s\n", reason)
    return
}

// Trade with calculated size
ticket, _ := sugar.BuyMarketWithPips(symbol, lotSize, 500, 1000)
fmt.Printf("Position #%d opened (risking %.1f%%)\n", ticket, riskPercent)

4. Complete trading workflowΒΆ

// Step 1: Check connection
if !sugar.IsConnected() {
    sugar.QuickConnect("FxPro-MT5 Demo")
}

// Step 2: Check symbol availability
available, _ := sugar.IsSymbolAvailable("EURUSD")
if !available {
    log.Fatal("Symbol not available")
}

// Step 3: Calculate position size (risk 2%, 500-point SL)
lotSize, _ := sugar.CalculatePositionSize("EURUSD", 2.0, 500)

// Step 4: Validate
canOpen, reason, _ := sugar.CanOpenPosition("EURUSD", lotSize)
if !canOpen {
    log.Fatalf("Cannot trade: %s", reason)
}

// Step 5: Trade
ticket, _ := sugar.BuyMarketWithPips("EURUSD", lotSize, 500, 1000)
fmt.Printf("βœ… Position #%d opened\n", ticket)

5. Monitor positions and close on drawdownΒΆ

// Check total floating P/L
totalProfit, _ := sugar.GetTotalProfit()
fmt.Printf("Floating P/L: $%.2f\n", totalProfit)

// Emergency close on drawdown
if totalProfit < -500 {
    fmt.Println("🚨 Drawdown $500 - closing all positions!")
    closedCount, err := sugar.CloseAllPositions()
    fmt.Printf("Closed %d positions\n", closedCount)
    if err != nil {
        // e.g. "1 of 3 position(s) not closed: position #123: close rejected, ..."
        fmt.Printf("⚠️  %v\n", err)
    }
}

6. Daily performance reportΒΆ

// Get account snapshot
info, _ := sugar.GetAccountInfo()
fmt.Printf("Account: #%d, Balance: $%.2f, Equity: $%.2f\n",
    info.Login, info.Balance, info.Equity)

// Get today's stats
stats, _ := sugar.GetDailyStats()
fmt.Printf("\nToday's Performance:\n")
fmt.Printf("  Trades: %d\n", stats.TotalDeals)
fmt.Printf("  Win rate: %.1f%%\n", stats.WinRate)
fmt.Printf("  Total profit: $%.2f\n", stats.TotalProfit)
fmt.Printf("  Best trade: $%.2f\n", stats.BestDeal)
fmt.Printf("  Worst trade: $%.2f\n", stats.WorstDeal)

7. Symbol-specific analysisΒΆ

symbol := "EURUSD"

// Check if we have open positions
hasPosition, _ := sugar.HasOpenPosition(symbol)
fmt.Printf("%s has open position: %v\n", symbol, hasPosition)

// Get P/L for this symbol
profit, _ := sugar.GetProfitBySymbol(symbol)
fmt.Printf("%s floating P/L: $%.2f\n", symbol, profit)

// Close all positions of this symbol if losing
if profit < -100 {
    closed, _ := sugar.CloseAllBySymbol(symbol)
    fmt.Printf("Closed %d positions\n", closed)
}

8. Pending order with validationΒΆ

symbol := "EURUSD"
volume := 0.1
limitPrice := 1.08500

// Get current price to ensure limit is valid
priceInfo, _ := sugar.GetPriceInfo(symbol)
fmt.Printf("Current bid: %.5f, ask: %.5f\n", priceInfo.Bid, priceInfo.Ask)

// Validate margin
requiredMargin, _ := sugar.CalculateRequiredMargin(symbol, volume)
freeMargin, _ := sugar.GetFreeMargin()

if requiredMargin > freeMargin {
    log.Fatal("Insufficient margin")
}

// Place Buy Limit below current price
if limitPrice < priceInfo.Ask {
    ticket, _ := sugar.BuyLimitWithSLTP(symbol, volume, limitPrice, 1.08000, 1.09000)
    fmt.Printf("Buy Limit placed: #%d\n", ticket)
}

9. Weekly performance trackingΒΆ

// Get this week's deals
dealsThisWeek, _ := sugar.GetDealsThisWeek()
fmt.Printf("Trades this week: %d\n", len(dealsThisWeek))

// Calculate metrics
totalProfit := 0.0
winners := 0

for _, deal := range dealsThisWeek {
    totalProfit += deal.Profit
    if deal.Profit > 0 {
        winners++
    }
}

winRate := 0.0
if len(dealsThisWeek) > 0 {
    winRate = (float64(winners) / float64(len(dealsThisWeek))) * 100
}

fmt.Printf("Win rate: %.1f%%\n", winRate)
fmt.Printf("Total profit: $%.2f\n", totalProfit)

10. Multi-symbol portfolio managementΒΆ

symbols := []string{"EURUSD", "GBPUSD", "USDJPY"}

fmt.Println("PORTFOLIO STATUS")
fmt.Println("================")

totalFloating := 0.0

for _, symbol := range symbols {
    count := 0
    profit := 0.0

    positions, _ := sugar.GetPositionsBySymbol(symbol)
    count = len(positions)

    if count > 0 {
        profit, _ = sugar.GetProfitBySymbol(symbol)
        totalFloating += profit
    }

    fmt.Printf("%s: %d positions, P/L: $%.2f\n", symbol, count, profit)
}

fmt.Printf("\nTotal floating P/L: $%.2f\n", totalFloating)


πŸ“¦ ArchitectureΒΆ

MT5Sugar (High-level) ← You are here
    ↓ Simplified trading, risk management, analytics
    ↓
MT5Service (Mid-level)
    ↓ Type conversion, timeout management
    ↓
MT5Account (Low-level)
    ↓ Direct gRPC/Protobuf calls
    ↓
MetaTrader 5 Terminal

Layer Comparison:

Feature MT5Account MT5Service MT5Sugar
Complexity Low-level Proto Mid-level typed High-level convenience
Learning curve Steep Moderate Gentle
Verbosity High Medium Low
Risk management Manual Manual Built-in
Position sizing Manual Manual Automatic
SL/TP Prices only Prices only Point distances or prices
Use case Custom wrappers Standard apps Trading bots

πŸ“ ConventionsΒΆ

  • Most methods return (result, error) (or just error) - always check errors; IsConnected() returns only bool
  • Prices are always absolute (e.g., 1.08500), not relative
  • Volumes are always in lots (e.g., 0.1), not currency units
  • Points - minimum price increment (for 5-digit: 0.00001)
  • Pips - standard trader unit (for 5-digit: 1 pip = 10 points = 0.0001)
  • SL/TP distances in the ...WithPips methods, CalculateSLTP and CalculatePositionSize are points, despite the "pips" names
  • No normalization in the order methods - volumes and prices are sent exactly as given (the helpers round SL/TP to Digits and computed volumes down to VolumeStep)
  • Timeouts are built-in (3-130 seconds depending on the operation) - no need to specify:
  • QuickConnect: the server waits up to 120 s for the terminal, the call has a 130 s deadline; Disconnect: 30 s
  • Trading (orders, modify, close): 30 s per request - an order that times out on the client side may still have been executed
  • Balance / price queries, IsConnected, Ping, CountOpenPositions, IsSymbolAvailable, GetMinStopLevel, GetSymbolDigits: 3 s
  • Positions, GetSymbolInfo, GetAccountInfo (one deadline for the whole call), CalculatePositionSize: 10 s; GetMaxLotSize, CanOpenPosition, CalculateRequiredMargin: 5 s
  • CloseAllPositions / CloseAllBySymbol: 10 s to list the positions, then 30 s for each close
  • History: 15 s for today/yesterday/week, 30 s for month/custom range (all pages together); GetAllSymbols: 60 s for all pages
  • Times: PriceInfo.Time / tick Time are broker server time, the ...Utc fields are UTC
  • History ranges (today / yesterday / week / month) use the local calendar of the computer running the program (sent to the server as UTC), and positions are selected by their open time; profit sums are the Profit field (no commission/swap/fee)
  • Always call Disconnect() when done - also on error paths. Note that log.Fatal exits without running deferred calls, so a defer sugar.Disconnect() does not run after it

πŸŽ“ Best PracticesΒΆ

Risk ManagementΒΆ

// ALWAYS use CalculatePositionSize for risk-based trading
lotSize, _ := sugar.CalculatePositionSize("EURUSD", 2.0, 500)  // βœ… Good (500-point SL)

// Don't use fixed lot sizes (ignores account size)
lotSize := 0.1  // ❌ Bad - doesn't scale with account

Pre-Trade ValidationΒΆ

// ALWAYS validate before trading
canOpen, reason, _ := sugar.CanOpenPosition("EURUSD", lotSize)
if !canOpen {
    log.Printf("Cannot trade: %s", reason)
    return
}

// Then trade
ticket, _ := sugar.BuyMarketWithPips("EURUSD", lotSize, 500, 1000)

Error HandlingΒΆ

// ALWAYS check errors
ticket, err := sugar.BuyMarket("EURUSD", 0.1)
if err != nil {
    log.Printf("Trade failed: %v", err)
    return
}
fmt.Printf("Success: #%d\n", ticket)

Use Distance-Based MethodsΒΆ

// Prefer distance-based methods (more intuitive; distances in points)
sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000)  // βœ… Easy to understand

// Instead of price-based (error-prone)
sugar.BuyMarketWithSLTP("EURUSD", 0.1, 1.08450, 1.08950)  // ❌ Manual calculation

Connection ManagementΒΆ

// Check connection before trading
if !sugar.IsConnected() {
    if err := sugar.QuickConnect("FxPro-MT5 Demo"); err != nil {
        log.Fatal(err)
    }
}

// Verify with ping
if err := sugar.Ping(); err != nil {
    log.Fatal("Connection lost")
}

πŸš€ Quick StartΒΆ

MT5Sugar lives in the repository's examples module (github.com/MetaRPC/GoMT5/examples, package mt5 in examples/mt5). Get it by cloning the repository and building your program inside that module - it is not a separate go get package.

package main

import (
    "fmt"
    "log"

    mt5 "github.com/MetaRPC/GoMT5/examples/mt5"
)

func main() {
    // log.Fatal exits without running deferred calls - so the work runs in run(),
    // whose deferred Disconnect always runs, and main only reports the error.
    if err := run(); err != nil {
        log.Fatal(err)
    }
}

func run() error {
    // 1. Create MT5Sugar instance (login, password, gRPC server; "" = default mt5.mrpc.pro:443)
    sugar, err := mt5.NewMT5Sugar(12345678, "your_password", "mt5.mrpc.pro:443")
    if err != nil {
        return err
    }
    // Stop the terminal when done - also when QuickConnect failed (it may already have started)
    defer func() {
        if err := sugar.Disconnect(); err != nil {
            log.Printf("disconnect: %v", err)
        }
    }()

    // 2. Connect (the server waits up to 120 s for the terminal)
    if err := sugar.QuickConnect("YourBroker-MT5 Demo"); err != nil {
        return err
    }

    // 3. Calculate position size (risk 2%, 500-point SL = 50 pips on 5-digit EURUSD)
    lotSize, err := sugar.CalculatePositionSize("EURUSD", 2.0, 500)
    if err != nil {
        return err
    }

    // 4. Validate
    canOpen, reason, err := sugar.CanOpenPosition("EURUSD", lotSize)
    if err != nil {
        return err
    }
    if !canOpen {
        return fmt.Errorf("cannot trade: %s", reason)
    }

    // 5. Trade with SL/TP distances in points
    ticket, err := sugar.BuyMarketWithPips("EURUSD", lotSize, 500, 1000)
    if err != nil {
        return err
    }

    fmt.Printf("βœ… Position #%d opened!\n", ticket)
    fmt.Printf("   Risk: 2%% | SL: 500 points | TP: 1000 points | R:R 1:2\n")
    return nil
}

πŸŽ‰ You're ready to build professional trading bots with MT5Sugar!

Pro tip: Start with BuyMarketWithPips(), CalculatePositionSize(), and CanOpenPosition() - these three methods cover 80% of trading needs!