cTrader.
The ECN-style FX/CFD platform with a modern automation API. cAlgo is real C# with bracket orders, multi-symbol robots, and a cloud backtester. No bolt-on EA quirks.
The honest pitch.
cTrader is what serious FX traders pick when MetaTrader's single-threaded EA model starts hurting. cAlgo (now cTrader Automate) is real .NET, robots inherit from a clean Robot base class, and the order API includes ExecuteMarketOrder, ModifyPosition, ClosePosition, and bracket-order parameters as first-class arguments — not as separate orders you have to babysit. The catch: broker support is narrower than MT5, so you pick a cTrader broker first and the platform comes with it.
Auth, orders, limits.
| Auth | Broker-account credentials in cTrader desktop; cBots run inside the platform process. |
|---|---|
| Order API | ExecuteMarketOrder / ExecutePendingOrder with StopLoss + TakeProfit in pips on the same call. |
| Backtester | Cloud-based, multi-thread; replay on tick data with realistic spread modelling. |
| Rate limits | Broker-enforced; cTrader Open API has additional REST rate limits. |
| Sandbox | Demo account from your cTrader broker (free, instant). |
| Platform | Windows desktop primary; cTrader Web for monitoring. |
Hello-world, but real.
cAlgo's ExecuteMarketOrder takes StopLoss and TakeProfit (in pips) on the same call — no race condition between order and bracket attach. The Label guards against duplicate entries on the same bar.
| 1 | using cAlgo.API; |
| 2 | using cAlgo.API.Indicators; |
| 3 | |
| 4 | [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] |
| 5 | public class RsiBracketBot : Robot |
| 6 | { |
| 7 | [Parameter("RSI Periods", DefaultValue = 14)] public int RsiPeriods { get; set; } |
| 8 | [Parameter("Lots", DefaultValue = 0.10)] public double Lots { get; set; } |
| 9 | [Parameter("SL pips", DefaultValue = 25)] public double SL { get; set; } |
| 10 | [Parameter("TP pips", DefaultValue = 50)] public double TP { get; set; } |
| 11 | |
| 12 | private RelativeStrengthIndex _rsi; |
| 13 | private const string Label = "RsiBracketBot"; |
| 14 | |
| 15 | protected override void OnStart() { |
| 16 | _rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, RsiPeriods); |
| 17 | } |
| 18 | |
| 19 | protected override void OnBar() { |
| 20 | if (Positions.FindAll(Label, SymbolName).Length > 0) return; |
| 21 | |
| 22 | var volume = Symbol.QuantityToVolumeInUnits(Lots); |
| 23 | var prev = _rsi.Result.Last(1); |
| 24 | |
| 25 | if (prev < 30) ExecuteMarketOrder(TradeType.Buy, SymbolName, volume, Label, SL, TP); |
| 26 | else if (prev > 70) ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, Label, SL, TP); |
| 27 | } |
| 28 | |
| 29 | protected override void OnStop() { |
| 30 | foreach (var p in Positions.FindAll(Label, SymbolName)) ClosePosition(p); |
| 31 | } |
| 32 | } |
The traps everyone hits.
Real production failure modes. Sev1 = capital loss risk. Sev2 = data integrity / silent wrongness. Sev3 = developer ergonomics that bite later.
Pip vs point vs tick confusion
Sev1What happens. On 5-digit FX brokers, 1 pip = 10 points. Set StopLoss=25 thinking 25 pips and you actually get 2.5 pips — your stop is hit almost immediately.
Fix. Always use Symbol.PipSize and Symbol.PointSize explicitly. Never hardcode a number without dividing by PipSize.
Broker fills below minimum lot
Sev2What happens. Some cTrader brokers reject orders below 0.01 lots silently; the OnError event fires but your strategy continues as if filled.
Fix. Always check the OnError event and the return value of ExecuteMarketOrder — never assume success. Log every rejection with the broker's error code.
Server time vs UTC
Sev2What happens. cTrader robots default to broker server timezone, which is often EET (Athens). Schedule-based logic runs at the wrong wall-clock time.
Fix. Set [Robot(TimeZone = TimeZones.UTC, ...)] explicitly. Convert to session-local time only when displaying.
Backtest spread = current spread
Sev3What happens. The cloud backtester uses the current broker spread, not the historical spread. News-event backtests can look unrealistically clean.
Fix. Use 'Tick data from server' mode with realistic spread modelling, and add a per-trade slippage penalty when reporting expectancy.
What to pair it with.
No platform stands alone. These are the layers that — paired with cTrader — produce production-grade automation.
| Layer | Recommended | Why |
|---|---|---|
| Broker | IC Markets, Pepperstone, Spotware-native brokers | Pick a broker first (regulation + spread). cTrader follows. |
| Backtesting | cTrader Optimization + Python parameter sweep | Cloud opt for the heavy lifting; pandas/sklearn for cross-validation and walk-forward. |
| Monitoring | cTrader Web + Telegram bot via Open API | Web shows positions; Telegram pings on every fill or robot stop. |
| Code hosting | Git + ReSharper / Rider | Write cAlgo files in your IDE, copy into the cTrader Automate editor, and version control everything externally. |