[HandlerName("TrailStopStd")]
[HandlerCategory("vvTrade")]
public class TrailStop : IPosition2Double
{
[HandlerParameter(true, "1.5", Min = "0.1", Max = "0.6", Step = "0.05", Name = "Stop Loss")]
public double StopLoss { get; set; }
[HandlerParameter(true, "0.5", Min = "0.1", Max = "0.6", Step = "0.05", Name = "Trail Enable")]
public double TrailEnable { get; set; }
[HandlerParameter(true, "0.5", Min = "0.1", Max = "1.5", Step = "0.05", Name = "Trail Loss")]
public double TrailLoss { get; set; }
public double Execute(IPosition pos, int barNum)
{
if (pos == null) return 0;
//
var curProfit = pos.OpenMFEPct(barNum);
//---- сразу делаем расчёт стопа, будто трейл не включен
double shift = (0 - StopLoss) / 100;
double stop = pos.EntryPrice * (1 + (pos.IsLong ? shift : -shift));
double entrystop = stop;
//---- если трейл включен
if (curProfit > TrailEnable)
{
shift = (curProfit - TrailLoss) / 100;
stop = pos.EntryPrice * (1 + (pos.IsLong ? shift : -shift));
}
//---- проверяем, чтобы стоп был правильным (при включении трейла не уходил ниже\выше
//---- начального стоплосса)
stop = pos.IsLong ? (Math.Max(stop, entrystop)) : (Math.Min(stop, entrystop));
var lastStop = pos.GetStop(barNum);
if (lastStop == 0)
{
return stop;
}
return pos.IsLong ? Math.Max(stop, lastStop) : Math.Min(stop, lastStop);
}
}