DOt on chart on indicator crossover

Created at 16 Feb 2022, 14:23
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
PJ

PJ_Ctrader

Joined 04.02.2022

DOt on chart on indicator crossover
16 Feb 2022, 14:23


Below are QQE indicator and MACD zero lag. How can I insert a code that will give a blue dot when bullish and red dot when bearish on chart

  • when MACD is bullish and QQE crosses over bullish and opposite for bearish

Any suggestion would be great. This gives a very good indicator for signal for both buy and sell.

 

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

namespace cAlgo.Indicators
{
    [Indicator(AccessRights = AccessRights.None)]
    public class QQE : Indicator
    {
        private int _wildersPeriod;
        private int _startBar;
        private const int SF = 1;
        private ExponentialMovingAverage _ema;
        private ExponentialMovingAverage _emaAtr;
        private ExponentialMovingAverage _emaRsi;
        private RelativeStrengthIndex _rsi;


        private IndicatorDataSeries _atrRsi;

        [Parameter(DefaultValue = 8)]
        public int Period { get; set; }

        [Output("Main", Color = Colors.Green)]
        public IndicatorDataSeries Result { get; set; }

        [Output("Signal", Color = Colors.Red, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries ResultS { get; set; }

        [Output("Upper", Color = Colors.Gray, LineStyle = LineStyle.DotsRare)]
        public IndicatorDataSeries Upper { get; set; }

        [Output("Lower", Color = Colors.Gray, LineStyle = LineStyle.DotsRare)]
        public IndicatorDataSeries Lower { get; set; }

        [Output("Middle", Color = Colors.Gray, LineStyle = LineStyle.DotsRare)]
        public IndicatorDataSeries Middle { get; set; }

        protected override void Initialize()
        {

            _atrRsi = CreateDataSeries();
            CreateDataSeries();

            _wildersPeriod = Period * 2 - 1;
            _startBar = _wildersPeriod < SF ? SF : _wildersPeriod;

            _rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, Period);
            _emaRsi = Indicators.ExponentialMovingAverage(_rsi.Result, SF);
            _emaAtr = Indicators.ExponentialMovingAverage(_atrRsi, _wildersPeriod);
            _ema = Indicators.ExponentialMovingAverage(_emaAtr.Result, _wildersPeriod);

        }

        public override void Calculate(int index)
        {
            Result[index] = _emaRsi.Result[index];

            if (index <= _startBar)
            {
                ResultS[index] = 0;
                return;
            }

            _atrRsi[index] = Math.Abs(Result[index - 1] - Result[index]);

            double tr = ResultS[index - 1];

            if (Result[index] < ResultS[index - 1])
            {
                tr = Result[index] + _ema.Result[index] * 4.236;

                if (Result[index - 1] < ResultS[index - 1] && tr > ResultS[index - 1])
                    tr = ResultS[index - 1];
            }
            else if (Result[index] > ResultS[index - 1])
            {
                tr = Result[index] - _ema.Result[index] * 4.236;

                if (Result[index - 1] > ResultS[index - 1] && tr < ResultS[index - 1])
                    tr = ResultS[index - 1];
            }

            ResultS[index] = tr;

            Upper[index] = 70;
            Lower[index] = 30;
            Middle[index] = 50;
        }


    }




    public class ZeroLagMacd : Indicator
    {
        private ExponentialMovingAverage _emaLong;
        private ExponentialMovingAverage _emaShort;
        private ExponentialMovingAverage _emaSignal;
        private ExponentialMovingAverage _emaLong2;
        private ExponentialMovingAverage _emaShort2;

        [Parameter("Long Cycle", DefaultValue = 26)]
        public int LongCycle { get; set; }

        [Parameter("Short Cycle", DefaultValue = 12)]
        public int ShortCycle { get; set; }

        [Parameter("Signal Periods", DefaultValue = 9)]
        public int SignalPeriods { get; set; }

        [Output("Histogram", Color = Colors.Turquoise, PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Histogram { get; set; }

        [Output("MACD", Color = Colors.Blue)]
        public IndicatorDataSeries MACD { get; set; }

        [Output("Signal", Color = Colors.Red, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries Signal { get; set; }

        private IndicatorDataSeries _zeroLagEmaShort;
        private IndicatorDataSeries _zeroLagEmaLong;



        protected override void Initialize()
        {

            _zeroLagEmaShort = CreateDataSeries();
            _zeroLagEmaLong = CreateDataSeries();

            _emaLong = Indicators.ExponentialMovingAverage(MarketSeries.Close, LongCycle);
            _emaLong2 = Indicators.ExponentialMovingAverage(_emaLong.Result, LongCycle);

            _emaShort = Indicators.ExponentialMovingAverage(MarketSeries.Close, ShortCycle);
            _emaShort2 = Indicators.ExponentialMovingAverage(_emaShort.Result, ShortCycle);

            _emaSignal = Indicators.ExponentialMovingAverage(MACD, SignalPeriods);
        }

        public override void Calculate(int index)
        {
            _zeroLagEmaShort[index] = _emaShort.Result[index] * 2 - _emaShort2.Result[index];
            _zeroLagEmaLong[index] = _emaLong.Result[index] * 2 - _emaLong2.Result[index];

            MACD[index] = _zeroLagEmaShort[index] - _zeroLagEmaLong[index];

            Signal[index] = _emaSignal.Result[index];
            Histogram[index] = MACD[index] - Signal[index];
        }
    }


}

 


cTrader
@PJ_Ctrader
Replies

amusleh
17 Feb 2022, 09:17

Hi,

Try this:

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class QQE : Indicator
    {
        private int _wildersPeriod;
        private int _startBar;
        private const int SF = 1;
        private ExponentialMovingAverage _ema;
        private ExponentialMovingAverage _emaAtr;
        private ExponentialMovingAverage _emaRsi;
        private RelativeStrengthIndex _rsi;

        private IndicatorDataSeries _atrRsi, _main, _signal;

        private ZeroLagMacd _zeroLagMacd;

        [Parameter(DefaultValue = 8)]
        public int Period { get; set; }

        [Parameter("Long Cycle", DefaultValue = 26)]
        public int LongCycle { get; set; }

        [Parameter("Short Cycle", DefaultValue = 12)]
        public int ShortCycle { get; set; }

        [Parameter("Signal Periods", DefaultValue = 9)]
        public int SignalPeriods { get; set; }

        [Output("Bullish Dots", LineColor = "Green", LineStyle = LineStyle.Dots, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries BullishDots { get; set; }

        [Output("Bearish Dots", LineColor = "Red", LineStyle = LineStyle.Dots, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries BearishDots { get; set; }

        protected override void Initialize()
        {
            _atrRsi = CreateDataSeries();

            _wildersPeriod = Period * 2 - 1;
            _startBar = _wildersPeriod < SF ? SF : _wildersPeriod;

            _rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, Period);
            _emaRsi = Indicators.ExponentialMovingAverage(_rsi.Result, SF);
            _emaAtr = Indicators.ExponentialMovingAverage(_atrRsi, _wildersPeriod);
            _ema = Indicators.ExponentialMovingAverage(_emaAtr.Result, _wildersPeriod);

            _zeroLagMacd = Indicators.GetIndicator<ZeroLagMacd>(LongCycle, ShortCycle, SignalPeriods);

            _main = CreateDataSeries();
            _signal = CreateDataSeries();
        }

        public override void Calculate(int index)
        {
            _main[index] = _emaRsi.Result[index];

            if (index <= _startBar)
            {
                _signal[index] = 0;

                return;
            }

            _atrRsi[index] = Math.Abs(_main[index - 1] - _main[index]);

            double tr = _signal[index - 1];

            if (_main[index] < _signal[index - 1])
            {
                tr = _main[index] + _ema.Result[index] * 4.236;

                if (_main[index - 1] < _signal[index - 1] && tr > _signal[index - 1])
                    tr = _signal[index - 1];
            }
            else if (_main[index] > _signal[index - 1])
            {
                tr = _main[index] - _ema.Result[index] * 4.236;

                if (_main[index - 1] > _signal[index - 1] && tr < _signal[index - 1])
                    tr = _signal[index - 1];
            }

            _signal[index] = tr;

            BullishDots[index] = double.NaN;
            BearishDots[index] = double.NaN;

            if (_zeroLagMacd.MACD[index] > _zeroLagMacd.Signal[index] && _main[index] > _signal[index])
            {
                BullishDots[index] = Bars.LowPrices[index];
            }
            else if (_zeroLagMacd.MACD[index] < _zeroLagMacd.Signal[index] && _main[index] < _signal[index])
            {
                BearishDots[index] = Bars.HighPrices[index];
            }
        }
    }
}

The above indicator is QQE and it uses zero lag MACD, you have to reference the zero lag MACD before building it via cTrader automate reference manager.


@amusleh

PJ_Ctrader
22 Feb 2022, 10:10 ( Updated at: 21 Dec 2023, 09:22 )

RE:

amusleh said:

Hi,

Try this:

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class QQE : Indicator
    {
        private int _wildersPeriod;
        private int _startBar;
        private const int SF = 1;
        private ExponentialMovingAverage _ema;
        private ExponentialMovingAverage _emaAtr;
        private ExponentialMovingAverage _emaRsi;
        private RelativeStrengthIndex _rsi;

        private IndicatorDataSeries _atrRsi, _main, _signal;

        private ZeroLagMacd _zeroLagMacd;

        [Parameter(DefaultValue = 8)]
        public int Period { get; set; }

        [Parameter("Long Cycle", DefaultValue = 26)]
        public int LongCycle { get; set; }

        [Parameter("Short Cycle", DefaultValue = 12)]
        public int ShortCycle { get; set; }

        [Parameter("Signal Periods", DefaultValue = 9)]
        public int SignalPeriods { get; set; }

        [Output("Bullish Dots", LineColor = "Green", LineStyle = LineStyle.Dots, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries BullishDots { get; set; }

        [Output("Bearish Dots", LineColor = "Red", LineStyle = LineStyle.Dots, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries BearishDots { get; set; }

        protected override void Initialize()
        {
            _atrRsi = CreateDataSeries();

            _wildersPeriod = Period * 2 - 1;
            _startBar = _wildersPeriod < SF ? SF : _wildersPeriod;

            _rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, Period);
            _emaRsi = Indicators.ExponentialMovingAverage(_rsi.Result, SF);
            _emaAtr = Indicators.ExponentialMovingAverage(_atrRsi, _wildersPeriod);
            _ema = Indicators.ExponentialMovingAverage(_emaAtr.Result, _wildersPeriod);

            _zeroLagMacd = Indicators.GetIndicator<ZeroLagMacd>(LongCycle, ShortCycle, SignalPeriods);

            _main = CreateDataSeries();
            _signal = CreateDataSeries();
        }

        public override void Calculate(int index)
        {
            _main[index] = _emaRsi.Result[index];

            if (index <= _startBar)
            {
                _signal[index] = 0;

                return;
            }

            _atrRsi[index] = Math.Abs(_main[index - 1] - _main[index]);

            double tr = _signal[index - 1];

            if (_main[index] < _signal[index - 1])
            {
                tr = _main[index] + _ema.Result[index] * 4.236;

                if (_main[index - 1] < _signal[index - 1] && tr > _signal[index - 1])
                    tr = _signal[index - 1];
            }
            else if (_main[index] > _signal[index - 1])
            {
                tr = _main[index] - _ema.Result[index] * 4.236;

                if (_main[index - 1] > _signal[index - 1] && tr < _signal[index - 1])
                    tr = _signal[index - 1];
            }

            _signal[index] = tr;

            BullishDots[index] = double.NaN;
            BearishDots[index] = double.NaN;

            if (_zeroLagMacd.MACD[index] > _zeroLagMacd.Signal[index] && _main[index] > _signal[index])
            {
                BullishDots[index] = Bars.LowPrices[index];
            }
            else if (_zeroLagMacd.MACD[index] < _zeroLagMacd.Signal[index] && _main[index] < _signal[index])
            {
                BearishDots[index] = Bars.HighPrices[index];
            }
        }
    }
}

The above indicator is QQE and it uses zero lag MACD, you have to reference the zero lag MACD before building it via cTrader automate reference manager.

Thank you so much for the help. It does work but I wanted a DOT on crossover of QMP main above QMP Signal so that only one dot is printed around 1*ATR under the low of the bar at which the first signal occurred. The current code plots a series of dots one signal true. I know the code is very close to what I am looking for but I am new to C completely. thanks

Here is tradingview example,


@PJ_Ctrader

amusleh
23 Feb 2022, 08:57

Hi,

Try this one please:

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class QQE : Indicator
    {
        private int _wildersPeriod;
        private int _startBar;
        private const int SF = 1;
        private ExponentialMovingAverage _ema;
        private ExponentialMovingAverage _emaAtr;
        private ExponentialMovingAverage _emaRsi;
        private RelativeStrengthIndex _rsi;

        private IndicatorDataSeries _atrRsi, _main, _signal;

        private ZeroLagMacd _zeroLagMacd;

        [Parameter(DefaultValue = 8)]
        public int Period { get; set; }

        [Parameter("Long Cycle", DefaultValue = 26)]
        public int LongCycle { get; set; }

        [Parameter("Short Cycle", DefaultValue = 12)]
        public int ShortCycle { get; set; }

        [Parameter("Signal Periods", DefaultValue = 9)]
        public int SignalPeriods { get; set; }

        [Output("Bullish Dots", LineColor = "Green", LineStyle = LineStyle.Dots, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries BullishDots { get; set; }

        [Output("Bearish Dots", LineColor = "Red", LineStyle = LineStyle.Dots, PlotType = PlotType.Points, Thickness = 3)]
        public IndicatorDataSeries BearishDots { get; set; }

        protected override void Initialize()
        {
            _atrRsi = CreateDataSeries();

            _wildersPeriod = Period * 2 - 1;
            _startBar = _wildersPeriod < SF ? SF : _wildersPeriod;

            _rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, Period);
            _emaRsi = Indicators.ExponentialMovingAverage(_rsi.Result, SF);
            _emaAtr = Indicators.ExponentialMovingAverage(_atrRsi, _wildersPeriod);
            _ema = Indicators.ExponentialMovingAverage(_emaAtr.Result, _wildersPeriod);

            _zeroLagMacd = Indicators.GetIndicator<ZeroLagMacd>(LongCycle, ShortCycle, SignalPeriods);

            _main = CreateDataSeries();
            _signal = CreateDataSeries();
        }

        public override void Calculate(int index)
        {
            _main[index] = _emaRsi.Result[index];

            if (index <= _startBar)
            {
                _signal[index] = 0;

                return;
            }

            _atrRsi[index] = Math.Abs(_main[index - 1] - _main[index]);

            double tr = _signal[index - 1];

            if (_main[index] < _signal[index - 1])
            {
                tr = _main[index] + _ema.Result[index] * 4.236;

                if (_main[index - 1] < _signal[index - 1] && tr > _signal[index - 1])
                    tr = _signal[index - 1];
            }
            else if (_main[index] > _signal[index - 1])
            {
                tr = _main[index] - _ema.Result[index] * 4.236;

                if (_main[index - 1] > _signal[index - 1] && tr < _signal[index - 1])
                    tr = _signal[index - 1];
            }

            _signal[index] = tr;

            BullishDots[index] = double.NaN;
            BearishDots[index] = double.NaN;

            if (_zeroLagMacd.MACD[index] > _zeroLagMacd.Signal[index] && _main[index] > _signal[index] && _main[index - 1] < _signal[index - 1])
            {
                BullishDots[index] = Bars.LowPrices[index];
            }
            else if (_zeroLagMacd.MACD[index] < _zeroLagMacd.Signal[index] && _main[index] < _signal[index] && _main[index - 1] > _signal[index - 1])
            {
                BearishDots[index] = Bars.HighPrices[index];
            }
        }
    }
}

It only draws the dots when there is a crossover between QMP lines.


@amusleh