Adding a Trailing stop
Adding a Trailing stop
27 Nov 2020, 13:57
Hi together, i tried to set a trailing stop to this bot. but it doesn't work and i don't know why.
Is anyone able to fix this? The bot has good results in backtesting and i think with a trailing stop it could be nice.
thx for your help
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.None)]
public class Gerbil : Robot
{
[Parameter("Start Hour", DefaultValue = 10.0)]
public double StartTime { get; set; }
[Parameter("Stop Hour", DefaultValue = 12.0)]
public double StopTime { get; set; }
[Parameter("Take Profit (Pips)", DefaultValue = 6, MinValue = 1, Step = 1)]
public int TakeProfit { get; set; }
[Parameter("Stop Loss (Pips)", DefaultValue = 150, MinValue = 1, Step = 1)]
public int StopLoss { get; set; }
[Parameter("trigger ", DefaultValue = 20)]
public int Trigger { get; set; }
[Parameter("Trailing", DefaultValue = 10)]
public int Trailing { get; set; }
[Parameter("Calculate Volume by Percentage?", DefaultValue = false)]
public bool RiskPercent { get; set; }
[Parameter("Quantity (%Risk or Lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
[Parameter("RSI Source")]
public DataSeries RSISource { get; set; }
[Parameter("RSI Period", DefaultValue = 7, MinValue = 1, Step = 1)]
public int RSIPeriods { get; set; }
[Parameter("RSI Overbought Level", DefaultValue = 80, MinValue = 1, Step = 1)]
public int RSIOverB { get; set; }
[Parameter("RSI Oversold Level", DefaultValue = 40, MinValue = 1, Step = 1)]
public int RSIOverS { get; set; }
[Parameter("ATR Periods", DefaultValue = 15, MinValue = 1, Step = 1)]
public int ATRPeriods { get; set; }
[Parameter("ATR From", DefaultValue = 10, MinValue = 1, Step = 1)]
public int ATRFrom { get; set; }
[Parameter("ATR To", DefaultValue = 100, MinValue = 1, Step = 1)]
public int ATRTo { get; set; }
[Parameter("Max Positions", DefaultValue = 1, MinValue = 1, Step = 1)]
public int MaxPos { get; set; }
[Parameter("Max DD Positions", DefaultValue = 0, MinValue = 0, Step = 1)]
public int MaxDDPos { get; set; }
[Parameter("KillHours", DefaultValue = 0, MinValue = 0, Step = 1)]
public int KillHours { get; set; }
private DateTime _startTime;
private DateTime _stopTime;
private RelativeStrengthIndex rsi;
private AverageTrueRange atr;
private int DDPos = 0;
private const string label = "SampleRSI";
protected override void OnStart()
{
rsi = Indicators.RelativeStrengthIndex(RSISource, RSIPeriods);
atr = Indicators.AverageTrueRange(ATRPeriods, MovingAverageType.Simple);
{
// Start Time is the same day at 22:00:00 Server Time
_startTime = Server.Time.Date.AddHours(StartTime);
// Stop Time is the next day at 06:00:00
_stopTime = Server.Time.Date.AddHours(StopTime);
Print("Start Time {0},", _startTime);
Print("Stop Time {0},", _stopTime);
}
}
protected override void OnBar()
{
if (Trade.IsExecuting)
return;
var currentHours = Server.Time.TimeOfDay.TotalHours;
bool tradeTime = StartTime < StopTime ? currentHours > StartTime && currentHours < StopTime : currentHours < StopTime || currentHours > StartTime;
if (!tradeTime)
return;
if (Positions.Count != 0)
return;
{
var atrVal = atr.Result.LastValue * 100000;
if (atrVal > ATRFrom && atrVal < ATRTo)
{
if (Positions.Count < MaxPos)
{
if (rsi.Result.LastValue < RSIOverS)
{
Open(TradeType.Buy);
}
else if (rsi.Result.LastValue > RSIOverB)
{
Open(TradeType.Sell);
}
}
}
}
if (KillHours != 0)
{
foreach (var position in Positions.FindAll("SampleRSI", Symbol))
{
if (Time > position.EntryTime.AddMinutes(KillHours * 60))
ClosePosition(position);
}
}
}
private void Open(TradeType tradeType)
{
//var position = Positions.Find("SampleRSI", Symbol, tradeType);
var volumeInUnits = CalculateVolume();
ExecuteMarketOrder(tradeType, Symbol, volumeInUnits, "SampleRSI", StopLoss, TakeProfit);
}
private void TRAILING()
{
if (Trailing > 0 && Trigger > 0)
{
Position[] positions = Positions.FindAll(label, Symbol);
foreach (Position position in positions)
{
if (position.TradeType == TradeType.Sell)
{
double distance = position.EntryPrice - Symbol.Ask;
if (distance >= Trigger * Symbol.PipSize)
{
double newStopLossPrice = Symbol.Ask + Trailing * Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
else
{
double distance = Symbol.Bid - position.EntryPrice;
if (distance >= Trigger * Symbol.PipSize)
{
double newStopLossPrice = Symbol.Bid - Trailing * Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
}
}
}
double CalculateVolume()
{
if (!RiskPercent)
{
return (Symbol.QuantityToVolumeInUnits(Quantity));
}
else
{
// Calculate the total risk allowed per trade.
double riskPerTrade = (Account.Balance * Quantity) / 100;
double totalSLPipValue = (StopLoss + Symbol.Spread) * Symbol.PipValue;
double calculatedVolume = riskPerTrade / totalSLPipValue;
double normalizedCalculatedVolume = Symbol.NormalizeVolumeInUnits(calculatedVolume, RoundingMode.ToNearest);
return normalizedCalculatedVolume;
}
}
}
}
firemyst
29 Nov 2020, 09:57
How did you "try" adding a trailing stop loss?
The simple way to do it is:
position.ModifyTrailingStop(true);
or
position.ModifyTrailingStop(false);
@firemyst