-
Notifications
You must be signed in to change notification settings - Fork 5
/
BollingerBandTrendFollowStrategy.cs
104 lines (79 loc) · 4.02 KB
/
BollingerBandTrendFollowStrategy.cs
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class BollingerBandTrendFollow_cBot : Robot
{
// ********************************
// User defined inputs
// ********************************
// Basic settings
[Parameter("Length", Group ="Basic settings", DefaultValue = 20)]
public int Length { get; set; }
[Parameter("Upper", Group ="Basic settings", DefaultValue = 1)]
public int MultiplierUpper { get; set; }
[Parameter("Lower", Group ="Basic settings", DefaultValue = 0.5)]
public double MultiplierLower { get; set; }
[Parameter("Risk percentage", Group ="Basic settings", DefaultValue = 2.5)]
public double RiskPercentage { get; set; }
[Parameter("Atr Multiplier", Group ="Basic settings", DefaultValue = 2)]
public int AtrMultiplier {get; set;}
[Parameter("Atr Length", Group ="Basic settings", DefaultValue = 20)]
public int AtrLength { get; set; }
// Filter settings
[Parameter("Enable Filter", Group ="Filter settings", DefaultValue =false)]
public bool EnableFilter {get; set;}
[Parameter("Price above SMA(X)", Group ="Filter settings", DefaultValue =200)]
public int SmaLength {get;set;}
[Parameter("RSI > X", Group ="Filter settings", DefaultValue = 0)]
public int RsiValue {get;set;}
protected override void OnStart()
{
}
protected override void OnBarClosed()
{
// **********************************
// Perform calculations and analysis
// **********************************
double stdLastValue = Indicators.StandardDeviation(Bars.ClosePrices, Length, MovingAverageType.Simple).Result.LastValue;
double smaLastValue = Indicators.SimpleMovingAverage(Bars.ClosePrices, Length).Result.LastValue;
double upperBand = smaLastValue + (MultiplierUpper * stdLastValue);
double lowerBand = smaLastValue - (MultiplierLower * stdLastValue);
string label = $"BollingerBandTrendFollow_cBot-{Symbol.Name}";
// Filter
double lastClosePrice = Bars.ClosePrices.LastValue;
bool priceAboveSMA = lastClosePrice > Indicators.SimpleMovingAverage(Bars.ClosePrices, SmaLength).Result.LastValue;
bool rsiAboveValue = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 14).Result.LastValue > RsiValue;
bool filter = EnableFilter ? priceAboveSMA && rsiAboveValue : true;
// Check position
Position position = Positions.Find(label);
bool isOpenPosition = position != null;
// Trade amount
double qty = ((RiskPercentage/100) * Account.Balance) / (AtrMultiplier * Indicators.AverageTrueRange(AtrLength, MovingAverageType.Simple).Result.LastValue);
double qtyInLots = ((int)(qty /Symbol.VolumeInUnitsStep)) * Symbol.VolumeInUnitsStep;
bool buyCondition = lastClosePrice > upperBand && !isOpenPosition && filter;
bool sellCondition = lastClosePrice < lowerBand && isOpenPosition;
// ********************************
// Manage trade
// ********************************
// Entry
if(buyCondition)
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, qtyInLots, label);
}
// Exit
if(sellCondition) {
position.Close();
}
Print("Sucessful call OnBarClosed() method.");
}
}
}