Category Oscilators  Published on 17/05/2023

Demand index indicator

Description

The Demand Index indicator, developed by James Sibbet, combines price and volume and is often considered a leading indicator of price changes.

It has one configurable parameter: Period - calculation periods.

James Sibbet defined six "rules" for the Demand Index:

  1. Divergence between the Demand Index and the price indicates an upcoming price reversal.
  2. The price often reaches new highs after an extreme peak in the Demand Index, as the index acts as a leading indicator.
  3. A high price accompanied by a lower peak in the Demand Index usually coincides with an important peak, serving as a confirmation indicator.
  4. The Demand Index breaking the zero level indicates a trend change, although with a delay, making it a confirmation indicator.
  5. If the Demand Index consistently fluctuates around zero, it suggests that the current price trend has weak potential and is unlikely to last long.
  6. A significant long-term divergence between prices and the Demand Index indicates an important market top or bottom.


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

namespace cAlgo
{
    [Levels(0)]
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class mDemandIndex : Indicator
    {
        [Parameter("Period (5)", DefaultValue = 5, MinValue = 2)]
        public int inpPeriod { get; set; }

        [Output("Demand Index", LineColor = "Black", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries outDemandIndex { get; set; }

        private IndicatorDataSeries _di, _tr, _ratiopr, _ratiovol, _constant, _buypreassure, _sellpreassure, _bulls, _bears, _sign, _raw;
        private MovingAverage _travg, _volavg;
        

        protected override void Initialize()
        {
            _di = CreateDataSeries();
            _tr = CreateDataSeries();
            _travg = Indicators.MovingAverage(_tr, inpPeriod, MovingAverageType.Simple);
            _volavg = Indicators.MovingAverage(Bars.TickVolumes, inpPeriod, MovingAverageType.Simple);
            _ratiopr = CreateDataSeries();
            _ratiovol = CreateDataSeries();
            _constant = CreateDataSeries();
            _buypreassure = CreateDataSeries();
            _sellpreassure = CreateDataSeries();
            _bulls = CreateDataSeries();
            _bears = CreateDataSeries();
            _sign = CreateDataSeries();
            _raw = CreateDataSeries();
        }

        public override void Calculate(int i)
        {
            _tr[i] = i>1 ? Math.Max(Bars.HighPrices[i],Bars.HighPrices[i-1]) - Math.Min(Bars.LowPrices[i],Bars.LowPrices[i-1]) : Bars.HighPrices[i] - Bars.LowPrices[i];
            if(i>1 && Bars.WeightedPrices[i] != 0 && Bars.WeightedPrices[i-1] != 0 && _travg.Result[i] !=0 && _volavg.Result[i] != 0)
            {
                _ratiopr[i] = i>1 ? (Bars.WeightedPrices[i] - Bars.WeightedPrices[i-1]) / Math.Min(Bars.WeightedPrices[i],Bars.WeightedPrices[i-1]) : 0.01;
                _ratiovol[i] = Bars.TickVolumes[i] / _volavg.Result[i];
                _constant[i] = _ratiovol[i] /Math.Exp(Math.Min(3.0 * Math.Abs(_ratiopr[i]) * Bars.WeightedPrices[i] / _travg.Result[i], 88.0));
                _buypreassure[i] = _ratiopr[i] > 0 ? _ratiovol[i] : _constant[i];
                _sellpreassure[i] = _ratiopr[i] > 0 ? _constant[i] : _ratiovol[i];
                _bulls[i] = ((i>inpPeriod ? _bulls[i-1] : 0) * (inpPeriod - 1) + _buypreassure[i]) / inpPeriod;
                _bears[i] = ((i>inpPeriod ? _bears[i-1] : 0) * (inpPeriod - 1) + _sellpreassure[i]) / inpPeriod;
                _raw[i] = 1;
                _sign[i] = 0;
                if(_bears[i] > _bulls[i])
                {
                    _sign[i] = -1;
                    if(_bears[i] != 0)
                        _raw[i] = _bulls[i] / _bears[i];
                }
                else
                {
                    _sign[i] = +1;
                    if(_bulls[i] != 0)
                        _raw[i] = _bears[i] / _bulls[i];
                }
                _di[i] = (_raw[i] * _sign[i] < 0 ? (-1.0 - (_raw[i] * _sign[i])) : (1.0 - (_raw[i] * _sign[i])));
            }
            else
                _di[i] = 0;
            
            outDemandIndex[i] = _di[i];
        }
    }
}

mfejza's avatar
mfejza

Joined on 25.01.2022

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: mDemandIndex.algo
  • Rating: 5
  • Installs: 579
  • Modified: 17/05/2023 10:34
Comments
Log in to add a comment.
No comments found.