Индикаторы - совместный проект

Индикаторы - совместный проект
Atom
31.05.2011
Mikhail Sukhov


Приветствую всех участников!

Месяц назад я публиковал призыв о совместной разработке индикаторов на базе C#. Прошел месяц, мною было сделано 3 стандартных индикатора SMA, EMA и WMA. И ни строчки кода ни от одного пользователя S#. Каждый день задают вопросы (причем, большинство явно не относящиеся к S# как таковому), получают ответы, но свою помощь предложить не хотят. Стесняются, наверное.

Я понимаю, что дело в мотивации. Зачем помогать делать что-то, если можно подождать пару месяцев (пол года) или сделать самому, а потом пересесть на стандартное. Поэтому я решил найти мотивацию. И я ее нашел. Это лето объявляется летом "Ты мне - я тебе".

Схема простая. Вы делаете индикатор - я отвечаю на три любых вопроса. Вопросы по глюкам S# остаются как есть и раньше - ответ всегда получите. Но вопросы по C#, WFP, примерам, документации, Квику и всему прочему - только за индикатор.[smile] Я думаю честно.

Сделав 5 индикаторов, вы получается бонус - кружку с символикой S#.

Репозитарий с исходниками расположен по адресу http://stocksharpconnectors.codeplex.com Чтобы получить доступ на запись регистрируйтесь на сайте, пишите в эту тему свой логин и какие индюки хотите сделать. Стиль кодирование указывается через R#. Настройки в репозитарии.

Что сделано сейчас:

  1. Acceleration
  2. Alligator
  3. AwesomeOscillator
  4. Fractals
  5. GatorOscillator
  6. MarketFacilitationIndex
  7. BollingerBands
  8. ExponentialMovingAverage
  9. Macd
  10. ParabolicSar
  11. RAVI
  12. SimpleMovingAverage
  13. SmoothedMovingAverage
  14. StandartDeviation
  15. VolumeWeightedMovingAverage
  16. WeightedMovingAverage
  17. WilderMovingAverage
  18. Adx
  19. Atr
  20. ChandeMomentumOscillator
  21. CommodityChannelIndex
  22. DiMinus
  23. DiPlus
  24. Dx
  25. Ichimoku
  26. Momentum
  27. RateOfChange
  28. RelativeStrengthIndex
  29. RVI
  30. TrueRange
  31. DetrendedPriceOscillator
  32. Highest
  33. LinearReg
  34. LinearRegression
  35. LinearRegSlope
  36. Lowest
  37. MeanDeviation
  38. MedianPrice
  39. Peak
  40. PeakBar
  41. QStick
  42. RSquared
  43. StandardError
  44. StochK
  45. Sum
  46. Trix
  47. Trough
  48. TroughBar
  49. UltimateOsc
  50. VerticalHorizontalFilter
  51. Vidya
  52. Volatility
  53. WilliamsR

Теги:


Спасибо:


<< < 24 25 26 27 28  > >>
Mikhail Sukhov

Фотография
Дата: 18.10.2011
Ответить


danl

Да, вопрос интересный. Мысль о том, что нужно разнести регистрацию источников данных и самих индикаторов была, но имеет это смысл или нет, пока не осознал... Если есть понимание того, что это нужно, давайте делать.

Если я провильно понял идею, то даем возможность пользователю регистрировать источники. Коллекцию источников в IndicatorManager я уже добавлял, просто делаем к ней public методы доступа. В методе регистрации индикатора просто добавляем поиск зарегистрированного источника по аргументу (методы для сравнения object'a и источников выносим в IndicatorSource, что бы все было расширяемо). И, собственно, всё. Клиентский код будет выглядить примерно так:
Код
var candleToken = candleManager.RegisterTimeFrameCandles(security, timeFrame);
indicatorManager.RegisterSource(new CandleTokenIndicatorSource(candleToken));
...

var indicatorToken = indicatorManager.RegisterIndicator(new SimpleMovingAverage { Length = 80 }, candleToken);

Я правильно понял? Делать так?


Уже явно лучше, что при формировании индюка не нужно указывать источник и следовательно их хранить (сейчас я храню в словаре). Но надо еще помозговать над этой темой. Метод IIndicator.IsSupport был создан для проверки, поддерживает ли данные индикатор передаваемое значение. Если делать привязку индюк-источник, то такой метод отпадает сам собой. Но при регистрации я думаю нужно проверить, а есть ли вообще источники для регистрируемого индюка.
Спасибо:

danl

Фотография
Дата: 18.10.2011
Ответить


Mikhail Sukhov
Уже явно лучше, что при формировании индюка не нужно указывать источник и следовательно их хранить (сейчас я храню в словаре). Но надо еще помозговать над этой темой. Метод IIndicator.IsSupport был создан для проверки, поддерживает ли данные индикатор передаваемое значение. Если делать привязку индюк-источник, то такой метод отпадает сам собой. Но при регистрации я думаю нужно проверить, а есть ли вообще источники для регистрируемого индюка.

При регистрации проверять наличие источника это само сабой. В принципе, можно, сделать фабрику источников и научить IndicatorManager создавать источники самому, например по CandleToken источник создается однозначно, вся необходимоя информация есть. При этом ручная регистрация источников все равно остается, для экзотических случаев.

Если до вечера новых идей не будет, то пока сделаю так, потом посмотрим на готовый код, может поправим.


Mikhail Sukhov
Еще как. Клон - это такой метод, который лучше иметь, чем не иметь. Вот например сейчас делаю редактирование индюков в проп Гриде. Приходится править на живом. Соответственно, Undo операция невозможно.

Ок, делаем клонирование.
Спасибо:

Daenur

Фотография
Дата: 18.10.2011
Ответить


Прошу добавить в группу Daenur
Попробую сваять JMA
Спасибо:

danl

Фотография
Дата: 19.10.2011
Ответить


Mikhail Sukhov
Соответственно, при регистрации индикатора мне кажется имеет смысл передавать туда object. Object будет или CandleToken, или MarketDepth (или Security).


Начал я реализовывать это дело и понял, что не клеется. Дело в том, что одного объекта не достаточно для однозначной идентификации источника. Так как очень много индикаторов строится не на свечах, а просто на числовом ряде, то нужно из свечей уметь делать числа. По текущей концепции эта задача ложится на BaseCandleIndicatorSource, от которого унаследован CandleTokenIndicatorSource. Таким образом, получаем, что клиентский код должен сообщить менеджеру 3 параметра: индикатор, токен свечи, функцию преобразования. Если же индикатор строится целиком на свече, то 2 параметра. Может есть случаи, когда нужно и больше параметров для однозначной идентификации источника. Получается передавать object не достаточно.
Вижу следующие варианты решения:
Вариант 1. Передавать не object, а массив object[]. Все остальное как и было. Единственный минус - коряво это как-то. Из сигнатуры метода не ясно как им пользоваться, проверка корректности только во время выполнения, нужно знать как заполнять этот массив для каждого типа индикаторов. Пытались упростить использование менеджера, а получилась совершенно не прозрачная структура.
Вариант 2. Ввести новую абстракцию IIndicatorSourceIdentifier, сделать несколько реализаций для свечей, частей свечей и т.д. По сути, для каждого источника своя реализация IIndicatorSourceIdentifier. Клиентский код будет создавать соответствующий класс, заполнять параметрами и вперед.
Вариант 3. Помыслив над вторым вариантом не увидил большой разницы с тем что уже есть. Клиентский код передает IIndicatorSource. Если посмотреть на вариант 2, то абстракция IIndicatorSourceIdentifier служит только для одной функции: идентифицировать источник, для создания этого идентификатора нужны те же параметры, что и для самого источника. Соответственно, если аккуратно переопределить Equals у источников, то клиентский код останется одинаковым. Отсюда вопрос стоит ли плодить новые сущности в данном случае?
Хочу еще заметить, что для 3его варианта не нужно хранить список источников в клиентском коде. Можно просто при регистрации индикатора создавать новый источник, IndicatorManager сам найдет соответсвующий ему источник в своей коллекции и будет использовать его. Предварительная регистрация источников не нужна как в том так и в другом случае.

Для этих вариантов клиентский код будет выглядеть примерно так (на мой взгляд это где-то в инициализации стратегии):
Вариант 1.
Код
var candleToken = candleManager.RegisterTimeFrameCandles(security, timeFrame);
var indicatorToken = indicatorManager.RegisterIndicator(new SimpleMovingAverage { Length = 80 },
                     new object[] {candleToken, BaseCandleIndicatorSource.ByOpen});

Вариант 2.
Код
var candleToken = candleManager.RegisterTimeFrameCandles(security, timeFrame);
var indicatorToken = indicatorManager.RegisterIndicator(new SimpleMovingAverage { Length = 80 },
                     new CandleTokenSourceIdentifier (candleToken, BaseCandleIndicatorSource.ByOpen));


Вариант 3.
Код
var candleToken = candleManager.RegisterTimeFrameCandles(security, timeFrame);
var indicatorToken = indicatorManager.RegisterIndicator(new SimpleMovingAverage { Length = 80 },
                     new CandleTokenIndicatorSource (candleToken, BaseCandleIndicatorSource.ByOpen));


Вариант 1 мне не нравится. Варианты 2 и 3 считаю приемлемыми, пока наиболее склоняюсь к варианту 3, так как сущность IIndicatorSourceIdentifier не несет большой нагрузки и вполне может быть объеденина с сущностью IIndicatorSource.

Оставляем 3й варианта, может есть новые идеи?
Спасибо:

Mikhail Sukhov

Фотография
Дата: 19.10.2011
Ответить


Daenur
Прошу добавить в группу Daenur
Попробую сваять JMA


Сделал. Большая просьба. Перед добавлением посмотрите, как делаются другие индикаторы. Есть свои нюансы.
Спасибо:

Daenur

Фотография
Дата: 19.10.2011
Ответить


Спасибо.
Обязательно!
Спасибо:

Mikhail Sukhov

Фотография
Дата: 19.10.2011
Ответить


danl
Вариант 1 мне не нравится. Варианты 2 и 3 считаю приемлемыми, пока наиболее склоняюсь к варианту 3, так как сущность IIndicatorSourceIdentifier не несет большой нагрузки и вполне может быть объеденина с сущностью IIndicatorSource.

Оставляем 3й варианта, может есть новые идеи?


Какова вероятность, что трейдер будет использовать для один индикаторов цену закрытия, а для других открытия? Я думаю для индюков выбираю что-то одно. Для пункта 3 придется регистрировать каждый раз новые источник для каждого индюка. Но этот пункт мне тоже больше других нравится.
Спасибо:

Mikhail Sukhov

Фотография
Дата: 20.10.2011
Ответить


Залил небольшие изменения. Если будут вопросы, можно обсудить.
Спасибо:

danl

Фотография
Дата: 20.10.2011
Ответить


Mikhail Sukhov
Залил небольшие изменения. Если будут вопросы, можно обсудить.


Изменения видел, все понятно, у меня возражений нет [smile].
Так же сделал ряд изменений. Добавил Equals в источники индикаторов, теперь при регистрации одного источника несколько раз отрабатывает корректно, берет уже зарегистрированный, новый не регистрирует. Добавил тесты для класса IndicatorManager (конечно, не 100% покрытие, но основные ситуации рассмотрел). Удалось отловить ряд багов, теперь вроде даже работает [smile].
Спасибо:

esper

Фотография
Дата: 20.10.2011
Ответить


Хотелось бы обсудить несколько вопросов относительно IIndicatorValue.

1. Возможно стоит добавить свойство IsEmpty для значений индикаторов. Есть индикаторы, в которых не для каждого входного значения есть выходное, к тому же для индикаторов, которые еще не сформированы, сейчас выставляется значение по умолчанию равное default(T), что тоже неправильно.

2. Сейчас событие Changed у индюка вызывается при каждом добавлении значения в индикатор, даже если значение индикатора не меняется, правильнее вызывать его только при изменении значения. Предлагаю для IIndicatorValue реализовать IEquitable.

3. У комплексного значения индикатора не ясно какое значение что представляет. Так же комплексное значение может хранить несколько значений индикаторов, типы которых могут совпадать, не ясно как получить нужное нам значение. Для тестов это особой роли не играет, а вот при выводе индикаторов на график необходимо делать подписи для серий, или при возникновении события Changed как-то определять какое значение нам необходимо.

4. Сейчас могут строится цепочки индикаторов, когда один индикатор возвращает комплексное значение и оно передается на вход другому, то не понятно как оттуда достать нужное значение.

По пунктам 3 и 4 как изначально предполагалось действовать в таких ситуациях?
Спасибо:
<< < 24 25 26 27 28  > >>

Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy