[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); } }