Backtesting in Plugins
cTrader Algo allows for backtesting cBots directly from a plugin, which opens many possibilities for algo developers. Read our one-minute summary below to learn more.
Backtesting in Plugins in One Minute!
- Launch backtesting programatically or in response to user feedback and output the results in any suitable place in the cTrader UI where a plugin could be placed!
- Extend built-in backtesting capabilities inside cTrader by adding new backtesting strategies such as Monte Carlo simulation.
- Add custom statistics to backtesting results and show them directly in the cTrader UI!
- Create complex optimisation methods going beyond the standard genetic algorithm.
How Backtesting in Plugins Works
The Plugin
base class has access to the Backtesting
interface from which it can call the Start()
method with the following signature.
| BacktestingProcess Start(RobotType robotType, string symbolName, TimeFrame timeFrame, BacktestingSettings settings, params object[] parameterValues);
|
Parameters
In the parameterValues
array, cBot parameters must be passed in a fixed order (the order in which they are specified in the cTrader UI). If some parameters are missing, default values are inserted automatically.
Backtesting Processes
When launching backtesting programmatically, you can launch several backtesting processes in parallel, which potentially could save plenty of time for you and users.
In addition, the interface also contains two events, namely ProgressChanged
and Completed
. The arguments for the Completed
event (BacktestingCompletedEventArgs
) contain a JSON object of the final backtesting results (JsonReport
), allowing you to interpret them as needed and display the resulting statistics to new users.
Creating an Example Plugin
The following plugin displays a new block in the ASP. Inside the block, the plugin allows users to choose any cBot they own and backtest it on EURUSD h1. After backtesting concludes, the plugin displays the final ROI and net profit.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 | using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
namespace cAlgo.Plugins
{
[Plugin(AccessRights = AccessRights.None)]
public class BacktestingInPluginsSample : Plugin
{
// Declaring the necessary UI elements
// and the cBot (RobotType) selected in the ComboBox
private Grid _grid;
private ComboBox _cBotsComboBox;
private Button _startBacktestingButton;
private TextBlock _resultsTextBlock;
private RobotType _selectedRobotType;
protected override void OnStart()
{
// Initialising and structuring the UI elements
_grid = new Grid(3, 1);
_cBotsComboBox = new ComboBox();
_startBacktestingButton = new Button
{
BackgroundColor = Color.Green,
CornerRadius = new CornerRadius(5),
Text = "Start Backtesting",
};
_resultsTextBlock = new TextBlock
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Text = "Select a cBot...",
};
_grid.AddChild(_cBotsComboBox, 0, 0);
_grid.AddChild(_startBacktestingButton, 1, 0);
_grid.AddChild(_resultsTextBlock, 2, 0);
var block = Asp.SymbolTab.AddBlock("Backtesting Plugin");
block.Child = _grid;
// Populating the ComboBox with existing cBots
PopulateCBotsComboBox();
// Assigning event handlers to the Button.Click,
// ComboBox.SelectedItemChanged, and Backtesting.Completed events
_startBacktestingButton.Click += StartBacktestingButton_Click;
_cBotsComboBox.SelectedItemChanged += CBotsComboBox_SelectedItemChanged;
Backtesting.Completed += Backtesting_Completed;
}
protected void StartBacktestingButton_Click(ButtonClickEventArgs obj)
{
// Initialising and configuring the backtesting settings
var backtestingSettings = new BacktestingSettings
{
DataMode = BacktestingDataMode.M1,
StartTimeUtc = new DateTime(2023, 6, 1),
EndTimeUtc = DateTime.UtcNow,
Balance = 10000,
};
// Starting backtesting on EURUSD h1
Backtesting.Start(_selectedRobotType, "EURUSD", TimeFrame.Hour, backtestingSettings);
// Disabling other controls and changing
// the text inside the TextBlock
_cBotsComboBox.IsEnabled = false;
_startBacktestingButton.IsEnabled = false;
_resultsTextBlock.Text = "Backtesting in progress...";
}
protected void PopulateCBotsComboBox()
{
// Iterating over the AlgoRegistry and
// getting the names of all installed cBots
foreach (var robotType in AlgoRegistry.OfType<RobotType>())
{
_cBotsComboBox.AddItem(robotType.Name);
}
}
protected void Backtesting_Completed(BacktestingCompletedEventArgs obj)
{
// Attaining the JSON results of backtesting
string jsonResults = obj.JsonReport;
// Converting the JSON string into a JsonNode
JsonNode resultsNode = JsonNode.Parse(jsonResults);
// Attaining the ROI and net profit from backtesting results
_resultsTextBlock.Text = $"ROI: {resultsNode["main"]["roi"]}\nNet Profit: {resultsNode["main"]["netProfit"]}";
// Re-enabling controls after backteting is finished
_cBotsComboBox.IsEnabled = true;
_startBacktestingButton.IsEnabled = true;
}
protected void CBotsComboBox_SelectedItemChanged(ComboBoxSelectedItemChangedEventArgs obj)
{
// Updading the variable to always contain
// the cBto selected in the ComboBox
_selectedRobotType = AlgoRegistry.Get(obj.SelectedItem) as RobotType;
}
}
}
|
The plugin dynamically reacts to the status of the backtesting process. As soon as backtesting is finished, the plugin shows the results in the TextBlock
. The _startBacktestingButton
and the _cBotsComboBox
are disabled throughout backtesting.
Summary
Backtesting via plugins is a powerful feature allowing you to build UI extensions on top of the already poweful backtesting logic provided by cTrader. Coupled with other API members such as AlgoRegistry
, backtesting in plugins offers plenty of possibilities for anyone selling and/or developing cTrader algos.