Skip to content

Commit 70a2acc

Browse files
authored
Merge pull request spotware#9 from spotware/sk/CNT-622-custom-fithess-function
Custom Fitness example added
2 parents 366bf0f + b57ba3c commit 70a2acc

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.31729.503
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Custom Fitness Functions", "Custom Fitness Functions\Custom Fitness Functions.csproj", "{49475144-FF7C-4585-9AD9-C08086B6F166}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{49475144-FF7C-4585-9AD9-C08086B6F166}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{49475144-FF7C-4585-9AD9-C08086B6F166}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{49475144-FF7C-4585-9AD9-C08086B6F166}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{49475144-FF7C-4585-9AD9-C08086B6F166}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {F2873C00-C250-48B2-AD49-9ECC1163E33A}
24+
EndGlobalSection
25+
EndGlobal
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// -------------------------------------------------------------------------------------------------
2+
//
3+
// This code is a cTrader Automate API example.
4+
//
5+
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
6+
// profit of any kind. Use it at your own risk.
7+
//
8+
// All changes to this file might be lost on the next application update.
9+
// If you are going to modify this file please make a copy using the "Duplicate" command.
10+
//
11+
// This example is based on the "Sample Trend cBot". The "Sample Trend cBot" will buy when fast period moving average crosses the slow period moving average and sell when
12+
// the fast period moving average crosses the slow period moving average. The orders are closed when an opposite signal
13+
// is generated. There can only by one Buy or Sell order at any time. The bot also includes a custom fitness function for optimisation.
14+
//
15+
// -------------------------------------------------------------------------------------------------
16+
17+
using cAlgo.API;
18+
using cAlgo.API.Indicators;
19+
using System;
20+
using System.Linq;
21+
22+
namespace cAlgo
23+
{
24+
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
25+
public class CustomFitnessFunctions : Robot
26+
{
27+
[Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
28+
public double Quantity { get; set; }
29+
30+
[Parameter("MA Type", Group = "Moving Average")]
31+
public MovingAverageType MAType { get; set; }
32+
33+
[Parameter("Source", Group = "Moving Average")]
34+
public DataSeries SourceSeries { get; set; }
35+
36+
[Parameter("Slow Periods", Group = "Moving Average", DefaultValue = 10)]
37+
public int SlowPeriods { get; set; }
38+
39+
[Parameter("Fast Periods", Group = "Moving Average", DefaultValue = 5)]
40+
public int FastPeriods { get; set; }
41+
42+
private MovingAverage slowMa;
43+
private MovingAverage fastMa;
44+
private const string label = "Sample Trend cBot";
45+
46+
protected override void OnStart()
47+
{
48+
fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType);
49+
slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType);
50+
}
51+
52+
protected override void OnTick()
53+
{
54+
var longPosition = Positions.Find(label, SymbolName, TradeType.Buy);
55+
var shortPosition = Positions.Find(label, SymbolName, TradeType.Sell);
56+
57+
var currentSlowMa = slowMa.Result.Last(0);
58+
var currentFastMa = fastMa.Result.Last(0);
59+
var previousSlowMa = slowMa.Result.Last(1);
60+
var previousFastMa = fastMa.Result.Last(1);
61+
62+
if (previousSlowMa > previousFastMa && currentSlowMa <= currentFastMa && longPosition == null)
63+
{
64+
if (shortPosition != null)
65+
ClosePosition(shortPosition);
66+
67+
ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, label);
68+
}
69+
else if (previousSlowMa < previousFastMa && currentSlowMa >= currentFastMa && shortPosition == null)
70+
{
71+
if (longPosition != null)
72+
ClosePosition(longPosition);
73+
74+
ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, label);
75+
}
76+
}
77+
78+
private double VolumeInUnits
79+
{
80+
get { return Symbol.QuantityToVolumeInUnits(Quantity); }
81+
}
82+
83+
protected override double GetFitness(GetFitnessArgs args)
84+
{
85+
if(args.TotalTrades > 20 && args.MaxEquityDrawdownPercentages < 50)
86+
{
87+
return Math.Pow(args.WinningTrades + 1, 2) / (args.LosingTrades + 1);
88+
}
89+
else
90+
{
91+
return double.MinValue;
92+
}
93+
}
94+
}
95+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net6.0</TargetFramework>
4+
</PropertyGroup>
5+
6+
<ItemGroup>
7+
<PackageReference Include="cTrader.Automate" Version="1.*-*" />
8+
</ItemGroup>
9+
</Project>

0 commit comments

Comments
 (0)