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 toDigits/VolumeStep). The helpers do round:CalculateSLTPandBuy/SellMarketWithPipsround SL/TP prices to the symbol'sDigits;CalculatePositionSizeandGetMaxLotSizeround the volume down toVolumeStep.
Navigation by CategoryΒΆ
[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 MT5ServiceGetAccount()- access underlying MT5AccountDisconnect(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 whenQuickConnectfailed (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;SpreadPipsis 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.) β DocsDailyStats- 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)
π Related DocumentationΒΆ
- MT5Account Documentation - Low-level gRPC/Proto methods
- MT5Service Documentation - Mid-level service layer
- MT5Sugar (this document) - High-level convenience methods
π¦ 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 justerror) - always check errors;IsConnected()returns onlybool - 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
...WithPipsmethods,CalculateSLTPandCalculatePositionSizeare 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
Digitsand computed volumes down toVolumeStep) - 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/ tickTimeare broker server time, the...Utcfields 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
Profitfield (no commission/swap/fee) - Always call
Disconnect()when done - also on error paths. Note thatlog.Fatalexits without running deferred calls, so adefer 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(), andCanOpenPosition()- these three methods cover 80% of trading needs!