Skip to content

MT5Account · Streaming Methods - Overview

Real-time streams: ticks, trades, profit updates, transaction log. Use this page to choose the right API for real-time subscriptions.

📁 What lives here

Real-Time Price Updates

Trading Events

  • OnTrade - position/order changes (opened, closed, modified).
  • OnTradeTransaction - detailed transaction log (complete audit trail).

Position Monitoring


📚 Step-by-step tutorials

Note: Streaming methods are channel-based APIs. Check individual method pages for detailed examples of goroutine patterns and channel handling.


🧭 Plain English

  • OnSymbolTickstream live prices for symbols (bid, ask, volume updates).
  • OnTrademonitor trade events (position opened/closed/modified).
  • OnTradeTransactiondetailed audit log of all trading operations.
  • OnPositionProfitperiodic P/L updates for open positions.
  • OnPositionsAndPendingOrdersTicketsperiodic ticket lists (lightweight monitoring).

Rule of thumb: need live pricesOnSymbolTick; need trade notificationsOnTrade; need detailed auditOnTradeTransaction; need P/L monitoringOnPositionProfit.


Quick choose

If you need… Use Returns (stream) Key inputs
Real-time price ticks OnSymbolTick Channel of MqlTick Symbol name
Trade event notifications OnTrade Channel of TradeInfo (none)
Detailed transaction audit log OnTradeTransaction Channel of TradeTransaction (none)
Real-time profit/loss updates OnPositionProfit Channel of PositionProfit Symbol filter (optional)
Real-time ticket list changes OnPositionsAndPendingOrdersTickets Channel of ticket arrays (none)

❌ Cross‑refs & gotchas

  • Streaming = Go channels - Methods return two channels: data channel and error channel.
  • Context cancellation - Use context.WithCancel() or context.WithTimeout() to stop streams.
  • Goroutine required - You MUST consume channels in goroutines to avoid blocking.
  • OnSymbolTick - High frequency, can generate many updates per second.
  • OnTrade - Triggered on every trade event (open, close, modify, delete).
  • OnTradeTransaction - Most detailed, includes all transaction types and states.
  • OnPositionProfit - Real-time updates triggered by price changes.
  • Resource management - Always cancel context when done to close channels and stop streams.
  • Error handling - Errors are sent through error channel, nil data indicates closed channel.

🟢 Minimal snippets

// Stream live ticks for EURUSD
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

dataChan, errChan := account.OnSymbolTick(ctx, &pb.OnSymbolTickRequest{
    SymbolNames: []string{"EURUSD"},
})

go func() {
    for {
        select {
        case tick := <-dataChan:
            if tick == nil {
                return
            }
            fmt.Printf("EURUSD: Bid=%.5f, Ask=%.5f\n", tick.Bid, tick.Ask)

        case err := <-errChan:
            if err != nil {
                log.Printf("Stream error: %v\n", err)
                return
            }
        }
    }
}()

// Keep running...
time.Sleep(30 * time.Second)
// Monitor trade events
dataChan, errChan := account.OnTrade(ctx, &pb.OnTradeRequest{})

go func() {
    for {
        select {
        case trade := <-dataChan:
            if trade == nil {
                return
            }
            fmt.Printf("Trade event received\n")

        case err := <-errChan:
            if err != nil {
                return
            }
        }
    }
}()
// Monitor position profit/loss
dataChan, errChan := account.OnPositionProfit(ctx, &pb.OnPositionProfitRequest{
    Symbol: "EURUSD", // Or empty for all symbols
})

go func() {
    for {
        select {
        case profitData := <-dataChan:
            if profitData == nil {
                return
            }
            fmt.Printf("#%d %s: $%.2f\n",
                profitData.Ticket, profitData.Symbol, profitData.Profit)

        case err := <-errChan:
            if err != nil {
                return
            }
        }
    }
}()
// Monitor position tickets
dataChan, errChan := account.OnPositionsAndPendingOrdersTickets(
    ctx,
    &pb.OnPositionsAndPendingOrdersTicketsRequest{},
)

go func() {
    for {
        select {
        case update := <-dataChan:
            if update == nil {
                return
            }
            fmt.Printf("Open positions: %v\n", update.PositionTickets)
            fmt.Printf("Pending orders: %v\n", update.PendingOrderTickets)

        case err := <-errChan:
            if err != nil {
                return
            }
        }
    }
}()
// Detailed transaction log
dataChan, errChan := account.OnTradeTransaction(ctx, &pb.OnTradeTransactionRequest{})

go func() {
    for {
        select {
        case transaction := <-dataChan:
            if transaction == nil {
                return
            }
            fmt.Printf("Transaction event\n")

        case err := <-errChan:
            if err != nil {
                return
            }
        }
    }
}()
// Multiple streams concurrently
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

// Stream 1: Ticks
tickData, tickErr := account.OnSymbolTick(ctx, &pb.OnSymbolTickRequest{
    SymbolNames: []string{"EURUSD"},
})

go func() {
    for {
        select {
        case tick := <-tickData:
            if tick == nil {
                return
            }
            fmt.Printf("[TICK] EURUSD: %.5f\n", tick.Bid)

        case err := <-tickErr:
            if err != nil {
                return
            }
        }
    }
}()

// Stream 2: Trades
tradeData, tradeErr := account.OnTrade(ctx, &pb.OnTradeRequest{})

go func() {
    for {
        select {
        case trade := <-tradeData:
            if trade == nil {
                return
            }
            fmt.Printf("[TRADE] Event received\n")

        case err := <-tradeErr:
            if err != nil {
                return
            }
        }
    }
}()

// Let streams run for 30 seconds
time.Sleep(30 * time.Second)
cancel() // Stop all streams

See also