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