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


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

Месяц назад я публиковал призыв о совместной разработке индикаторов на базе 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

Теги:


Спасибо:



Скидка 15% на все продукты до 5 апреля (осталось 5 дней).

340 Ответов
<< < 9 10 11 12 13  > >>
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

Фотография
Дата: 18.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

Фотография
Автор статей Программист Трейдер
Дата: 18.10.2011
Ответить


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


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

Daenur

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


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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 18.10.2011
Ответить


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

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


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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 19.10.2011
Ответить


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

danl

Фотография
Дата: 19.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 как изначально предполагалось действовать в таких ситуациях?
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.10.2011
Ответить


1. А как этот индикатор будет отображаться графически? Будет разрыв в линии? Можно пример индюка.
2. Не согласен. Если индюк на следующей свечке приобрел тоже значение, что и на предыдущей (например, индикатор объема), то он должен сообщать о том, что он изменился. Потому что он приобрел новое состояние.
3. Посмотри в студии класс CandleChartIndicatorCollection.
4. Комплексный индюк может быть последовательным, а может быть и параллельным (частое значение). Я в аллигаторе и Ишимоку проделал такое, можно посмотреть как сделано.
Автор топика
Спасибо:

Supervisor

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


1. Фракталы например
Спасибо: Mikhail Sukhov

esper

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


Mikhail Sukhov Перейти
1. А как этот индикатор будет отображаться графически? Будет разрыв в линии? Можно пример индюка.

Как сказали выше, это фрактал, который рисуется только точками в соответствующих вершинах. Сюда можно отнести зигзаг, который рисуется ломаными линиями, где известны только вершины, а не промежуточные значения. Сейчас возвращается предыдущее сформированное значение индикатора с соответствующим смещением, но это не совсем корректно.

Mikhail Sukhov Перейти
2. Не согласен. Если индюк на следующей свечке приобрел тоже значение, что и на предыдущей (например, индикатор объема), то он должен сообщать о том, что он изменился. Потому что он приобрел новое состояние.

Да, видимо для некоторых индюков это имеет смысл. Т.к. это связано с первым пунктом, то "пустое значение" решит эту проблему.

Mikhail Sukhov Перейти
4. Комплексный индюк может быть последовательным, а может быть и параллельным (частое значение). Я в аллигаторе и Ишимоку проделал такое, можно посмотреть как сделано.

С параллельными пока проблем не было, несколько таких индикаторов поправил и они нормально проходят тесты. Ишимоку и аллигатором тесты не проходят, почему пока не разобрался. Но вот с ADX возникла сложность, он строится на базе WilderMovingAverage, который должен быть построен на базе Dx, при этом Dx тоже возвращает комплексное значение, а WilderMovingAverage на входе требуется только одно decimal значение, какое из 3-х значений возвращаемых Dx взять не понятно. Тип у этих 3-х значений тоже может совпадать. Если честно, я бы просто упростил этот индикатор, чтобы он возвращал только свое значение. Действительно ли надо чтобы Dx выдавал еще DiPlus и DiMinus, на базе которых он считается?
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.10.2011
Ответить


esper Перейти
С параллельными пока проблем не было, несколько таких индикаторов поправил и они нормально проходят тесты. Ишимоку и аллигатором тесты не проходят, почему пока не разобрался. Но вот с ADX возникла сложность, он строится на базе WilderMovingAverage, который должен быть построен на базе Dx, при этом Dx тоже возвращает комплексное значение, а WilderMovingAverage на входе требуется только одно decimal значение, какое из 3-х значений возвращаемых Dx взять не понятно. Тип у этих 3-х значений тоже может совпадать. Если честно, я бы просто упростил этот индикатор, чтобы он возвращал только свое значение. Действительно ли надо чтобы Dx выдавал еще DiPlus и DiMinus, на базе которых он считается?


ADX - это три значения в моменте. Это сложный индикатор.
Автор топика
Спасибо:

esper

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


Посмотрел CandleChartIndicatorCollection, сейчас не обрабатывается ситуация когда вложенный индикатор так же сложный, собственно про это я и говорю.
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.10.2011
Ответить


esper Перейти
Посмотрел CandleChartIndicatorCollection, сейчас не обрабатывается ситуация когда вложенный индикатор так же сложный, собственно про это я и говорю.


Понял, спасибо... Ну да, надо это сделать.
Автор топика
Спасибо:

Daenur

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


Написал JMA. По-сути, за основу взял SMA и в функцию расчета перенес код индикатора на C#, найденный на просторах интернета. Поскольку официальной версии от Юрика у меня нет, то и сравнивать его результаты не с чем. Работает, результаты меня устраивают.
Как правильно его выложить?
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 26.10.2011
Ответить


Daenur Перейти
Написал JMA. По-сути, за основу взял SMA и в функцию расчета перенес код индикатора на C#, найденный на просторах интернета. Поскольку официальной версии от Юрика у меня нет, то и сравнивать его результаты не с чем. Работает, результаты меня устраивают.
Как правильно его выложить?


Через CodePlex. Логин уже есть?
Автор топика
Спасибо:

Daenur

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


Да, есть, Daenur.
Использую TortoiseSVN, с ее помощью залил себе весь проект. Могу обратно выкладывать файл с индикатором?
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 26.10.2011
Ответить


Daenur Перейти
Да, есть, Daenur.
Использую TortoiseSVN, с ее помощью залил себе весь проект. Могу обратно выкладывать файл с индикатором?


Я не знаю как работать с SVN. Я работаю через TFS.
Автор топика
Спасибо:

Daenur

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


Подключился через VS2010, выложил JurikMovingAverage в папку Trend.
В проект не добавлял, т.к. мой проект несколько отличается от того, что есть на сервере, не хочется портить общую работу. Добавьте этот файл в общий проект.
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 26.10.2011
Ответить


Daenur Перейти
Подключился через VS2010, выложил JurikMovingAverage в папку Trend.
В проект не добавлял, т.к. мой проект несколько отличается от того, что есть на сервере, не хочется портить общую работу. Добавьте этот файл в общий проект.


Один вопрос, а почему такой код страшный?RollEyes Можете дать ссылку на описание алго?
Автор топика
Спасибо:

Daenur

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


Страшный - в смысле непонятных расчетов? Просто не имеется в открытом доступе его кода, Jurik продает его в виде DLL. То, что есть в интернете - результат дизассемблирования.
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 26.10.2011
Ответить


Daenur Перейти
Страшный - в смысле непонятных расчетов? Просто не имеется в открытом доступе его кода, Jurik продает его в виде DLL. То, что есть в интернете - результат дизассемблирования.


Я так и подумал. А разве это не нарушение прав?
Автор топика
Спасибо:

Daenur

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


А в чем? Дизассемблированием уж точно не я занимался. А какой угодно код никто писать не запрещает.
Ради интереса посмотрел сайт Юрика - никаких слов о запатентованности алгоритма и т.п. не увидел.
Спасибо:
<< < 9 10 11 12 13  > >>

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

loading
clippy