r/cTrader

Need help - cTrader engine for backdating configuration OR why do even well known classical strategies fall apart on cTrader?

Question for you guys — why do even well-known classical strategies fall apart on cTrader?

I've been trying to test standard classical strategies on cTrader because I can't build anything that actually works. I went down the path of implementing well-known, already-tested, old-school strategies

Like the Connors "Double 7s" strategy (buy when SPY closes at a 7 day low while above the 200-day MA, sell at a 7 day high)- and I'm still getting very bad results. I don't get it.

What is it about the engine that seems to break even simple stuff that's supposed to work? If I do it manually on TradingView, I get noticeably better results.

I don't understand the whole thing here. its ANNOYING AS F***

What are the caveats or things I need to know in order to structure properly working strategies in cTrader?

Because honestly, it feels like the engine's calculations or the data are skewed or something — I don't even know how to describe it. I don't know where to start, but I've tried simple stuff and it's not working.

Any insight would be appreciated.

So this taken in US500 ok ? same same should be smooth as slik easy peasy ?

well NOT.. i get -7% eventually --- sooo .. annoying

any how this is just a "BASIC" concept startegy nothing facny im just .. tying to make a point here

so a-... help up a brother 🎯

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;


namespace cAlgo.Robots
{
    public enum RiskMode { FixedLots, RiskPercent }


    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Connors7Down7UpBot : Robot
    {
        [Parameter("Consecutive Bars", Group = "Connors Setup", DefaultValue = 7, MinValue = 2)]
        public int ConsecutiveBars { get; set; }


        [Parameter("Use Exit SMA", Group = "Exit Rules", DefaultValue = true)]
        public bool UseExitSma { get; set; }


        [Parameter("Exit SMA Period", Group = "Exit Rules", DefaultValue = 5, MinValue = 1)]
        public int ExitSmaPeriod { get; set; }


        [Parameter("Use 200 Trend Filter", Group = "Trend Filter", DefaultValue = false)]
        public bool UseTrendFilter { get; set; }


        [Parameter("Trend SMA Period", Group = "Trend Filter", DefaultValue = 200, MinValue = 10)]
        public int TrendSmaPeriod { get; set; }


        [Parameter("Risk Mode", Group = "Risk Management", DefaultValue = RiskMode.RiskPercent)]
        public RiskMode AccountRiskMode { get; set; }


        [Parameter("Risk Percent (%)", Group = "Risk Management", DefaultValue = 1.0, MinValue = 0.1)]
        public double RiskPercent { get; set; }


        [Parameter("Fixed Lots", Group = "Risk Management", DefaultValue = 0.1, MinValue = 0.01)]
        public double FixedLots { get; set; }


        [Parameter("Stop Loss (Pips)", Group = "Risk Management", DefaultValue = 50.0, MinValue = 0.0)]
        public double StopLossPips { get; set; }


        [Parameter("Take Profit (Pips)", Group = "Risk Management", DefaultValue = 100.0, MinValue = 0.0)]
        public double TakeProfitPips { get; set; }


        private SimpleMovingAverage _exitSma;
        private SimpleMovingAverage _trendSma;
        private const string Label = "Connors7Down7Up";


        protected override void OnStart()
        {
            _exitSma = Indicators.SimpleMovingAverage(Bars.ClosePrices, ExitSmaPeriod);
            _trendSma = Indicators.SimpleMovingAverage(Bars.ClosePrices, TrendSmaPeriod);
        }


        protected override void OnBar()
        {
            ManageExits();
            CheckEntries();
        }


        private void CheckEntries()
        {
            if (HasActivePosition()) return;


            bool is7Down = IsConsecutiveDown(ConsecutiveBars);
            bool is7Up = IsConsecutiveUp(ConsecutiveBars);


            double lastClose = Bars.ClosePrices.Last(1);


            // Buy Setup: Mean reversion bounce after 7 consecutive down closes
            if (is7Down)
            {
                if (UseTrendFilter && lastClose < _trendSma.Result.Last(1))
                    return;


                double volume = CalculateVolume(StopLossPips);
                ExecuteMarketOrder(TradeType.Buy, SymbolName, volume, Label, 
                    StopLossPips > 0 ? StopLossPips : (double?)null, 
                    TakeProfitPips > 0 ? TakeProfitPips : (double?)null);
            }
            // Sell Setup: Mean reversion pull-back after 7 consecutive up closes
            else if (is7Up)
            {
                if (UseTrendFilter && lastClose > _trendSma.Result.Last(1))
                    return;


                double volume = CalculateVolume(StopLossPips);
                ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, Label, 
                    StopLossPips > 0 ? StopLossPips : (double?)null, 
                    TakeProfitPips > 0 ? TakeProfitPips : (double?)null);
            }
        }


        private void ManageExits()
        {
            if (!UseExitSma) return;


            double lastClose = Bars.ClosePrices.Last(1);
            double smaValue = _exitSma.Result.Last(1);


            foreach (var position in Positions.FindAll(Label, SymbolName))
            {
                // Exit Long when price closes above 5-period SMA
                if (position.TradeType == TradeType.Buy && lastClose > smaValue)
                {
                    ClosePosition(position);
                }
                // Exit Short when price closes below 5-period SMA
                else if (position.TradeType == TradeType.Sell && lastClose < smaValue)
                {
                    ClosePosition(position);
                }
            }
        }


        private bool IsConsecutiveDown(int count)
        {
            for (int i = 1; i <= count; i++)
            {
                if (Bars.ClosePrices.Last(i) >= Bars.ClosePrices.Last(i + 1))
                    return false;
            }
            return true;
        }


        private bool IsConsecutiveUp(int count)
        {
            for (int i = 1; i <= count; i++)
            {
                if (Bars.ClosePrices.Last(i) <= Bars.ClosePrices.Last(i + 1))
                    return false;
            }
            return true;
        }


        private double CalculateVolume(double slPips)
        {
            if (AccountRiskMode == RiskMode.FixedLots)
            {
                double targetUnits = FixedLots * Symbol.LotSize;
                return Symbol.NormalizeVolumeInUnits(targetUnits, RoundingMode.ToNearest);
            }


            double riskPips = slPips > 0 ? slPips : 50.0;
            double riskAmount = Account.Equity * (RiskPercent / 100.0);
            double riskPerPip = riskAmount / riskPips;
            double rawVolume = riskPerPip / Symbol.PipValue;


            return Symbol.NormalizeVolumeInUnits(rawVolume, RoundingMode.ToNearest);
        }


        private bool HasActivePosition()
        {
            return Positions.Any(p => p.Label == Label && p.SymbolName == SymbolName);
        }
    }
}
reddit.com
u/Leo6-2 — 11 days ago