Cant get Trailing StopLoss Working
Cant get Trailing StopLoss Working
04 Feb 2024, 18:31
Hi first and foremost I would like to apologise if this is in the wrong section of the website :)
For the life of me i cannot get the trailing stop loss to work when i run a backtest the only variables that change the outcome of the cbot is take profit and stop loss this is really confusing me now im very new to coding ive spent a full day on this now before coming here lol i tried, could someone please explain what ive done wrong and how to correct it please?
any help would be very much appreciated thankyou in advance
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.UTC, AccessRights = AccessRights.None)]
public class ADXCrossingBot : Robot
{
private bool isTradeOpen = false;
[Parameter("Instance Name", DefaultValue = "ADX TS")]
public string InstanceName { get; set; }
[Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
[Parameter("ADX Periods", Group = "ADX", DefaultValue = 20, MinValue = 6, Step = 1, MaxValue = 1000)]
public int AdxPeriods { get; set; }
[Parameter("MA", Group = "ADX", DefaultValue = 21, MinValue = 6, Step = 1, MaxValue = 1000)]
public int TrendMME { get; set; }
[Parameter("Take Profit", Group = "Risk", DefaultValue = 150, MinValue = 0, Step = 1, MaxValue = 1000)]
public int TakeProfit { get; set; }
[Parameter("Stop Loss", Group = "Risk", DefaultValue = 150, MinValue = 0, Step = 1, MaxValue = 1000)]
public int StopLoss { get; set; }
//[Parameter("Trade Label", DefaultValue = "ADX Crossing")]
//public string TradeLabel { get; set; }
[Parameter("Include Trailing Stop", Group = "Risk",DefaultValue = true)]
public bool IncludeTrailingStop { get; set; }
[Parameter("Trailing Stop Trigger (pips)", Group = "Risk", DefaultValue = 20)]
public double TrailingStopTrigger { get; set; }
[Parameter("Trailing Stop Step (pips)", Group = "Risk", DefaultValue = 10)]
public double TrailingStopStep { get; set; }
private DirectionalMovementSystem adx;
private double volumeInUnits;
private ExponentialMovingAverage mme;
private RelativeStrengthIndex rsi;
protected override void OnStart()
{
volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
adx = Indicators.DirectionalMovementSystem(AdxPeriods);
mme = Indicators.ExponentialMovingAverage(Bars.ClosePrices, TrendMME);
rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 14);
Positions.Closed += OnPositionClosed;
}
protected override void OnTick()
{
// Check if a trade is already open
if (isTradeOpen)
return;
if (IncludeTrailingStop)
{
// Trailing stop logic
SetTrailingStop();
}
if (adx.DIMinus.Last(3) < adx.DIPlus.Last(3) && adx.DIMinus.Last(1) > adx.DIPlus.Last(1) && adx.DIMinus.LastValue > adx.DIPlus.LastValue)
{
if (Symbol.Bid < mme.Result.Last(2))
if (rsi.Result.LastValue <= 70)
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, volumeInUnits, InstanceName, StopLoss, TakeProfit);
isTradeOpen = true;
}
}
else if (adx.DIPlus.Last(3) < adx.DIMinus.Last(3) && adx.DIPlus.Last(1) > adx.DIMinus.Last(1) && adx.DIPlus.LastValue > adx.DIMinus.LastValue)
{
if (Symbol.Bid > mme.Result.Last(2))
if (rsi.Result.LastValue >= 30)
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, volumeInUnits, InstanceName, StopLoss, TakeProfit);
isTradeOpen = true;
}
}
}
private void SetTrailingStop()
{
var sellPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Sell);
foreach (var position in sellPositions)
{
double distance = position.EntryPrice - Symbol.Ask;
if (distance < TrailingStopTrigger * Symbol.PipSize)
continue;
double newStopLossPrice = Symbol.Ask + TrailingStopStep * Symbol.PipSize;
double newTakeProfit = position.TakeProfit ?? 0;
if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, newTakeProfit);
Print("Trailing Stop Loss triggered...");
}
}
var buyPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Buy);
foreach (var position in buyPositions)
{
double distance = Symbol.Bid - position.EntryPrice;
if (distance < TrailingStopTrigger * Symbol.PipSize)
continue;
double newStopLossPrice = Symbol.Bid - TrailingStopStep * Symbol.PipSize;
double newTakeProfit = position.TakeProfit ?? 0;
if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, newTakeProfit);
Print("Trailing Stop Loss triggered...");
}
}
}
private void OnPositionClosed(PositionClosedEventArgs args)
{
// Reset the flag when a position is closed
isTradeOpen = false;
if (args.Position.Label != InstanceName) //Comment changed to InstanceName
return;
if (args.Reason == PositionCloseReason.StopLoss || args.Reason == PositionCloseReason.TakeProfit)
{
Print($"Position closed by {args.Reason}. Profit: {args.Position.GrossProfit}");
}
}
}
}