NaN

Ниже приведен код Detrended Price Oscilator:

private MovingAverage movingAverage;    protected override void Initialize()
{      movingAverage = Indicators.SimpleMovingAverage(Source, Periods);  }    public override void
Calculate(int index)  {      Result[index] = Source[index] — movingAverage.Result[index — Periods / 2 — 1];  }


Как Вы можете видеть, в коде описано просто общее правило для расчета, но нет проверки на любые граничные условия.

Например, если мы используем скользящую среднюю из 10 периодов, первые 9 значений не могут быть правильно рассчитаны. Поэтому мы не можем использовать эту формулу для любого индекса меньше, чем 9. Кроме того, чтобы вычислить значение для указанного индекса, мы используем значение скользящей средней с индексом — Периоды / 2 — 1. Поэтому мы должны добавить следующие условия:

public override void Calculate(int index)  {      if (index >= Periods + Periods / 2 + 1)
{          Result[index] = Source[index]  movingAverage.Result[index  Periods / 2  1];      }  }


Код простой скользящей средней нужно также проверить на условие индекс >=периодам. Более того, если мы используем другой вложенный индикатор, например, другой тип скользящей средней, это условие должно быть разным. Источником серии также может быть результатом другого индикатора и содержать в начале нерасчитанный значения. Все это делает разработку индикаторов достаточно сложной, так как мы должны думать о вещах, которые могут быть обработаны автоматически.

Для решения этой задачи можно использовать арифметику NaN (Not-a-Number). Скажем, если значение индикатора не определено указанным индексом, он имеет некоторые особые значения, которые можно назвать «не число» — NaN. Если мы будем использовать это значение в наших расчетах, мы всегда получаем NaN в качестве результата. Если мы используем нерассчетную величину или значение при отрицательном индексе из серии данных, мы хотим, чтобы они были NaN. 

К счастью, тип для чисел с плавающей запятой — двоичный уже имеет такие значения: Double.NaN, и она имеет необходимое поведение. При выполнении некоторых операций с числом NaN и обычным числом, Вы всегда получите NaN в результате, например, Double.NaN + 1,4 == Double.NaN. DataSeries возвращает NaN, когда Вы запрашиваете значение при отрицательном индексе, Вы можете пропустить все эти предварительные условия и описать только общее правило расчета индикатора. Если результат содержит NaN в некотором индексе, это значение может просто не быть нарисовано на графике.

Рекурсивные индикаторы

При расчете рекурсивного индикатора, то есть индикатора, значение которого зависит от предыдущего значения этого индикатора, необходимо обрабатывать значения NaN явно, например, ниже приведен расчет экспоненциальной скользящей средней:

public override void Calculate(int index)  {      var previousValue = Result[index  1];        if (double.IsNaN

(previousValue))      {          Result[index] = Source[index];      }      else      {          Result[index] = Source

[index] * _exp + previousValue * (1  _exp);      }  }


В EMA, где текущее значение зависит от предыдущего, первое значение должно быть установлено явно. Для проверки этого мы используем метод double.IsNaN (previousValue). Обратите внимание, что мы не можем использовать оператор ==, как в методе previousValue == double.IsNaN потому, что NaN == х всегда ложно, даже если х является NaN.

Добавить комментарий

Войти с помощью: 

Ваш e-mail не будет опубликован. Обязательные поля помечены *