Example #1
0
        //populate
        public override void Populate()
        {
            BarHistory bars       = Parameters[0].AsBarHistory;
            Int32      period     = Parameters[1].AsInt;
            Int32      emaPeriod1 = Parameters[2].AsInt;
            Int32      emaPeriod2 = Parameters[3].AsInt;

            DateTimes = bars.DateTimes;

            if (period <= 0 || bars.Count == 0)
            {
                return;
            }

            var FirstValidValue = Math.Max(emaPeriod1, Math.Max(emaPeriod2, period));

            if (FirstValidValue > bars.Count || FirstValidValue < 0)
            {
                FirstValidValue = bars.Count;
            }

            var HP     = Highest.Series(bars.High, period);
            var LP     = Lowest.Series(bars.Low, period);
            var MA12   = EMA.Series(bars.Close, emaPeriod1);
            var MA26   = EMA.Series(bars.Close, emaPeriod2);
            var ST12   = (MA12 - LP) / (HP - LP);
            var ST26   = (MA26 - LP) / (HP - LP);
            var STMACD = (ST12 - ST26) * 100;

            for (int bar = 0; bar < bars.Count; bar++)
            {
                Values[bar] = STMACD[bar];
            }
        }
Example #2
0
        public override void Populate()
        {
            BarHistory bars    = base.Parameters[0].AsBarHistory;
            int        period1 = base.Parameters[1].AsInt;
            int        period2 = base.Parameters[2].AsInt;

            this.DateTimes = bars.DateTimes;
            int FirstValidValue = Math.Max(period1, period2) + 1;

            if (bars.Count < FirstValidValue)
            {
                return;
            }
            var MLTP       = 2.0 / ((double)period1 + 1.0);
            var MLTP2      = (bars.Close - Lowest.Series(bars.Low, period2) - (Highest.Series(bars.High, period2) - bars.Close)).Abs() / (Highest.Series(bars.High, period2) - Lowest.Series(bars.Low, period2));
            var timeSeries = MLTP * (1.0 + MLTP2);

            for (int i = 0; i < FirstValidValue; i++)
            {
                base[i] = FastSMA.Series(bars.Close, period1)[i];
            }

            for (int j = FirstValidValue; j < bars.Count; j++)
            {
                base.Values[j] = base.Values[j - 1] + timeSeries[j] * (bars.Close[j] - base.Values[j - 1]);
            }
        }
Example #3
0
        public MSR(Bars bars, int per1, int per2, string description)
            : base(bars, description)
        {
            base.FirstValidValue = 252;

            //MSR= (10-day median of (H, L, C) – 20-day  MAX (H, L, C))/(20-day  MAX (H, L, C))
            //then take the 252-day percentrank of MSR or percentile ranking

            DataSeries msrTemp = new DataSeries(bars, "msrTemp(" + per1 + "," + per2 + ")");

            for (int bar = Math.Max(per1, per2); bar < bars.Count; bar++)
            {
                double        max20  = Highest.Series(bars.High, per2)[bar];
                List <double> prices = new List <double>(per1 * 3);
                for (int i = bar; i > bar - per1; i--)
                {
                    prices.Add(bars.High[i]); prices.Add(bars.Low[i]); prices.Add(bars.Close[i]);
                }

                prices.Sort();
                msrTemp[bar] = (GetMedian(prices) - max20) / max20;
            }

            for (int bar = FirstValidValue; bar < bars.Count; bar++)
            {
                base[bar] = PercentRank.Series(msrTemp, 252)[bar];
                //base[bar] = PrcRank.Series(msrTemp, 252)[bar];
            }
        }
Example #4
0
        public SenkouSpanB(Bars bars)
            : base(bars, "Senkou Span B")
        {
            int p1 = 9;
            int p2 = 26;
            int p3 = 52;
            int p4 = 26;

            if (bars.Count < p3)
            {
                return;
            }

            DataSeries TenkanSen = ((Highest.Series(bars.High, p1) + Lowest.Series(bars.Low, p1)) / 2);
            DataSeries KijunSen  = ((Highest.Series(bars.High, p2) + Lowest.Series(bars.Low, p2)) / 2);
            DataSeries ssA       = ((TenkanSen + KijunSen) / 2) >> p4;
            DataSeries ssB       = ((Highest.Series(bars.High, p3) + Lowest.Series(bars.Low, p3)) / 2) >> p4;

            base.FirstValidValue = p3;

            for (int bar = p3; bar < bars.Count; bar++)
            {
                base[bar] = ssB[bar];
            }
        }
Example #5
0
        //Constructor
        public PivotPointBar(Bars bars, int period, bool pivotPointHigh, bool tradeable, string description)
            : base(bars, description)
        {
            _bars      = bars;
            _ppHigh    = pivotPointHigh;
            _period    = period;
            _tradeable = tradeable;

            FirstValidValue += _period;
            if (bars.Count < _period)
            {
                return;
            }

            for (int bar = _period; bar < bars.Count; bar++)
            {
                this[bar] = -1d;        // returns -1 until a Valid Pivot Point is found
            }

            for (int bar = _period; bar < bars.Count; bar++)
            {
                if (_tradeable)
                {
                    if (_ppHigh)
                    {
                        if (bars.High[bar] >= Highest.Series(bars.High, _period)[bar - 1])
                        {
                            _lastPP = bar;
                        }
                    }
                    else if (bars.Low[bar] <= Lowest.Series(bars.Low, _period)[bar - 1])
                    {
                        _lastPP = bar;
                    }
                }
                else
                {
                    int periodFwd = _period;
                    if (bar + period >= bars.Count)
                    {
                        periodFwd = bars.Count - bar - 1;
                    }
                    if (_ppHigh)
                    {
                        if (bars.High[bar] >= Highest.Series(bars.High, _period)[bar - 1] &&
                            bars.High[bar] >= Highest.Value(bar + periodFwd, bars.High, periodFwd))     // use Value method since periodFwd is variable at the end
                        {
                            _lastPP = bar;
                        }
                    }
                    else if (bars.Low[bar] <= Lowest.Series(bars.Low, _period)[bar - 1] &&
                             bars.Low[bar] <= Lowest.Value(bar + periodFwd, bars.Low, periodFwd))
                    {
                        _lastPP = bar;
                    }
                }
                this[bar] = _lastPP;
            }
        }
Example #6
0
 public HiLoRange(Bars bars, int period, string description)
     : base(bars, description)
 {
     for (int bar = period; bar < bars.Count; bar++)
     {
         base[bar] = Highest.Series(bars.High, period)[bar] - Lowest.Series(bars.Low, period)[bar];
     }
 }
Example #7
0
 public TR2DSeries(Bars bars, string description)
     : base(bars, description)
 {
     this.FirstValidValue = 2;
     for (int bar = FirstValidValue; bar < bars.Count; bar++)
     {
         double h3 = Math.Max(Highest.Series(bars.High, 2)[bar], bars.Close[bar - 2]);
         double l3 = Math.Min(Lowest.Series(bars.Low, 2)[bar], bars.Close[bar - 2]);
         base[bar] = h3 - l3;
     }
 }
Example #8
0
 //===========================================================================================================
 // Show 52 weeks high
 //-----------------------------------------------------------------------------------------------------------
 protected void show52WeeksHigh(int numBarsIn52Weeks)
 {
     // 52-week high
     for (int bar = numBarsIn52Weeks; bar < Bars.Count; bar++)
     {
         if (High[bar] > Highest.Series(High, numBarsIn52Weeks)[bar - 1])
         {
             // New 52-week high detected.  Paint the chart blue
             SetBackgroundColor(bar, Color.FromArgb(15, Color.Blue));
         }
     }
 }
Example #9
0
        //populate
        public override void Populate()
        {
            BarHistory source   = Parameters[0].AsBarHistory;
            Int32      period   = Parameters[1].AsInt;
            Double     level    = Parameters[2].AsDouble;
            Double     minrange = Parameters[3].AsDouble;

            DateTimes = source.DateTimes;

            if (period > DateTimes.Count)
            {
                period = DateTimes.Count;
            }
            if (DateTimes.Count < period || period <= 0)
            {
                return;
            }

            var HiLoRange = Highest.Series(source.High, period) - Lowest.Series(source.Low, period);

            for (int n = 0; n < period; n++)
            {
                Values[n] = 0;
            }

            for (int bar = period; bar < source.Count; bar++)
            {
                double result = 0.0;

                double ls = Lowest.Series(source.Low, period)[bar];

                if (minrange == 0.0)
                {
                    result = ls + (HiLoRange[bar] * (level / 100));
                }
                else
                {
                    double l      = ls;
                    double range  = HiLoRange[bar];
                    double mid    = l + range / 2;
                    double mrange = l * minrange / 100.0;

                    if (range < mrange)
                    {
                        range = mrange;
                    }

                    result = mid + (level / 100.0 - 0.5) * range;
                }

                Values[bar] = result;
            }
        }
Example #10
0
        public Density(Bars bars, int NBars, string description)
            : base(bars, description)
        {
            base.FirstValidValue = NBars;

            DataSeries Area = (Highest.Series(bars.High, NBars) - Lowest.Series(bars.Low, NBars));

            for (int bar = FirstValidValue; bar < bars.Count; bar++)
            {
                base[bar] = Sum.Series(TrueRange.Series(bars), NBars)[bar] / Area[bar];
            }
        }
Example #11
0
        public PercentRange(DataSeries ds, int period, string description)
            : base(ds, description)
        {
            base.FirstValidValue = period;

            DataSeries r = ds * 0;

            r = ds / (Highest.Series(ds, period) - Lowest.Series(ds, period));

            for (int bar = FirstValidValue; bar < ds.Count; bar++)
            {
                base[bar] = r[bar];
            }
        }
Example #12
0
        public Highest2(DataSeries ds1, DataSeries ds2, int period)
            : base(ds2, "Highest Of Two")
        {
            DataSeries tmp = ds1 - ds1;

            for (int bar = tmp.FirstValidValue; bar < ds2.Count; bar++)
            {
                tmp[bar] = Math.Max(ds1[bar], ds2[bar]);
            }

            for (int bar = tmp.FirstValidValue; bar < ds2.Count; bar++)
            {
                this[bar] = Highest.Series(tmp, period)[bar];
            }
        }
Example #13
0
        public override void CalculatePartialValue()
        {
            if (_bars.Count < _period || _bars.Low.PartialValue == Double.NaN || _bars.High.PartialValue == Double.NaN)
            {
                PartialValue = Double.NaN;
                return;
            }

            int bar = _bars.Count;          // bar - 1 is last bar number (prior to PartialBar)

            if (_tradeable)
            {
                if (_ppHigh)
                {
                    if (_bars.High.PartialValue >= Highest.Series(_bars.High, _period)[bar - 1])
                    {
                        _lastPP = bar;
                    }
                }
                else if (_bars.Low.PartialValue <= Lowest.Series(_bars.Low, _period)[bar - 1])
                {
                    _lastPP = bar;
                }
            }
            else
            {
                int periodFwd = _period;
                if (bar + _period >= _bars.Count)
                {
                    periodFwd = _bars.Count - bar - 1;
                }
                if (_ppHigh)
                {
                    if (_bars.High.PartialValue >= Highest.Series(_bars.High, _period)[bar - 1] &&
                        _bars.High.PartialValue >= Highest.Value(bar + periodFwd, _bars.High, periodFwd))     // use Value method since periodFwd is variable at the end
                    {
                        _lastPP = bar;
                    }
                }
                else if (_bars.Low.PartialValue <= Lowest.Series(_bars.Low, _period)[bar - 1] &&
                         _bars.Low.PartialValue <= Lowest.Value(bar + periodFwd, _bars.Low, periodFwd))
                {
                    _lastPP = bar;
                }
            }
            this.PartialValue = _lastPP;
        }
Example #14
0
        public TenkanSen(Bars bars)
            : base(bars, "TenkanSen")
        {
            int p1 = 9;

            base.FirstValidValue = p1;

            if (bars.Count < p1)
            {
                return;
            }

            for (int bar = FirstValidValue; bar < bars.Count; bar++)
            {
                base[bar] = ((Highest.Series(bars.High, p1)[bar] + Lowest.Series(bars.Low, p1)[bar]) / 2);
            }
        }
Example #15
0
        public KijunSen(Bars bars)
            : base(bars, "KijunSen")
        {
            int p2 = 26;

            base.FirstValidValue = p2;

            if (bars.Count < p2)
            {
                return;
            }

            for (int bar = FirstValidValue; bar < bars.Count; bar++)
            {
                base[bar] = ((Highest.Series(bars.High, p2)[bar] + Lowest.Series(bars.Low, p2)[bar]) / 2);
            }
        }
Example #16
0
        public override void Populate()
        {
            TimeSeries ds          = Parameters[0].AsTimeSeries;
            Int32      rsiPeriod   = Parameters[1].AsInt;
            Int32      stochPeriod = Parameters[2].AsInt;
            Int32      smaPeriod   = Parameters[3].AsInt;

            DateTimes = ds.DateTimes;
            var period = Math.Max(Math.Max(rsiPeriod, stochPeriod), smaPeriod);

            if (period <= 0 || DateTimes.Count == 0)
            {
                return;
            }

            // First we buffer the RSI indicator --------------------------------------------------
            var rsi = new RSI(ds, rsiPeriod);

            // Buffering the Highest High and lowest low RSI during the Stochastic lookback period
            var HiRSI_Buffer  = Highest.Series(rsi, stochPeriod);
            var LowRSI_Buffer = Lowest.Series(rsi, stochPeriod);

            // Now we buffer the RSI minus the Low RSI value of the lookback period
            // Doing the same for the High minus Low RSI value of the lookback period.
            var RSILow_Buffer = new TimeSeries(DateTimes);
            var HiLow_Buffer  = new TimeSeries(DateTimes);

            for (int i = 0; i < DateTimes.Count; i++)
            {
                RSILow_Buffer[i] = (rsi[i] - LowRSI_Buffer[i]);
                HiLow_Buffer[i]  = (HiRSI_Buffer[i] - LowRSI_Buffer[i]);
            }

            // Next action is creating the SMA of this 2 last values
            var ema_Buffer1 = SMA.Series(RSILow_Buffer, smaPeriod);
            var ema_Buffer2 = SMA.Series(HiLow_Buffer, smaPeriod);

            // Finally the Stochastics formula is applied
            // %K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100

            for (int bar = period; bar < ds.Count; bar++)
            {
                Values[bar] = ema_Buffer1[bar] / (0.1 + (ema_Buffer2[bar])) * 100;
            }
        }
Example #17
0
    //===========================================================================================================
    // RS Line
    // indexUpFactor - typically 1.02 to 1.2
    // rsDownFactor - typically 0.60 to 0.85
    //-----------------------------------------------------------------------------------------------------------
    protected void drawIndexAndRsLines(double indexUpFactor, double rsDownFactor)
    {
        // Index Line
        Bars       SPX           = GetExternalSymbol(".SPX", true);
        double     highRefPrice  = Highest.Series(High, 200)[Bars.Count - 1];
        DataSeries SPXNormalized = highRefPrice * indexUpFactor * SPX.Close / SPX.Close[Bars.Count - 1];

        PlotSeries(PricePane, SPXNormalized, Color.Black, LineStyle.Solid, 1);
        //DataSeries SPXNormalized2 = highRefPrice/2 + highRefPrice/2 * 1.02 * SPX.Close / SPX.Close[Bars.Count-1];
        //PlotSeries (PricePane, SPXNormalized2, Color.Red, LineStyle.Solid, 1 );

        // RS Line
        DataSeries RS  = Bars.Close / SPX.Close;
        DataSeries RS2 = Close[Bars.Count - 1] * rsDownFactor * RS / RS[Bars.Count - 1];

        //PlotSeries (CreatePane( 30, true, true ), RS, Color.Blue, LineStyle.Solid, 1 );
        PlotSeries(PricePane, RS2, Color.Blue, LineStyle.Solid, 1);
    }
Example #18
0
        public DVSuperSmoothedDSO(Bars bars, int period1, int period2, string description)
            : base(bars, description)
        {
            StochK     step1    = StochK.Series(bars, period1);
            DataSeries step2    = (step1 - Lowest.Series(step1, period1)) / (Highest.Series(step1, period1) - Lowest.Series(step1, period1));
            DataSeries step3    = Community.Indicators.FastSMA.Series(step2, period2);
            DataSeries DV_SSDSO = 0.85 * step3 + 0.15 * (step3 >> 1);

            base.FirstValidValue = Math.Max(period1, period2);
            if (FirstValidValue == 1)
            {
                return;
            }

            for (int bar = base.FirstValidValue; bar < bars.Count; bar++)
            {
                base[bar] = DV_SSDSO[bar] * 100;
            }
        }
Example #19
0
        public IrwinCycle(Bars bars, DataSeries ds, int period, string description)
            : base(ds, description)
        {
            base.FirstValidValue = period * 3;

            Highest    H1     = Highest.Series(bars.High, period);
            Lowest     L1     = Lowest.Series(bars.Low, period);
            DataSeries C1     = H1 - L1;
            EMA        R1     = EMA.Series(((ds - L1) / C1) * 100, 3, EMACalculation.Modern);
            Highest    H2     = Highest.Series(R1, period);
            Lowest     L2     = Lowest.Series(R1, period);
            DataSeries C2     = H2 - L2;
            DataSeries Result = EMA.Series(((R1 - L2) / C2) * 100, 3, EMACalculation.Modern);

            for (int bar = FirstValidValue; bar < bars.Count; bar++)
            {
                base[bar] = Result[bar];
            }
        }
Example #20
0
        public BressertDSS(Bars bars, int periodStochastic, int periodEMA, string description)
            : base(bars, description)
        {
            var X    = EMAModern.Series(StochK.Series(bars, periodEMA), periodStochastic);
            var bDSS = EMAModern.Series(((X - Lowest.Series(X, periodEMA)) / (Highest.Series(X, periodEMA) - Lowest.Series(X, periodEMA)) * 100d), periodStochastic);

            base.FirstValidValue = Math.Max(periodEMA, periodStochastic);
            if (FirstValidValue == 1)
            {
                return;
            }

            if (bars.Count < Math.Max(periodStochastic, periodEMA))
            {
                return;
            }

            for (int bar = base.FirstValidValue; bar < bars.Count; bar++)
            {
                base[bar] = bDSS[bar];
            }
        }
Example #21
0
        public VK_SH_Band(DataSeries ds, int IntervalSize, int IntervalCount, string description)
            : base(ds, description)
        {
            //base.FirstValidValue = period;

            if (ds.Count < Math.Max(IntervalSize, IntervalCount))
            {
                return;
            }

            double val = 0;

            for (int bar = IntervalSize * IntervalCount; bar < ds.Count; bar++)
            {
                val = 0;
                for (int sequenz = 0; sequenz < IntervalCount; sequenz++)
                {
                    val += Highest.Series(ds, IntervalSize)[bar - sequenz * IntervalSize] / IntervalCount;
                }
                base[bar] = val;
            }
        }
Example #22
0
        public DSR(Bars bars, int period, string description)
            : base(bars, description)
        {
            base.FirstValidValue = 252;
            List <double> lst    = new List <double>();
            DataSeries    rawDSR = new DataSeries(bars, "raw dsr(" + period + ")");

            for (int bar = period; bar < bars.Count; bar++)
            {
                lst.Clear();

                for (int i = bar; i > bar - period; i--)
                {
                    lst.Add(bars.High[i]); lst.Add(bars.Low[i]); lst.Add(bars.Close[i]);
                }

                //DSR differential=  average(  65th percentile (H,L,C, 20-days), 80th percentile  (H,L,C, 20-days)) –
                //average(  35th percentile (H,L,C, 20-days), 20th percentile  (H,L,C, 20-days))

                double dsrDiff = (percentile(lst, 65) + percentile(lst, 80) / 2) - (percentile(lst, 35) + percentile(lst, 20) / 2);

                //DSR raw=  DSR differential/(max(H,L,C, 20-days)-min(H,L,C, 20-days))

                double dsrRaw = dsrDiff / (Highest.Series(bars.High, period)[bar] - Lowest.Series(bars.Low, period)[bar]);
                rawDSR[bar] = dsrRaw;
            }

            //DSR= 252-day percentrank of ( 10-day sma of DSR raw )
            var rangePartitioner = Partitioner.Create(FirstValidValue, bars.Count);

            Parallel.ForEach(rangePartitioner, (range, loopState) =>
            {
                for (int bar = range.Item1; bar < range.Item2; bar++)
                {
                    base[bar] = PercentRank.Series(Community.Indicators.FastSMA.Series(rawDSR, 10), 252)[bar];
                }
            });
        }
Example #23
0
        public NewMax(DataSeries ds, int period, string description)
            : base(ds, description)
        {
            base.FirstValidValue = period;
            double h, l, x, Value; l = 0;

            for (int bar = FirstValidValue; bar < ds.Count; bar++)
            {
                h = Highest.Series(ds, period)[bar];
                l = Lowest.Series(ds, period)[bar];
                x = ds[bar];
                if ((h - l) > 0)
                {
                    Value = (x - l) / (h - l) * 200 - 100;
                }
                else
                {
                    Value = 0;
                }

                base[bar] = Value;
            }
        }
Example #24
0
        /*
         * H = CurrentClose – (High MAX + Low MIN) / 2
         *
         * HS1 =Exponential Moving Average(H,3)
         * HS2 = Exponential Moving Average(HS1,3)
         *
         * DHL1 =Exponential Moving Average  (High MAX – Low MIN,3)
         * DHL2 = Exponential Moving Average (High MAX – Low MIN, 3) / 2
         *
         * SMI TODAY = (HS2 / DHL2) * 100
         */

        public SMI(Bars bars, int period1, int period2, int period3, string description)
            : base(bars, description)
        {
            base.FirstValidValue = Math.Max(Math.Max(period1, period2), period3);
            if (FirstValidValue <= 1)
            {
                return;
            }

            DataSeries h    = Highest.Series(bars.High, period1);
            DataSeries l    = Lowest.Series(bars.Low, period1);
            DataSeries c    = (h + l) / 2;
            DataSeries H    = bars.Close - c;
            DataSeries HS1  = EMA.Series(H, period2, EMACalculation.Modern);
            DataSeries HS2  = EMA.Series(HS1, period2, EMACalculation.Modern);
            DataSeries DHL1 = EMA.Series(h - l, period3, EMACalculation.Modern);
            DataSeries DHL2 = EMA.Series(h - l, period3, EMACalculation.Modern) / 2;
            DataSeries smi  = (HS2 / DHL2) * 100;

            for (int bar = base.FirstValidValue; bar < bars.Count; bar++)
            {
                base[bar] = smi[bar];
            }
        }
Example #25
0
        protected override void Execute()
        {
            int level;

            signleToSell     = false;
            priceAtCross     = 0;
            firstUp          = false;
            firstDown        = false;
            priceAtCrossDown = 0;
            rocAtCrossDown   = 0;

            topPrice   = 0;
            lastTop    = 0;
            breakPrice = 0;
            rocPrice   = 0;

            //Create and plot  period RSI
            RSI       rsi20   = RSI.Series(Close, rsiPeriod.ValueInt);
            ChartPane rsiPane = CreatePane(50, true, true);

            PlotSeries(rsiPane, rsi20, Color.Navy, LineStyle.Solid, 3);
            DrawHorzLine(rsiPane, oversold.Value, Color.Red, LineStyle.Dotted, 2);
            DrawHorzLine(rsiPane, overbought.Value, Color.Green, LineStyle.Dotted, 2);


            ChartPane paneROC1 = CreatePane(40, true, true);

            PlotSeries(paneROC1, ROC.Series(Close, rocPeriod.ValueInt), Color.FromArgb(255, 112, 128, 144), LineStyle.Dotted, 2);
            DrawHorzLine(paneROC1, 0, Color.Red, LineStyle.Solid, 2);

            int period = Math.Max(rsiPeriod.ValueInt, rocPeriod.ValueInt);


            if (initPosition)
            {
                // init starting state to force buy into the market
                priceAtCrossDown = Close[period + 1];
                rocAtCrossDown   = ROC.Value(period + 1, Close, rocPeriod.ValueInt);
                firstDown        = true;
            }

            double High60           = 0;
            double Low60            = 0;
            int    n                = Bars.BarInterval;
            int    num              = (60 / n) - 1; // the first hour bar
            int    firstIntradayBar = -1;


            //Trading system main loop
            for (int bar = period + 1; bar < Bars.Count; bar++)
            {
                if (Bars.IntradayBarNumber(bar) == 0)
                {
                    firstIntradayBar = bar;
                }

                if (Bars.IntradayBarNumber(bar) <= num)                    // highlight the first hour
                {
                    SetBarColor(bar, Color.Silver);
                }

                if (Bars.IntradayBarNumber(bar) == num)                    // get the highest high and the lowest low after first hour
                {
                    High60 = Highest.Series(Bars.High, num + 1)[bar];
                    Low60  = Lowest.Series(Bars.Low, num + 1)[bar];

                    if (firstIntradayBar > -1)
                    {
                        DrawLine(PricePane, bar, High60, firstIntradayBar, High60, Color.Blue, LineStyle.Dashed, 1);
                        DrawLine(PricePane, bar, Low60, firstIntradayBar, Low60, Color.Red, LineStyle.Dashed, 1);
                    }
                }

                if (Close[bar] > topPrice)
                {
                    topPrice = Close[bar];
                }

                level = oversold.ValueInt;

                if (CrossUnder(bar, rsi20, level))
                {
                    if (!firstDown)
                    {
                        // first time to go below
                        // set cross happen and record the targit price
                        firstDown        = true;
                        priceAtCrossDown = Close[bar];
                        rocAtCrossDown   = ROC.Value(bar, Close, rocPeriod.ValueInt);
                    }
                }

                // play trayling
                int  addToPosition = 0;
                bool rsiOk         = false;
                bool priceOK       = false;
                if (firstDown)
                {
                    // ROC must improve by delta
                    double delta = Math.Abs(rocAtCrossDown * 0.2);

                    double newrocSMA = ROC.Value(bar, Close, rocPeriod.ValueInt);


                    if (bar == Bars.Count - 1)
                    {
                        rocPrice = rocAtCrossDown + delta;
                    }

                    if (newrocSMA <= (rocAtCrossDown + delta))
                    {
                        if (newrocSMA < rocAtCrossDown)
                        {
                            rocAtCrossDown = newrocSMA;
                        }
                    }
                    else
                    {
                        rsiOk = true;
                    }

                    double riseV = priceRise.ValueInt;
                    delta = priceAtCrossDown * (riseV / 1000.0 + 0.00017);

                    if (bar == Bars.Count - 1)
                    {
                        breakPrice = priceAtCrossDown + delta;
                    }

                    if (Close[bar] < (priceAtCrossDown + delta))
                    {
                        // DrawLabel(PricePane, "ready to buy, price is not rising: " + Close[bar].ToString() + " less than " + (priceAtCrossDown + delta).ToString());

                        if (Close[bar] < priceAtCrossDown)
                        {
                            priceAtCrossDown = Close[bar];
                        }
                    }
                    else
                    {
                        priceOK = true;
                    }

                    if (priceOK && rsiOk)
                    {
                        addToPosition++;
                        firstDown = false;
                    }
                }

                // you can  have only one active position
                foreach (Position pos in Positions)
                {
                    if (pos.Active && pos.PositionType == PositionType.Long)
                    {
                        addToPosition = 0;
                        break;
                    }
                }

                if (addToPosition > 0)
                {
                    // OverSold
                    // Close all shorts
                    foreach (Position pos in Positions)
                    {
                        if (pos.Active && pos.PositionType == PositionType.Short)
                        {
                            CoverAtMarket(bar + 1, pos);
                        }
                    }

                    //	    DrawLabel(PricePane, "buy at bar = " + bar.ToString());
                    Position p = BuyAtMarket(bar + 1);
                    firstUp = false;
                }


                level = overbought.ValueInt;
                int ClosedTrades = 0;
                signleToSell = false;
                if (CrossOver(bar, rsi20, overbought.ValueInt))
                {
                    if (!firstUp)
                    {
                        // first time to go above
                        // set cross happen and record the targit price
                        firstUp      = true;
                        priceAtCross = Close[bar];
                    }
                }

                if (firstUp)
                {
                    double riseV = priceRise.ValueInt;

                    double delta = priceAtCross * (riseV / 1000 + 0.00017);

                    priceOK = true;
                    if (Close[bar] >= (priceAtCross - delta))
                    {
                        if (Close[bar] > priceAtCross)
                        {
                            priceAtCross = Close[bar];
                        }
                    }
                    else
                    {
                        priceOK = false;
                    }

                    // keep as long ROC over zero
                    if (ROC.Value(bar, Close, rocPeriod.ValueInt) <= 0 && !priceOK)
                    {
                        signleToSell = true;
                        firstUp      = false;
                    }
                }

                // sync real account with strategy
                //			if (Bars.Date[bar] == syncDate)
                //			{
                //				signleToSell = true;  // close postions
                //			}

                // Over Bought
                // wait until price either move up or stopped out
                if (signleToSell)
                {
                    firstUp = false;
                    //DrawLabel(PricePane, ActivePositions.Count.ToString());
                    foreach (Position pos in Positions)
                    {
                        if (pos.Active && pos.PositionType == PositionType.Long)
                        {
                            SellAtMarket(bar + 1, pos);
                            ClosedTrades++;
                        }
                    }
                    signleToSell = false;

                    if (ClosedTrades > 0)
                    {
                        // Short only after sell long position
                        if (!trend)
                        {
                            ShortAtMarket(bar + 1);
                        }
                    }
                }
                // sell on % lose
                foreach (Position pos in Positions)
                {
                    if (pos.Active &&
                        pos.PositionType == PositionType.Long &&
                        pos.EntryPrice > (Close[bar] + pos.EntryPrice * (0.01 + stopLose.ValueInt * 0.001)) &&
                        bar >= pos.EntryBar
                        )
                    {
                        SellAtMarket(bar + 1, pos, "stop lose");
                        signleToSell = false;
                        firstUp      = false;
                        firstDown    = false;
                        continue;
                    }
                    if (pos.Active &&
                        pos.PositionType == PositionType.Short &&
                        Close[bar] > (pos.EntryPrice + pos.EntryPrice * (0.01 + stopLose.ValueInt * 0.001)) &&
                        bar >= pos.EntryBar
                        )
                    {
                        CoverAtMarket(bar + 1, pos, "stop lose Short");
                    }
                }
            }
            double currentPrice = Close[Bars.Count - 1];

            DrawLabel(paneROC1, "Top: " + topPrice.ToString(), Color.Red);
            DrawLabel(paneROC1, "Current Price: " + currentPrice.ToString());

            DrawLabel(paneROC1, "Goal : " + " At +5%  " + (currentPrice * 1.05).ToString(), Color.BlueViolet);
            DrawLabel(paneROC1, "Goal : " + " At +8%  " + (currentPrice * 1.08).ToString(), Color.MediumSpringGreen);
            DrawLabel(paneROC1, "Goal : " + " At +10% " + (currentPrice * 1.10).ToString(), Color.DarkOliveGreen);


            DrawLabel(PricePane, "Drop          : " + " At -5%  " + (topPrice * 0.95).ToString(), Color.DarkGreen);
            DrawLabel(PricePane, "Correction   : " + " At -8%  " + (topPrice * 0.92).ToString(), Color.DarkBlue);
            DrawLabel(PricePane, "Correction   : " + " At -10% " + (topPrice * 0.90).ToString(), Color.Red);
            DrawLabel(PricePane, "Bear market: " + " At -20% " + (topPrice * 0.80).ToString(), Color.DarkRed);

            if (breakPrice > 0)
            {
                DrawLabel(PricePane, "Break above Price: " + breakPrice.ToString(), Color.DarkGoldenrod);
            }
            if (rocPrice > 0)
            {
                DrawLabel(PricePane, "Break above Momuntem: " + rocPrice.ToString(), Color.DarkGoldenrod);
            }


            DrawHorzLine(PricePane, currentPrice * 1.05, Color.BlueViolet, LineStyle.Solid, 6);
            DrawHorzLine(PricePane, currentPrice * 1.08, Color.MediumSpringGreen, LineStyle.Solid, 3);
            DrawHorzLine(PricePane, currentPrice * 1.10, Color.DarkOliveGreen, LineStyle.Solid, 3);


            DrawHorzLine(PricePane, topPrice * 0.95, Color.DarkGreen, LineStyle.Solid, 3);
            DrawHorzLine(PricePane, topPrice * 0.92, Color.DarkBlue, LineStyle.Solid, 3);
            DrawHorzLine(PricePane, topPrice * 0.90, Color.Red, LineStyle.Solid, 3);
            DrawHorzLine(PricePane, topPrice * 0.80, Color.DarkRed, LineStyle.Solid, 3);


            if (breakPrice > 0)
            {
                DrawHorzLine(PricePane, breakPrice, Color.DarkGoldenrod, LineStyle.Solid, 4);
            }
        }