Вопрос алготрайдерам по внутреннему механизму сведения позиций.
Добрый день,
Хочу поинтересоваться у тех у кого крутятся одновременно большое количество стратегий с пересекающимися инструментами.
Каким образом реализовано, технически, сведение позиций между стратегиями?
Ведь возникает масса проблем с таймингом и типом исполнения. Как пример лимитный и маркет ордер, не говоря уже о алгоритмах исполнения брокера.
В целом я вижу только один более менее простой и разумный вариант это группировки стратегий по типу исполнения, используемого тайм фрейма и тд. Только в таком случае можно как то гарантировать внутренние перекрытие и не потерять в скорости выставления заявок.
SergeyJu, ну это в принципе группировка стратегий по одному принципу работы… в таком случае никаких проблем не возникнет. Можно не выводить взаимоисключающие позиции на рынок :)
Дмитрий Овчинников, хмм… Ок… а спред?
Т.е. одна стратегия берет 100 акций по цене 100.05 вторая в это же время продает по 100.00. То что можно было бы не выводить в рынок и перекрыть открывается и мы тратим 5$ на спред + скажем 0.5$ за каждую операцию (т.е 0.5$х2=1$)… далее мы эти обе позиции закрываем и получаем то же самое. В итоге 12$
Или я не прав в расчетах?
CloseToAlgoTrading,
если вы торгуете лимитками, то стоя по разным сторонам спреда, работаете ММ и забираете спред.
Если из теоретической проблемы снизойти до практики, то мне сложно представить, чтобы стратегии получали одновременно разнонаправленные сигналы.
Дмитрий Овчинников, с этим я согласен… однако в данном случае меня больше техническая сторона вопроса интересует, поэтому проблему я именно с теоретической позиции описал
CloseToAlgoTrading,
да нет там никакой технической стороны, работайте в каждом алгоритме только со своими ордерами/позициями и никаких проблем. Максимум во что можно упереться на неликвидах при различном типе заявок это в такую проблему: https://smart-lab.ru/blog/971378.php
И то это легко лечится на макро-уровне.
У меня архитектура такая, что стратегия-TF-всеТикеры — сигналы на исполнение брокеру в одно время улетают (последовательно, но есть момент времени где я уже вижу все сигналы). А вот соседние такие же комбинации, например, другая стратегия — они уже «сами по себе» и нигде нету участка где мы ждём отстающих. Теоретически я могу ждать пока все подтянутся и дальше какую угодно логику натягивать, в т.ч. сальдировать и выводить на рынок только разницу, но в этом случае либо надо ждать самых медленных ну либо ждать какое-то время в которое N% сигналов укладывается, уложившихся сводить, остальные без сведения. В общем в любом случае «ждать» — это какие-то доп. расходы (на проскальзывании), скомпенсирует ли оно излишние комиссии — долей таких перекрытий определяется. У меня пока, вроде, не особо актуально.
Replikant_mih, ждать это как бы изначально не вариант, но как вы сами указали все зависит от издержек… как я выше описал, мне видится наверное самый простой и оптимальный вариант это объединять стратегии по типу и исполнения и таймфрейму. В этом случае все более менее просто…
Но если переходить на торговлю по потоку ордеров то уже не все так однозначно…
ак я выше описал, мне видится наверное самый простой и оптимальный вариант это объединять стратегии по типу и исполнения и таймфрейму. В этом случае все более менее просто…
Не знаю, как это работает и точно не уверен, про что это), в моей архитектуре это тоже будет означать «ждать». В любом случае во моем TODO листе этот механизм не приоритет). Но послушать любопытно в любом случае).
Про один таймфрейм (M1) и унифицированное исполнение (лимитки) уже выше поминали. Все страты на одном тикере не сами выставляют ордера, а отправляют хочухи {цена, объем, знак} на следующий бар в общий котел. Там вычисляется общая позиция в стакане, из нее вычитается текущая позиция, сначала накатываются отмены заявок, потом добавления.
Код интернализации действительно срабатывает очень редко, он кстати на заставке профиля :). Но сведение заявок от десятков страт к 1-2 транзакциям полезно каждый день, без него брокер бы меня давно придушил за к-во транзакций/сек.
Внутри бара исполнение еще много чего делает, на практике реакция на изменение спреда много раз в минуту. Но для стратегий время нарезано по минутам, чаще они менять мнение не могут. При совершении трейдов по ордерам промежуточный слой раздает позиции по стратегиям, в справедливых пропорциях и с учетом реальной цены трейда.
По каждой стратегии на основе этих виртуальных трейдов независимо считаются все метрики — профит, ДД текущий/максимальный, рекавери, профит фактор, средний трейд и т.д. Может быть так, что одна страта в лонг, другая там же в шорт. Внутри робота бурлят страсти, а на бирже общая поза 0.
Разнонаправленные позы бывают нередко, но вероятность того, что зеркальные стратегии примут решение встать в разные стороны именно таки на одном и том же баре, околоноля. Если такое происходит, то даже в лог 1 уровня пишется запись типа «охнихренасебе случай»
имхо проблема надумана… нет такой проблемы вообще...
маркет ордера исполняются в порядке очереди и мнгновенно,
а лимитники так вообще проблем нет на покупку ставишь в бид а на продажу в аск
даже если возникнет конфликт, то он разрешится автоматически на следующей свече
ves2010, ну отчего же надумана… у меня есть реальный кейс. Сейчас он реализован как одна стратегия но их на самом деле две… стратегии на долгий срок…
Суть такова что две стратегии работают на одном и том же наборе (снп500) и выбирают активы примерно по одному и тому же принципу… и вот в моменты ребалансировки часто получается что в одной модели позиция увеличивается а в другой уменьшается…
Следовательно нет смысла выводить два ордера брокеру, а просто пересчитать разницу и вывести один ордер… куда более интересный вариант возникает если использовать разные варианты исполнения, скажем адаптивный в середину среда и лимит на открытии рыка..
Но так как это происходит раз в месяц, то это не проблема, но если это будет происходить раз в минуту то тут есть над чем подумать
Если правильно разрабатывать архитектуру алго, то такие вопросы наверное сами решаются в процессе разработки.
Если алго продукт очень большой, то правильней будет, если он состоит из независмых модулей: стратегии, коннекторы, менеджер ордеров, менеджер биржевых данных.
Выше описанная задача решается исключительно в рамках менеджера ордеров. Фактически тут будет зашит конвертер, на входе которого много ордеров, на выходе несколько.
Андрей К, А как разрулить то, что ордера не одномоментно прилетают в этот модуль? Квантовать как-то, типа нарубаем на какие-то равные промежутки времени, кто в эту электричку набился — их сводим, остальные в рамках следующей электрички?
Replikant_mih, тут мы вываливаемся в вопрос, синхронный или асинхронный алго реализован. То есть умудрился ли разраб наделать кучу параллельных потоков, которые пуляют командами в менеджера и думает, что так будет быстрее всего или все сделал в одном потоке.
Если синхронный, то тут же все просто. У тебя страты на обсчет будут вызываться последовательно и последняя будет дергать некий commit, после которого ордер менеджер все начнет переваривать.
Если асинхронный, то тут фантазии нет предела )) Можно твою идею, кстати так биржа реализовала свои алгоритмы в ядре ) По какому то периоду N делать обсчет ордеров.
Мой мозг заточен всегда на самые быстрые оптимальные решения, я бы пошел другим путем. Наверное, я бы сделал, что каждая страта должна ставить флаг, что она сделала расчет. А менеджер бы следил за кол-ом поставленных флагов и по всем выставленным флагам высчитывал общую позу по заявкам. Но надо сказать, что асинхронным методом я бы точно не пошел )
Моя архитектура далека от идеальной), с одной стороны скорость моих стратегий этого и не требует, с другой по чуть-чуть всё равно что-то подкручиваю. Но мне она нравится). И по функционалу и чисто эстетически)).
У меня execution сервис, он принимает на вход сигналы (сигнал — ну типа тикер, объем, направление). Дальше эта хреновина уже брокеру соответствующему это направляет в виде заявки. Этому сервису без разницы кто его дергает, но дергают его стратегии. И стратегии это тоже отдельные приложения). Например, 10 стратегий это 10 запущенных приложений, они берут данные, что-то вычисляют и в ExecutionAPI пуляют набор сигналов. Стратегия за один run может сгенерировать несколько сигналов, но даже они сейчас в ExecutionAPI прилетят последовательно (надо метод для пакетной отправки сделать). В общем стратегически грамотное место чтобы инкапсулировать логику сведения ордеров уже есть). Правда само сведение пока не особо нужно).
Андрей К,
нет такой проблемы у медленных трейдеров. Кирилл, сводящий в 1М таймфрейме сводит по факту единичные случаи в год. И это при том, что у него все стратегии пересчитывают одновременно. Добавить вариативность времени пересчета и даже эти единицы пропадут.
Андрей К,
Давайте представим есть некий набор расчетных модулей (назовем их стратегиями) есть модули которые реализуют исполнение для каждой стратегии. Коммуникация между стратегией и модулем синхронная. Данные пусть будут для простоты [ тикер, количество ]. Т е. Мы имеем
Стратегия _1:1_ исполнитель.
Исполнитель отсылает:
1. Заявки на прямую брокеру
2. Исполнитель отсылает заявки в пул для агрегации
Каждая такая связка отдельный процесс.
При первом варианте все просто, нет никакой возможности сводить позиции внутри.
При втором варианте мы имеем:
[Стратегия_1:1_исполнитель]_n:1_пул
На самом деле взаимосвязь должна быть м: н но пусть буде н:1.
Тут не важно синхронно или асинхронно мы пуляем заявки в пул. Ибо либо он их сразу выполняет либо он ждёт некоторое время (пусть будет настраиваемый параметр T_wait)..
При моментально исполнении мы можем только агрегировать и консолидировать наши заявки по лимитным ордерам, либо по отложенным ордерам, вроде он дей пен и тд.
Андрей К,
В варианте где менеджер следит за выставленными флагами есть одно но… если менеджер опрашивает флаги сам то придется делать это циклично, а это опять таки явная задержка. Если стратегия дёргает метод в менеджере синхронно, то это блокировка других стратегий на время обработки…
В варианте где менеджер следит за выставленными флагами есть одно но… если менеджер опрашивает флаги сам то придется делать это циклично, а это опять таки явная задержка
это мы сейчас вываливаемся в тему синхронизации данных, где и надо решить задачу узкого горлышка. В любых асинхронных задачах, вопрос синхронизации является узким горлышком.
что я понял из ваших комментов: куча разного кода в разных модулях имееет асинхронный доступ к пулу, который управляет заявками.
Я бы начал тестить модель «много писателей, один читатель». В данном случае, куча стратегий будет писать в одну и туже 32-х/64-х битную переменную, каждая в свой бит. (первая страта в 0 бит, вторая страта в 1 бит, третья страта в 2 бит и тд..)… тогда пулу не надо опрашивать каждую страту, ему только надо атомарно зачитать эту переменную и сравнить ее с конкретным значением (например если у вас 16 страт, то нужно сделать сравнение strategy_flags == 0xFF)
получается, когда вы получили новый котир/новый тик/новую свечу текущего таймфрема, ваши страты сделали расчет, а пул в этот момент следит за битными флагами.
это конечно если все позволит язык. Если вдруг это на qlua, даже не знаю, как это там все решать
Андрей К, с флагами это был ваш вариант...
В моем я предлагалюслать иветы с данными и да много писателей один читатель.
Просто когда я размышляю о данной проблеме… я что то прихожу к выводу что для оптимального решения надо в ручную группировать стратегии по некоторым признакам и как то оптимально высчитывать время которое нужно на консолидацию заявок, что бы выигрыш от всего этого окупал бы вложенное время
Лучше торговать одну стратегию сайзом 10, чем 100 стратегий сайзом 0,1.
Если стратегий разные и «взаимоисключающие» наблюдать как каждую секунду сыпятся ордера +0,1;-0,1+0,1;-0,1… а позиция >50% времени находится у 0.
22022022, это рассуждения вокруг сферического коня в вакууме. Если ваши стратегии что-то полезное делают а не монетку подбрасывают, то не будет там ни шевеления каждый такт, ни среднего 0 по суммированию ненулевых позиций.
Тредер, Почему 20? Прогноз вроде около 10ти. Потом там гэп не закрыт с конца сентября, да и просадка была за 25%, тренд медвежий, хотя движение цены в деталях не смотрел.
таймфрейм — один, самый мелкий
Если прям невмоготу, создайте второй портфель с маркет исполнением, там встречка не парит.
это мифы. @Кирилл Гудков интернализирует внутри себя. За год по-моему на 50 копеек наэкономил.
Т.е. одна стратегия берет 100 акций по цене 100.05 вторая в это же время продает по 100.00. То что можно было бы не выводить в рынок и перекрыть открывается и мы тратим 5$ на спред + скажем 0.5$ за каждую операцию (т.е 0.5$х2=1$)… далее мы эти обе позиции закрываем и получаем то же самое. В итоге 12$
Или я не прав в расчетах?
если вы торгуете лимитками, то стоя по разным сторонам спреда, работаете ММ и забираете спред.
Если из теоретической проблемы снизойти до практики, то мне сложно представить, чтобы стратегии получали одновременно разнонаправленные сигналы.
да нет там никакой технической стороны, работайте в каждом алгоритме только со своими ордерами/позициями и никаких проблем. Максимум во что можно упереться на неликвидах при различном типе заявок это в такую проблему: https://smart-lab.ru/blog/971378.php
И то это легко лечится на макро-уровне.
Послушаю в сторонке).
У меня архитектура такая, что стратегия-TF-всеТикеры — сигналы на исполнение брокеру в одно время улетают (последовательно, но есть момент времени где я уже вижу все сигналы). А вот соседние такие же комбинации, например, другая стратегия — они уже «сами по себе» и нигде нету участка где мы ждём отстающих. Теоретически я могу ждать пока все подтянутся и дальше какую угодно логику натягивать, в т.ч. сальдировать и выводить на рынок только разницу, но в этом случае либо надо ждать самых медленных ну либо ждать какое-то время в которое N% сигналов укладывается, уложившихся сводить, остальные без сведения. В общем в любом случае «ждать» — это какие-то доп. расходы (на проскальзывании), скомпенсирует ли оно излишние комиссии — долей таких перекрытий определяется. У меня пока, вроде, не особо актуально.
Но если переходить на торговлю по потоку ордеров то уже не все так однозначно…
Не знаю, как это работает и точно не уверен, про что это), в моей архитектуре это тоже будет означать «ждать». В любом случае во моем TODO листе этот механизм не приоритет). Но послушать любопытно в любом случае).
Про один таймфрейм (M1) и унифицированное исполнение (лимитки) уже выше поминали. Все страты на одном тикере не сами выставляют ордера, а отправляют хочухи {цена, объем, знак} на следующий бар в общий котел. Там вычисляется общая позиция в стакане, из нее вычитается текущая позиция, сначала накатываются отмены заявок, потом добавления.
Код интернализации действительно срабатывает очень редко, он кстати на заставке профиля :). Но сведение заявок от десятков страт к 1-2 транзакциям полезно каждый день, без него брокер бы меня давно придушил за к-во транзакций/сек.
Внутри бара исполнение еще много чего делает, на практике реакция на изменение спреда много раз в минуту. Но для стратегий время нарезано по минутам, чаще они менять мнение не могут. При совершении трейдов по ордерам промежуточный слой раздает позиции по стратегиям, в справедливых пропорциях и с учетом реальной цены трейда.
По каждой стратегии на основе этих виртуальных трейдов независимо считаются все метрики — профит, ДД текущий/максимальный, рекавери, профит фактор, средний трейд и т.д. Может быть так, что одна страта в лонг, другая там же в шорт. Внутри робота бурлят страсти, а на бирже общая поза 0.
Разнонаправленные позы бывают нередко, но вероятность того, что зеркальные стратегии примут решение встать в разные стороны именно таки на одном и том же баре, околоноля. Если такое происходит, то даже в лог 1 уровня пишется запись типа «охнихренасебе случай»
маркет ордера исполняются в порядке очереди и мнгновенно,
а лимитники так вообще проблем нет на покупку ставишь в бид а на продажу в аск
даже если возникнет конфликт, то он разрешится автоматически на следующей свече
Суть такова что две стратегии работают на одном и том же наборе (снп500) и выбирают активы примерно по одному и тому же принципу… и вот в моменты ребалансировки часто получается что в одной модели позиция увеличивается а в другой уменьшается…
Следовательно нет смысла выводить два ордера брокеру, а просто пересчитать разницу и вывести один ордер… куда более интересный вариант возникает если использовать разные варианты исполнения, скажем адаптивный в середину среда и лимит на открытии рыка..
Но так как это происходит раз в месяц, то это не проблема, но если это будет происходить раз в минуту то тут есть над чем подумать
Если правильно разрабатывать архитектуру алго, то такие вопросы наверное сами решаются в процессе разработки.
Если алго продукт очень большой, то правильней будет, если он состоит из независмых модулей: стратегии, коннекторы, менеджер ордеров, менеджер биржевых данных.
Выше описанная задача решается исключительно в рамках менеджера ордеров. Фактически тут будет зашит конвертер, на входе которого много ордеров, на выходе несколько.
Если синхронный, то тут же все просто. У тебя страты на обсчет будут вызываться последовательно и последняя будет дергать некий commit, после которого ордер менеджер все начнет переваривать.
Если асинхронный, то тут фантазии нет предела )) Можно твою идею, кстати так биржа реализовала свои алгоритмы в ядре ) По какому то периоду N делать обсчет ордеров.
Мой мозг заточен всегда на самые быстрые оптимальные решения, я бы пошел другим путем. Наверное, я бы сделал, что каждая страта должна ставить флаг, что она сделала расчет. А менеджер бы следил за кол-ом поставленных флагов и по всем выставленным флагам высчитывал общую позу по заявкам. Но надо сказать, что асинхронным методом я бы точно не пошел )
Спасибо за ответ :).
Моя архитектура далека от идеальной), с одной стороны скорость моих стратегий этого и не требует, с другой по чуть-чуть всё равно что-то подкручиваю. Но мне она нравится). И по функционалу и чисто эстетически)).
У меня execution сервис, он принимает на вход сигналы (сигнал — ну типа тикер, объем, направление). Дальше эта хреновина уже брокеру соответствующему это направляет в виде заявки. Этому сервису без разницы кто его дергает, но дергают его стратегии. И стратегии это тоже отдельные приложения). Например, 10 стратегий это 10 запущенных приложений, они берут данные, что-то вычисляют и в ExecutionAPI пуляют набор сигналов. Стратегия за один run может сгенерировать несколько сигналов, но даже они сейчас в ExecutionAPI прилетят последовательно (надо метод для пакетной отправки сделать). В общем стратегически грамотное место чтобы инкапсулировать логику сведения ордеров уже есть). Правда само сведение пока не особо нужно).
нет такой проблемы у медленных трейдеров. Кирилл, сводящий в 1М таймфрейме сводит по факту единичные случаи в год. И это при том, что у него все стратегии пересчитывают одновременно. Добавить вариативность времени пересчета и даже эти единицы пропадут.
Давайте представим есть некий набор расчетных модулей (назовем их стратегиями) есть модули которые реализуют исполнение для каждой стратегии. Коммуникация между стратегией и модулем синхронная. Данные пусть будут для простоты [ тикер, количество ]. Т е. Мы имеем
Стратегия _1:1_ исполнитель.
Исполнитель отсылает:
1. Заявки на прямую брокеру
2. Исполнитель отсылает заявки в пул для агрегации
Каждая такая связка отдельный процесс.
При первом варианте все просто, нет никакой возможности сводить позиции внутри.
При втором варианте мы имеем:
[Стратегия_1:1_исполнитель]_n:1_пул
На самом деле взаимосвязь должна быть м: н но пусть буде н:1.
Тут не важно синхронно или асинхронно мы пуляем заявки в пул. Ибо либо он их сразу выполняет либо он ждёт некоторое время (пусть будет настраиваемый параметр T_wait)..
При моментально исполнении мы можем только агрегировать и консолидировать наши заявки по лимитным ордерам, либо по отложенным ордерам, вроде он дей пен и тд.
Если T_wait != 0 то мы можем это делать с любым типом заявок, но нам придется платить тем что мы будем терять в скорости.
В итоге нам придется в любом случае как-то аллокировать стратегия к пулам, т.е. группировать их по какой-то логике…
ЗЫ. Коммуникацию к пулу лучше делать асинхронной в любом случае.
В варианте где менеджер следит за выставленными флагами есть одно но… если менеджер опрашивает флаги сам то придется делать это циклично, а это опять таки явная задержка. Если стратегия дёргает метод в менеджере синхронно, то это блокировка других стратегий на время обработки…
это мы сейчас вываливаемся в тему синхронизации данных, где и надо решить задачу узкого горлышка. В любых асинхронных задачах, вопрос синхронизации является узким горлышком.
что я понял из ваших комментов: куча разного кода в разных модулях имееет асинхронный доступ к пулу, который управляет заявками.
Я бы начал тестить модель «много писателей, один читатель». В данном случае, куча стратегий будет писать в одну и туже 32-х/64-х битную переменную, каждая в свой бит. (первая страта в 0 бит, вторая страта в 1 бит, третья страта в 2 бит и тд..)… тогда пулу не надо опрашивать каждую страту, ему только надо атомарно зачитать эту переменную и сравнить ее с конкретным значением (например если у вас 16 страт, то нужно сделать сравнение strategy_flags == 0xFF)
получается, когда вы получили новый котир/новый тик/новую свечу текущего таймфрема, ваши страты сделали расчет, а пул в этот момент следит за битными флагами.
это конечно если все позволит язык. Если вдруг это на qlua, даже не знаю, как это там все решать
В моем я предлагалюслать иветы с данными и да много писателей один читатель.
Просто когда я размышляю о данной проблеме… я что то прихожу к выводу что для оптимального решения надо в ручную группировать стратегии по некоторым признакам и как то оптимально высчитывать время которое нужно на консолидацию заявок, что бы выигрыш от всего этого окупал бы вложенное время
Лучше торговать одну стратегию сайзом 10, чем 100 стратегий сайзом 0,1.
Если стратегий разные и «взаимоисключающие» наблюдать как каждую секунду сыпятся ордера +0,1;-0,1+0,1;-0,1… а позиция >50% времени находится у 0.