public void draw(IContext context) { ISecurity baseSource = source.getBaseSource(); IDictionary <int, Trade> trades = source.getBarIndexedTrades(); IList <double> losses = new List <double>(baseSource.Bars.Count); IList <double> wins = new List <double>(baseSource.Bars.Count); for (int i = 0; i < baseSource.Bars.Count; i++) { if (trades.ContainsKey(i)) { if (trades[i].getProfit() > 0) { wins.Add(1); losses.Add(0); } else { wins.Add(0); losses.Add(1); } } else { wins.Add(0); losses.Add(0); } } IPane tradesPanel = context.CreatePane("Trades", 10.0, true); tradesPanel.AddList( "Win trades", wins, ListStyles.HISTOHRAM, 0x00ff00, LineStyles.SOLID, PaneSides.VSIDE_LAST ); tradesPanel.AddList( "Loss trades", losses, ListStyles.HISTOHRAM, 0xff0000, LineStyles.SOLID, PaneSides.VSIDE_LAST ); }
public PnLReport draw(IContext context) { IPane profitPane = context.CreatePane("Profit", 20.0, true); if (null != profitSource) { profitPane.AddList( "ProfitPerMonth", profitSource, ListStyles.HISTOHRAM, 0x336699, LineStyles.SOLID, PaneSides.VSIDE_LAST ); } if (null != maxLossSource) { profitPane.AddList( "MaxLossPerMonth", maxLossSource, ListStyles.HISTOHRAM, 0xff00000, LineStyles.SOLID, PaneSides.VSIDE_LAST ); } if (null != profitSource) { IList <double> profitSma = context.GetData( "ProfitSma", new[] { "3" }, delegate { return(Series.SMA(profitSource, 3)); } ); profitPane.AddList( "ProfitPerMonthSma", profitSma, ListStyles.LINE, 0xff0000, LineStyles.SOLID, PaneSides.LEFT ); } return(this); }
//================================================================================ public virtual void Execute(IContext ctx, ISecurity source) { #region Variables int Period; // период расчета ATR double vATR; // значение ATR для текущего бара int Dir; // направление тренда (+1 вверх, -1 вниз) int PrevDir; // предыдущее направление тренда double Up; // значение верхней границы для текущего бара double Down; // значение нижней границы для текущего бара double Multiplier; // множитель double vTrend; double PrevUp, PrevDown; double Price; // цена закрытия текущего бара double AvgPrice; // средняя цена дл ятекущего бара // серия значений верхней границы IList <double> nHighRange = new List <double>(source.Bars.Count); // серия значений нижней границы IList <double> nLowRange = new List <double>(source.Bars.Count); // серия значений для фильтра тренда IList <double> nDir = new List <double>(source.Bars.Count); // серия значений индикатора тренда IList <double> nTrend = new List <double>(source.Bars.Count); #endregion //-------------------------------------------------------------------------------- #region Init vars Dir = 0; Up = 0; Down = 0; #endregion //-------------------------------------------------------------------------------- #region Obtain parameters Period = PeriodParam; Multiplier = MultiplierParam; // серия значений ATR // кэширование с учетом параметра Period IList <double> nATR = ctx.GetData("ATR", new[] { Period.ToString() }, delegate { return(GenATR(source, Period)); }); #endregion //================================================================================ #region основной цикл - проход по барам int barsCount = source.Bars.Count; vATR = source.ClosePrices[0]; for (int bar = 0; bar < barsCount; bar++) { //-------------------------------------------------------------------------------- #region calculate values Price = source.ClosePrices[bar]; vATR = nATR[bar]; vTrend = 0; PrevUp = Up; PrevDown = Down; PrevDir = Dir; AvgPrice = (source.HighPrices[bar] + source.LowPrices[bar]) / 2; Up = AvgPrice + Multiplier * vATR; Down = AvgPrice - Multiplier * vATR; if (Price > PrevUp) { Dir = 1; } if (Price < PrevDown) { Dir = -1; } if (Dir > 0 && Down < PrevDown) { Down = PrevDown; } if (Dir < 0 && Up > PrevUp) { Up = PrevUp; } if (Dir > 0 && PrevDir < 0) { Down = AvgPrice - Multiplier * vATR; } if (Dir < 0 && PrevDir > 0) { Up = AvgPrice + Multiplier * vATR; } if (Dir == 1) { vTrend = Down; } if (Dir == -1) { vTrend = Up; } #endregion //-------------------------------------------------------------------------------- #region data series nHighRange.Add(Up); nLowRange.Add(Down); nATR.Add(vATR); nDir.Add(Dir); nTrend.Add(vTrend); #endregion //-------------------------------------------------------------------------------- #region generate signals // сброс значений сигналов bBuy = false; bSell = false; bShort = false; bCover = false; // установка сигналов по условиям if (Dir > 0 && PrevDir <= 0) { bBuy = true; bCover = true; } if (Dir < 0 && PrevDir >= 0) { bShort = true; bSell = true; } #endregion //================================================================================ #region execute signals //-------------------------------------------------------------------------------- // выполнение сигналов для длинной позиции IPosition LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos == null) { // Если нет активной длинной позиции if (bBuy) { // Если есть сигнал Buy, // выдаем ордер на открыте новой длинной позиции. source.Positions.BuyAtMarket(bar + 1, 1, "LN"); } } else { // Если есть активная длинная позиция if (bSell) { // Если есть сигнал Sell, // выдаем ордер на закрыте длинной позиции. LongPos.CloseAtMarket(bar + 1, "LX"); } } //-------------------------------------------------------------------------------- // выполнение сигналов для короткой позиции IPosition ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos == null) { // Если нет активной короткой позиции if (bShort) { // Если есть сигнал Short // выдаем ордер на открыте новой короткой позиции. source.Positions.SellAtMarket(bar + 1, 1, "SN"); } } else { // Если есть активная короткая позиция, if (bCover) { // Если есть сигнал Cover // выдаем ордер на закрыте короткой позиции. ShortPos.CloseAtMarket(bar + 1, "SX"); } } #endregion } #endregion //================================================================================ #region прорисовка графиков // Берем основную панель (Pane) IPane mainPane = ctx.First; // Отрисовка верхней и нижней границы условных прямоугольников //mainPane.AddList("HighRange", nHighRange, ListStyles.LINE, 0x0000a0, LineStyles.DOT, PaneSides.RIGHT); //mainPane.AddList("LowRange", nLowRange, ListStyles.LINE, 0xa00000, LineStyles.DOT, PaneSides.RIGHT); mainPane.AddList("Trend Indicator", nTrend, ListStyles.LINE, 0xa000a0, LineStyles.DOT, PaneSides.RIGHT); // Создаем дополнительную панель для ATR. IPane ATRPane = ctx.CreatePane("ATR", 10, false, false); // Отрисовка графика ATR ATRPane.AddList(string.Format("ATR"), nATR, ListStyles.LINE, 0x5050a0, LineStyles.SOLID, PaneSides.RIGHT); // Создаем дополнительную панель для филтра тренда. IPane FilterPane = ctx.CreatePane("Filtr", 10, false, false); // Отрисовка графика фильтра тренда FilterPane.AddList(string.Format("TREND"), nDir, ListStyles.HISTOHRAM_FILL, 0x00ff00, LineStyles.SOLID, PaneSides.RIGHT); #endregion //-------------------------------------------------------------------------------- }
//================================================================================ 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 //-------------------------------------------------------------------------------- }