Общий вопрос по реализации Индикаторов

Общий вопрос по реализации Индикаторов
Atom
5/12/2012
VoDA


Всем доброго дня )))

Вопрос такой: почему индикаторы сделаны через дженерики таким образом, что могут не отрабатывать контракт?

На примере кода:

var candle = new TimeFrameCandle() ; IIndicator indicator = new ExponentialMovingAverage(); var result = indicator.Process(new CandleIndicatorValue(candle));

Если же взять Peak индикатор, то код внезапно начинает работать. Самое обидное, что контракт - всегда выполнен. Любой индикатор поддерживает интерфейс взаимодействия IIndicator, на вход Process подается IIndicatorValue. Но в одном случае IIndicatorValue обрабатывается корректно, а в другом - дает сбой.

Расследование показало, что это происходит из за вызова var newValue = input.GetValue<decimal>(); в EMA. Т.е. EMA исходит из того, что input строго decimal, хотя контрактом на EMA это не регламентировано.

Что делать?


Tags:


Thanks:


Кот Матроскин

Avatar
Date: 5/12/2012
Reply


VoDA: Всем доброго дня )))

Вопрос такой: почему индикаторы сделаны через дженерики таким образом, что могут не отрабатывать контракт?

Расследование показало, что это происходит из за вызова var newValue = input.GetValue<decimal>(); в EMA. Т.е. EMA исходит из того, что input строго decimal, хотя контрактом на EMA это не регламентировано.

Что делать? Поясни:

  • что значит "могут не отрабатывать контракт"
  • почему input не должен быть decimal
  • каким "контрактом на EMA это не регламентировано"
Thanks:

VoDA

Avatar
Date: 5/12/2012
Reply


Кот Матроскин: Поясни:

  • что значит "могут не отрабатывать контракт"
  • почему input не должен быть decimal
  • каким "контрактом на EMA это не регламентировано"

Контракт это соглашение о том какие параметры должны обрабатываться методом или объектом. Все интерфейсы и базовые классы - это своего рода контракты для реализующих их классов. В данном случае линия наследования ExponentialMovingAverage:LengthIndicator, LengthIndicator:BaseIndicator, BaseIndicator:IIndicator показывает, что EMA должен отрабатывать все вызовы, которые присутствуют в IIndicator.

В IIndicator есть Process, который принимает IIndicatorValue. Т.е. любой потомок IIndicator должен обработать все, что есть IIndicatorValue. Я создаю new CandleIndicatorValue(new TimeFrameCandle...), который по наследования является IIndicatorValue.

Почему при передаче валидного IIndicatorValue в метод Process летит Эксепшен?

Теперь по пунктам:

  • при передаче IIndicatorValue в метод Process класса EMA вылетает Эксепшен. ИМХО если метод принимает параметер определенного типа (тип прописан в сигнатуре), то он должен его обработать.
  • input может быть IIndicatorValue содержащим decimal, а может быть IIndicatorValue содержащим любой другой тип, который захотел программист.
  • IIndicator разрешает любой IIndicatorValue.

Решения с точки зрения программирования: Если IIndicatorValue должен как то приводиться к decimal, то ИМХО стоит сделать метод public decimal ConvertToDecimal(), где все типы должны приводиться самим создателем наследника от IIndicatorValue. Если не все IIndicatorValue приводимы к decimal, то ИМХО стоит выделить приводимые к decimal в наследника IIndicatorValue. А методы типа IIndicatorValue Process(IIndicatorValue input); заменить на этого наследника для всех приводимых к decimal типов.

Вероятно, я не до конца понимаю объектную модель индикаторов 😀 Пока смотрел исходники появилась еще одна идея - типизировать сам IIndicator, а в наследниках указывать какие именно типа объектов может принимать Process. Возможно это тоже сможет упростить дело.

Thanks:

VoDA

Avatar
Date: 5/12/2012
Reply


**Кот Матроскин:**В продолжение темы: Как правильно кормить индикаторы?

Тот же ChaikinVolatility делает input.GetValue<Candle>(); А ExponentialMovingAverage - input.GetValue<decimal>(); Оба в момент обработки входных данных.

Рассмотрим пример IndicatorsManager.cs из IndicatorsXaml.

Если есть общий список индикторов, то в момент их вызова (функция public void AddPoint(TimeFrameCandle candle)) Придется проверять типы этих индикторов, чтобы понять в каком виде им нужно предоставить Сandle.

Именно поэтому часть кода закомментирована - тот же SimpleMovingAverage просто не работает с данным кодом.

Я правильно понимаю, что единственный выход в данной ситуации это вереница if с проверкой какого типа индикатор и конвертацией Candle в подходящий для индикатора тип?

Thanks:


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

loading
clippy