public double Execute(IPosition pos, int barNum) { if (pos == null) { return(0); } // ReSharper disable CompareOfFloatsByEqualityOperator return(pos.Shares == 0 ? 0 : pos.CurrentProfitPct(barNum)); // ReSharper restore CompareOfFloatsByEqualityOperator }
/// <summary> /// Выставление стоп-лосса для позиции, включая стоп-лосс для перевода позициив безубыток /// </summary> /// <param name="pos">Позиция, для которой выставляется стоп-лосс</param> public void SetStopLoss(IPosition pos, int numBar) { if (pos == null || !pos.IsActiveForBar(numBar)) { return; } // предельно минимальное значение стоп-лоса для позиции double minLimitStopLoss = (pos.IsLong) ? 0 : double.MaxValue; // предыдущее значение стоп-лосса для позиции double prevStopPrice = (pos.GetStop(numBar) != 0) ? pos.GetStop(numBar) : minLimitStopLoss; // новое значение стоп-лосса double stopPrice = 0; // значение стоп-лосса для перевода позиции в безубыток double breakevenStopPrice; if (OnStopLoss || OnBreakevenStop) { // вычисляем обычный стоп-лосс if (OnStopLoss && _stopType == StopType.Stop) { stopPrice = pos.GetStopPrice(StopLossPct); } // вычисляем трейл-стоп else if (OnStopLoss && _stopType == StopType.Trail) { stopPrice = _trailStopHnd.Execute(pos, numBar); } // вычисляем стоп для перевода позиции в безубыток if (OnBreakevenStop && pos.CurrentProfitPct(numBar) > ProfitForBreakevenPct) { breakevenStopPrice = (pos.IsLong) ? pos.EntryPrice + 10 * pos.Security.Tick : pos.EntryPrice - 10 * pos.Security.Tick; if (pos.IsLong) { stopPrice = Math.Max(stopPrice, breakevenStopPrice); } else if (pos.IsShort) { stopPrice = (stopPrice == 0) ? breakevenStopPrice : (Math.Min(stopPrice, breakevenStopPrice)); } } // Сравниваем с предыдущим значением стопа // и берем максимальное или минимальное значение в зависимости от позиции if (pos.IsLong) { stopPrice = Math.Max(stopPrice, prevStopPrice); } else if (pos.IsShort) { stopPrice = (stopPrice == 0)? prevStopPrice : (Math.Min(stopPrice, prevStopPrice)); } // если значение стопа было вычислено, то выставляем стоп на следующий бар if (pos.IsLong && stopPrice != 0) { pos.CloseAtStop(numBar + 1, stopPrice, Slippage * pos.Security.Tick, "LXS"); } else if (pos.IsShort && Math.Abs(stopPrice - double.MaxValue) > Eps) { pos.CloseAtStop(numBar + 1, stopPrice, Slippage * pos.Security.Tick, "SXS"); } } }