public void createOn(IPosition position, int barIndex) { position.CloseAtStop( barIndex, stopLossPrice, Signals.STOP_LOSS_CLOSE ); }
public void createOn(IPosition position, int barIndex) { double stopLossPrice = 0.0; if (position.IsShort) { stopLossPrice = position.EntryPrice + maxLoss; } else { stopLossPrice = position.EntryPrice - maxLoss; } position.CloseAtStop( barIndex, stopLossPrice, Signals.STOP_LOSS_CLOSE ); }
public void createOn(IPosition position, int barIndex) { double stopLossPrice = based[barIndex - 1] * koeff; if (position.IsShort) { stopLossPrice = position.EntryPrice + stopLossPrice; } else { stopLossPrice = position.EntryPrice - stopLossPrice; } position.CloseAtStop( barIndex, stopLossPrice, Signals.STOP_LOSS_CLOSE ); }
/// <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"); } } }
//================================================================================ public virtual void Execute(IContext ctx, ISecurity source) { int StartBar = 0; #region Variables int MDir; // напраление адаптивной скользящей средней (+1 вверх, -1 вниз) int StdPeriod; // период для определения стандартного отклонения double HighRange, LowRange; // границы диапазона для определения сигналов double kShift; // коэффициент смещения для расчета NRMA double kMShift; // коэффициент смещения для определения границ диапазона double kStd; // коэффициент для стандартного (среднеквадратичного) отклонения double kSharp; // степень для усиления выраженности индикатора NRTR double vNRMA; // значение NRMA для текущего бара double vPrevNRMA; // значение NRMA для предыдущего бара #endregion //-------------------------------------------------------------------------------- #region Init vars MDir = 0; kShift = 10; kSharp = 2; kMShift = 1; StdPeriod = 14; kStd = 0.7; // массив значений для вычисления среднеквадратичного отклонения double[] aMA = new double[StdPeriod]; HighRange = source.HighPrices[StartBar]; LowRange = source.LowPrices[StartBar]; #endregion //-------------------------------------------------------------------------------- // Obtain parameters kMShift = ParamShift; // серия значений индикатора NRMA // кэширование с учетом параметров kShift и kSharp IList <double> nNRMA = ctx.GetData("NRMA", new[] { kShift.ToString() + "_" + kSharp.ToString() }, delegate { return(GenNRMA(source, kShift, kSharp)); }); // серии значений границ диапазона IList <double> nHighRange = new List <double>(source.Bars.Count); IList <double> nLowRange = new List <double>(source.Bars.Count); //================================================================================ #region основной цикл - проход по барам int barsCount = source.Bars.Count; vNRMA = nNRMA[0]; for (int bar = 0; bar < barsCount; bar++) { //-------------------------------------------------------------------------------- #region calculate values // значение NRMA vPrevNRMA = vNRMA; vNRMA = nNRMA[bar]; // определение среднеквадратичнонго отклонения for (int i = 1; i < StdPeriod; i++) { aMA[i - 1] = aMA[i]; } aMA[StdPeriod - 1] = vNRMA; double sum = 0; for (int i = 0; i < StdPeriod; i++) { sum = sum + aMA[i]; } double avg = sum / StdPeriod; sum = 0; for (int i = 0; i < StdPeriod; i++) { sum = sum + Math.Pow((aMA[i] - avg), 2); } double std = Math.Pow(sum, 0.5); // смещение границ диапазона от скользящей средней double MShift = kMShift * std * kStd; // изменение направления индикатора NRMA // при движении вверх if (MDir > -1) { if (vNRMA < vPrevNRMA) { MDir = -1; } if (MDir > -1) { LowRange = vNRMA * (1 - MShift / 100); } } // при движении вниз if (MDir < 1) { if (vNRMA > vPrevNRMA) { MDir = 1; } if (MDir < 1) { HighRange = vNRMA * (1 + MShift / 100); } } #endregion //-------------------------------------------------------------------------------- #region data series // добавление новых значений в последовательности if (bar == 0) { // смещение значений на один бар для соответствия стопов на графике nHighRange.Add(HighRange); nLowRange.Add(LowRange); } nHighRange.Add(HighRange); nLowRange.Add(LowRange); #endregion //-------------------------------------------------------------------------------- #region generate signals // сброс значений сигналов StopBuyPrice = 0; StopSellPrice = 0; StopShortPrice = 0; StopCoverPrice = 0; // установка сигналов по условиям // если направление вверх if (MDir > 0) { StopBuyPrice = HighRange; StopCoverPrice = HighRange; } // если направление вниз if (MDir < 0) { StopSellPrice = LowRange; StopShortPrice = LowRange; } #endregion //================================================================================ #region execute signals //-------------------------------------------------------------------------------- // выполнение сигналов для длинной позиции IPosition LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos == null) { // Если нет активной длинной позиции if (StopBuyPrice > 0) { // Если есть сигнал StopBuy, // выдаем стоп-ордер на открыте новой длинной позиции. source.Positions.BuyIfGreater(bar + 1, 1, StopBuyPrice, "LN"); } } else { // Если есть активная длинная позиция if (StopSellPrice > 0) { // Если есть сигнал StopSell, // выдаем стоп-ордер на закрыте длинной позиции. LongPos.CloseAtStop(bar + 1, StopSellPrice, "LX"); } } //-------------------------------------------------------------------------------- // выполнение сигналов для короткой позиции IPosition ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos == null) { // Если нет активной короткой позиции if (StopShortPrice > 0) { // Если есть сигнал StopShort // выдаем стоп-ордер на открыте новой короткой позиции. source.Positions.SellIfLess(bar + 1, 1, StopShortPrice, "SN"); } } else { // Если есть активная короткая позиция, if (StopCoverPrice > 0) { // Если есть сигнал StopCover // выдаем стоп-ордер на закрыте короткой позиции. ShortPos.CloseAtStop(bar + 1, StopCoverPrice, "SX"); } } #endregion } #endregion //================================================================================ #region прорисовка графиков // Берем основную панель (Pane) IPane mainPane = ctx.First; // Отрисовка mainPane.AddList("NRMA", nNRMA, ListStyles.LINE, 0xa000a0, LineStyles.SOLID, PaneSides.RIGHT); mainPane.AddList("HighRange", nHighRange, ListStyles.LINE, 0x0000a0, LineStyles.DOT, PaneSides.RIGHT); mainPane.AddList("LowRange", nLowRange, ListStyles.LINE, 0xa00000, LineStyles.DOT, PaneSides.RIGHT); #endregion //-------------------------------------------------------------------------------- }