ADX, DiPlus, DiMinus
Atom
6/8/2012
Sergey Sokolov


Обнаружил, что способ расчета DiPlus, DiMinus и, как следствие, ADX, не совпадает с описываемым тут а также со значениями из как минимум 2 программ теханализа (WLD, AlfaDirect).
После моего фикса считает правильно.

Единственным исправлением было использование параметров по умолчанию у AverageTrueRange при расчете DiPart. (+удаление неиспользуемого DmTrueRange)
Было:
Code
protected DiPart()
{
    _averageTrueRange = new AverageTrueRange(new ExponentialMovingAverage(), new DmTrueRange());
    _movingAverage = new WilderMovingAverage();
}


Стало:
Code
protected DiPart()
{
    _averageTrueRange = new AverageTrueRange();
    _movingAverage = new WilderMovingAverage();
}


в связи с чем у меня вопрос:
Это вообще баг или расчет +-DI/ADX намеренно выполняется с использованием нестандартных параметров?
Если это не баг, то каким образом коммитить фикс? Как отдельный индикатор?

Tags:


Thanks:


OvcharenkoVI

Avatar
Date: 6/11/2012
Reply


Мне самому нужна была формула для ADX, когда искал - нашел кучу вариаций, после чего написал в тех поддержку Альфы, они прислали мне код, правда он был не на C#, но смысл я понял.

Прикладываю класс индюка DiPart. Реализован не через Length indicator, а просто как класс. Полностью совпадает с альфой.

Получить Di+ можно свойством Dlpp, Di- свойством Dlmm.

Методом Process Добавляем готовую свечку(не через CandleIndicatorValue, а просто candle),

Также добавлен метод UpDate, чтобы индюк мог меняться внутри свечи(также добавляем туда candle). Также считает верно.

Code
[h]public class ADX
    {
        public decimal Length;

        private decimal dH;

        private decimal dL;

        private decimal DXp;

        private decimal DXm;

        private decimal TR;

        private decimal TRPpast;

        private decimal Dlp;

        private decimal Dlm;

        public decimal Dlpp;

        public decimal DLmm;

        private Candle _prevCandle;

        private List<decimal> list = new List<decimal>(); 

        public void Process(Candle candle)
        {
            if(_prevCandle == null)
            {
                _prevCandle = candle;

                return;
            }

            dH = candle.HighPrice - _prevCandle.HighPrice;

            dL = _prevCandle.LowPrice - candle.LowPrice;

            DXp = dH > 0 ? dH : 0;

            DXm = dL > 0 ? dL : 0;

            if(DXp == DXm)
            {
                DXm = 0;
                DXp = 0;
            }
            else
            {
                if (DXp > DXm)
                    DXm = 0;

                if (DXm > DXp)
                    DXp = 0;
            }

            list.Add(Math.Abs(candle.HighPrice - candle.LowPrice));
            list.Add(Math.Abs(candle.HighPrice - _prevCandle.ClosePrice));
            list.Add(Math.Abs(candle.LowPrice - _prevCandle.ClosePrice));

            _prevCandle = candle;

            TR = list.Max();

            list.Clear();

            TR = TRPpast - TRPpast/Length + TR/Length;

            TRPpast = TR;

            if(TR == 0)
            {
                DXp = 0;
                DXm = 0;
                Dlp = Dlp - Dlp/Length + DXp/Length;
                Dlm = Dlm - Dlm/Length + DXm/Length;
            }
            else
            {
                Dlp = Dlp - Dlp/Length + DXp/Length;
                Dlm = Dlm - Dlm/Length + DXm/Length;
                Dlpp = Dlp/TR*100;
                DLmm = Dlm/TR*100;
            }
        }

        public void UpDate(Candle candle)
        {
            dH = candle.HighPrice - _prevCandle.HighPrice;

            dL = _prevCandle.LowPrice - candle.LowPrice;

            DXp = dH > 0 ? dH : 0;

            DXm = dL > 0 ? dL : 0;

            if (DXp == DXm)
            {
                DXm = 0;
                DXp = 0;
            }
            else
            {
                if (DXp > DXm)
                    DXm = 0;

                if (DXm > DXp)
                    DXp = 0;
            }

            list.Add(Math.Abs(candle.HighPrice - candle.LowPrice));
            list.Add(Math.Abs(candle.HighPrice - _prevCandle.ClosePrice));
            list.Add(Math.Abs(candle.LowPrice - _prevCandle.ClosePrice));

            TR = list.Max();

            list.Clear();

            TR = TRPpast - TRPpast / Length + TR / Length;

            if (TR == 0)
            {
                DXp = 0;
                DXm = 0;
                var dlp = Dlp - Dlp / Length + DXp / Length;
                var dlm = Dlm - Dlm / Length + DXm / Length;
            }
            else
            {
                var dlp = Dlp - Dlp / Length + DXp / Length;
                var dlm = Dlm - Dlm / Length + DXm / Length;
                Dlpp = dlp / TR * 100;
                DLmm = dlm / TR * 100;
            }
        }
[/h]

}
ADX.cs 3 KB (220)
Thanks: Кот Матроскин


Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy