Replies

icollocollo
30 May 2022, 14:44

RE:

amusleh said:

Hi,

Not sure what you are looking for, If the issue was mismatch between indicator and cBot values then it's resolved on the code I posted.

Yes, let me try to put it in a way you will understand,

I am trying to get the last two values at any point. But i can only get the last value. Thats why i am asking if indicator series saves value. 

 


@icollocollo

icollocollo
27 May 2022, 22:32 ( Updated at: 21 Dec 2023, 09:22 )

RE:

amusleh said:

Hi,

I just tested and it works fine, indicator and cBot output results are matching.

Test below cBot on visual back test mode.

Test this please:

using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class springg : Robot
    {
        private Spring i_fractal;

        protected override void OnStart()
        {
            i_fractal = Indicators.GetIndicator<Spring>();
        }

        protected override void OnBar()
        {
            var index = Bars.Count - 2;

            if (i_fractal.UpFractal[index] > 0)
            {
                Chart.DrawVerticalLine(index.ToString(), index, Color.Red);
            }

            if (i_fractal.DownFractal[index] > 0)
            {
                Chart.DrawVerticalLine(index.ToString(), index, Color.Blue);
            }
        }
    }
}

 

Indicator:

using cAlgo.API;

namespace cAlgo
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None, TimeZone = TimeZones.EAfricaStandardTime)]
    public class Spring : Indicator
    {
        [Output("Up Fractal", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries UpFractal { get; set; }

        [Output("Down Fractal", Color = Colors.Blue, PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries DownFractal { get; set; }

        private Bars HSeries;

        protected override void Initialize()
        {
            HSeries = MarketData.GetBars(TimeFrame.Hour4);
        }

        public override void Calculate(int index)
        {
            if (index == 1)
                return;

            DrawUpFractal(index);
            DrawDownFractal(index);
        }

        private void DrawUpFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]) - 1;

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];

            bool up = false;

            for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex + 1])
                {
                    up = true;
                    break;
                }
            }

            if (up)
            {
                UpFractal[index] = middleValue;
            }
            else
            {
                UpFractal[index] = double.NaN;
            }
        }

        private void DrawDownFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]) - 1;

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];
            bool down = false;

            for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex + 1])
                {
                    down = true;
                    break;
                }
            }
            if (down)
            {
                DownFractal[index] = middleValue;
            }
            else
            {
                DownFractal[index] = double.NaN;
            }
        }
    }
}

 

still doesn't work, it doesn't get those value i want.

Last clarification we close this. How do an indicator store values of the output. I have tried using a for loop of all the values but still it only works for only last value and i want the last 2 valueS. This gets me thinking like once you start onbar it can only access 1 last indicator value. Look at the images below. The red and blue values are the ones i want printed I.E 2 Red values and 2 last blue values. but all i can achieve is only index -1. all other values cannot be printed be it index-2, index, index-5, etc. Please note that the value i_fractal.DownFractal[indexD - 1] prints the correct Last(0) value. i used GBPjpY.


@icollocollo

icollocollo
26 May 2022, 10:09

RE: RE: RE:

amusleh said:

icollocollo said:

amusleh said:

Hi,

Fractal can lag x number of bars based on your provided period number, so try to use earlier bar index when accessing data.

I can only guide you and help you regarding specific API related questions, I can't help you to fully develop your cBot or indicator.

If a value on a data series in NAN it means you haven't set the value for that index, and you have to check your code and find what's causing it. 

Thank you for all your input. I have gone through data series API and have tried this before. It just that when it comes to this particular situation i don't get the value.

Also note i used a method that does not put period to use. I wanted to be sure when backtesting. A while ago i noticed when you test a cbot using periods it will give different results when you adjust the time of backtesting. 

Just need this small input for last 1 and last 0. Stuck here for months. This index issue. 

Hi,

I can't see your cBot code, can you post it again, I will try once more.

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class springg : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        private Spring i_fractal;

        protected override void OnStart()
        {
            i_fractal = Indicators.GetIndicator<Spring>();
        }

        protected override void OnBar()
        {
            for (int i = i_fractal.UpFractal.Count; i > i_fractal.UpFractal.Count - 10; i--)
            {

                for (int j = i_fractal.DownFractal.Count; j > i_fractal.DownFractal.Count - 10; j--)
                {
                    Print("UpFractal : {0}", i_fractal.UpFractal.Last(0));
                    Print("UpFractal2: {0}", i_fractal.UpFractal.Last(1));
                    Print("DownFractal:{0}", i_fractal.DownFractal.Last(0));
                    Print("DownFractal2:{0}", i_fractal.DownFractal.Last(1));
                }
            }
        }

    }
}

 


@icollocollo

icollocollo
25 May 2022, 13:36

RE:

amusleh said:

Hi,

Fractal can lag x number of bars based on your provided period number, so try to use earlier bar index when accessing data.

I can only guide you and help you regarding specific API related questions, I can't help you to fully develop your cBot or indicator.

If a value on a data series in NAN it means you haven't set the value for that index, and you have to check your code and find what's causing it. 

Thank you for all your input. I have gone through data series API and have tried this before. It just that when it comes to this particular situation i don't get the value.

Also note i used a method that does not put period to use. I wanted to be sure when backtesting. A while ago i noticed when you test a cbot using periods it will give different results when you adjust the time of backtesting. 

Just need this small input for last 1 and last 0. Stuck here for months. This index issue. 


@icollocollo

icollocollo
24 May 2022, 14:26 ( Updated at: 21 Dec 2023, 09:22 )

RE:

amusleh said:

Hi,

Then decrease the index by 1:

using cAlgo.API;

namespace cAlgo
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None, TimeZone = TimeZones.EAfricaStandardTime)]
    public class Spring : Indicator
    {
        [Output("Up Fractal", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries UpFractal { get; set; }

        [Output("Down Fractal", Color = Colors.Blue, PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries DownFractal { get; set; }

        private Bars HSeries;

        protected override void Initialize()
        {
            HSeries = MarketData.GetBars(TimeFrame.Hour4);
        }

        public override void Calculate(int index)
        {
            if (index == 1)
                return;

            DrawUpFractal(index);
            DrawDownFractal(index);
        }

        private void DrawUpFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]) - 1;

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];

            bool up = false;

            for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex + 1])
                {
                    up = true;
                    break;
                }
            }

            if (up)
                UpFractal[index] = middleValue;
        }

        private void DrawDownFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]) - 1;

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];
            bool down = false;

            for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex + 1])
                {
                    down = true;
                    break;
                }
            }
            if (down)
                DownFractal[index] = middleValue;
        }
    }
}

 

About this indicator, it worked when i used middle index instead of index in the result part. Would that affect how the cbot check the values when i use last 0 and last 1?

private void DrawUpFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];

            bool up = false;

            for (int i = 1; i <= HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex + 1])
                {
                    up = true;
                    break;
                }
            }

            if (up)
                UpFractal[middleIndex] = middleValue;
        }

#Update 

i tested and still don't get exact values. This are from GBPJPY

Print("DownFractal:{0}", i_fractal.DownFractal.Last(0));
Print("DownFractal2:{0}", i_fractal.DownFractal.Last(1));

As you can see, .Last (1) gives NaN

Could there be a problem with output?


@icollocollo

icollocollo
23 May 2022, 19:08 ( Updated at: 21 Dec 2023, 09:22 )

RE:

amusleh said:

Hi,

The index is the current chart bars index, not the index of time frame that you loaded.

You have to change the index to the loaded time frame bars index first then use it, try this:

using cAlgo.API;

namespace cAlgo
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None, TimeZone = TimeZones.EAfricaStandardTime)]
    public class Spring : Indicator
    {
        [Output("Up Fractal", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries UpFractal { get; set; }

        [Output("Down Fractal", Color = Colors.Blue, PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries DownFractal { get; set; }

        private Bars HSeries;

        protected override void Initialize()
        {
            HSeries = MarketData.GetBars(TimeFrame.Hour4);
        }

        public override void Calculate(int index)
        {
            if (index == 1)
                return;

            DrawUpFractal(index);
            DrawDownFractal(index);
        }

        private void DrawUpFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];

            bool up = false;

            for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex + 1])
                {
                    up = true;
                    break;
                }
            }

            if (up)
                UpFractal[index] = middleValue;
        }

        private void DrawDownFractal(int index)
        {
            var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            int middleIndex = hSeriesIndex - 2;
            double middleValue = HSeries.ClosePrices[middleIndex];
            bool down = false;

            for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
            {
                if (HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex + 1])
                {
                    down = true;
                    break;
                }
            }
            if (down)
                DownFractal[index] = middleValue;
        }
    }
}

 

Thank you @Amusleh only problem is that the index uses the candle that has not closed. See example in the image below. so the lastvalue is definitely wrong


@icollocollo

icollocollo
13 May 2022, 16:16

RE:

amusleh said:

Hi,

We can only help you if you post a code sample that can reproduce this issue.

Please post the code for your cBot and the custom indicator you are using.

Updated Please check, really need these values. 


@icollocollo

icollocollo
26 Apr 2022, 12:00

RE:

amusleh said:

Hi,

You can store the partially closed position ID on a collection like a List and check if it's already partially closed or not.

Thanks amusleh for the reply, i have seen that list offers great way for doing that. Unfortunately am not really experienced with it. Do you have an example of an indicator or cbot that fully exploits linq that can be help in illustrating this?. Also need lists for a supply and demand indicator


@icollocollo

icollocollo
26 Apr 2022, 09:10

RE: RE: RE: RE:

amusleh said:

icollocollo said:

ncel01 said:

amusleh,

That's clear. Thanks for the extra clarifications!

Is it possible to use this position modified in another Method? @amusleh

Hi,

What do you mean by using the position on another method?

I was looking for a way to stop my positions from bwing modified twice in a cbot but i realized this is and event so i think i will try to use an if logic to implement that. Thank you


@icollocollo

icollocollo
25 Apr 2022, 17:34

RE: RE:

ncel01 said:

amusleh said:

Hi,

You can do something like this:

using cAlgo.API;
using System.Collections.Generic;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        private Dictionary<int, double> _positionsVolume = new Dictionary<int, double>(100);

        protected override void OnStart()
        {
            foreach (var position in Positions)
            {
                _positionsVolume.Add(position.Id, position.VolumeInUnits);
            }

            Positions.Opened += Positions_Opened;
            Positions.Closed += Positions_Closed;
            Positions.Modified += Positions_Modified;
        }

        private void Positions_Closed(PositionClosedEventArgs obj)
        {
            if (_positionsVolume.ContainsKey(obj.Position.Id))
            {
                _positionsVolume.Remove(obj.Position.Id);
            }
        }

        private void Positions_Opened(PositionOpenedEventArgs obj)
        {
            _positionsVolume.Add(obj.Position.Id, obj.Position.VolumeInUnits);
        }

        private void Positions_Modified(PositionModifiedEventArgs obj)
        {
            if (_positionsVolume.ContainsKey(obj.Position.Id))
            {
                var positionPreviousVolume = _positionsVolume[obj.Position.Id];

                if (positionPreviousVolume == obj.Position.VolumeInUnits)
                {
                    // It means volume desn't changed
                }
                // volume changed
                else
                {
                    // new volume added
                    if (positionPreviousVolume < obj.Position.VolumeInUnits)
                    {
                        Print("Position {0} volume increased, new volume: {1} | previous volume: {2}", obj.Position.Id, obj.Position.VolumeInUnits, positionPreviousVolume);
                    }
                    // position partially closed
                    else
                    {
                        Print("Position {0} partially closed, new volume: {1} | previous volume: {2}", obj.Position.Id, obj.Position.VolumeInUnits, positionPreviousVolume);
                    }
                }

                _positionsVolume[obj.Position.Id] = obj.Position.VolumeInUnits;
            }
            else
            {
                _positionsVolume.Add(obj.Position.Id, obj.Position.VolumeInUnits);
            }
        }
    }
}

 

amusleh,

That's clear. Thanks for the extra clarifications!

Is it possible to use this position modified in another Method? @amusleh


@icollocollo

icollocollo
25 Apr 2022, 10:01

RE:

firemyst said:

Yes.

In your code set a boolean flag to indicate that you've done your modification on the position. For example, "alreadyModifiedPosition = true;"

Every time you go through your code, only enter into the part that does the position modification if the flag is set to false.

Eg:

if (!alreadyModifiedPosition)

{

   /// do your position modification

   alreadyModifiedPosition = true;

}

 

Then you just have to figure out the logic when you reset alreadyModifiedPosition back to false. Every time you start your bot? When the position is closed? Something else?

Good luck! :-)

Thank you for your reply. Please check this thread for the code. An example will be of help since i already use for each position in positions.

 


@icollocollo

icollocollo
25 Apr 2022, 01:37 ( Updated at: 25 Apr 2022, 01:41 )

RE: RE: RE: RE:

icollocollo said:

amusleh said:

icollocollo said:

amusleh said:

Hi,

Can you provide more context and what you are after?

If you want to close a position when it reach 2 Risk:Reward, then you can use the Position Pips, if it's double the amount of stop loss in pips then close it.

You don't have to use volume to calculate it.

Reason i am trying to use Volume is because my SL varies from one to the other. And TP is a multiple of SL, say SL*5. Closing partials at SL * 2 and modifying the remaining to break even at +2 pips.

Hi,

It doesn't matter if your SLs varies or not, you can get each position current SL in pips, for example if your position current pips is 10 and your stop loss is 5 pips then it means your position is reached 2 RR, and you can close half of its volume, no need for calculating volume.

 

UPDATE! Got the code below working,,,

{
            var allPositions = Positions.FindAll(MyLabel, SymbolName);
            foreach (Position p in allPositions)
            {
                double entryPrice = p.EntryPrice;
                double distance = p.TradeType == TradeType.Buy ? (Symbol.Bid - entryPrice) / Symbol.PipSize : (entryPrice - Symbol.Ask) / Symbol.PipSize;
                double newVol = Symbol.NormalizeVolumeInUnits((p.VolumeInUnits / 2), RoundingMode.Up);
                var sl = p.TradeType == TradeType.Buy ? (entryPrice - p.StopLoss) / Symbol.PipSize : (p.StopLoss - entryPrice) / Symbol.PipSize;


                if (p.TradeType == TradeType.Buy)
                {
                    if (distance / sl == 2)
                    {
                        ModifyPosition(p, newVol);
                        Print("Partial closing " + newVol + " of " + p + "2RR Achieved!");
                    }

                }
                if (p.TradeType == TradeType.Sell)
                {
                    if (distance / sl == 2)
                    {
                        ModifyPosition(p, newVol);
                        Print("Partial closing " + newVol + " of " + p + "2RR Achieved!");
                    }

                }


                // Close trades without stoploss or takeprofit

                if (p.StopLoss == null || p.TakeProfit == null)
                {

                    ClosePosition(p);

                }
            }

        }

 

Hello @Amusleh here is a problem with this code. I want to prevent a position from being modified twice. Like the position after partials is closed. Should either hit SL or TP. But since price moves up and down when price distance is equal to 2 again. The same percentage of the remaining volume is calculated again. 

E.g 50 % of 1000 is 500. When condition is true again 50% of 500 = 250 is closed again then 125 then 62.5 theb 31.5 until tp or sl is hit. 

Please help

 

 

 

 


@icollocollo

icollocollo
20 Jan 2022, 16:31 ( Updated at: 20 Jan 2022, 19:11 )

RE: RE: RE:

amusleh said:

icollocollo said:

amusleh said:

Hi,

Can you provide more context and what you are after?

If you want to close a position when it reach 2 Risk:Reward, then you can use the Position Pips, if it's double the amount of stop loss in pips then close it.

You don't have to use volume to calculate it.

Reason i am trying to use Volume is because my SL varies from one to the other. And TP is a multiple of SL, say SL*5. Closing partials at SL * 2 and modifying the remaining to break even at +2 pips.

Hi,

It doesn't matter if your SLs varies or not, you can get each position current SL in pips, for example if your position current pips is 10 and your stop loss is 5 pips then it means your position is reached 2 RR, and you can close half of its volume, no need for calculating volume.

 

UPDATE! Got the code below working,,,

{
            var allPositions = Positions.FindAll(MyLabel, SymbolName);
            foreach (Position p in allPositions)
            {
                double entryPrice = p.EntryPrice;
                double distance = p.TradeType == TradeType.Buy ? (Symbol.Bid - entryPrice) / Symbol.PipSize : (entryPrice - Symbol.Ask) / Symbol.PipSize;
                double newVol = Symbol.NormalizeVolumeInUnits((p.VolumeInUnits / 2), RoundingMode.Up);
                var sl = p.TradeType == TradeType.Buy ? (entryPrice - p.StopLoss) / Symbol.PipSize : (p.StopLoss - entryPrice) / Symbol.PipSize;


                if (p.TradeType == TradeType.Buy)
                {
                    if (distance / sl == 2)
                    {
                        ModifyPosition(p, newVol);
                        Print("Partial closing " + newVol + " of " + p + "2RR Achieved!");
                    }

                }
                if (p.TradeType == TradeType.Sell)
                {
                    if (distance / sl == 2)
                    {
                        ModifyPosition(p, newVol);
                        Print("Partial closing " + newVol + " of " + p + "2RR Achieved!");
                    }

                }


                // Close trades without stoploss or takeprofit

                if (p.StopLoss == null || p.TakeProfit == null)
                {

                    ClosePosition(p);

                }
            }

        }

 


@icollocollo

icollocollo
20 Jan 2022, 09:02

RE:

amusleh said:

Hi,

Can you provide more context and what you are after?

If you want to close a position when it reach 2 Risk:Reward, then you can use the Position Pips, if it's double the amount of stop loss in pips then close it.

You don't have to use volume to calculate it.

Reason i am trying to use Volume is because my SL varies from one to the other. And TP is a multiple of SL, say SL*5. Closing partials at SL * 2 and modifying the remaining to break even at +2 pips.


@icollocollo

icollocollo
10 Jan 2022, 14:16

RE:

firemyst said:

A few questions:

1) have you looked in the "Log" tab when your bot is running to see what happens? If there's a crash or something?

2) Have you tried putting any "Print" statements in your code to output information to the log? for instance, how do you know all the following statements ever evaluate to "true" for the order to be opened?

if (UpHigh && UpTrend)
                    {
                        if (UpBreak || DownSpring)
                        {

                            if (UpKabuti)
                            {
                                Open_Buy_Order();
                                return;
                            }
                        }
                    }

For all you know, all those "if" statements may not be evaluating to true, and thus the "Open_Buy_Order" method is never executed.

 

So I would try putting in Print statements to log output, so you can see where the code is executing, and if it's even getting to the method to open an order.

Thank you for your reply,

for number 1, i get backtesting started and backtesting finished.

i will definitely try to print some statements. Its very possible that some statements never evaluate to true. Thank you for this insight!


@icollocollo

icollocollo
26 Nov 2021, 11:19

RE: RE:zigzag to use closes instead of highs and lows.

heforus said:

Thank you so much Panagiotis,

I will work with this. I am so grateful.

 

PanagiotisCharalampous said:

Hi herofus,

Here you go

Indicator Code

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


namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ZigZag : Indicator
    {

        [Parameter(DefaultValue = 12)]
        public int Depth { get; set; }

        [Parameter(DefaultValue = 5)]
        public int Deviation { get; set; }

        [Parameter(DefaultValue = 3)]
        public int BackStep { get; set; }

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

        #region Private fields

        private double _lastLow;
        private double _lastHigh;
        private double _low;
        private double _high;
        private int _lastHighIndex;
        private int _lastLowIndex;
        private int _type;
        private double _point;
        private double _currentLow;
        private double _currentHigh;

        public IndicatorDataSeries HighZigZags;
        public IndicatorDataSeries LowZigZags;

        #endregion

        protected override void Initialize()
        {
            HighZigZags = CreateDataSeries();
            LowZigZags = CreateDataSeries();
            _point = Symbol.PointSize;
        }

        public override void Calculate(int index)
        {

            if (index < Depth)
            {
                Result[index] = 0;
                HighZigZags[index] = 0;
                LowZigZags[index] = 0;
                return;
            }

            _currentLow = Functions.Minimum(MarketSeries.Low, Depth);
            if (Math.Abs(_currentLow - _lastLow) < double.Epsilon)
                _currentLow = 0.0;
            else
            {
                _lastLow = _currentLow;

                if ((MarketSeries.Low[index] - _currentLow) > (Deviation * _point))
                    _currentLow = 0.0;
                else
                {
                    for (int i = 1; i <= BackStep; i++)
                    {
                        if (Math.Abs(LowZigZags[index - i]) > double.Epsilon && LowZigZags[index - i] > _currentLow)
                            LowZigZags[index - i] = 0.0;
                    }
                }
            }
            if (Math.Abs(MarketSeries.Low[index] - _currentLow) < double.Epsilon)
                LowZigZags[index] = _currentLow;
            else
                LowZigZags[index] = 0.0;

            _currentHigh = MarketSeries.High.Maximum(Depth);

            if (Math.Abs(_currentHigh - _lastHigh) < double.Epsilon)
                _currentHigh = 0.0;
            else
            {
                _lastHigh = _currentHigh;

                if ((_currentHigh - MarketSeries.High[index]) > (Deviation * _point))
                    _currentHigh = 0.0;
                else
                {
                    for (int i = 1; i <= BackStep; i++)
                    {
                        if (Math.Abs(HighZigZags[index - i]) > double.Epsilon && HighZigZags[index - i] < _currentHigh)
                            HighZigZags[index - i] = 0.0;
                    }
                }
            }

            if (Math.Abs(MarketSeries.High[index] - _currentHigh) < double.Epsilon)
                HighZigZags[index] = _currentHigh;
            else
                HighZigZags[index] = 0.0;


            switch (_type)
            {
                case 0:
                    if (Math.Abs(_low - 0) < double.Epsilon && Math.Abs(_high - 0) < double.Epsilon)
                    {
                        if (Math.Abs(HighZigZags[index]) > double.Epsilon)
                        {
                            _high = MarketSeries.High[index];
                            _lastHighIndex = index;
                            _type = -1;
                            Result[index] = _high;
                        }
                        if (Math.Abs(LowZigZags[index]) > double.Epsilon)
                        {
                            _low = MarketSeries.Low[index];
                            _lastLowIndex = index;
                            _type = 1;
                            Result[index] = _low;
                        }
                    }
                    break;
                case 1:
                    if (Math.Abs(LowZigZags[index]) > double.Epsilon && LowZigZags[index] < _low && Math.Abs(HighZigZags[index] - 0.0) < double.Epsilon)
                    {
                        Result[_lastLowIndex] = double.NaN;
                        _lastLowIndex = index;
                        _low = LowZigZags[index];
                        Result[index] = _low;
                    }
                    if (Math.Abs(HighZigZags[index] - 0.0) > double.Epsilon && Math.Abs(LowZigZags[index] - 0.0) < double.Epsilon)
                    {
                        _high = HighZigZags[index];
                        _lastHighIndex = index;
                        Result[index] = _high;
                        _type = -1;
                    }
                    break;
                case -1:
                    if (Math.Abs(HighZigZags[index]) > double.Epsilon && HighZigZags[index] > _high && Math.Abs(LowZigZags[index] - 0.0) < double.Epsilon)
                    {
                        Result[_lastHighIndex] = double.NaN;
                        _lastHighIndex = index;
                        _high = HighZigZags[index];
                        Result[index] = _high;
                    }
                    if (Math.Abs(LowZigZags[index]) > double.Epsilon && Math.Abs(HighZigZags[index]) <= double.Epsilon)
                    {
                        _low = LowZigZags[index];
                        _lastLowIndex = index;
                        Result[index] = _low;
                        _type = 1;
                    }
                    break;
                default:
                    return;
            }

        }
    }
}

cBot code

using cAlgo.API;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = 12)]
        public int Depth { get; set; }

        [Parameter(DefaultValue = 5)]
        public int Deviation { get; set; }

        [Parameter(DefaultValue = 3)]
        public int BackStep { get; set; }

        private ZigZag _zigzag;

        protected override void OnStart()
        {
            _zigzag = Indicators.GetIndicator<ZigZag>(Depth, Deviation, BackStep);
        }

        protected override void OnBar()
        {
            var result = _zigzag.Result.Last(1);
            Print("High: " + _zigzag.HighZigZags.Last(1));
            Print("Low: " + _zigzag.LowZigZags.LastValue);
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

Best Regards,

Panagiotis 

Join us on Telegram

 

Hello @panagiotis

Thank you for you input in this forum, i have seen this thread and i am looking for a zigzag solution that puts into use the values of the closes of candles as opposed to highs and Low. In my instance it would look like matching thos highs and lows of a line chart. Please advice how to go about to achieve this. Thank you.

Still new to c automate.


@icollocollo