🛡️ Safe-by-Default Examples & Feature Toggles (C#)
Run the examples safely by default. Turn on the powerful (but potentially dangerous) trading calls only when you explicitly decide to.
🪪 Requirements
.NET SDK 8.0+-
appsettings.jsonwith MT4 credentials and connection details (seeMT4Optionssection) -
User,Password - Either
ServerNameorHost+Port DefaultSymbol(e.g.,"EURUSD")- You do not have to call
MT4Accountdirectly — use theMT4Servicemethods in examples.
⚡ Quick Start (Safe Mode)
- Fill
appsettings.json. - Build & run:
dotnet run --project MetaRPC.CSharpMT4.csproj
✨ Feature Toggles (Safe by Default)
Place these flags near the top of your Program.cs (they already exist in the template):
// ===== Feature toggles (safe by default) =====
private static readonly bool EnableTradingExamples = false; // ⚠️ Real trading operations
private const bool EnableStreams = true; // ticks/profit/tickets
đź”§ What each toggle does
-
EnableTradingExamples -
false(recommended default): trading methods are not executed. true: allows examples that open/modify/close orders.-
EnableStreams -
Enables read‑only streaming examples (quotes, opened‑orders profit/tickets, trade updates).
Tip: You can keep these toggles in version control with safe defaults, and flip them locally when testing.
đź§© Example Layout in Program.cs
Keep Main readable and declarative. The toggles control the “dangerous” parts.
// --- đź“‚ Account Info ---
await _service.ShowAccountSummary();
// --- đź“‚ Order Operations (read-only) ---
await _service.ShowOpenedOrders();
await _service.ShowOpenedOrderTickets();
await _service.ShowOrdersHistory(); // one-time snapshot
// --- ⚠️ Trading (DANGEROUS) ---
if (EnableTradingExamples)
{
await _service.ShowOrderSendExample(symbol);
// Real tickets are required for the following:
// await _service.CloseOrderExample(12345678);
// await _service.CloseByOrderExample(12345678, 12345679);
// await _service.ShowOrderModifyExample(12345678); // if you add an implementation
}
// --- đź“‚ Market / Symbols ---
await _service.ShowQuote(symbol);
await _service.ShowQuotesMany(new[] { "EURUSD", "GBPUSD", "USDJPY" });
await _service.ShowQuoteHistory(symbol); // one-time
await _service.ShowAllSymbols();
await _service.ShowTickValues(new[] { "EURUSD", "GBPUSD", "USDJPY" });
await _service.ShowSymbolParams("EURUSD");
await _service.ShowSymbolInfo(symbol);
// Quick live tick: first tick OR timeout; will not hang indefinitely.
await _service.ShowRealTimeQuotes(symbol, timeoutSeconds: 5, ct);
// --- đź“‚ Streaming / Subscriptions (read-only) ---
if (EnableStreams && !ct.IsCancellationRequested)
{
// Live ticks for a fixed time
await _service.StreamQuotesForSymbolsAsync(new[] { "EURUSD", "GBPUSD" }, durationSeconds: 10);
// Demo streams: examples exit after the first message
await _service.StreamTradeUpdates();
await _service.StreamOpenedOrderProfits();
await _service.StreamOpenedOrderTickets();
}
Note:
CTRL+Cin the console triggers a graceful shutdown — the code wires a cancellation token to stop streams and exit cleanly.
đźš« Dangerous vs âś… Safe
Dangerous (disabled by default):
ShowOrderSendExample— opens a trade (market/pending)ShowOrderModifyExample— changes SL/TP (requires valid ticket)CloseOrderExample— closes a ticketCloseByOrderExample— closes against an opposite ticket- (Any method that modifies account state)
Safe (read‑only):
- All
Show*info calls (account, symbols, quotes, history) Stream*subscriptions: quotes, opened‑order profits, tickets, trade updates
🏗️ How to Use the Toggles (Step by Step)
- Open
Program.csand locate the Feature toggles block:
private static readonly bool EnableTradingExamples = false;
private const bool EnableStreams = true;
EnableTradingExamples = false.
3. When ready to try trading:
- Set
EnableTradingExamples = true. - Pass real, valid tickets into modify/close/close‑by helpers (copy from
ShowOpenedOrders). - Prefer DEMO first.
- Run normally (
dotnet run --project MetaRPC.CSharpMT4.csproj).
âś… Safety Checklist (before enabling trading)
- You’re on a DEMO account for first runs.
ShowAccountSummarylooks sane — you understandEquityandFreeMargin.- Symbol, volume, SL/TP comply with broker rules (check
ShowSymbolParams). - Tickets are real (from
ShowOpenedOrders/ShowOpenedOrderTickets).
âť“ FAQ
Do I need to call MT4Account directly?
No. Use MT4Service methods (_service.Show..., _service.Stream...). MT4Account is managed inside the service and in Program.cs during connect/disconnect.
Where do connection settings live?
In appsettings.json → MT4Options section (User, Password, ServerName or Host+Port, DefaultSymbol).
Why do some streams stop quickly?
Examples intentionally stop after a first message or a short timeout (e.g., ShowRealTimeQuotes uses a 5s timeout; StreamQuotesForSymbolsAsync runs for 10s). Tune or remove those limits in your own code.
I see RpcException: Cancelled. Is that bad?
Not necessarily — when we cancel via token or a short example timeout, a Cancelled status is expected and treated as a clean completion.
đź§° Troubleshooting
- “Nothing happens in trading examples” →
EnableTradingExamplesis likely stillfalse. - “Modify/close fails” → Invalid ticket or unsupported action (e.g., trying to delete a market order;
CloseByrequires opposite positions of matching volume). - “Streams stop too soon” → Increase the example timeouts or remove the first‑message
break;in wrappers. - “Not connected / missing options” → Ensure
ServerNameorHost+Portis set inappsettings.jsonand credentials are correct.
That’s it — a clean Main, safe defaults, and powerful features behind a single switch. Flip the toggle when you’re ready, and proceed step by step.