S#

Создание CandleManager при неодновременном запуске двух стратегий в одном приложении


Создание CandleManager при неодновременном запуске двух стратегий в одном приложении
Atom Reply
1/4/2017


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



Thanks:




24 Answers
Mikhail Sukhov

Avatar
Articles author Programmer Trader
Date: 1/5/2017
Reply


Это все зависит от кода стратегий и самого приложения.

Подхода стокшарпа не существует, так как это АПИ, а не конкретное приложение. Есть подход по правильному написанию программ на .NET и WPF. Лучше их читать.
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/6/2017
Reply


Вообще-то в разных стратегиях если Вы подписались на инструменты и сделки в обоих, то и candlemanager каждой стратегии строят свечки не зависимо друг от друга. По крайней мере в более поздних версиях именно так. Проверяйте свой код.
Thanks:

Evgeny

Avatar
Training
Date: 1/7/2017
Reply


RomSunZ, у меня главная предпосылка была, что стратегии и их соответствующие candlemanager`ы запускаются неодновременно.
То есть сначала запускается первая стратегия с первым менеджером свечек, происходит подписка на тики по инструменту и этот первый менеджер свечек все нормально строит.
Затем (например, через час) запускается вторая стратегия со вторым менеджером свечек. Этот второй менеджер свечек тоже подпишется на событие получения новых сделок (TradeCandleBuilderSource), но ведь от этого второй менеджер свечек уже все равно не получит тики за первый час, пока работал только первый менеджер свечек.
Или не так и я что-то упустил?
Topic starter
Thanks:

gem81

Avatar
Date: 1/9/2017
Reply


Вопрос возник такой же)
Попробую пояснить что не так.
Есть соединение public QuikTrader client = new QuikTrader(); общее для всего приложения.
Далее Мы создаём TradeCandleBuilderSource(client) и запускаем _candleManager.Start(_series);
я опустил все инициации серий и т.п.
затем через какое-то время мы нажимаем кнопку запустить второй алгоритм по тому же инструменту. Скрипт так сделан, что контролирует количество открытых им позиций по алгоритму, и ему не важно, сколько открывает позиций параллельный алгоритм.
И вот теперь при попытке запустить второй экземпляр окна со своим набором TradeCandleBuilderSource(client) и _candleManager.Start(_series); ничего не происходит.
из глобальных переменных тут только client, всё остальное формируется в классе нового окна с чартом. Cursing
пояснил, у самого моск подкоптился
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/9/2017
Reply


Вопрос на засыпку, как в примерах с отдельными ChartWindow (суть с разными экземплярами "стратегий") все строится, а у Вас нет?
Thanks:

gem81

Avatar
Date: 1/9/2017
Reply


RomSunZ Перейти
Вопрос на засыпку, как в примерах с отдельными ChartWindow (суть с разными экземплярами "стратегий") все строится, а у Вас нет?


Написано всё как в примере. Результат на картинке. Первый раз всё вырисовывает, открываешь второй раз чарт по тому же инструменту, пусто

sh_double_sec.png

sh_double_sec.png 202.1KB (12)
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/9/2017
Reply


На сколько помню, при запуске candlemanager можно было задавать начальную/конечную дату. Попробуйте, может быть поможет.
Thanks:

Evgeny

Avatar
Training
Date: 1/10/2017
Reply


Я запустил у себя стандартный пример со свечками. И ожидаемо увидел тоже самое. При открытии того же окна с тем же инструментом график рисоваться не будет. С другим инструментом - будет, а с тем же - нет.
И причина, насколько я понимаю, именно в том, что TradeCandleBuilderSource, который отвечает за построение онлайн свечек, вызывает перестроение свечи только при появлении нового тика. А когда открывается второе окно - старые тики, поступившие к этому моменту, второй раз не поступят, и соответственно свечи заново не сгенерятся.
Возможно проблему можно решить добавив другой источник, который построит свечи либо по данным в хранилище, либо по данным коллекции тиков.
Но в обоих случаях я вижу подводные камни.
Я поэтому и хотел, чтобы на эту тему отписались разработчики. Каким-то образом, они же решали эту проблему, например, в дизайнере.
Topic starter
Thanks:

Support

Avatar
Date: 1/12/2017
Reply


1. Я бы рекомендовал использовать один CandleManager
2. "По повод тиков с начала сессии". Для CandleManager существуют "источники данных", в частности, для работы с тиковыми реал-тайм данными используется RealTimeCandleBuilderSource<T>. Вы можете попробовать использовать для каждого CandleManager один RealTimeCandleBuilderSource.
3. Все сформированные свечи хранятся в контейнере CandleManager. Эту "историю" Вы можете использовать при запуске второй стратегии.
Thanks:

Support

Avatar
Date: 1/12/2017
Reply


gem81 Перейти
Вопрос возник такой же)
Попробую пояснить что не так.
Есть соединение public QuikTrader client = new QuikTrader(); общее для всего приложения.
Далее Мы создаём TradeCandleBuilderSource(client) и запускаем _candleManager.Start(_series);
я опустил все инициации серий и т.п.
затем через какое-то время мы нажимаем кнопку запустить второй алгоритм по тому же инструменту. Скрипт так сделан, что контролирует количество открытых им позиций по алгоритму, и ему не важно, сколько открывает позиций параллельный алгоритм.
И вот теперь при попытке запустить второй экземпляр окна со своим набором TradeCandleBuilderSource(client) и _candleManager.Start(_series); ничего не происходит.
из глобальных переменных тут только client, всё остальное формируется в классе нового окна с чартом. Cursing
пояснил, у самого моск подкоптился


Если у вас один candleManager, то второй раз вызывать _candleManager.Start(_series) не надо, можно просто во второй стратегии еще раз подписаться на событие CandleManager.Processing.. Вам нужно иметь ссылки на CandleSeries, и каждый раз при попытке вызова candleManager.Start(_series) проверять есть ли такая серия в CandleManager.Series... Если есть, то серия уже запущена... Уже построенные свечи получаем при помощи _candleManager.GetCandles<T>(CandleSeries)...
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/13/2017
Reply


Ага, только в таком подходе можно получить пропуск свечек в промежутке между обработкой результатов candleManager.GetCandles и подписью на событие CandleManager.Processing. Придется городить огород с проверками и т.п.
Thanks:

Support

Avatar
Date: 1/13/2017
Reply


нельзя...
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/13/2017
Reply


Что значит нельзя?
Вариант 1:
Вы вызываете candleManager.GetCandles<T>(CandleSeries). Получаете коллекцию. Обрабатываете ее - это занимает некоторое время, подписываетесь на событие Processing, начинаете получать сообщения. Но со времени получения и обработки коллекции уже могли произойти изменения в коллекции в candleManager (потоки-то разные), и какие-то из изменений могли пройти мимо нас.

Вариант 2:
Подписываемся на Processing и начинаем получать сообщения. Вызываем candleManager.GetCandles<T>(CandleSeries). Получаем коллекцию. Обрабатываете ее, но во время ее обработки может придти сообщение от Processing - проблемы с синхронизацией обработки.

Есть еще какие-либо варианты?
Thanks:

Evgeny

Avatar
Training
Date: 1/13/2017
Reply


Потратил кучу времени и выяснил вот что: вторая стратегия, запущенная позднее старта первой стратегии (или второй чарт) все-таки получают данные с начала торговой сессии при следующих условиях:
1. CandleManager должен быть обязательно один и тот же.
2. CandleSeries должны быть обязательно разные (даже если стратегии или чарты используют абсолютно идентичные свечи с тем же инструментом и таймфреймом).
3. С момента запуска второй стратегии по этому инструменту должен придти хотя бы один тик. Если до конца сессии новых сделок так и не будет, то вторая стратегия так и не получит данные с начала сессии. Если же новые сделки будут получены, то вторая стратегия сначала получит все сформированные свечи с начала сессии, а потом начнёт получать реальные данные.

Третий пункт как раз меня и gem81 судя по всему и сбил с толку. Так как если запускать стандартный пример с графиками ChartWindow после окончания торговой сессии (то есть новых сделок уже точно не поступит), то второй чарт по одному инструменту не строится. Но если его запускать во время торговой сессии и по инструменту продолжают поступать сделки, то все строится нормально.

То есть по идее, если третье условие считать допустимым, то можно не прибегать к использованию метода GetCandles.
В идеале, конечно, хотелось бы получить подтверждение от поддержки, что описанное действительно работает (и главное - должно работать) именно так, а я не набрёл на очередной частный случай.
Topic starter
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/14/2017
Reply


1. Не обязательно.
2. Должны.
3. Я же Вам написал ранее. Используйте candlemanager.Start(startTime, endTime) и получите Ваши свечи не зависимо от других запущенных стратегий.
Thanks:

Evgeny

Avatar
Training
Date: 1/14/2017
Reply


RomSunZ, вы сами пробовали на последней версии API запустить пример SampleQuikCandles с двумя чартами по одному инструменту предварительно сделав те доработки, про которые вы говорите?
1. Если создавать два экземпляра CandleManager для одного коннектора, то при старте серии свечек по второму появляется ошибка System.InvalidOperationException: Subscribed. Появляется она из-за того, что в RealTimeCandleBuilderSource.Start производится подписка на получение тиков по инструменту. Попытка это вторая, т.к. при старте первого менеджера свечек подписка на тики уже ранее была произведена.
Соответственно после появления этой ошибки ничего уже не строится.
3. Это не работает. В том же примере заменяю строку запуске серии на candleManager.Start(series, System.DateTime.Today.AddDays(-1), System.DateTime.MaxValue); и от этого ничего не меняется. На втором чарте по тому же инструменту свечи появятся только если после запуска этого второго чарта придет хотя бы один тик. А он после окончания сессии никогда не придет.
Topic starter
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/18/2017
Reply


В таком случае пишите свой обработчик загрузки истории, иначе никак.
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/20/2017
Reply


А Вы смотрели поведение candlemanager например в S#.Disigner? Если там все работает, то значит решение есть, его просто надо увидеть :)
Thanks:

Support

Avatar
Date: 1/26/2017
Reply


Для вашей задачи оптимальным будет следующее решение..
Во второй стратегии Вы просто подписываетесь на событие CandleManager.Processing..., кроме того создаете флаг для первой свечи в этой стратегии... При получении первой свечи запрашиваете все свечи CandleManager.GetCandles, выполняет нужные операции, сбрасываете флаг....
При создании дополнительных CandleManager или дополнительных CandleSeries накладные расходы программы будут больше....
Thanks:

RomSunZ

Avatar
Programmer
Date: 1/27/2017
Reply


Тут вопрос в другом. Событие появления обработки свечек сработает только после получения новой сделки по инструменту и Ваше решение бесполезно. А человеку надо получить свечки сразу после запуска второй стратегии, т.к. сделки придут неизвестно через какой промежуток времени (например после окончания торговой сессии это будет только на следующий рабочий день). Тогда уж наверное при запуске стратегии сначала делать запрос GetCandles и после их обработки подписываться на обработку. Правда как я уже писал придется проверять появились ли изменения в свечках с момента их получения до момента подписки на событие обработки.
Thanks:

Support

Avatar
Date: 1/27/2017
Reply


Я не вижу в этом никакой проблемы...Получение свечей проходит очень быстро... Можно конечно проверять, но это принципиально ни на что не повлияет...
Thanks:

Evgeny

Avatar
Training
Date: 1/27/2017
Reply


Скажите, пожалуйста, если все-таки создавать дополнительный CandleSeries, то по свечам, которые уже были сформированы к моменту запуска второй стратегии, во второй стратегии должны срабатывать правила WhenCandlesStarted, WhenCandlesChanged и т.д.? Или только правило окончания свечи?
Topic starter
Thanks:

Support

Avatar
Date: 1/30/2017
Reply


Да.
Thanks:

RomSunZ

Avatar
Programmer
Date: 2/2/2017
Reply


В общем суть проблемы в том, что класс RealTimeCandleBuilderSource, который является базовым для TradeCandleBuilderSource, вызывает метод AddNewValues только когда получает новый тик. А в этом методе идет проверка
Код

                    if (series.IsNew)
                    {
                        RaiseProcessing(series, Convert(GetSecurityValues(security)).OrderBy(v => v.Time));
                        series.IsNew = false;
                    }
                    else
                    {
                        RaiseProcessing(series, securityValues);
                    }

в котором проверяется новая серия или нет. Если новая идет запрос всех сделок, если нет - обрабатываются поступившие.
Вам нужно переписать этот класс и запрос всех сделок делать сразу после добавления новой серии.
Thanks:


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

loading
clippy