Skip to content

MT5Service - Account Methods (Mid-Level API)ΒΆ

4 convenient methods for quick access to account properties without protobuf wrappers

🧩 API Layer: MID-LEVEL - wrappers over MT5Account with Go native types

Implementation:

These methods are implemented in examples/mt5/MT5Service.go, which wraps package/Helpers/MT5Account.go low-level API with convenient helpers for ease of use.

Demo files:

  • examples/demos/service/04_service_demo.go - comprehensive examples of all service wrapper methods

  • examples/demos/service/05_service_streaming.go - streaming methods examples


🎯 Why These Methods Exist¢

Problem: In MT5Account, every call returns a protobuf Data object that needs to be unpacked:

// Low-level (MT5Account)
data, err := account.AccountInfoDouble(ctx, &pb.AccountInfoDoubleRequest{
    PropertyId: pb.AccountInfoDoublePropertyType_ACCOUNT_BALANCE,
})
balance := data.GetRequestedValue()  // ← additional call!

Solution: MT5Service provides direct methods that return values immediately:

// Mid-level (MT5Service)
balance, err := service.GetAccountDouble(ctx,
    pb.AccountInfoDoublePropertyType_ACCOUNT_BALANCE)  // βœ… done!

Advantages:

  • βœ… Less code (1-2 lines instead of 3-4)
  • βœ… No need to call .GetRequestedValue()
  • βœ… Returns clean Go types (float64, int64, string)
  • βœ… Automatic creation of request structures
  • βœ… Conversion *timestamppb.Timestamp β†’ *time.Time (in GetAccountSummary)

πŸ“‹ All 4 MethodsΒΆ

Method Returns Low-Level Equivalent
GetAccountSummary(ctx) *AccountSummary struct AccountSummary(ctx, &pb.AccountSummaryRequest{})
GetAccountDouble(ctx, propertyID) float64 AccountInfoDouble(ctx, &pb.AccountInfoDoubleRequest{propertyID})
GetAccountInteger(ctx, propertyID) int64 AccountInfoInteger(ctx, &pb.AccountInfoIntegerRequest{propertyID})
GetAccountString(ctx, propertyID) string AccountInfoString(ctx, &pb.AccountInfoStringRequest{propertyID})

πŸ“¦ AccountSummary Struct (DTO)ΒΆ

type AccountSummary struct {
    Login                   int64                        // Account number
    Balance                 float64                      // Balance (without floating P&L)
    Equity                  float64                      // Equity (Balance + Floating P&L)
    UserName                string                       // Client name
    Leverage                int64                        // Leverage (100 = 1:100)
    TradeMode               pb.MrpcEnumAccountTradeMode  // Account type (demo/real/contest)
    CompanyName             string                       // Broker name
    Currency                string                       // Deposit currency (USD, EUR, ...)
    ServerTime              *time.Time                   // Server time (already *time.Time!)
    UtcTimezoneShiftMinutes int64                        // UTC timezone shift (minutes)
    Credit                  float64                      // Credit
}

Advantage: All important properties in one struct, ServerTime is already *time.Time (no need for .AsTime()).


πŸ“– Method SignaturesΒΆ

1) GetAccountSummaryΒΆ

func (s *MT5Service) GetAccountSummary(ctx context.Context) (*AccountSummary, error)

Returns all account information in a single call.


2) GetAccountDoubleΒΆ

func (s *MT5Service) GetAccountDouble(
    ctx context.Context,
    propertyID pb.AccountInfoDoublePropertyType,
) (float64, error)

Available propertyID:

  • ACCOUNT_BALANCE - balance
  • ACCOUNT_CREDIT - credit
  • ACCOUNT_PROFIT - current profit
  • ACCOUNT_EQUITY - equity
  • ACCOUNT_MARGIN - used margin
  • ACCOUNT_MARGIN_FREE - free margin
  • ACCOUNT_MARGIN_LEVEL - margin level (%)
  • ACCOUNT_MARGIN_SO_CALL - margin call level
  • ACCOUNT_MARGIN_SO_SO - stop out level
  • ACCOUNT_MARGIN_INITIAL - initial margin
  • ACCOUNT_MARGIN_MAINTENANCE - maintenance margin
  • ACCOUNT_ASSETS - current assets
  • ACCOUNT_LIABILITIES - current liabilities
  • ACCOUNT_COMMISSION_BLOCKED - blocked commission

3) GetAccountIntegerΒΆ

func (s *MT5Service) GetAccountInteger(
    ctx context.Context,
    propertyID pb.AccountInfoIntegerPropertyType,
) (int64, error)

Available propertyID:

  • ACCOUNT_LOGIN - account number
  • ACCOUNT_TRADE_MODE - account type (0=demo, 2=real)
  • ACCOUNT_LEVERAGE - leverage
  • ACCOUNT_LIMIT_ORDERS - max number of pending orders
  • ACCOUNT_MARGIN_SO_MODE - minimum margin setting mode
  • ACCOUNT_TRADE_ALLOWED - is trading allowed (0/1)
  • ACCOUNT_TRADE_EXPERT - is trading allowed for EA (0/1)
  • ACCOUNT_MARGIN_MODE - margin calculation mode
  • ACCOUNT_CURRENCY_DIGITS - number of decimal places in currency
  • ACCOUNT_FIFO_CLOSE - mandatory FIFO closing (0/1)
  • ACCOUNT_HEDGE_ALLOWED - are hedged positions allowed (0/1)

4) GetAccountStringΒΆ

func (s *MT5Service) GetAccountString(
    ctx context.Context,
    propertyID pb.AccountInfoStringPropertyType,
) (string, error)

Available propertyID:

  • ACCOUNT_CURRENCY - deposit currency (USD, EUR, ...)
  • ACCOUNT_COMPANY - broker name
  • ACCOUNT_NAME - account owner name
  • ACCOUNT_SERVER - trading server name

πŸ’‘ Usage ExamplesΒΆ

Example 1: Getting Balance and EquityΒΆ

// ❌ BEFORE (MT5Account) - 6 lines:
req1 := &pb.AccountInfoDoubleRequest{
    PropertyId: pb.AccountInfoDoublePropertyType_ACCOUNT_BALANCE,
}
balanceData, _ := account.AccountInfoDouble(ctx, req1)
balance := balanceData.GetRequestedValue()

req2 := &pb.AccountInfoDoubleRequest{
    PropertyId: pb.AccountInfoDoublePropertyType_ACCOUNT_EQUITY,
}
equityData, _ := account.AccountInfoDouble(ctx, req2)
equity := equityData.GetRequestedValue()

// βœ… AFTER (MT5Service) - 2 lines:
balance, _ := service.GetAccountDouble(ctx,
    pb.AccountInfoDoublePropertyType_ACCOUNT_BALANCE)
equity, _ := service.GetAccountDouble(ctx,
    pb.AccountInfoDoublePropertyType_ACCOUNT_EQUITY)

fmt.Printf("Balance: %.2f, Equity: %.2f\n", balance, equity)

Code reduction: 67% (6 lines β†’ 2 lines)


Example 2: Calculating Margin LevelΒΆ

// ❌ BEFORE (MT5Account) - hard to read:
req1 := &pb.AccountInfoDoubleRequest{
    PropertyId: pb.AccountInfoDoublePropertyType_ACCOUNT_EQUITY,
}
equityData, _ := account.AccountInfoDouble(ctx, req1)
equity := equityData.GetRequestedValue()

req2 := &pb.AccountInfoDoubleRequest{
    PropertyId: pb.AccountInfoDoublePropertyType_ACCOUNT_MARGIN,
}
marginData, _ := account.AccountInfoDouble(ctx, req2)
margin := marginData.GetRequestedValue()

marginLevel := (equity / margin) * 100.0
fmt.Printf("Margin Level: %.2f%%\n", marginLevel)

// βœ… AFTER (MT5Service) - reads like normal Go code:
equity, _ := service.GetAccountDouble(ctx,
    pb.AccountInfoDoublePropertyType_ACCOUNT_EQUITY)
margin, _ := service.GetAccountDouble(ctx,
    pb.AccountInfoDoublePropertyType_ACCOUNT_MARGIN)

marginLevel := (equity / margin) * 100.0
fmt.Printf("Margin Level: %.2f%%\n", marginLevel)

Code reduction: 50% (10 lines β†’ 5 lines)


Example 3: Checking Account Type (Demo/Real)ΒΆ

// βœ… MT5Service - compact and clear
tradeMode, err := service.GetAccountInteger(ctx,
    pb.AccountInfoIntegerPropertyType_ACCOUNT_TRADE_MODE)
if err != nil {
    return err
}

switch tradeMode {
case 0:
    fmt.Println("βœ… Demo account - safe for testing")
case 2:
    fmt.Println("🚨 REAL account - trading with real money!")
}

Example 4: Getting Full Account InformationΒΆ

// βœ… BEST way - use GetAccountSummary for multiple properties
summary, err := service.GetAccountSummary(ctx)
if err != nil {
    return err
}

fmt.Printf("Account: %d\n", summary.Login)
fmt.Printf("Balance: %.2f %s\n", summary.Balance, summary.Currency)
fmt.Printf("Equity: %.2f\n", summary.Equity)
fmt.Printf("Leverage: 1:%d\n", summary.Leverage)
fmt.Printf("Broker: %s\n", summary.CompanyName)

// ServerTime is already *time.Time (no need for .AsTime()!)
if summary.ServerTime != nil {
    fmt.Printf("Server time: %s\n", summary.ServerTime.Format("15:04:05"))
}

Example 5: Balance MonitoringΒΆ

func MonitorBalance(service *mt5.MT5Service, interval time.Duration) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()

    for range ticker.C {
        ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)

        // βœ… One line instead of 3-4
        balance, err := service.GetAccountDouble(ctx,
            pb.AccountInfoDoublePropertyType_ACCOUNT_BALANCE)
        cancel()

        if err != nil {
            fmt.Printf("❌ Error: %v\n", err)
            continue
        }

        fmt.Printf("[%s] Balance: %.2f\n",
            time.Now().Format("15:04:05"), balance)
    }
}

Example 6: Checking Free Margin Before Opening a PositionΒΆ

func CanOpenPosition(service *mt5.MT5Service, requiredMargin float64) (bool, error) {
    ctx := context.Background()

    // βœ… Simple and clear code
    freeMargin, err := service.GetAccountDouble(ctx,
        pb.AccountInfoDoublePropertyType_ACCOUNT_MARGIN_FREE)
    if err != nil {
        return false, err
    }

    if freeMargin < requiredMargin {
        fmt.Printf("⚠️ Insufficient margin: %.2f (required: %.2f)\n",
            freeMargin, requiredMargin)
        return false, nil
    }

    fmt.Printf("βœ… Sufficient margin: %.2f\n", freeMargin)
    return true, nil
}

πŸ”§ When to Use Which MethodΒΆ

βœ… GetAccountSummaryΒΆ

Use when:

  • You need multiple properties at once (Balance + Equity + Currency)
  • Building a dashboard or report
  • Need complete account information

Example:

summary, _ := service.GetAccountSummary(ctx)
fmt.Printf("Balance: %.2f %s, Equity: %.2f, Leverage: 1:%d\n",
    summary.Balance, summary.Currency, summary.Equity, summary.Leverage)

βœ… GetAccountDouble / GetAccountInteger / GetAccountStringΒΆ

Use when:

  • You need one specific property
  • Writing checks or validations
  • Monitoring a specific metric

Example:

// Only balance - use GetAccountDouble
balance, _ := service.GetAccountDouble(ctx,
    pb.AccountInfoDoublePropertyType_ACCOUNT_BALANCE)

πŸ’‘ RecommendationsΒΆ

  1. For a single property β†’ use GetAccountDouble/Integer/String
  2. For 2-3 properties β†’ use GetAccountSummary (already has everything)
  3. For all information β†’ use GetAccountSummary


🎯 Summary¢

MT5Service Account methods solve one task - remove protobuf ceremony:

  • ❌ No need to create requests manually
  • ❌ No need to call .GetRequestedValue()
  • ❌ No need to convert timestamps
  • βœ… Get clean Go types (float64, int64, string, *AccountSummary)
  • βœ… Code reads like normal Go, without protobuf dependencies