Skip to content

Streaming — Overview

This section groups real‑time streams from MT4: price ticks, trade events, and live snapshots of open orders (P/L or ticket lists). Use these when you need continuously updating data rather than one‑off RPC calls.


📂 Methods in this folder


⚡ Typical Workflows

1) Show the first live tick for a symbol

// Quick wrapper (cancels after first tick or timeout)
await _service.ShowRealTimeQuotes("EURUSD", timeoutSeconds: 5, ct);

// Low-level: break on first item or cancel via token
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
await foreach (var tick in _mt4.OnSymbolTickAsync(new[] { "EURUSD" }, cts.Token))
{
    var q = tick.SymbolTick;
    Console.WriteLine($"Tick: {q.Symbol} {q.Bid}/{q.Ask} @ {q.Time}");
    break; // stop after first
}

2) Monitor floating P/L per open order

// Wrapper demo exits after the first update
await _service.StreamOpenedOrderProfits();

// Low-level: 1s interval, cancel on condition
using var cts = new CancellationTokenSource();
_ = Task.Run(async () => { await Task.Delay(TimeSpan.FromSeconds(30)); cts.Cancel(); });

await foreach (var o in _mt4.OnOpenedOrdersProfitAsync(1000, cts.Token))
{
    Console.WriteLine($"{o.Symbol} #{o.Ticket} P/L={o.Profit}");
    if (o.Profit > 100) cts.Cancel(); // arbitrary exit condition
}

3) Track when tickets change

await foreach (var update in _mt4.OnOpenedOrdersTicketsAsync(1000, ct))
{
    Console.WriteLine($"Open tickets: {string.Join(", ", update.Tickets)}");
}

4) Snapshot + streaming combo

// Get a snapshot first...
var syms = new[] { "EURUSD", "GBPUSD" };
var snap = await _mt4.QuoteManyAsync(syms);
// ...then stream ticks to keep UI “live”
await foreach (var t in _mt4.OnSymbolTickAsync(syms, ct))
{
    // update widgets/pricing panels incrementally
}

✅ Best Practices

  1. Always pass a CancellationToken. Streams are open‑ended; you control their lifetime.
  2. Expect Cancelled on shutdown. Both client‑initiated and server‑initiated cancellations are normal termination paths.
  3. Choose sensible intervals. For OpenedOrderProfits/OpenedOrderTickets, 500–2000 ms is typical. Faster polling increases load.
  4. Backoff & reconnect. The client retries on transient gRPC statuses (Unavailable/DeadlineExceeded/Internal) with exponential backoff; persistent failures bubble up to you.
  5. Validate inputs.

  6. OnSymbolTickAsync requires at least one existing symbol (e.g., "EURUSD").

  7. Use the same casing and broker suffixes (EURUSD.m, XAUUSD-RAW) the server exposes.
  8. Keep prices raw for math; round only for display. Timestamps are UTC.

🎯 Purpose

Streaming APIs power real‑time UIs, alerting, and automation:

  • Quotes: live panels, best‑bid/ask triggers, latency‑sensitive logic.
  • Opened orders: on‑the‑fly risk views (P/L), change detection via ticket lists.
  • Trades: immediate reaction to fills/closures for logging, analytics, or hedging.

Use this page as a map and dive into each file for signatures, fields, and examples.