public void Initialise(StockSerie serie)
 {
     this.stockSerie = serie;
     this.lowSerie = stockSerie.GetSerie(StockDataType.LOW);
     this.highSerie = stockSerie.GetSerie(StockDataType.HIGH);
     this.closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
 }
        public override void ApplyTo(StockSerie stockSerie)
        {
            this.CreateEventSeries(stockSerie.Count);

             FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE).CalculateEMA((int)this.parameters[1]);
             FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);
             FloatSerie hlSerie= new FloatSerie(stockSerie.Count, this.SerieNames[0]);
             this.Series[0] = hlSerie;

             int period = (int)this.parameters[0];

             float min, max;
             for (int i = 0; i < period; i++)
             {
            min = lowSerie.GetMin(0, i);
            max = highSerie.GetMax(0, i);
            hlSerie[i] = (min + max)/2f;
             }
             for (int i = period; i < stockSerie.Count; i++)
             {
            min = lowSerie.GetMin(i-period, i);
            max = highSerie.GetMax(i - period, i);
            hlSerie[i] = (min + max)/2f;
             }

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);
             for (int i = 2; i < hlSerie.Count; i++)
             {
            this.eventSeries[0][i] = (hlSerie[i - 2] > hlSerie[i - 1] && hlSerie[i - 1] < hlSerie[i]);
            this.eventSeries[1][i] = (hlSerie[i - 2] < hlSerie[i - 1] && hlSerie[i - 1] > hlSerie[i]);
            this.eventSeries[2][i] = closeSerie[i - 1] < hlSerie[i - 1] && closeSerie[i] > hlSerie[i];
            this.eventSeries[3][i] = closeSerie[i - 1] > hlSerie[i - 1] && closeSerie[i] < hlSerie[i];
            this.eventSeries[4][i] = lowSerie[i] > hlSerie[i] && lowSerie[i - 1] < hlSerie[i - 1];
            this.eventSeries[5][i] = highSerie[i] < hlSerie[i] && highSerie[i - 1] > hlSerie[i - 1];
            this.eventSeries[6][i] = lowSerie[i] > hlSerie[i] && closeSerie[i - 1] < closeSerie[i];
            this.eventSeries[7][i] = highSerie[i] < hlSerie[i] && closeSerie[i - 1] > closeSerie[i];
            if (this.eventSeries[8][i - 1])
            {
               // Check if BullRun Persists
               this.eventSeries[8][i] = !this.eventSeries[5][i];
            }
            else
            {
               // Check if BullRun Starts
               this.eventSeries[8][i] = this.eventSeries[4][i];
            }
            if (this.eventSeries[9][i - 1])
            {
               // Check if BearRun Persists
               this.eventSeries[9][i] = !this.eventSeries[4][i];
            }
            else
            {
               // Check if BearRun Starts
               this.eventSeries[9][i] = this.eventSeries[5][i];
            }
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
             FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);
             int fastPeriod = (int)this.parameters[0];
             int slowPeriod = (int)this.parameters[1];
             FloatSerie maSerie = closeSerie.CalculateKEMA(fastPeriod, slowPeriod);
             this.series[0] = maSerie;
             this.series[0].Name = this.Name;

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);
             for (int i = 2; i < maSerie.Count; i++)
             {
            this.eventSeries[0][i] = (maSerie[i - 2] > maSerie[i - 1] && maSerie[i - 1] < maSerie[i]);
            this.eventSeries[1][i] = (maSerie[i - 2] < maSerie[i - 1] && maSerie[i - 1] > maSerie[i]);
            this.eventSeries[2][i] = closeSerie[i-1] < maSerie[i-1] && closeSerie[i] > maSerie[i];
            this.eventSeries[3][i] = closeSerie[i-1] > maSerie[i-1] && closeSerie[i] < maSerie[i];
            this.eventSeries[4][i] = lowSerie[i] > maSerie[i] && lowSerie[i - 1] < maSerie[i - 1];
            this.eventSeries[5][i] = highSerie[i] < maSerie[i] && highSerie[i - 1] > maSerie[i - 1];
            this.eventSeries[6][i] = lowSerie[i] > maSerie[i] && closeSerie[i - 1] < closeSerie[i];
            this.eventSeries[7][i] = highSerie[i] < maSerie[i] && closeSerie[i - 1] > closeSerie[i];
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie lowEMASerie = stockSerie.GetIndicator(this.SerieNames[0]).Series[0];
            FloatSerie highEMASerie = stockSerie.GetIndicator(this.SerieNames[1]).Series[0];

            FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
            FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
            FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);

            this.Series[0] = lowEMASerie;
            this.Series[1] = highEMASerie;

            // Detecting events
            this.CreateEventSeries(stockSerie.Count);

            for (int i = (int)this.parameters[0]; i < stockSerie.Count; i++)
            {
                if (lowSerie[i] > highEMASerie[i])
                {
                    this.Events[0][i] = true;
                    if (!this.Events[0][i-1])
                        this.Events[2][i] = true;
                }
                else if (highSerie[i] < lowEMASerie[i])
                {
                    this.Events[1][i] = true;
                    if (!this.Events[1][i - 1])
                        this.Events[3][i] = true;
                }
                else
                {
                    this.Events[4][i] = true;
                }
            }
        }
        public override void Initialise(StockSerie stockSerie, StockOrder lastBuyOrder, bool supportShortSelling)
        {
            base.Initialise(stockSerie, lastBuyOrder, supportShortSelling);

             IStockIndicator indicator = TriggerIndicator as IStockIndicator;
             middleUpBandSerie = indicator.Series[1];
             middleBandSerie = indicator.Series[2];
             middleDownBandSerie = indicator.Series[3];

             lowSerie = stockSerie.GetSerie(StockDataType.LOW);
             highSerie = stockSerie.GetSerie(StockDataType.HIGH);
             closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie emaSerie = stockSerie.GetSerie(StockDataType.CLOSE).CalculateEMA((int)this.Parameters[0]);
             FloatSerie indexSerie = new FloatSerie(stockSerie.Count);

             for (int i = 1; i < stockSerie.Count; i++)
             {
            int count = 0;
            for (int j = i - 1; j >= 0; j--)
            {
               if (emaSerie[i] > emaSerie[j])
               {
                  count++;
               }
               else
               {
                  break;
               }
            }
            indexSerie[i] = count;
             }

             this.series[0] = indexSerie;
             this.Series[0].Name = this.Name;
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH).CalculateEMA((int)this.Parameters[1]);
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW).CalculateEMA((int)this.Parameters[1]);
             FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE).CalculateEMA((int)this.Parameters[1]);

             FloatSerie atrSerie = new FloatSerie(stockSerie.Count);

             for (int i = 1; i < stockSerie.Count; i++)
             {
            atrSerie[i] = 100f*(highSerie[i] - lowSerie[i]) / closeSerie[i - 1];
             }

             this.series[0] = atrSerie.CalculateEMA((int)this.Parameters[0]);
             this.Series[0].Name = this.Name;
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie atrSerie = stockSerie.GetSerie(StockDataType.ATR).CalculateEMA((int)this.Parameters[0]);
             FloatSerie lowCloseSerie = new FloatSerie(stockSerie.Count);
             int i = 0;
             foreach (StockDailyValue dailyValue in stockSerie.Values)
             {
            lowCloseSerie[i++] = dailyValue.CLOSE - dailyValue.LOW;
             }
             lowCloseSerie = lowCloseSerie.CalculateEMA((int)this.Parameters[0]);
             lowCloseSerie = lowCloseSerie / atrSerie;
             lowCloseSerie = (lowCloseSerie * 100.0f) - 50.0f;

             this.series[0] = lowCloseSerie.CalculateEMA((int)this.Parameters[0] / 4);
             this.Series[0].Name = this.Name;
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
             int period = (int)this.parameters[0];
             int iteration = (int)this.parameters[1];

             FloatSerie memaSerie = closeSerie;
             for (int i = 0; i < iteration; i++)
             {
            memaSerie = memaSerie.CalculateEMA(period);
             }
            this.series[0] = memaSerie;
             this.series[0].Name = this.Name;

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);
             for (int i = 2; i < memaSerie.Count; i++)
             {
            this.eventSeries[0][i] = (memaSerie[i - 2] > memaSerie[i - 1] && memaSerie[i - 1] < memaSerie[i]);
            this.eventSeries[1][i] = (memaSerie[i - 2] < memaSerie[i - 1] && memaSerie[i - 1] > memaSerie[i]);
            this.eventSeries[2][i] = closeSerie[i] > memaSerie[i];
            this.eventSeries[3][i] = closeSerie[i] < memaSerie[i];
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
             FloatSerie rsiSerie;
             if (closeSerie.Min <= 0.0f)
             {
            rsiSerie = closeSerie.CalculateRSI((int)this.parameters[0], false);
             }
             else
             {
            rsiSerie = closeSerie.CalculateRSI((int)this.parameters[0], true);
             }
             rsiSerie = rsiSerie.CalculateEMA((int)this.parameters[1]);

             FloatSerie trailSerie = rsiSerie.CalculateHLTrail((int)this.parameters[2]);

             this.series[0] = rsiSerie;
             this.series[0].Name = this.SerieNames[0];
             this.series[1] = trailSerie;
             this.series[1].Name = this.SerieNames[1];

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             float overbought = (float)this.parameters[3];
             float oversold = (float)this.parameters[4];

             bool isOverSold = false;
             bool isOverBought = false;

             for (int i = 1; i < rsiSerie.Count; i++)
             {
            int j = 0;
            this.eventSeries[j++][i] = rsiSerie[i] > trailSerie[i];
            this.eventSeries[j++][i] = rsiSerie[i] < trailSerie[i];
            this.eventSeries[j++][i] = (rsiSerie[i - 1] < trailSerie[i - 1] && rsiSerie[i] > trailSerie[i]);
            this.eventSeries[j++][i] = (rsiSerie[i - 1] > trailSerie[i - 1] && rsiSerie[i] < trailSerie[i]);
            isOverSold = rsiSerie[i] <= oversold;
            isOverBought = rsiSerie[i] >= overbought;
            this.eventSeries[j++][i] = isOverBought;
            this.eventSeries[j++][i] = isOverSold;
            this.eventSeries[j++][i] = (!isOverSold) && this.eventSeries[j - 2][i - 1];
            this.eventSeries[j++][i] = (!isOverBought) && this.eventSeries[j - 4][i - 1];
            this.eventSeries[j++][i] = rsiSerie[i] >= 50;
            this.eventSeries[j++][i] = rsiSerie[i] < 50;
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie longStopSerie;
             FloatSerie shortStopSerie;
             FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);

             float indicatorMax = (float)this.Parameters[2];
             float indicatorCenter = (float)this.Parameters[3];
             float indicatorWeight = (float)this.Parameters[4];

             stockSerie.CalculateVarTrailStop((int)this.Parameters[0], ((string)this.Parameters[1]).Replace('_', ','), indicatorMax, indicatorCenter, indicatorWeight, out longStopSerie, out shortStopSerie);
             this.Series[0] = longStopSerie;
             this.Series[1] = shortStopSerie;

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             for (int i = (int)this.Parameters[0]; i < stockSerie.Count; i++)
             {
            this.Events[0][i] = !float.IsNaN(longStopSerie[i]);
            this.Events[1][i] = !float.IsNaN(shortStopSerie[i]);
            this.Events[2][i] = float.IsNaN(longStopSerie[i - 1]) && !float.IsNaN(longStopSerie[i]);
            this.Events[3][i] = float.IsNaN(shortStopSerie[i - 1]) && !float.IsNaN(shortStopSerie[i]);
            this.Events[4][i] = !float.IsNaN(longStopSerie[i - 1]) && !float.IsNaN(longStopSerie[i]) && longStopSerie[i - 1] < longStopSerie[i];
            this.Events[5][i] = !float.IsNaN(shortStopSerie[i - 1]) && !float.IsNaN(shortStopSerie[i]) && shortStopSerie[i - 1] > shortStopSerie[i];
            this.Events[6][i] = !float.IsNaN(longStopSerie[i]) && !float.IsNaN(longStopSerie[i - 1]) && lowSerie[i] > longStopSerie[i] && lowSerie[i - 1] <= longStopSerie[i - 1];
            this.Events[7][i] = !float.IsNaN(shortStopSerie[i]) && !float.IsNaN(shortStopSerie[i - 1]) && highSerie[i] < shortStopSerie[i] && highSerie[i - 1] >= shortStopSerie[i - 1];
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE).CalculateEMA((int)this.parameters[3]);
            FloatSerie volumeSerie = stockSerie.GetSerie(StockDataType.VOLUME);
            FloatSerie mfiSerie = new FloatSerie(stockSerie.Count);

            int period = (int)this.parameters[0];

            for (int i = period + 1; i < stockSerie.Count; i++)
            {
                float upFlow = 0f, downFlow = 0f;
                for (int j = 0; j < period; j++)
                {
                    if (closeSerie[i - j - 1] < closeSerie[i - j])
                    {
                        upFlow += volumeSerie[i - j] * closeSerie[i - j];
                    }
                    else
                    {
                        downFlow += volumeSerie[i - j] * closeSerie[i - j];
                    }
                }
                if (downFlow == 0)
                {
                    mfiSerie[i] = 100f;
                }
                else
                {
                    float ratio = upFlow / downFlow;
                    mfiSerie[i] = 100f - 100f / (1f + ratio);
                }
            }

            this.series[0] = mfiSerie;
            this.series[0].Name = this.Name;

            // Detecting events
            this.CreateEventSeries(stockSerie.Count);

            float overbought = (float)this.parameters[1];
            float oversold = (float)this.parameters[2];

            for (int i = 2; i < mfiSerie.Count; i++)
            {
                this.eventSeries[0][i] = (mfiSerie[i - 2] < mfiSerie[i - 1] && mfiSerie[i - 1] > mfiSerie[i]);
                this.eventSeries[1][i] = (mfiSerie[i - 2] > mfiSerie[i - 1] && mfiSerie[i - 1] < mfiSerie[i]);
                this.eventSeries[2][i] = mfiSerie[i] >= overbought;
                this.eventSeries[3][i] = mfiSerie[i] <= oversold;
                this.eventSeries[4][i] = this.eventSeries[2][i - 1] && !this.eventSeries[2][i];
                this.eventSeries[5][i] = this.eventSeries[3][i - 1] && !this.eventSeries[3][i];
            }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie longStopSerie;
             FloatSerie shortStopSerie;

             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);
             FloatSerie HighSerie = stockSerie.GetSerie(StockDataType.HIGH);

             IStockIndicator bbIndicator = stockSerie.GetIndicator(this.Name.Replace("TRAIL", ""));
             stockSerie.CalculateBBTrailStop(bbIndicator.Series[1], bbIndicator.Series[0], out longStopSerie, out shortStopSerie);
             this.Series[0] = longStopSerie;
             this.Series[1] = shortStopSerie;

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             for (int i = 5; i < stockSerie.Count; i++)
             {
            bool upTrend;
            this.Events[0][i] = upTrend = float.IsNaN(shortStopSerie[i]);
            this.Events[1][i] = !upTrend;
            this.Events[2][i] = upTrend && !this.Events[0][i - 1];
            this.Events[3][i] = !upTrend && !this.Events[1][i - 1];
            this.Events[4][i] = upTrend && this.Events[0][i - 1] && lowSerie[i - 1] <= longStopSerie[i - 1] && lowSerie[i] > longStopSerie[i];
            this.Events[5][i] = !upTrend && this.Events[1][i - 1] && HighSerie[i - 1] >= shortStopSerie[i - 1] && HighSerie[i] < shortStopSerie[i]; ;
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            Queue<float> resistanceQueue = new Queue<float>(new float[] { float.MinValue, float.MinValue });
            Queue<float> supportQueue = new Queue<float>(new float[] { float.MaxValue, float.MaxValue });

            FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);
            FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
            FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
            int period = (int)this.Parameters[0];

            IStockTrailStop trailStop = stockSerie.GetTrailStop("TRAILHL(" + period + ")");

            FloatSerie longStopSerie = trailStop.Series[0];
            FloatSerie shortStopSerie = trailStop.Series[1];

            BoolSerie brokenUpSerie = trailStop.Events[2];
            BoolSerie brokenDownSerie = trailStop.Events[3];

            FloatSerie supportSerie = new FloatSerie(stockSerie.Count, "TRAILHL.S"); supportSerie.Reset(float.NaN);
            FloatSerie resistanceSerie = new FloatSerie(stockSerie.Count, "TRAILHL.R"); resistanceSerie.Reset(float.NaN);

            this.Series[0] = supportSerie;
            this.Series[1] = resistanceSerie;

            // Detecting events
            this.CreateEventSeries(stockSerie.Count);
            this.Events[0] = brokenUpSerie;
            this.Events[1] = brokenDownSerie;

            // Begin Sequence

            // Calculate Support/Resistance
            float extremum = lowSerie[0];
            bool waitingForEndOfTrend = false;
            int i = 0;
            for (; i < stockSerie.Count && (!brokenUpSerie[i] && !brokenDownSerie[i]); i++)
            {
                //if (float.IsNaN(longStopSerie[i]))
                //{
                //    this.UpDownState[i] = StockSerie.Trend.DownTrend; // Down trend
                //    supportSerie[i] = float.NaN;
                //    resistanceSerie[i] = highSerie.GetMax(0, i);
                //    resistanceQueue.Dequeue();
                //    resistanceQueue.Enqueue(resistanceSerie[i]);
                //    extremum = highSerie.GetMax(0, i);
                //}
                //else
                //{
                //    this.UpDownState[i] = StockSerie.Trend.UpTrend; // Up trend

                //    supportSerie[i] = lowSerie.GetMin(0, i);
                //    supportQueue.Dequeue();
                //    supportQueue.Enqueue(supportSerie[i]);
                //    resistanceSerie[i] = float.NaN;
                //    extremum = lowSerie.GetMin(0, i);
                //}
            }
            if (i < stockSerie.Count)
            {
                if (brokenUpSerie[i])
                {
                    this.UpDownState[i] = StockSerie.Trend.UpTrend;
                    extremum = lowSerie.GetMin(0, i);
                }
                if (brokenDownSerie[i])
                {
                    this.UpDownState[i] = StockSerie.Trend.DownTrend;
                    extremum = highSerie.GetMax(0, i);
                }
            }

            for (; i < stockSerie.Count; i++)
            {
                bool upSwing = float.IsNaN(shortStopSerie[i]);
                this.UpDownState[i] = StockUpDownIndicatorBase.BoolToTrend(upSwing);

                this.Events[8][i] = upSwing;
                this.Events[9][i] = !upSwing;

                if (brokenUpSerie[i])
                {
                    supportSerie[i] = extremum;
                    supportQueue.Dequeue();
                    supportQueue.Enqueue(extremum);
                    resistanceSerie[i] = float.NaN;

                    if (waitingForEndOfTrend)
                    {// Detect EndOfUptrend
                        waitingForEndOfTrend = false;
                        this.Events[3][i] = true;
                    }
                    else if (extremum > resistanceQueue.ElementAt(0))
                    {// Detect if pullback in uptrend
                        this.Events[2][i] = true;
                        waitingForEndOfTrend = true;
                    }

                    if (extremum > supportQueue.ElementAt(0))
                    {
                        // Higher Low detected
                        this.Events[4][i] = true;
                    }
                    else
                    {
                        // Lower Low
                        this.Events[11][i] = true;
                    }

                    extremum = highSerie[i];
                }
                else if (brokenDownSerie[i])
                {
                    supportSerie[i] = float.NaN;
                    resistanceSerie[i] = extremum;
                    resistanceQueue.Dequeue();
                    resistanceQueue.Enqueue(extremum);

                    if (waitingForEndOfTrend)
                    {// Detect EndOfUptrend
                        waitingForEndOfTrend = false;
                        this.Events[3][i] = true;
                    }
                    else if (extremum < supportQueue.ElementAt(0))
                    {// Detect if pullback in downTrend
                        this.Events[2][i] = true;
                        waitingForEndOfTrend = true;
                    }

                    if (extremum < resistanceQueue.ElementAt(0))
                    {
                        // Lower high detected
                        this.Events[5][i] = true;
                    }
                    else
                    {
                        // Higher high detected
                        this.Events[10][i] = true;
                    }

                    extremum = lowSerie[i];
                }
                else
                {
                    supportSerie[i] = supportSerie[i - 1];
                    resistanceSerie[i] = resistanceSerie[i - 1];
                    if (float.IsNaN(supportSerie[i])) // Down trend
                    {
                        extremum = Math.Min(extremum, lowSerie[i]);
                        if (closeSerie[i - 1] >= supportQueue.ElementAt(1) && closeSerie[i] < supportQueue.ElementAt(1))
                        {
                            // Previous support broken
                            this.Events[7][i] = true;
                        }
                    }
                    else
                    {
                        extremum = Math.Max(extremum, highSerie[i]);
                        if (closeSerie[i - 1] <= resistanceQueue.ElementAt(1) && closeSerie[i] > resistanceQueue.ElementAt(1))
                        {
                            // Previous resistance broken
                            this.Events[6][i] = true;
                        }
                    }
                }
            }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            // Calculate Bands
             int period = (int)this.parameters[0];
             FloatSerie ema = stockSerie.GetIndicator("EMA(" + period + ")").Series[0];
             FloatSerie atr = stockSerie.GetIndicator("ATR(" + period + ")").Series[0];

             float upCoef = (float)this.parameters[1];
             float downCoef = (float)this.parameters[2];

             FloatSerie upperKeltnerBand = ema + atr * upCoef;
             this.series[0] = upperKeltnerBand;
             this.Series[0].Name = this.SerieNames[0];

             FloatSerie lowerKeltnerBand = ema + atr * downCoef;
             this.series[1] = lowerKeltnerBand;
             this.Series[1].Name = this.SerieNames[1];

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);
             FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);

             for (int i = 1; i < upperKeltnerBand.Count; i++)
             {
            this.eventSeries[0][i] = closeSerie[i] > upperKeltnerBand[i];
            this.eventSeries[1][i] = closeSerie[i] < lowerKeltnerBand[i];
            this.eventSeries[2][i] = closeSerie[i] >= lowerKeltnerBand[i] && closeSerie[i] <= upperKeltnerBand[i];
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            // Calculate Bollinger Bands
             FloatSerie upperBB = null;
             FloatSerie lowerBB = null;
             FloatSerie ema = stockSerie.GetIndicator(this.parameters[1] + "(" + (int)this.parameters[0] + ")").Series[0];

             stockSerie.GetSerie(StockDataType.CLOSE).CalculateBB(ema, (int)this.parameters[0], 1f, -1f, ref upperBB, ref lowerBB);

             FloatSerie widthLog = ((upperBB - lowerBB)/ema)*20.0f;
             for (int i = (int) this.parameters[0]; i < stockSerie.Count; i++)
             {
            widthLog[i] = (float)Math.Log10(widthLog[i]);
             }

             this.series[0] = widthLog;
             this.Series[0].Name = this.SerieNames[0];

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie fastSerie = stockSerie.GetIndicator(this.SerieNames[0]).Series[0];
             FloatSerie slowSerie = stockSerie.GetIndicator(this.SerieNames[1]).Series[0];

             FloatSerie closeSerie = (stockSerie.GetSerie(StockDataType.CLOSE) + stockSerie.GetSerie(StockDataType.HIGH) + stockSerie.GetSerie(StockDataType.LOW)) / 3.0f;

             this.Series[0] = fastSerie;
             this.Series[1] = slowSerie;

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             for (int i = 2; i < stockSerie.Count; i++)
             {
            if (fastSerie[i] > slowSerie[i])
            {
               if (closeSerie[i] > fastSerie[i])
               {
                  this.Events[2][i] = true;
               }
               else
               {
                  this.Events[4][i] = true;
               }
               if (fastSerie[i - 1] < slowSerie[i - 1])
               {
                  this.Events[0][i] = true;
               }
            }
            else
            {
               if (closeSerie[i] < fastSerie[i])
               {
                  this.Events[3][i] = true;
               }
               else
               {
                  this.Events[5][i] = true;
               }
               if (fastSerie[i - 1] > slowSerie[i - 1])
               {
                  this.Events[1][i] = true;
               }
            }
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            int period = (int)this.Parameters[0];
             int smoothing = (int)this.Parameters[1];
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW).CalculateEMA(smoothing);
             FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH).CalculateEMA(smoothing);
             FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE).CalculateEMA(smoothing);

             FloatSerie pivotSerie = new FloatSerie(stockSerie.Count, "PIVOT");
             FloatSerie s1Serie = new FloatSerie(stockSerie.Count, "S1");
             FloatSerie s2Serie = new FloatSerie(stockSerie.Count, "S2");
             FloatSerie s3Serie = new FloatSerie(stockSerie.Count, "S3");
             FloatSerie r1Serie = new FloatSerie(stockSerie.Count, "R1");
             FloatSerie r2Serie = new FloatSerie(stockSerie.Count, "R2");
             FloatSerie r3Serie = new FloatSerie(stockSerie.Count, "R3");

             this.Series[0] = pivotSerie;
             this.Series[1] = s1Serie;
             this.Series[2] = s2Serie;
             this.Series[3] = s3Serie;
             this.Series[4] = r1Serie;
             this.Series[5] = r2Serie;
             this.Series[6] = r3Serie;

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             if (stockSerie.StockName.StartsWith("INT_"))
             {
            List<StockDailyValue> dailyValues = stockSerie.GenerateDailyFromIntraday();
            IEnumerator<StockDailyValue> dailyEnumerator = dailyValues.GetEnumerator();

            dailyEnumerator.Reset();
            dailyEnumerator.MoveNext();
            StockDailyValue dailyValue = dailyEnumerator.Current;

            float pivot;
            float s1;
            float r1;
            float r2;
            float s2;
            float r3;
            float s3;

            dailyValue.CalculatePivot(out pivot, out s1, out r1, out r2, out s2, out r3, out s3);

            DateTime intradayBarDate = stockSerie.Values.First().DATE.Date;

            int count = 0;
            bool first = true;
            foreach (StockDailyValue intradayValue in stockSerie.Values)
            {
               if (intradayBarDate != intradayValue.DATE.Date)
               {
                  if (first)
                  {
                     first = false;
                  }
                  else
                  {
                     dailyEnumerator.MoveNext();
                     dailyEnumerator.Current.CalculatePivot(out pivot, out s1, out r1, out r2, out s2, out r3,
                         out s3);
                  }
                  intradayBarDate = intradayValue.DATE.Date;
               }

               pivotSerie[count] = pivot;
               r1Serie[count] = r1;
               s1Serie[count] = s1;

               r2Serie[count] = r2;
               s2Serie[count] = s2;

               r3Serie[count] = r3;
               s3Serie[count] = s3;

               count++;
            }
             }
             else
             {
            for (int i = 0; i <= period; i++)
            {
               s1Serie[i] = closeSerie[i];
               s2Serie[i] = closeSerie[i];
               s3Serie[i] = closeSerie[i];
               r1Serie[i] = closeSerie[i];
               r2Serie[i] = closeSerie[i];
               r3Serie[i] = closeSerie[i];
            }
            for (int i = period + 1; i < stockSerie.Count; i++)
            {
               float low = lowSerie.GetMin(i - period - 1, i - 1);
               float high = highSerie.GetMax(i - period - 1, i - 1);
               float pivot = (low + high + closeSerie[i - 1]) / 3;

               pivotSerie[i] = pivot;
               r1Serie[i] = (2 * pivot) - low;
               s1Serie[i] = (2 * pivot) - high;

               r2Serie[i] = (pivot - s1Serie[i]) + r1Serie[i];
               s2Serie[i] = pivot - (r1Serie[i] - s1Serie[i]);

               r3Serie[i] = (pivot - s2Serie[i]) + r2Serie[i];
               s3Serie[i] = pivot - (r2Serie[i] - s2Serie[i]);
            }
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            // Detecting events
             this.CreateEventSeries(stockSerie.Count);
             FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);

             if (stockSerie.StockAnalysis.DrawingItems.ContainsKey(stockSerie.BarDuration))
             {
            var drawingItems = stockSerie.StockAnalysis.DrawingItems[stockSerie.BarDuration].Where(di => di is Line2DBase);
            for (int i = 20; i < stockSerie.Count; i++)
            {
               foreach (Line2DBase item in drawingItems)
               {
                  if (item.ContainsAbsciss(i) && item.ContainsAbsciss(i - 1))
                  {
                     float itemValue = item.ValueAtX(i);
                     float itemPreviousValue = item.ValueAtX(i - 1);
                     if (closeSerie[i - 1] < itemPreviousValue && closeSerie[i] > itemValue)
                     {
                        // Resistance Broken
                        this.Events[0][i] = true;
                     }
                     else if (closeSerie[i - 1] > itemPreviousValue && closeSerie[i] < itemValue)
                     {
                        // Support Broken
                        this.Events[1][i] = true;
                     }
                  }
               }
            }
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            int period = (int)this.parameters[0];
             int smoothing = (int)this.parameters[1];
             IStockIndicator donchianIndicator = stockSerie.GetIndicator("DONCHIAN(" + period + ")");

             // Calculate Donchian Channel
             FloatSerie upLine = donchianIndicator.Series[0];
             FloatSerie downLine = donchianIndicator.Series[4];

             FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);

             this.series[0] = ((upLine - downLine) / (closeSerie * 0.01f)).CalculateEMA(smoothing);
             this.Series[0].Name = this.SerieNames[0];

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie varSerie = stockSerie.GetSerie(StockDataType.VARIATION);
             FloatSerie emaSerie = varSerie.CalculateEMA( (int)this.parameters[0]);

             FloatSerie cumulSerie = new FloatSerie(emaSerie.Count);
             float cumul = 0f;
             for (int i = 0; i < emaSerie.Count; i++)
             {
            cumulSerie[i] = cumul += emaSerie[i];
             }

             this.series[0] = cumulSerie;
             this.Series[0].Name = this.Name;
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            using (MethodLogger ml = new MethodLogger(this))
             {
            FloatSerie fastMom = stockSerie.CalculateBuySellMomemtum((int)this.parameters[0], (bool)this.parameters[1]);
            this.series[0] = fastMom;
            this.Series[0].Name = this.Name;

            if (this.series[0] != null && this.Series[0].Count > 0)
            {
               this.CreateEventSeries(stockSerie.Count);

               FloatSerie upExLimit = new FloatSerie(stockSerie.Count, this.SerieNames[1]);
               FloatSerie downExLimit = new FloatSerie(stockSerie.Count, this.SerieNames[2]);
               FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
               FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);
               for (int i = 1; i < this.SeriesCount; i++)
               {
                  this.Series[i] = new FloatSerie(stockSerie.Count, this.SerieNames[i]);
               }
               FloatSerie indicatorToDecorate = this.Series[0];
               float exhaustionSellLimit = indicatorToDecorate[0];
               float exhaustionBuyLimit = indicatorToDecorate[0];
               float exhaustionBuyPrice = highSerie[0];
               float exhaustionSellPrice = lowSerie[0];
               float exFadeOut = (100.0f - (float)this.parameters[2]) / 100.0f;

               float previousValue = indicatorToDecorate[0];
               float currentValue;

               for (int i = 1; i < indicatorToDecorate.Count - 1; i++)
               {
                  currentValue = indicatorToDecorate[i];

                  if (currentValue < previousValue)
                  {
                     if (indicatorToDecorate.IsBottom(i))
                     {
                        if (currentValue <= exhaustionSellLimit)
                        {
                           // This is an exhaustion selling
                           exhaustionSellPrice = lowSerie[i];
                           exhaustionSellLimit = currentValue;
                        }
                        else
                        {
                           exhaustionSellLimit *= exFadeOut;
                        }
                        exhaustionBuyLimit *= exFadeOut;
                     }
                     else
                     { // trail exhaustion limit down
                        exhaustionSellLimit = Math.Min(currentValue, exhaustionSellLimit);
                        exhaustionBuyLimit *= exFadeOut;
                     }
                  }
                  else if (currentValue > previousValue)
                  {
                     if (indicatorToDecorate.IsTop(i))
                     {
                        if (currentValue >= exhaustionBuyLimit)
                        {
                           // This is an exhaustion selling
                           exhaustionBuyPrice = highSerie[i];
                           exhaustionBuyLimit = currentValue;
                        }
                        else
                        {
                           exhaustionSellLimit *= exFadeOut;
                        }
                        exhaustionBuyLimit *= exFadeOut;
                     }
                     else
                     { // trail exhaustion limit up
                        exhaustionBuyLimit = Math.Max(currentValue, exhaustionBuyLimit);
                        exhaustionSellLimit *= exFadeOut;
                     }
                  }
                  else
                  {
                     exhaustionSellLimit *= exFadeOut;
                     exhaustionBuyLimit *= exFadeOut;
                  }
                  previousValue = currentValue;
                  upExLimit[i] = exhaustionBuyLimit;
                  downExLimit[i] = exhaustionSellLimit;
               }
               upExLimit[indicatorToDecorate.Count - 1] = exhaustionBuyLimit;
               downExLimit[indicatorToDecorate.Count - 1] = exhaustionSellLimit;
               this.series[1] = upExLimit;
               this.series[2] = downExLimit;

               for (int i = 5; i < indicatorToDecorate.Count - 1; i++)
               {
                  this.eventSeries[0][i] = fastMom[i - 1] == upExLimit[i - 1] && fastMom[i] < fastMom[i - 1];
                  this.eventSeries[1][i] = fastMom[i - 1] == downExLimit[i - 1] && fastMom[i] > fastMom[i - 1];
               }
            }
            else
            {
               for (int i = 0; i < this.SeriesCount; i++)
               {
                  this.Series[i] = new FloatSerie(0, this.SerieNames[i]);
               }
            }
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie pukeSerie = new FloatSerie(stockSerie.Count);

             int period = ((int)this.parameters[0]);
             int smoothing = ((int)this.parameters[1]);
             int signalSmoothing = ((int)this.parameters[3]);
             int inputSmoothing = ((int)this.parameters[2]);

             FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE).CalculateEMA(inputSmoothing);

             var values = stockSerie.ValueArray;

             // Calculate PUKE
             for (int i = period; i < stockSerie.Count; i++)
             {

            int puke = 0;
            for (int j = i - period+1; j <= i; j++)
            {
               StockDailyValue dv = values[j];
               if (closeSerie[j] - closeSerie[j-1] >= 0) puke++;
               else  puke--;
            }
            pukeSerie[i] = puke;
             }

             pukeSerie = pukeSerie.CalculateEMA(smoothing);

             this.Series[0] = pukeSerie;
             this.series[0].Name = this.SerieNames[0];

             FloatSerie signalSerie = pukeSerie.CalculateEMA(signalSmoothing);
             this.series[1] = signalSerie;
             this.series[1].Name = this.SerieNames[1];

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             for (int i = period; i < stockSerie.Count; i++)
             {
            this.eventSeries[0][i] = (signalSerie[i - 1] > pukeSerie[i - 1] && signalSerie[i] < pukeSerie[i]);
            this.eventSeries[1][i] = (signalSerie[i - 1] < pukeSerie[i - 1] && signalSerie[i] > pukeSerie[i]);
            this.eventSeries[2][i] = pukeSerie[i] > signalSerie[i];
            this.eventSeries[3][i] = pukeSerie[i] < signalSerie[i];
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            // Detecting events
            this.CreateEventSeries(stockSerie.Count);

            FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
            FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);

            FloatSerie atr1Serie = stockSerie.GetIndicator("ATR(1)").Series[0];
            FloatSerie atr20Serie = stockSerie.GetIndicator("ATR(20)").Series[0];

            for (int i = 1; i < stockSerie.Count; i++)
            {
                // Check Gaps
                this.eventSeries[0][i] = highSerie[i - 1] < lowSerie[i];
                this.eventSeries[1][i] = lowSerie[i - 1] > highSerie[i];
                this.eventSeries[2][i] = atr1Serie[i] > 1.5*atr20Serie[i];
            }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            StockSerie seasonSerie = stockSerie.CalculateSeasonality();
             FloatSerie seasonCloseSerie = new FloatSerie(stockSerie.Count);

             int i = 0;
             float previousClose = stockSerie.Values.First().CLOSE;
             FloatSerie seasonClose = seasonSerie.GetSerie(StockDataType.CLOSE);
             int indexOfDate;
             int previousIndexOfDate = 0;
             foreach (StockDailyValue dailyValue in stockSerie.Values)
             {
            indexOfDate = seasonSerie.IndexOf(new DateTime(2000, dailyValue.DATE.Month, dailyValue.DATE.Day));
            if (indexOfDate != -1)
            {
               if (indexOfDate >= previousIndexOfDate)
               {
                  seasonCloseSerie[i] = previousClose * (1 + (seasonClose[indexOfDate] - seasonClose[previousIndexOfDate]) / seasonClose[previousIndexOfDate]);
               }
               previousIndexOfDate = indexOfDate;
            }
            else
            {
               seasonCloseSerie[i] = previousClose;
            }
            previousClose = seasonCloseSerie[i];
            i++;
             }

             this.series[0] = stockSerie.GetSerie(StockDataType.CLOSE).CalculateCorrelation(seasonCloseSerie, (int)parameters[0]);
             this.Series[0].Name = this.Name;
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            // Set HLine value
             float trendThreshold = (float)this.Parameters[1];

             int period = (int)this.Parameters[0];
             FloatSerie atrSerie = stockSerie.GetIndicator("ATR(" + period + ")").Series[0];

             FloatSerie pDM = new FloatSerie(stockSerie.Count);
             FloatSerie mDM = new FloatSerie(stockSerie.Count);

             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW).CalculateEMA((int)this.Parameters[2]);
             FloatSerie higherie = stockSerie.GetSerie(StockDataType.HIGH).CalculateEMA((int)this.Parameters[2]);

             // Calculate +DM and -DM
             for (int i = 1; i < stockSerie.Count; i++)
             {
            float rangeUp = higherie[i] - higherie[i - 1];
            float rangeDown = lowSerie[i - 1] - lowSerie[i];

            if (rangeUp > rangeDown)
            {
               pDM[i] = Math.Max(0, rangeUp);
            }
            else
            {
               mDM[i] = Math.Max(0, rangeDown);
            }
             }

             // Calclate +DI and -DI
             FloatSerie pDI = pDM.CalculateEMA(period).Div(atrSerie).Mult(100);
             FloatSerie mDI = mDM.CalculateEMA(period).Div(atrSerie).Mult(100);

             FloatSerie ADX = ((pDI - mDI).Abs() / (pDI + mDI)).CalculateEMA(period).Mult(100);

             ADX.Name = this.SerieNames[0];
             pDI.Name = this.SerieNames[1];
             mDI.Name = this.SerieNames[2];

             this.Series[0] = ADX;
             this.Series[1] = pDI;
             this.Series[2] = mDI;

             // Manage events
             this.CreateEventSeries(stockSerie.Count);

             for (int i = period; i < stockSerie.Count; i++)
             {
            this.eventSeries[0][i] = ADX[i] > trendThreshold && ADX[i] > ADX[i - 1] && pDI[i] > mDI[i];
            this.eventSeries[1][i] = ADX[i] > trendThreshold && ADX[i] > ADX[i - 1] && pDI[i] < mDI[i];
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            using (MethodLogger ml = new MethodLogger(this))
             {
            List<StockDailyValue> dailyValues = stockSerie.GenerateHeikinAshiBarFromDaily(stockSerie.Values.ToList());
            FloatSerie upVolume = new FloatSerie(stockSerie.Count);
            FloatSerie downVolume = new FloatSerie(stockSerie.Count);

            int i = -1;
            foreach (StockDailyValue dailyValue in dailyValues)
            {
               i++;
               float R = dailyValue.HIGH - dailyValue.LOW; // Bar range

               float R2 = Math.Abs(dailyValue.CLOSE - dailyValue.OPEN); // Body range

               if (R == 0 || R2 == 0)
               {
                  upVolume[i] = downVolume[i] = dailyValue.VOLUME / 2L;
                  continue;
               }

               float R1 = dailyValue.HIGH - Math.Max(dailyValue.CLOSE, dailyValue.OPEN); // Higher shade range
               float R3 = Math.Min(dailyValue.CLOSE, dailyValue.OPEN) - dailyValue.LOW; // Lower shade range

               float V = dailyValue.VOLUME;
               float V1 = V * (R1 / R);
               float V2 = V * (R2 / R);
               float V3 = V * (R3 / R);

               if (dailyValue.CLOSE > dailyValue.OPEN) // UpBar
               {
                  upVolume[i] = V2 + (V1 + V3) / 2.0f;
                  downVolume[i] = V - upVolume[i];
               }
               else // DownBar
               {
                  downVolume[i] = V2 + (V1 + V3) / 2.0f;
                  upVolume[i] = V - downVolume[i];
               }

               //V = V(R1/R) + V(R2/R) + V(R3/R);

            }

            //FloatSerie upVolume = stockSerie.GetSerie(StockDataType.UPVOLUME).Sqrt();
            //FloatSerie downVolume = stockSerie.GetSerie(StockDataType.DOWNVOLUME).Sqrt();
            FloatSerie cumulVolume = (upVolume - downVolume).Cumul();
            FloatSerie diffVolume = (cumulVolume - cumulVolume.CalculateEMA((int)this.parameters[0])).CalculateEMA((int)this.parameters[1]);
            FloatSerie fastSerie = diffVolume;

            FloatSerie fastMom = fastSerie;
            this.series[0] = fastMom;
            this.Series[0].Name = this.Name;

            FloatSerie signalSerie = fastMom.CalculateEMA(((int)this.parameters[2]));
            this.series[1] = signalSerie;
            this.Series[1].Name = this.SerieNames[1];

            if (this.series[0] != null && this.Series[0].Count > 0)
            {
               this.CreateEventSeries(stockSerie.Count);

               FloatSerie upExLimit = new FloatSerie(stockSerie.Count, this.SerieNames[1]);
               FloatSerie downExLimit = new FloatSerie(stockSerie.Count, this.SerieNames[2]);
               FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
               FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);

               FloatSerie indicatorToDecorate = this.Series[0];
               float exhaustionSellLimit = indicatorToDecorate[0];
               float exhaustionBuyLimit = indicatorToDecorate[0];
               float exhaustionBuyPrice = highSerie[0];
               float exhaustionSellPrice = lowSerie[0];
               float exFadeOut = (100.0f - (float)this.parameters[3]) / 100.0f;

               float previousValue = indicatorToDecorate[0];
               float currentValue;

               for (i = 1; i < indicatorToDecorate.Count - 1; i++)
               {
                  currentValue = indicatorToDecorate[i];

                  if (currentValue < previousValue)
                  {
                     if (indicatorToDecorate.IsBottom(i))
                     {
                        if (currentValue <= exhaustionSellLimit)
                        {
                           // This is an exhaustion selling
                           exhaustionSellPrice = lowSerie[i];
                           exhaustionSellLimit = currentValue;
                        }
                        else
                        {
                           exhaustionSellLimit *= exFadeOut;
                        }
                        exhaustionBuyLimit *= exFadeOut;
                     }
                     else
                     { // trail exhaustion limit down
                        exhaustionSellLimit = Math.Min(currentValue, exhaustionSellLimit);
                        exhaustionBuyLimit *= exFadeOut;
                     }
                  }
                  else if (currentValue > previousValue)
                  {
                     if (indicatorToDecorate.IsTop(i))
                     {
                        if (currentValue >= exhaustionBuyLimit)
                        {
                           // This is an exhaustion selling
                           exhaustionBuyPrice = highSerie[i];
                           exhaustionBuyLimit = currentValue;
                        }
                        else
                        {
                           exhaustionSellLimit *= exFadeOut;
                        }
                        exhaustionBuyLimit *= exFadeOut;
                     }
                     else
                     { // trail exhaustion limit up
                        exhaustionBuyLimit = Math.Max(currentValue, exhaustionBuyLimit);
                        exhaustionSellLimit *= exFadeOut;
                     }
                  }
                  else
                  {
                     exhaustionSellLimit *= exFadeOut;
                     exhaustionBuyLimit *= exFadeOut;
                  }
                  previousValue = currentValue;
                  upExLimit[i] = exhaustionBuyLimit;
                  downExLimit[i] = exhaustionSellLimit;
               }
               upExLimit[indicatorToDecorate.Count - 1] = exhaustionBuyLimit;
               downExLimit[indicatorToDecorate.Count - 1] = exhaustionSellLimit;
               this.series[2] = upExLimit;
               this.series[3] = downExLimit;

               //for ( i = 5; i < indicatorToDecorate.Count - 1; i++)
               //{
               //    this.eventSeries[0][i] = fastMom[i - 1] == upExLimit[i - 1] && fastMom[i] < fastMom[i - 1];
               //    this.eventSeries[1][i] = fastMom[i - 1] == downExLimit[i - 1] && fastMom[i] > fastMom[i - 1];
               //}
            }
            else
            {
               for (i = 0; i < this.SeriesCount; i++)
               {
                  this.Series[i] = new FloatSerie(0, this.SerieNames[i]);
               }
            }
            for (i = 0; i < stockSerie.Count; i++)
            {
               this.eventSeries[0][i] = fastMom[i] >= signalSerie[i];
               this.eventSeries[1][i] = fastMom[i] < signalSerie[i];
            }
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            // Calculate Bollinger Bands
             FloatSerie upperBB = null;
             FloatSerie lowerBB = null;
             IStockIndicator emaIndicator = stockSerie.GetIndicator(this.parameters[3] + "(" + (int)this.parameters[0] + ")");

             stockSerie.GetSerie(StockDataType.CLOSE).CalculateBBEX(emaIndicator.Series[0], (int)this.parameters[0], (float)this.parameters[1], (float)this.parameters[2], ref upperBB, ref lowerBB);

             this.series[0] = upperBB;
             this.Series[0].Name = this.SerieNames[0];

             this.series[1] = lowerBB;
             this.Series[1].Name = this.SerieNames[1];

             this.series[2] = emaIndicator.Series[0];
             this.Series[2].Name = this.SerieNames[2];

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);
             FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);

             bool waitingForBearSignal = false;
             bool waitingForBullSignal = false;

             for (int i = 1; i < upperBB.Count; i++)
             {
            if (waitingForBearSignal && highSerie[i - 1] >= highSerie[i] && closeSerie[i - 1] >= closeSerie[i])
            {
               // BearishSignal
               this.eventSeries[3][i] = true;
               waitingForBearSignal = false;
            }
            if (highSerie[i] >= upperBB[i])
            {
               waitingForBearSignal = true;
               this.eventSeries[0][i] = true;
            }
            if (waitingForBullSignal && lowSerie[i - 1] <= lowSerie[i] && closeSerie[i - 1] <= closeSerie[i])
            {
               // BullishSignal
               this.eventSeries[2][i] = true;
               waitingForBullSignal = false;
            }
            if (lowSerie[i] <= lowerBB[i])
            {
               waitingForBullSignal = true;
               this.eventSeries[1][i] = lowSerie[i] <= lowerBB[i];
            }
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie longStopSerie;
             FloatSerie shortStopSerie;
             FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);

             stockSerie.CalculateEMAEXTrailStop((int)this.Parameters[0], (int)this.Parameters[1], out longStopSerie, out shortStopSerie);
             this.Series[0] = longStopSerie;
             this.Series[1] = shortStopSerie;

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);

             for (int i = 5; i < stockSerie.Count; i++)
             {
            this.Events[0][i] = !float.IsNaN(longStopSerie[i]);
            this.Events[1][i] = !float.IsNaN(shortStopSerie[i]);
            this.Events[2][i] = float.IsNaN(longStopSerie[i - 1]) && !float.IsNaN(longStopSerie[i]);
            this.Events[3][i] = float.IsNaN(shortStopSerie[i - 1]) && !float.IsNaN(shortStopSerie[i]);
            this.Events[4][i] = !float.IsNaN(longStopSerie[i - 1]) && !float.IsNaN(longStopSerie[i]) && longStopSerie[i - 1] < longStopSerie[i];
            this.Events[5][i] = !float.IsNaN(shortStopSerie[i - 1]) && !float.IsNaN(shortStopSerie[i]) && shortStopSerie[i - 1] > shortStopSerie[i];
            this.Events[6][i] = !float.IsNaN(longStopSerie[i]) && !float.IsNaN(longStopSerie[i - 1]) && lowSerie[i] > longStopSerie[i] && lowSerie[i - 1] <= longStopSerie[i - 1];
            this.Events[7][i] = !float.IsNaN(shortStopSerie[i]) && !float.IsNaN(shortStopSerie[i - 1]) && highSerie[i] < shortStopSerie[i] && highSerie[i - 1] >= shortStopSerie[i - 1];
             }
        }
        public override void ApplyTo(StockSerie stockSerie)
        {
            FloatSerie closeSerie = stockSerie.GetSerie(StockDataType.CLOSE);
             FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH);
             FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW);
             FloatSerie maSerie = closeSerie.CalculateEMA((int)this.parameters[0]);
             this.series[0] = maSerie;
             this.series[0].Name = this.Name;

             // Detecting events
             this.CreateEventSeries(stockSerie.Count);
             for (int i = 2; i < maSerie.Count; i++)
             {
            this.eventSeries[0][i] = (maSerie[i - 2] > maSerie[i - 1] && maSerie[i - 1] < maSerie[i]);
            this.eventSeries[1][i] = (maSerie[i - 2] < maSerie[i - 1] && maSerie[i - 1] > maSerie[i]);
            this.eventSeries[2][i] = closeSerie[i - 1] < maSerie[i - 1] && closeSerie[i] > maSerie[i];
            this.eventSeries[3][i] = closeSerie[i - 1] > maSerie[i - 1] && closeSerie[i] < maSerie[i];
            this.eventSeries[4][i] = lowSerie[i] > maSerie[i] && lowSerie[i - 1] < maSerie[i - 1];
            this.eventSeries[5][i] = highSerie[i] < maSerie[i] && highSerie[i - 1] > maSerie[i - 1];
            this.eventSeries[6][i] = lowSerie[i] > maSerie[i] && closeSerie[i - 1] < closeSerie[i];
            this.eventSeries[7][i] = highSerie[i] < maSerie[i] && closeSerie[i - 1] > closeSerie[i];
            if (this.eventSeries[8][i - 1])
            {
               // Check if BullRun Persists
               this.eventSeries[8][i] = !this.eventSeries[5][i];
            }
            else
            {
               // Check if BullRun Starts
               this.eventSeries[8][i] = this.eventSeries[4][i];
            }
            if (this.eventSeries[9][i - 1])
            {
               // Check if BearRun Persists
               this.eventSeries[9][i] = !this.eventSeries[4][i];
            }
            else
            {
               // Check if BearRun Starts
               this.eventSeries[9][i] = this.eventSeries[5][i];
            }
             }
        }