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

Индикаторы - совместный проект
Atom
5/31/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

Tags:


Thanks:


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

Avatar
Date: 10/12/2011
Reply


worldexplorer
очень хочу присоединиться. пожалуйста добавьте пользователя codeplex worldexplorer (меня), и скажите какие индикаторы остались не разобранными? хочу кружку за пять индикаторов!! и авось втянусь в S#, хочу цепляться к квику, возможно из wealth-lab 5... это будет один из моих "трёх вопросов которые я могу задать", а может вопрос уже и отпадёт по мере написания индикатора :)) жду!!! :)


Нет кружки - нечем черпать желание.[laugh]

Провел рефакторинг по индюкам. Преследуемые цели и фичи:

1. Сделать единого наследника.
2. Выделить комплексные индикаторы.
3. Сделать универсальный объект Значение (который бы работал как с decimal, так и со свечкой).
4. Более простое использование IndicatorManager.

Возможно что-то поломал (вернее, скорее всего). Просьба к авторам проверить на предмет работоспособности.
Thanks:

danl

Avatar
Date: 10/14/2011
Reply


Mikhail Sukhov

Провел рефакторинг по индюкам. Преследуемые цели и фичи:

1. Сделать единого наследника.
2. Выделить комплексные индикаторы.
3. Сделать универсальный объект Значение (который бы работал как с decimal, так и со свечкой).
4. Более простое использование IndicatorManager.

Возможно что-то поломал (вернее, скорее всего). Просьба к авторам проверить на предмет работоспособности.


Добрый день.

Михаил, посмотрел последние изменения в индикаторах. Есть несколько мыслей по развитию.

Существенный момент в том, что источник данных для индикаторов BaseCandleManagerSource подписывается на событие менеджера формирования всех свечей. Таким образом, в каждый индикатор будут попадать данные всех свечей, то есть от всех инструментов, и всех тайм фрэймов (если TimeFrameCanles). Так как сами индикаторы ни на различение инструментов, ни параметров свечей не рассчитаны, то данные которые они вычисляют, не будут иметь смысла. Либо придется создавать по отдельному CandleManager для каждого инструмента и каждого типа свечей и отдавать соответствующий Manager в источник, что не удобно. В связи с этим предлагаю немного развить концепцию IndicatorManager’а, сделать его чем-то похожим на CandleManager. А именно:

  1. Сделать класс CandleTokenIndocatorSource, который будет передавать в индикатор только события пришедшие по определенному CandleToken, так же добавить метод InitIndicator, который будет прогонять исторические свечи имеющиеся в CandleManager через индикатор.

  2. Сделать класс IndicatorToken, который будет хранить индикатор и источник, который ассоциирован с ним, переопределить ему процедуру сравнения так, что бы равными считались токены не с полностью одинаковым состоянием, а те которые содержат одинакоые индикаторы и источники (текущее значение индикатора не сравнивается).

  3. Переработать IndicatorManager, так что бы он позволял регистрировать индикаторы в связке с источниками, возвращая при этом IndicatorToken.

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

  5. Что бы все это корректно работало, в каждом индикаторе потребуется реализовать метод, который проверяет равенство индикаторов не по полному текущему состоянию, а только по параметрам влияющим на рассчет.


Такой подход позволит при реализации прогрммы создавать один IndicatorManager и передавать его в стратегию, стратегия будет регистрировать необходимые ей индикаторы. В случае, если несколько стратегий пользуются одними и теми-же индикаторами, то индикатор будет регистрироваться один раз, а остальные стратегии будут пользоваться тем же индикатором.

Михаил, посмотри, пожалуйста, на предлагаемую концепцию IndicatorManager, если ты согласуешь такой подход, то я бы взялся за его реализацию (в любом случае, для себя буду что-то подобное делать, считаю, что и для остальных это может быть полезно).


Маленькое замечаени. В классе LengthIndicator создан буфер типа List<TResult>. В наследниках, обычно, происходит удаление первого элементо буфера, каждый раз, когда приходит новое значение для рассчета. Мне кажется, что в данном случае имеет смысл использовать какую-нибудь другую коллекцию, которая обеспечивает константное время удаления первого элемента, а не копирует все последующие элементы при каждой такой операции. На сколько я понимаю в StockSharp есть ряд своих разработанных коллекций, к сожалению документацию к ним я не нашел, поэтому на что корректно заменить List не знаю. Из сторонних могу привести пример Wintellect.PowerCollections.Deque (видил PowerCollections.dll в папке References, видимо где-то в StockSharp эти коллекции уже используются).

Прошу добавить меня к проекту разработкаи индикаторов, логин на codeplex: danl8
Thanks:

Mikhail Sukhov

Avatar
Date: 10/14/2011
Reply


Добавил в группу.

По IndicatorManager абсолютно верное замечания. Я забыл поправить этот момент. Буду очень рад, если поможете.

По коллекции тоже правы, но я думаю имеет смысл прогнать построение индикаторов комплексно и посмотреть все узкие места. Кто касается типа коллекции, то думаю очередь не очень удачное решение, так как там работа только с одним концом. Лучше наверное LinkedList.
Thanks:

danl

Avatar
Date: 10/17/2011
Reply


Выложил изменения по IndicatorManager, с реализацией того, о чем писал раньше. Сегодя-завтра вечером еще потестирую, поправлю баги.

Михаил, метод IIndicatorContainer.GetValues в Вашей реализации возвращает обеъкт Dictionary, хотел узнать почему именно Dictionary? Боюсь с этим могут быть проблемы, так как в Dictionary нельзя добавить 2 одинаковых ключа, если строить индикатор от чего-нибудь вроде decimal, то при вызове данного метода будет exception. Может пока не поздно поменять на IList<RefPair>?

Mikhail Sukhov
очередь не очень удачное решение, так как там работа только с одним концом. Лучше наверное LinkedList.

Почему его привел в пример, потому что там очередь реализована как круговой буфер, то есть добавление, как и удаление, элементов в начале и в конце это просто изменение начального или конечного индекса на 1, в остальном то же что и стандартный List<> (то есть доступ к произвольному элементу по индексу быстрый: O(1)). Можно и LinkedList, но у него доступ к произвольпому элементу меделенный.
Thanks:

Mikhail Sukhov

Avatar
Date: 10/17/2011
Reply


danl
Михаил, метод IIndicatorContainer.GetValues в Вашей реализации возвращает обеъкт Dictionary, хотел узнать почему именно Dictionary? Боюсь с этим могут быть проблемы, так как в Dictionary нельзя добавить 2 одинаковых ключа, если строить индикатор от чего-нибудь вроде decimal, то при вызове данного метода будет exception. Может пока не поздно поменять на IList<RefPair>?


Поэтому и существует такая вещь как IIndicatorValue, которая разруливает проблему с одинаковым входным значением. Неправильно ассоциировать с одним входящим значением несколько исходящих. Они (входящие) могут быть совершенно из разного диапазона времени.

Другой вопрос, нужен ли именно словарь для последующей работы. Возможно, доступ по ключу тут как раз бесполезен. Тогда да, лучше IEnumerable (лист предполагает динамическое добавление, лучше следовать LINQ традициям).

danl

Почему его привел в пример, потому что там очередь реализована как круговой буфер, то есть добавление, как и удаление, элементов в начале и в конце это просто изменение начального или конечного индекса на 1, в остальном то же что и стандартный List<> (то есть доступ к произвольному элементу по индексу быстрый: O(1)). Можно и LinkedList, но у него доступ к произвольпому элементу меделенный.


Очередь вроде вообще не дает по индексу. Может создать свою уникальную коллекцию для организации автоматического удаления хвостовых значений?

По коммиту ряд замечания.

1) Ставьте знаки препинания и точки в конце предложения.
2) Прописывайте все пункты в xml комментариях (некоторые ноды пустые).
3) this._privateField лучше заменять на _privateField
4) Устраняйте предупреждения через R#.
5)
Code
RefPair<IndicatorToken, int> inDict;
				if (_indicatorUsages.TryGetValue(indicatorToken, out inDict))

Заменяется на:
Code
var inDict = _indicatorUsages.TryGetValue(indicatorToken);
				if (inDict != null)

6) IIndicator.IndicatorEquals выглядит лишним.
Quote:
В отличии от стандартного Equals не проверяет полное состояние индикатора
Вот как стандартное проверяет просто ссылочную эквивалентность.
Лучше IIndicator отнаследовать от IEquatable{T}, а класс BaseIndicator от Equatable{T}.
7) Если в xml комментарии написано с разделами, то можно использовать ноду para.
8) Рефакторинг решил одну проблему, но добавил другую (как всегда[biggrin]). Не нравится тот момент, что теперь прикладной код само должен выбирать, по какому источнику строить индикатор. А такую работу предполагалось нагрузить на IndicatorManager. Тоесть, он должен решать, откуда и куда передавать данные (предотвращать дублирование, склеивать при пробелах и т.д.). Мне кажется, тут лучше сделать как сделано в последней версии CandleManager, который оперирует с коллекцией источников ICandleSource. Соответственно, при регистрации индикатора мне кажется имеет смысл передавать туда object. Object будет или CandleToken, или MarketDepth (или Security). А уж IndicatorManager будет дальше смотреть, откуда по запрашиваемым признакам брать данные (из какого IIndicatorSource).
Thanks:

esper

Avatar
Date: 10/17/2011
Reply


Mikhail Sukhov

3) this._privateField лучше заменять на _privateField

так решарпер при рефакторинге this сам добавляет, возможно это в настройках где-то задается
Thanks:

Mikhail Sukhov

Avatar
Date: 10/17/2011
Reply


esper
Mikhail Sukhov

3) this._privateField лучше заменять на _privateField

так решарпер при рефакторинге this сам добавляет, возможно это в настройках где-то задается


Да, это в настройках.
Thanks:

danl

Avatar
Date: 10/17/2011
Reply


Mikhail Sukhov
Другой вопрос, нужен ли именно словарь для последующей работы. Возможно, доступ по ключу тут как раз бесполезен. Тогда да, лучше IEnumerable (лист предполагает динамическое добавление, лучше следовать LINQ традициям).

На мой взгляд IEnumerable првильнее.

Mikhail Sukhov
Очередь вроде вообще не дает по индексу. Может создать свою уникальную коллекцию для организации автоматического удаления хвостовых значений?

Честно говорю Deque реализует интерфейс IList<> и поддерживает доступ по индексу [smile]
А что, кстати, за коллекция Ecng.Collections.FixedSynchronizedList, она, случайно, не подойдет?


Mikhail Sukhov
По коммиту ряд замечания.
...

Ок. Замечания 1-7 поправлю, в следующий раз буду внимательнее.


Mikhail Sukhov
8) Рефакторинг решил одну проблему, но добавил другую (как всегдаBigGrin). Не нравится тот момент, что теперь прикладной код само должен выбирать, по какому источнику строить индикатор. А такую работу предполагалось нагрузить на IndicatorManager. Тоесть, он должен решать, откуда и куда передавать данные (предотвращать дублирование, склеивать при пробелах и т.д.). Мне кажется, тут лучше сделать как сделано в последней версии CandleManager, который оперирует с коллекцией источников ICandleSource. Соответственно, при регистрации индикатора мне кажется имеет смысл передавать туда object. Object будет или CandleToken, или MarketDepth (или Security). А уж IndicatorManager будет дальше смотреть, откуда по запрашиваемым признакам брать данные (из какого IIndicatorSource).


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

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

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

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

danl

Avatar
Date: 10/18/2011
Reply


Mikhail Sukhov
Лучше IIndicator отнаследовать от IEquatable{T}, а класс BaseIndicator от Equatable{T}.

Сейчас посмотрел класс Equatable<T>, он, помимо всего прочего, реализует интерфейс IClonable, который потом придется тащить через всех наследников. Он нам точно нужен в BaseIndicator?
Пока оставляю его с NotImplementedException, если что, потом поправим.
Thanks:

Mikhail Sukhov

Avatar
Date: 10/18/2011
Reply


danl
Сейчас посмотрел класс Equatable<T>, он, помимо всего прочего, реализует интерфейс IClonable, который потом придется тащить через всех наследников. Он нам точно нужен в BaseIndicator?


Еще как. Клон - это такой метод, который лучше иметь, чем не иметь. Вот например сейчас делаю редактирование индюков в проп Гриде. Приходится править на живом. Соответственно, Undo операция невозможно.
Thanks:
<< < 23 24 25 26 27  > >>

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

loading
clippy