Category Oscilators  Published on 09/12/2016

Stochastic Oscillator: Trend + Values

Description

 

UP Trend begins when 2 lines cross DOWN level bottom-up and ends when 2 lines cross UP level top-down

DOWN Trend begins when 2 lines cross UP level top-down and ends when 2 lines cross DOWN level bottom-up

Also indicator shows changes between UP and DOWN trends.

 

/

#region Using declarations
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
#endregion

namespace cAlgo
{
    [Levels(10, 20, 50, 80, 90)]

    [Indicator(IsOverlay = false, AutoRescale = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SO : Indicator
    {

        #region Properties
        [Parameter("K Periods", DefaultValue = 200)]
        public int kPeriods { get; set; }

        [Parameter("K Slowing", DefaultValue = 3)]
        public int kSlowing { get; set; }

        [Parameter("D Periods", DefaultValue = 3)]
        public int dPeriods { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Triangular)]
        public MovingAverageType maType { get; set; }

        [Parameter("UP Level", DefaultValue = 90, MinValue = 80, MaxValue = 100, Step = 1)]
        public int Up_Level { get; set; }

        [Parameter("Down Level", DefaultValue = 10, MinValue = 0, MaxValue = 20, Step = 1)]
        public int Down_Level { get; set; }

        [Output("% D", Color = Colors.Aquamarine, Thickness = 2)]
        public IndicatorDataSeries Percent_D { get; set; }

        [Output("% K", Color = Colors.Purple, Thickness = 2)]
        public IndicatorDataSeries Percent_K { get; set; }

        [Output("Trend", Color = Colors.Yellow, Thickness = 1)]
        public IndicatorDataSeries Value { get; set; }
        #endregion


        #region Variables
        enum Direction
        {
            Up,
            Down
        }

        private Direction direction = Direction.Down;
        private StochasticOscillator so;

        private double Extremum_Value = 0.0;
        private int Extremum_Index = 0;
        private int Last_Up_Index = 0;
        private int Last_Down_Index = 0;

        #endregion

        protected override void Initialize()
        {
            so = Indicators.StochasticOscillator(kPeriods, kSlowing, dPeriods, maType);

            if (Lines_Are_Lower_Level(Down_Level, 0))
                direction = Direction.Up;

            if (Lines_Are_Higher_Level(Up_Level, 0))
                direction = Direction.Down;
        }

        public override void Calculate(int index)
        {
            Percent_K[index] = so.PercentK.LastValue;
            Percent_D[index] = so.PercentD.LastValue;

            /// Up Level
            if (Lines_Just_Crossed_From_Up_To_Down_Level(Up_Level, index))
            {
                if (direction == Direction.Up)
                {
                    direction = Direction.Down;
                    Last_Up_Index = index;
                    Set_Extremum_At(index, Up_Level);
                }

                if (direction == Direction.Down && Extremum_Value == Up_Level)
                {
                    Last_Up_Index = index;
                    Move_Extremum_At(index, Up_Level);
                }
            }

            /// Down Level
            if (Lines_Just_Crossed_From_Down_To_Up_Level(Down_Level, index))
            {
                if (direction == Direction.Down)
                {
                    direction = Direction.Up;
                    Last_Down_Index = index;
                    Set_Extremum_At(index, Down_Level);
                }

                if (direction == Direction.Up && Extremum_Value == Down_Level)
                {
                    Last_Down_Index = index;
                    Move_Extremum_At(index, Down_Level);
                }
            }

            if (index - 1 != Extremum_Index)
            {
                Value[index - 1] = Double.NaN;
                Value[index] = Percent_D[index];
            }
        }

        private bool Lines_Are_Lower_Level(double level, int index)
        {
            return Percent_K[index] < level && Percent_D[index] < level;
        }

        private bool Lines_Are_Higher_Level(double level, int index)
        {
            return Percent_K[index] > level && Percent_D[index] > level;
        }

        private bool Lines_Just_Crossed_From_Up_To_Down_Level(double level, int index)
        {
            return Lines_Are_Lower_Level(level, index) && (Percent_K[index - 1] >= level || Percent_D[index - 1] >= level);
        }

        private bool Lines_Just_Crossed_From_Down_To_Up_Level(double level, int index)
        {
            return Lines_Are_Higher_Level(level, index) && (Percent_K[index - 1] <= level || Percent_D[index - 1] <= level);
        }

        private void Move_Extremum_At(int index, double v)
        {
            Value[Extremum_Index] = Double.NaN;
            ChartObjects.RemoveObject("Info " + Extremum_Index);
            Set_Extremum_At(index, v);
        }

        private void Set_Extremum_At(int Index, double V)
        {
            Extremum_Index = Index;
            Extremum_Value = V;
            Value[Extremum_Index] = Extremum_Value;

            VerticalAlignment Point_VA = VerticalAlignment.Center;
            HorizontalAlignment Point_HA = HorizontalAlignment.Center;
            Colors Point_Color = Colors.Yellow;

            ChartObjects.DrawText("Direction " + Index, "•", Index, V, Point_VA, Point_HA, Point_Color);

            double Low = MarketSeries.Low[Last_Down_Index];
            double High = MarketSeries.High[Last_Up_Index];
            double Trend_Value = (High - Low) / Symbol.TickSize;
            string Dir = direction == Direction.Down ? "▲" : "▼";
            string Info = Dir + " " + Trend_Value.ToString("N0");

            VerticalAlignment Text_VA = VerticalAlignment.Center;
            HorizontalAlignment Text_HA = HorizontalAlignment.Center;
            Colors Text_Color = Colors.Yellow;

            ChartObjects.DrawText("Info " + Index, Info, Index, V >= 50 ? V - 10 : V + 10, Text_VA, Text_HA, Text_Color);
        }
    }
}


diiptrade's avatar
diiptrade

Joined on 17.11.2016

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: SO.algo
  • Rating: 5
  • Installs: 6445
  • Modified: 13/10/2021 09:54
Comments
Log in to add a comment.
PA
paul.williams125 · 4 years ago

// This Just puts an Icon above the price, on the chart.

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

//                   AutoRescale = true
namespace cAlgo
{

    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class SO : Indicator
    {


        [Parameter("K Periods", DefaultValue = 200)]
        public int kPeriods { get; set; }

        [Parameter("K Slowing", DefaultValue = 3)]
        public int kSlowing { get; set; }

        [Parameter("D Periods", DefaultValue = 3)]
        public int dPeriods { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Triangular)]
        public MovingAverageType maType { get; set; }

        [Parameter("UP Level", DefaultValue = 90, MinValue = 80, MaxValue = 100, Step = 1)]
        public int Up_Level { get; set; }

        [Parameter("Down Level", DefaultValue = 10, MinValue = 0, MaxValue = 20, Step = 1)]
        public int Down_Level { get; set; }


        private StochasticOscillator so;

        private double Extremum_Value = 0.0;
        private int Extremum_Index = 0;
        private int Last_Up_Index = 0;
        private int Last_Down_Index = 0;
        private int direction = 0;


        protected override void Initialize()
        {
            so = Indicators.StochasticOscillator(kPeriods, kSlowing, dPeriods, maType);
        }

        public override void Calculate(int index)
        {


//----------                                                                      K value is Stockastic value ( purple) , D is MA3 of it.
//-----------                                                                     if ( K is now < 90% and the previous K >= 90% )
//-----------                                                                     this is our setup for upper entry
//UP LEVEL

            if (so.PercentK[index] < Up_Level && so.PercentK[index - 1] >= Up_Level)
            {
                var high = MarketSeries.High[index];
                var highPlus2Pip = high + (5 * Symbol.PipSize);
                ChartObjects.DrawText("Info " + index, "▼", index, highPlus2Pip, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.White);
            }
//DOWN lEVEL

            if (so.PercentK[index] > Down_Level && so.PercentK[index - 1] <= Down_Level)
            {
                var low = MarketSeries.Low[index];
                var lowPlus2Pip = low - (5 * Symbol.PipSize);
                ChartObjects.DrawText("Info " + index, "▲", index, lowPlus2Pip, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.White);


            }


        }
    }
}

PA
paul.williams125 · 4 years ago

// This has been modified, to be more easily understandable.

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo
{
    [Levels(10, 20, 50, 80, 90)]

    [Indicator(IsOverlay = false, AutoRescale = true, AccessRights = AccessRights.None)]
    public class SO : Indicator
    {


        [Parameter("K Periods", DefaultValue = 200)]
        public int kPeriods { get; set; }

        [Parameter("K Slowing", DefaultValue = 3)]
        public int kSlowing { get; set; }

        [Parameter("D Periods", DefaultValue = 3)]
        public int dPeriods { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Triangular)]
        public MovingAverageType maType { get; set; }

        [Parameter("UP Level", DefaultValue = 90, MinValue = 80, MaxValue = 100, Step = 1)]
        public int Up_Level { get; set; }

        [Parameter("Down Level", DefaultValue = 10, MinValue = 0, MaxValue = 20, Step = 1)]
        public int Down_Level { get; set; }

        [Output("% D", Color = Colors.Aquamarine, Thickness = 2)]
        public IndicatorDataSeries Percent_D { get; set; }

        [Output("% K", Color = Colors.Purple, Thickness = 2)]
        public IndicatorDataSeries Percent_K { get; set; }

        [Output("Trend", Color = Colors.Yellow, Thickness = 1)]
        public IndicatorDataSeries Value { get; set; }


        private StochasticOscillator so;

        private double Extremum_Value = 0.0;
        private int Extremum_Index = 0;
        private int Last_Up_Index = 0;
        private int Last_Down_Index = 0;
        private int direction = 0;


        protected override void Initialize()
        {
            so = Indicators.StochasticOscillator(kPeriods, kSlowing, dPeriods, maType);
        }

        public override void Calculate(int index)
        {
            Percent_K[index] = so.PercentK[index];
            Percent_D[index] = so.PercentD[index];

//----------                                                                      K value is Stockastic value ( purple) , D is MA3 of it.
//-----------                                                                     if ( K is now < 90% and D < 90%  ) and  (the previous K >= 90%   or the Previous D is >= 90%)
//-----------                                                                     this is to get the position for the dot.
//UP LEVEL

            if ((Percent_K[index] < Up_Level && Percent_D[index] < Up_Level) && (Percent_K[index - 1] >= Up_Level || Percent_D[index - 1] >= Up_Level))
            {
                if (direction == 1)
                {
                    direction = 0;
                    Last_Up_Index = index;

                    Extremum_Index = index;
                    Extremum_Value = Up_Level;
                    Value[Extremum_Index] = Extremum_Value;

                    ChartObjects.DrawText("Direction " + index, "•", index, Up_Level, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.Yellow);

                    double Low = MarketSeries.Low[Last_Down_Index];
                    double High = MarketSeries.High[Last_Up_Index];
                    double Trend_Value = (High - Low) / Symbol.TickSize;
                    string Dir = direction == 0 ? "▲" : "▼";
                    string Info = Dir + " " + Trend_Value.ToString("N0");

                    ChartObjects.DrawText("Info " + index, Info, index, Up_Level >= 50 ? Up_Level - 10 : Up_Level + 10, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.Yellow);

                }

                if (direction == 0 && Extremum_Value == Up_Level)
                {
                    Last_Up_Index = index;
                    Value[Extremum_Index] = Double.NaN;
                    ChartObjects.RemoveObject("Info " + Extremum_Index);
                    Extremum_Index = index;
                    Extremum_Value = Up_Level;
                    Value[Extremum_Index] = Extremum_Value;

                    ChartObjects.DrawText("Direction " + index, "•", index, Up_Level, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.Yellow);

                    double Low = MarketSeries.Low[Last_Down_Index];
                    double High = MarketSeries.High[Last_Up_Index];
                    double Trend_Value = (High - Low) / Symbol.TickSize;
                    string Dir = direction == 0 ? "▲" : "▼";
                    string Info = Dir + " " + Trend_Value.ToString("N0");
                    ChartObjects.DrawText("Info " + index, Info, index, Up_Level >= 50 ? Up_Level - 10 : Up_Level + 10, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.Yellow);
                }
            }
//---------------------------------------------------------------------------------



            /// Down Level
            if ((Percent_K[index] > Down_Level && Percent_D[index] > Down_Level) && (Percent_K[index - 1] <= Down_Level || Percent_D[index - 1] <= Down_Level))
            {
                if (direction == 0)
                {
                    direction = 1;
                    Last_Down_Index = index;

                    Extremum_Index = index;
                    Extremum_Value = Down_Level;
                    Value[Extremum_Index] = Extremum_Value;

                    ChartObjects.DrawText("Direction " + index, "•", index, Down_Level, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.Yellow);

                    double Low = MarketSeries.Low[Last_Down_Index];
                    double High = MarketSeries.High[Last_Up_Index];
                    double Trend_Value = (High - Low) / Symbol.TickSize;
                    string Dir = direction == 0 ? "▲" : "▼";
                    string Info = Dir + " " + Trend_Value.ToString("N0");
                    ChartObjects.DrawText("Info " + index, Info, index, Down_Level >= 50 ? Down_Level - 10 : Down_Level + 10, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.Yellow);
                }

                if (direction == 1 && Extremum_Value == Down_Level)
                {
                    Last_Down_Index = index;
                    Value[Extremum_Index] = Double.NaN;
                    ChartObjects.RemoveObject("Info " + Extremum_Index);
                    Extremum_Index = index;
                    Extremum_Value = Down_Level;
                    Value[Extremum_Index] = Extremum_Value;

                    ChartObjects.DrawText("Direction " + index, "•", index, Down_Level, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.Yellow);

                    double Low = MarketSeries.Low[Last_Down_Index];
                    double High = MarketSeries.High[Last_Up_Index];
                    double Trend_Value = (High - Low) / Symbol.TickSize;
                    string Dir = direction == 0 ? "▲" : "▼";
                    string Info = Dir + " " + Trend_Value.ToString("N0");
                    ChartObjects.DrawText("Info " + index, Info, index, Down_Level >= 50 ? Down_Level - 10 : Down_Level + 10, VerticalAlignment.Center, HorizontalAlignment.Center, Colors.Yellow);
                }

            }

            if (index - 1 != Extremum_Index)
            {
                Value[index - 1] = Double.NaN;
                Value[index] = Percent_D[index];
            }
        }
    }
}

IL
ilya430 · 5 years ago

That's a good one, my comrade!