Indicator that checks price movement

Created at 22 Oct 2018, 02:50
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!
PO

pogostick

Joined 12.05.2018

Indicator that checks price movement
22 Oct 2018, 02:50


I am looking for an indicator that keeps track of price movement within a bar. It must be able to provide the total number of times the market price moved within a bar as well as how many time it moved up and how many times it moved down.

Is there an indicator like this already before I start investigating how to build one myself?

Many thanks


@pogostick
Replies

freemangreat
22 Oct 2018, 04:27

genious idea)

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class UpNDown : Indicator
    {
//        [Parameter(DefaultValue = 0.0)]
//        public double Parameter { get; set; }
        
        [Output("UpTick",Color = Colors.Green, PlotType = PlotType.Histogram)]
        public IndicatorDataSeries UpTick { get; set; }

        [Output("DownTick", Color = Colors.Red, PlotType = PlotType.Histogram)]
        public IndicatorDataSeries DownTick { get; set; }
        
        private double TotalTick;
        private double fPrevTickValue =0;
        private int iLastBar;
        
        protected override void Initialize()
        {
            // Initialize and create nested indicators
        }

        public override void Calculate(int index)
        {
            if(IsLastBar) // not work on history
            {
                if(iLastBar != index) // new bar
                {
                    UpTick[index] =0;
                    DownTick[index] =0;
                    TotalTick =0;
                    iLastBar =index;
                }
                
                double fLastTickValue =MarketSeries.Close[index];
                
                if(fPrevTickValue != 0.0) // every tick if prev tick exist
                {
                    if(fLastTickValue > fPrevTickValue)
                        UpTick[index]++;
                    else
                        DownTick[index]--;
                        
                    TotalTick =(UpTick[index] - DownTick[index]);
                    ChartObjects.DrawText("info", "Total: " + TotalTick, StaticPosition.TopLeft);
                }
                
                fPrevTickValue =fLastTickValue;
            }
        }
    }
}

 


@freemangreat

pogostick
22 Oct 2018, 04:56

Thanks, freemangreat! Any thoughts on how to make it possible to use on historical data? I was thinking of using the 1 tick timeframe coupled with server time to segment into bar timeframes. Hope that makes sense.


@pogostick

freemangreat
22 Oct 2018, 14:15

Unfortunately, the data of tick timeframes are not available for calculation on the main timeframe.
https://ctrader.com/api/reference/timeframe


@freemangreat

pogostick
23 Oct 2018, 03:14

Thanks for pointing that out. I never noticed that the tick timeframes were not available. 


@pogostick

freemangreat
23 Oct 2018, 06:09

You can try to save the tick history from the tick chart to a file (binary or text format). And then in its indicator to restore this data from the file and use for calculations.

But I have no ready solution.
https://ctrader.com/forum/calgo-reference-samples/54


@freemangreat

afhacker
23 Oct 2018, 07:57

You can also use my Advanced Volume indicator, it counts each up/down tick of the last bar and shows it in two different up/down histogram bar.

For historical bars, it uses a formula to count the number of up/down ticks, you can find more detail on its description.


@afhacker

pogostick
24 Oct 2018, 02:14

Thanks, freemangreat. That was my thoughts exactly when I realised the 1 tick timeframe was not available.

 


@pogostick

pogostick
24 Oct 2018, 02:23

afhacker, thanks for the heads up on your indicator. That is an interesting approach for the historical data. I will definitely consider it. 

I have installed the indicator to test but the source code is not available for me to retrieve the variables of the indicator which is available to call in a cbot. Do you provide any other documentation with this information?

Thanks


@pogostick

afhacker
24 Oct 2018, 07:33

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AutoRescale = true)]
    public class AdvancedVolume : Indicator
    {
        #region Fields

        private double _lastPriceValue;

        #endregion Fields

        #region Parameters

        [Parameter("Use Live Data", DefaultValue = false)]
        public bool UseLiveData { get; set; }

        [Parameter("Show in %", DefaultValue = true)]
        public bool ShowInPercentage { get; set; }

        #endregion Parameters

        #region Outputs

        [Output("Bullish Volume", Color = Colors.Lime, PlotType = PlotType.Histogram, Thickness = 5)]
        public IndicatorDataSeries BullishVolume { get; set; }

        [Output("Bearish Volume", Color = Colors.Red, PlotType = PlotType.Histogram, Thickness = 5)]
        public IndicatorDataSeries BearishVolume { get; set; }

        #endregion Outputs

        #region Methods

        protected override void Initialize()
        {
            _lastPriceValue = MarketSeries.Close.LastValue;
        }

        public override void Calculate(int index)
        {
            if (IsLastBar && UseLiveData)
            {
                if (MarketSeries.Close.LastValue > _lastPriceValue)
                {
                    double volume = double.IsNaN(BullishVolume[index]) ? 1 : BullishVolume[index] + 1;

                    BullishVolume[index] = ShowInPercentage ? volume / MarketSeries.TickVolume[index] : volume;
                }
                else if (MarketSeries.Close.LastValue < _lastPriceValue)
                {
                    double volume = double.IsNaN(BearishVolume[index]) ? -1 : BearishVolume[index] - 1;

                    BearishVolume[index] = ShowInPercentage ? volume / MarketSeries.TickVolume[index] : volume;
                }

                _lastPriceValue = MarketSeries.Close.LastValue;
            }
            else
            {
                double barRange = MarketSeries.High[index] - MarketSeries.Low[index];

                double percentageAboveBarClose = (MarketSeries.High[index] - MarketSeries.Close[index]) / barRange;
                double percentageBelowBarClose = -(MarketSeries.Close[index] - MarketSeries.Low[index]) / barRange;

                BullishVolume[index] = ShowInPercentage ? percentageBelowBarClose : MarketSeries.TickVolume[index] * percentageBelowBarClose;
                BearishVolume[index] = ShowInPercentage ? percentageAboveBarClose : MarketSeries.TickVolume[index] * percentageAboveBarClose;
            }
        }


        #endregion Methods
    }
}

@afhacker

afhacker
24 Oct 2018, 07:34

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AutoRescale = true)]
    public class AdvancedVolume : Indicator
    {
        #region Fields

        private double _lastPriceValue;

        #endregion Fields

        #region Parameters

        [Parameter("Use Live Data", DefaultValue = false)]
        public bool UseLiveData { get; set; }

        [Parameter("Show in %", DefaultValue = true)]
        public bool ShowInPercentage { get; set; }

        #endregion Parameters

        #region Outputs

        [Output("Bullish Volume", Color = Colors.Lime, PlotType = PlotType.Histogram, Thickness = 5)]
        public IndicatorDataSeries BullishVolume { get; set; }

        [Output("Bearish Volume", Color = Colors.Red, PlotType = PlotType.Histogram, Thickness = 5)]
        public IndicatorDataSeries BearishVolume { get; set; }

        #endregion Outputs

        #region Methods

        protected override void Initialize()
        {
            _lastPriceValue = MarketSeries.Close.LastValue;
        }

        public override void Calculate(int index)
        {
            if (IsLastBar && UseLiveData)
            {
                if (MarketSeries.Close.LastValue > _lastPriceValue)
                {
                    double volume = double.IsNaN(BullishVolume[index]) ? 1 : BullishVolume[index] + 1;

                    BullishVolume[index] = ShowInPercentage ? volume / MarketSeries.TickVolume[index] : volume;
                }
                else if (MarketSeries.Close.LastValue < _lastPriceValue)
                {
                    double volume = double.IsNaN(BearishVolume[index]) ? -1 : BearishVolume[index] - 1;

                    BearishVolume[index] = ShowInPercentage ? volume / MarketSeries.TickVolume[index] : volume;
                }

                _lastPriceValue = MarketSeries.Close.LastValue;
            }
            else
            {
                double barRange = MarketSeries.High[index] - MarketSeries.Low[index];

                double percentageAboveBarClose = (MarketSeries.High[index] - MarketSeries.Close[index]) / barRange;
                double percentageBelowBarClose = -(MarketSeries.Close[index] - MarketSeries.Low[index]) / barRange;

                BullishVolume[index] = ShowInPercentage ? percentageBelowBarClose : MarketSeries.TickVolume[index] * percentageBelowBarClose;
                BearishVolume[index] = ShowInPercentage ? percentageAboveBarClose : MarketSeries.TickVolume[index] * percentageAboveBarClose;
            }
        }


        #endregion Methods
    }
}

 


@afhacker

pogostick
25 Oct 2018, 04:17

Thanks, afhacker. Much appreciated.


@pogostick