Drawing vertical lines at dataseries crosses

Created at 07 Jun 2014, 12:58
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!
PR

Prospect

Joined 21.03.2014

Drawing vertical lines at dataseries crosses
07 Jun 2014, 12:58


Hi All,

I have put together an MACD indicator based on the MGinley Dynamic, I don't think this has any practical use, it's more of a learning exercise for me.

In an attempt to visualise how a robot would behave I've tried to create an overlay indicator to reference the MACD indicator in order to draw a vertical line on the chart every time the signal data series (EMA of MD MACD  - "MDEMAResult") crosses above or below the MD data series (MDMACD).

I found the hascrossedabove and below functions and thought that these would do the job, but I've either misunderstood their purpose/how they work, implemented them wrong or both...

Indicator to overlay...

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


namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
    public class NewIndicator : Indicator
    {
        [Parameter()]
        public DataSeries Source { get; set; }

        [Parameter(DefaultValue = 100)]
        public int percentPeriod { get; set; }

        [Parameter(DefaultValue = 9)]
        public double EMAperiod { get; set; }

        MDCD mdcd;

        protected override void Initialize()
        {
            mdcd = Indicators.GetIndicator<MDCD>(Source, percentPeriod, EMAperiod);
        }

        public override void Calculate(int index)
        {

            if (Functions.HasCrossedAbove(mdcd.MDEMAResult, mdcd.MDMACD, 1))
            {
                Print("Signal has crossed above - MD {0}, Signal {1}, Index {2}", mdcd.MDEMAResult[index], mdcd.MDMACD[index], index);
                ChartObjects.DrawVerticalLine("vLine", index, Colors.Red, 1, LineStyle.Dots);
            }


            if (Functions.HasCrossedBelow(mdcd.MDEMAResult, mdcd.MDMACD, 1))
            {

                Print("Signal has crossed below - MD {0}, Signal {1}, Index {2}", mdcd.MDEMAResult[index], mdcd.MDMACD[index], index);
                ChartObjects.DrawVerticalLine("vLine2", index, Colors.Green, 1, LineStyle.Dots);
            }
        }
    }
}

 Indicator to reference... (which seems to be working fine)

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC)    ]
    public class MDCD : Indicator
    {
        [Parameter()]
        public DataSeries Source { get; set; }

        [Parameter(DefaultValue = 100)]
        public int percentPeriod { get; set; }

        [Parameter(DefaultValue = 9)]
        public double EMAperiod { get; set; }

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

        [Output("MDEMA", Color = Colors.Red)]
        public IndicatorDataSeries MDEMAResult { get; set; }


        private double exp, MD12, MD26;
        private IndicatorDataSeries MD12Result, MD26Result;


        protected override void Initialize()
        {
            exp = 2 / (EMAperiod + 1);

            MD12 = 12;
            MD26 = 26;

            MD12Result = CreateDataSeries();
            MD26Result = CreateDataSeries();
        }

        public override void Calculate(int index)
        {
            MD12Result[index] = MD(MD12 * percentPeriod / 100, MD12Result[index - 1], Source[index]);
            MD26Result[index] = MD(MD26 * percentPeriod / 100, MD26Result[index - 1], Source[index]);

            MDMACD[index] = MD12Result[index] - MD26Result[index];
            MDEMAResult[index] = MDEMA(MDMACD[index - 1], MDMACD[index]);
        }

        public double MD(double ratio, double previousValue, double input)
        {
            if (double.IsNaN(previousValue))
            {
                return input;
            }
            else
            {
                double currentValue = previousValue + (input - previousValue) / ratio * Math.Pow((input / previousValue), 4);
                return currentValue;
            }
        }

        public double MDEMA(double previousValue, double input)
        {
            if (double.IsNaN(previousValue))
            {
                return input;
            }
            else
            {
                double EMA = (input - previousValue) * exp + previousValue;
                return EMA;
            }
        }
    }
}

Any help much appreciated!!


@Prospect
Replies

Prospect
07 Jun 2014, 15:07

I'm still interested in peoples thoughts on the above as it'll help me better understand the platform, but I have also tried a different approach to this:

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


namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC)]
    public class NewIndicator : Indicator
    {
        [Parameter()]
        public DataSeries Source { get; set; }

        [Parameter(DefaultValue = 100)]
        public int percentPeriod { get; set; }

        [Parameter(DefaultValue = 9)]
        public double EMAperiod { get; set; }

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

        [Output("MDEMA", Color = Colors.Red)]
        public IndicatorDataSeries SignalResult { get; set; }

        MDCD mdcd;


        protected override void Initialize()
        {
            mdcd = Indicators.GetIndicator<MDCD>(Source, percentPeriod, EMAperiod);
        }

        public override void Calculate(int index)
        {

            double previousSignalval = mdcd.MDEMAResult[index - 1];
            double currentSignalval = mdcd.MDEMAResult[index];

            double previousMDval = mdcd.MDMACD[index - 1];
            double currentMDval = mdcd.MDMACD[index];


            if (previousSignalval > previousMDval && currentSignalval < currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine", index, Colors.Red, 1, LineStyle.Dots);
            }

            if (previousSignalval < previousMDval && currentSignalval > currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine2", index, Colors.Green, 1, LineStyle.Dots);
            }

            MDResult[index] = mdcd.MDMACD[index];
            SignalResult[index] = mdcd.MDEMAResult[index];
        }
    }
}

What I have found is that it produces something that looks like this:

I was expecting to see those green and red vertical lines all the way back through the chart. When I only saw them at the end I started printing the indexes and some other info to the log, I can see that index 0 is reached on the 6th June so is this why I don't have vertical lines plotted further back? Is this just the way that the platform works or is there something I need to do differently?


@Prospect

Prospect
07 Jun 2014, 20:19

My mistake, index 0 is at the beginning of the chart where I expected it to be, I still have no idea why more vertical lines weren't plotted.


@Prospect

Prospect
09 Jun 2014, 23:36

Well I guess the lack of responses means it wasn't a stupid question.

I found the solution anyway for anyone reading this.

            if (previousSignalval > previousMDval && currentSignalval < currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine", index, Colors.Red, 1, LineStyle.Dots);
            }
 
            if (previousSignalval < previousMDval && currentSignalval > currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine2", index, Colors.Green, 1, LineStyle.Dots);
            }

The above creates only two instances of vertical lines vLine and vline2, fairly obviously really, so you only ever see two lines which move with new data. Again, obvious during open trading as you see them move, not so otherwise. Suffixing the vLine strings with +index had the desired effect.

 


@Prospect

d.vietnguyen1011
07 Dec 2018, 14:07

RE:

badmonkeyface said:

Well I guess the lack of responses means it wasn't a stupid question.

I found the solution anyway for anyone reading this.

            if (previousSignalval > previousMDval && currentSignalval < currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine", index, Colors.Red, 1, LineStyle.Dots);
            }
 
            if (previousSignalval < previousMDval && currentSignalval > currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine2", index, Colors.Green, 1, LineStyle.Dots);
            }

The above creates only two instances of vertical lines vLine and vline2, fairly obviously really, so you only ever see two lines which move with new data. Again, obvious during open trading as you see them move, not so otherwise. Suffixing the vLine strings with +index had the desired effect.

 

So how did you fix it?


@d.vietnguyen1011

systemtradingvn02
13 Apr 2020, 07:04 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE:

Sorry, I'm not good at English.

I want draw the Vertical line at a specified time indicator.
for example, look at a this screenshot.

condition
1.draw vertical lines every day.
2.draw two vertical lines.
3.set specified time by parameter.
4.hold old vertical lines 10days.(if possible set by parameter)

 


@systemtradingvn02

PanagiotisCharalampous
13 Apr 2020, 09:11

Hi systemtradingvn02,

If you need somebody to develop the indicator for you, you can consider posting a Job or contact a Consultant.

Best Regards,

Panagiotis 

Join us on Telegram

 


@PanagiotisCharalampous

systemtradingvn02
13 Apr 2020, 10:25

RE:

yes thank sir


@systemtradingvn02