Visual Mode for BackTesting
Visual Mode for BackTesting
22 Mar 2018, 20:08
Hi All,
This page https://spotware.com/ctrader/trading/ctrader-automated-trading-platform
Claims that backtesting visual mode is there. But its actually not in the product? Am I missing something?
Replies
abotrader
08 Oct 2018, 23:05
HI,
My cAlgo version 3.03 is freezing in visual testing when i add this code :
void OnPositionOpened(PositionOpenedEventArgs args) { if (RunningMode != RunningMode.Optimization) { Chart.DrawVerticalLine(Guid.NewGuid().ToString(), args.Position.EntryTime, (args.Position.TradeType == TradeType.Buy ? Color.Red : Color.Blue)); Chart.DrawText(Guid.NewGuid().ToString(), "Opened " + args.Position.TradeType, args.Position.EntryTime, args.Position.EntryPrice, Color.White); } }
@abotrader
PanagiotisCharalampous
09 Oct 2018, 09:59
Hi aboukerker,
Can you please share the complete cBot code so that we can reproduce the issue?
Best Regards,
Panagiotis
@PanagiotisCharalampous
abotrader
09 Oct 2018, 20:50
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class MACD_PSAR_STOCH : Robot { const string Label = "MACD_PSAR_STOCH"; [Parameter(DefaultValue = 1, Step = 1, MaxValue = 1, MinValue = 1)] public int MaxTrades { get; set; } [Parameter(DefaultValue = 70, Step = 1, MaxValue = 300, MinValue = 70)] public double TakeProfit { get; set; } [Parameter(DefaultValue = 300, Step = 1, MaxValue = 350, MinValue = 70)] public double StopLoss { get; set; } // MACD [Parameter(DefaultValue = 26, Step = 1, MaxValue = 50, MinValue = 1)] public int LongCycle { get; set; } [Parameter(DefaultValue = 14, Step = 1, MaxValue = 30, MinValue = 1)] public int ShortCycle { get; set; } [Parameter(DefaultValue = 9, Step = 1, MaxValue = 50, MinValue = 1)] public int Period { get; set; } // Stochastic [Parameter(DefaultValue = 14, Step = 1, MaxValue = 50, MinValue = 1)] public int Kperiod { get; set; } [Parameter(DefaultValue = 3, Step = 1, MaxValue = 50, MinValue = 1)] public int KSlowing { get; set; } [Parameter(DefaultValue = 9, Step = 1, MaxValue = 50, MinValue = 1)] public int Dperiod { get; set; } [Parameter(DefaultValue = 2, Step = 1)] public int RiskPercent { get; set; } [Parameter(DefaultValue = 10, Step = 10)] public int Volume { get; set; } [Parameter(DefaultValue = MovingAverageType.Simple)] public MovingAverageType MAType { get; set; } MacdCrossOver macd; ParabolicSAR sar; StochasticOscillator stoch; protected override void OnStart() { Positions.Opened += OnPositionOpened; Positions.Closed += OnPositionClosed; macd = Indicators.MacdCrossOver(MarketSeries.Close, LongCycle, ShortCycle, Period); sar = Indicators.ParabolicSAR(0.02, 0.2); stoch = Indicators.StochasticOscillator(Kperiod, KSlowing, Dperiod, MAType); } protected override void OnTick() { double Bid = Symbol.Bid; double Ask = Symbol.Ask; double Point = Symbol.TickSize; if (sar.Result.Last(1) > Bid && macd.MACD.IsRising() && macd.MACD.HasCrossedAbove(macd.Signal, 0) && (stoch.PercentK.Last(0) < 35 || (stoch.PercentK.HasCrossedAbove(stoch.PercentD, 0) && stoch.PercentK.IsRising()))) { ClosePositions(TradeType.Sell); if (Check()) { ExecuteMarketOrder(TradeType.Buy, Symbol, CalculateVolume(), Label, StopLoss, TakeProfit); } } else if (sar.Result.Last(1) < Ask && macd.MACD.IsFalling() && macd.MACD.HasCrossedBelow(macd.Signal, 0) && (stoch.PercentK.Last(0) > 60 || (stoch.PercentD.HasCrossedAbove(stoch.PercentK, 0) && stoch.PercentD.IsRising()))) { ClosePositions(TradeType.Buy); if (Check()) { ExecuteMarketOrder(TradeType.Sell, Symbol, CalculateVolume(), Label, StopLoss, TakeProfit); } } } protected override void OnStop() { if (IsBacktesting) { foreach (var pos in Positions.FindAll(Label, Symbol)) { ClosePosition(pos); } } } void OnPositionOpened(PositionOpenedEventArgs args) { if (RunningMode != RunningMode.Optimization) { Chart.DrawVerticalLine(Guid.NewGuid().ToString(), args.Position.EntryTime, (args.Position.TradeType == TradeType.Buy ? Color.Red : Color.Blue)); //Chart.DrawText(Guid.NewGuid().ToString(), "Opened " + args.Position.TradeType, args.Position.EntryTime, args.Position.EntryPrice, Color.White); } } void OnPositionClosed(PositionClosedEventArgs args) { } double CalculateVolume() { double _volume = 0; if (Volume == 0) { // Our total balance is our account balance plus any reserve funds. We do not always keep all our money in the trading account. double totalBalance = Account.Balance / MaxTrades; // Calculate the total risk allowed per trade. double riskPerTrade = (totalBalance * RiskPercent) / 100; // Add the stop loss, commission pips and spread to get the total pips used for the volume calculation. double totalPips = StopLoss + Symbol.Spread + 0.8; // CommissionPips // Calculate the exact volume to be traded. Then round the volume to the nearest 100,000 and convert to an int so that it can be returned to the caller. _volume = Math.Round(riskPerTrade / (Symbol.PipValue * totalPips), 2); } else { _volume = Volume; } return Symbol.NormalizeVolumeInUnits(_volume); } int NumberOfOpenOrders() { return Positions.FindAll(Label, Symbol).Length; } bool Check() { bool result = true; if (NumberOfOpenOrders() >= MaxTrades) { result = false; } else if (Account.MarginLevel != null && Account.MarginLevel < 130) { string msg = String.Format("{0} Check => Equity {1} MarginLevel {2} ", Server.Time, Account.Equity, Account.MarginLevel); Print(msg); result = false; } return result; } void ClosePositions(TradeType tradeType) { foreach (var position in Positions.FindAll(Label, Symbol, tradeType)) { ClosePosition(position); } } double NormalizePrice(double d) { return Math.Round(d, Symbol.Digits); } protected override void OnError(Error error) { Print("Error Code : {0} ", error.Code); if (error.Code == ErrorCode.NoMoney) Stop(); } } }
parameter !
[ChartParameters]
Symbol = MICROSOFT
Timeframe = m1
[cBotParameters]
MaxTrades = 1
TakeProfit = 178
StopLoss = 235
LongCycle = 17
ShortCycle = 5
Period = 15
Kperiod = 11
KSlowing = 38
Dperiod = 20
RiskPercent = 2
Volume = 1
MAType = TimeSeries
@abotrader
PanagiotisCharalampous
10 Oct 2018, 10:11
Hi aboukerker,
I could not reproduce any issue. Visual backtesting seems to be working fine. Can you make sure that this is not caused because of the speed setting?
Best Regards,
Panagiotis
@PanagiotisCharalampous
abotrader
10 Oct 2018, 14:25
Please retry with this method
void OnPositionOpened(PositionOpenedEventArgs args) { if (RunningMode != RunningMode.Optimization) { Chart.DrawVerticalLine(Guid.NewGuid().ToString(), args.Position.EntryTime, (args.Position.TradeType == TradeType.Buy ? Color.Red : Color.Blue)); Chart.DrawText(Guid.NewGuid().ToString(), "Opened " + args.Position.TradeType, args.Position.EntryTime, args.Position.EntryPrice, Color.White); } }
@abotrader
PanagiotisCharalampous
11 Oct 2018, 10:58
Hi aboukerker,
That works fine as well. Is it possible to make a short video with your issue and send it to us?
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
23 Mar 2018, 09:10
Hi yjoura,
The current plan is to release visual backtesting in cTrader Desktop v3.01. Stay tuned!
Best Regards,
Panagiotis
@PanagiotisCharalampous