Создаем алгоритм маркет-мейкинга на MQL5
Что такое ликвидность
Ликвидность финансовых рынков - это "наполненность" рынка деньгами в виде ордеров и позиций. Это позволяет быстро реализовать акции (или валюты) на большие суммы. Чем выше ликвидность рынка, тем проще продать или купить актив на крупные суммы без существенных потерь на проскальзывании.
Проскальзывание - главное зло крупных игроков: крупнейшие фонды отмечают, что реализовать крупную позицию не так просто, и зачастую сделка закрывается в убыток только из-за потерь на "скольжении" ордеров. Проскальзывание ордеров - это когда сделка открывается по одной цене, а реализуется по другой, отличной от ожидаемой цены. Когда у трейдера всего пара сотен долларов, обычно проблем с ликвидностью не бывает, разве что на совсем неликвидных стаканах третьесортных криптовалют. Но вот когда счет идет на сотни миллионов долларов, тогда позицию сложно открыть и закрыть одномоментно. Это прямо связано с наполненностью рынка ликвидностью.
И ликвидность на рынке заполняется благодаря маркет-мейкерам. Их основная задача - поддерживать ликвидность. Эти участники рынка делают все, чтобы для вас торговля была как можно более плавной, чтобы не было резких разрывов котировок, чтобы и покупатель и продавец всегда получали устраивающие их цены.
На рынке, где нет маркет-мейкера, мы очень часто будем видеть резкие выстрелы цены в одну из сторон, огромные колебания актива, разрывы котировок (гэпы).
Как действует маркет-мейкер, и почему это не "кукловод"?
Многие трейдеры уверены в том, что маркет-мейкер является каким-то кукловодом, манипулятором, который двигает цены туда, куда ему нужно, срывает стопы толпы, разводит толпу на стоп-приказы, и т.п.
На самом деле, маркет-мейкеру совершенно не нужно сливать никакую "толпу". "Толпа" на рынке успешно сливается и сама по себе, благодаря постепенной потере на спреде, комиссии, и свопах.
Что касается сдвигов рынка в нужную сторону, то это тоже не входит в задачи маркет-мейкера. Все, что обязан по своему договору с биржей маркет-мейкер - это предоставить котировку на покупку покупателю, и котировку на продажу продавцу, и заполнить пустой "стакан цен" при необходимости.
Без маркет-мейкеров рынок был бы совершенно другим: мы бы постоянно видели ценовые разрывы, разрывы котировок, наблюдали бы постоянные сквизы в обе стороны, огромные скачки цен в обе стороны. Все это и сегодня можно встретить на тех рынках, где присутствовать маркет-мейкеру невыгодно. К примеру, на многих грошовых акциях США (пенни-сток).
Новые технологии AMM на крипто-рынке
А что если заменить участника смарт-контрактом? То есть, выставить вместо маркет-мейкеров автоматическую систему корректировки спроса и предложения, и общего котирования?
Примерно так появились децентрализованные биржи (DEX), на которых впервые был применен механизм АММ (автоматического маркет-мейкинга). Алгоритм АММ работает через специальный пул ликвидности, используя ресурс участников для сделок между ними, цена и объем обменов всегда будет контролироваться алгоритмом. Это позволяет свести всех продавцов со всеми покупателями, якобы без потерь для участников. На самом деле, на практике на всех DEX есть огромное проскальзывание цены, при большом объеме сделки вы гарантированно потеряете большой процент на обмене токенов.
Не сказать также, что такое нововведение привело к особому очищению рынка от манипуляций, их на DEX полно. Даже сам создатель токена на DEX может запросто запампить свой токен, и обналичить весь пул ликвидности токена.
Как маркет-мейкеры борятся с манипуляциями ценой?
Хоть это и не входит в обязанности маркет-мейкеров, но они часто тушат попытки устроить Pump&Dump в зародыше, когда цены только начинают разгонять нацеленные на мошенничество участники. В эти начальные фазы, маркет-мейкер закидывает игрока, который пытается "по рынку" взвинтить цены вверх, огромными долями лимитных ордеров. Это тушит спрос, и новички в деле пампа очень часто ломают зубы именно об маркет-мейкера. Но если памп хорошо спланирован и осуществляется по плану - наплыв множества рыночных ордеров, мощно двигающих ценник, вынуждает маркет-мейкера на время уйти с рынка.
Когда маркет-мейкеры уходят с рынка?
У большинства маркет-мейкеров в их соглашениях с биржами прописано, что в периоды праздничных дней, периоды аномальной активности, а также периоды выхода важных новостей - они отключают свои алгоритмы и уходят с рынка. Это связано с желанием ММ сохранить свой капитал без потерь.
Уход маркет-мейкера с рынка, мы видим сразу же - по расширенному спреду. Видели, как расширяется спред даже на ECN на мощной новости мирового масштаба? А ведь привычная узость спреда достигается усилиями маркет-мейкеров. Поэтому без них нас в первую очередь, ждут очень плохие торговые условия. Это и широкие спреды, и большие проскальзывания цен, и внезапные провалы и прострелы цены - все прелести дикого рынка.
Что такое inventory risk у маркет-мейкера?
Многим думается, что маркет-мейкер вообще не несет никаких рисков. Но это не так. Основной риск маркет-мейкера - это риск инвентаризации, или inventory risk. Этот риск заключается в том, что возможен резкий набор позиции в одну сторону, без возможности ее реализовать и заработать на спреде. К примеру, когда оголтелая толпа продает и продает актив, а маркет-мейкер вынужден выкупать все предложение, цена идет в минус, загоняя ММ в убытки.
Компании пытаются избежать этого риска с помощью использования специальных формул центровки спреда и определения оптимальной цены для покупки и реализации. Но это не всегда достижимо: даже если цена не оптимальна, твоя работа в поставке ликвидности на рынок, и ты должен делать эту работу, даже если временно работаешь себе в убыток.
Разбираем отчетность крупнейшего маркет-мейкера планеты - компании Кена Гриффина
Анализируя активность крупнейшего маркет-мейкера в мире — компании Citadel Securities, основанной Кеном Гриффином — становится ясно, насколько важна их роль на финансовых рынках.
Отчеты компании говорят о впечатляющем влиянии: 7 из 10 сделок на американском фондовом рынке зависят от ликвидности, которую предоставляет этот маркет-мейкер. Такая активность свидетельствует о значимой функции Citadel Securities в поддержании стабильности и доступности ликвидности на данном рынке.
Чтобы оценить масштаб влияния компании Гриффина, можно упомянуть, что ежедневно через их алгоритмы проходит около 900 миллионов лотов акций США. Этот значительный объем торгов отражает высокую активность и влияние компании на американской фондовой бирже.
Кстати, очень интересна эволюция Кена Гриффина, который переходит от направленной торговли к маркет-мейкингу. Компания Гриффина очень активно экспансирует на мировые рынки, в последние годы активно осваивая азиатские биржи и предоставляя ликвидность там. Возможно, при иных обстоятельствах, она также могла бы поставлять ликвидность и на Московской бирже.
Что касается маркет-мейкеров на фондовом рынке РФ, то главную скрипку тут играет БрокерКредитСервис, или по-простому, БКС, почти все высоколиквидные акции первого эшелона котируются именно этой компанией. Также в качестве мейкеров работают Финам, АЛОР, и не совсем известный мне банк Держава.
Каких-то специфических отчетов о прибылях и убытках они не выпускают, как и их западные коллеги. Можно лишь отметить явную тенденцию к тому, что в будущем появятся отдельные юридические лица, которые будут по своему уставу заниматься только маркет-мейкингом, как к примеру, подразделение Гриффина.
Заготовка эксперта - маркетмейкера
Итак, с теорией мы разобрались. Пришло время для старта практики по созданию советника - маркет-мейкера! Конечно, наш алгоритм будет совсем простым и элементарным, мы не будем пытаться выстроить спредовую торговлю по специальным формулам, которые иногда описывают в своих журналах кванты.
Вместо этого, мы реализуем самый простой алгоритм, который будет держать два постоянно открытых лимитных ордера - выше текущей цены на продажу (sell limit),и ниже текущей цены (buy limit).
Самая простая реализация маркет-мейкинга на MQL5
Разберем код нашего алгоритма. Заглавная часть кода. Этот раздел устанавливает основные параметры стратегии, такие как размер лота, уровни прибыли, магический номер советника, а также выбранные валютные пары для торговли и прочее. :
//+------------------------------------------------------------------+ //| MarketMaker.mq5 | //| Copyright 2023, Evgeniy Koshtenko | //| | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, Evgeniy Koshtenko" #property link "https://www.mql5.com/ru/users/koshtenko" #property version "1.00" #include <Trade\Trade.mqh> // Подключаем торговый класс CTrade //--- входные параметры input double Lots = 0.1; // лот input double Profit = 0.1; // прибыль input double BProfit = 11; // прибыль покупок input double SProfit = 11; // прибыль продаж input int StopLoss = 0; // стоп лосс input int TakeProfit = 0; // тейк профит input int Count = 5; // число ордеров input int Delta = 55; // дельта input int Magic = 123; // магик input bool BuyLimit = 1; // Buy Limit input bool SellLimit = 1; // Sell Limit input string Symbol1 = "EURUSD"; input string Symbol2 = "GBPUSD"; input string Symbol3 = "USDCHF"; input string Symbol4 = "USDJPY"; input string Symbol5 = "USDCAD"; input string Symbol6 = "AUDUSD"; input string Symbol7 = "NZDUSD"; input string Symbol8 = "EURGBP"; input string Symbol9 = "CADCHF"; input int MaxOrders = 20; // Макс. число ордеров CTrade trade; datetime t=0; int delta=0;
Она включает в себя базовые настройки, такие как дельту между ордерами, прибыль на закрытие (общую, прибыль покупок и прибыль продаж), мэджик-номер советника, импорт торговой библиотеки, а также выбор валютных пар для торговли и ограничение числа ордеров.
Функции инициализации и деинициализации в целом стандартны. Функция OnInit() вызывается при запуске советника, а OnDeinit() при его завершении. OnInit() задает магический номер советника и таймер для работы торговой функции:
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- // Установка таймера с разрешением 10000 миллисекунд (10 секунд) EventSetMillisecondTimer(100000); trade.SetExpertMagicNumber(Magic); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) {// Отключение таймера EventKillTimer(); Comment(""); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+
Вот функции подсчета открытых ордеров и открытых позиций. CountOrders и CountTrades занимаются подсчетом открытых ордеров и позиций для определенного символа с учетом магического номера советника.
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CountOrders(string symbol, ENUM_ORDER_TYPE orderType) { int count = 0; for(int i = OrdersTotal()-1; i >= 0; i--) { ulong ticket = OrderGetTicket(i); if(!OrderSelect(ticket)) { continue; } if(OrderGetInteger(ORDER_TYPE) != orderType) { continue; } if(PositionGetString(POSITION_SYMBOL) != symbol || PositionGetInteger(POSITION_MAGIC) != Magic) { continue; } count++; } return count; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CountTrades(string symbol, ENUM_POSITION_TYPE type) { int count = 0; for(int i=PositionsTotal()-1; i>=0; i--) { ulong ticket=PositionGetTicket(i); if(!PositionSelectByTicket(ticket)) { continue; } if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type) { count++; } } return count; }
Вот функции удаления ордеров, подсчета прибыли, и закрытия ордеров. DelOrder удаляет все ордера для определенного символа, используя магический номер. AllProfit вычисляет общую прибыль или прибыль от сделок на покупку/продажу для конкретного символа с учетом магического номера.
//+------------------------------------------------------------------+ //| Position Profit | //+------------------------------------------------------------------+ double AllProfit(string symbol, int positionType = -1) { double profit = 0; for(int i = PositionsTotal()-1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(!PositionSelectByTicket(ticket)) { continue; } if(PositionGetString(POSITION_SYMBOL) != symbol || PositionGetInteger(POSITION_MAGIC) != Magic) { continue; } if(positionType != -1 && PositionGetInteger(POSITION_TYPE) != positionType) { continue; } profit += PositionGetDouble(POSITION_PROFIT); } return profit; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseAll(string symbol, int positionType = -1) { for(int i = PositionsTotal()-1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(!PositionSelectByTicket(ticket)) { continue; } if(PositionGetString(POSITION_SYMBOL) != symbol || PositionGetInteger(POSITION_MAGIC) != Magic) { continue; } if(positionType != -1 && PositionGetInteger(POSITION_TYPE) != positionType) { continue; } trade.PositionClose(ticket); } }
И наконец, две главные функции - функция торговли и тиковая функция. Trade отвечает за размещение лимитных ордеров на покупку и продажу, учитывая заданные параметры. OnTimer вызывает функцию Trade для торговли выбранным символом и отображает информацию о прибыли для этого символа.
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void Trade(string symb) { double sl = 0, tp = 0; double pr=0; double Bid=SymbolInfoDouble(symb,SYMBOL_BID); if(AllProfit(symb)>Profit && Profit>0) CloseAll(symb); if(AllProfit(symb)>Profit && Profit>0) CloseAll(symb); if(AllProfit(symb,0)>BProfit && BProfit>0) CloseAll(symb,0); for(int i=1; i<=Count; i++) { if(BuyLimit) { if (StopLoss > 0) sl = NormalizeDouble(Bid - (StopLoss) * Point(), _Digits); if (TakeProfit > 0) tp = NormalizeDouble(Bid + (TakeProfit) * Point(), _Digits); pr=NormalizeDouble(Bid-(Delta+Step)*_Point*i,_Digits); trade.BuyLimit(Lots,pr,symb,sl, tp,0,0,""); } if(SellLimit) { if (StopLoss > 0) sl = NormalizeDouble(Bid + (_Point * StopLoss) * Point(), _Digits); if (TakeProfit > 0) tp = NormalizeDouble(Bid - (_Point * TakeProfit) * Point(), _Digits); pr=NormalizeDouble(Bid+(Delta+Step)*_Point*i,_Digits); trade.SellLimit(Lots,pr,symb,sl, tp,0,0,""); } } } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTimer() { DelOrder(); Trade(Symbol1); Trade(Symbol2); Trade(Symbol3); Comment("\n All Profit: ",AllProfit(Symbol1), "\n Buy Profit: ",AllProfit(Symbol1,0), "\n Sell Profit: ",AllProfit(Symbol1,1)); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+--------+
Вот в целом и весь код данного простого эксперта.
Результаты тестирования
Итак, запускаем советника с дефолтными настройками в тестере. Вот что советник выдал на парах EURUSD, GBPUSD, EURGBP, USDJPY, EURJPY, за период с 1 февраля 2023 по 18 февраля 2024:
Просадки по отношению к прибылям очень большие, просадка по средствам в целом больше годовой прибыли. Советник ведет себя не сильно иначе, чем себя ведут обычные сеточные советники. Вот статистика тестирования:
Приходим к выводу, что данный советник никак не окупает свои риски. Как и любой алгоритм без стопа, он является бомбой замедленного действия. Несмотря на отсутствие сливов, не факт что на рынке не повторится история с обвалом валют на 10-15% за сутки. Лично меня последние четыре года научили, что на рынке возможно абсолютно все, и даже самые невероятные сценарии могут реализоваться, поэтому боевой советник должен быть готов ко всему. Данный эксперт не подходит под мои критерии оценки, поэтому я и решил его опубликовать.
Заключение
Итак, мы с вами создали пример простейшего алгоритма маркет-мейкера. Конечно, этот пример иллюстративный и совсем простой — понятно, что так на рынке уже давно не работает ни один маркет-мейкер. Сегодня их алгоритмы идут в ногу со временем, используют машинное обучение и нейросети, используют глубокое обучение на основе потоковых данных из стакана ордеров, учитывают множество переменных и характеристик цены. Никто уже не размещает ордера просто вокруг цены — это чревато попаданием в inventory risk. В будущем возможно, будет разумно провести эксперимент с созданием маркет-мейкера на машинном обучении, который будет сам определять оптимальную дельту между ордерами.- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Где должны были бы генерироваться вируальные рыночные и лимитные ордера толпы, с разными вероятностями, а ты всесь такой ММ - подтверждаешь, или опровергаешь мифы про маркетмейкеров, своим взаимодействием с этой виртуальностью.
И выясняешь, тем самым - "кукловод", или - нет. Так сказать - на собственном, пусть и виртуальном, опыте.
Как-то давно в одном из неликвидных фьючей сам был "маркетмейкером" - до четверти всех сделок были мои. Хотя были там и мощные заявки от настоящего маркетоса, но в отдалении от актуальных цен.
И, вот, что помешает ММ самому устроить Pump&Dump, как и что-нибудь иное, дабы не быть, как минимум - в убытках, а как максимум - в нуле?! В тех случаях, когда ему нужно ту ликвидность, что они залили в рынок вывести в +.
Ведь, если твой контрагент ММ, то это означает, что он вошёл в рынок.
А если у него во флете образовался дисбаланс спроса и предложения, то он его компенсирует своей ликвидностью на размер дисбаланса - входит в рынок .
И угадай - куда цена пойдёт - против ММ, или в сторону его ордеров?
И вообще, если какая-то компания, или банк, или частное лицо является ММ, то из какой такой мотивации благотворительности?!
Не смешите тапочки ММ.
Функии ММ - делать привлекательной цену для мелкого спекулянта, путём сужения спреда.
Далее - обеспечивать ликвидность(что, в свою очередь, снижает волатильность ), в том числе и для мелкого спекулянта.
Далее - квантование цены(стабилизация цены) - выброс мелкого спекулянта с рынка.
Как ни странно, "выброс мелкого спекулянта" и есть "стабилизация цены". Ну, как раз, как в примере с флетом и дисбалансом в нём.
ММ использовал, на основании "сужения спреда" - "привлекательности цены", свою ликвидность в флете, с целью компенсировать дисбаланс. Если бы не использовал, то цена бы вышла из флета - была бы более волатильна. То есть, он сдержал свой ликвидностью волатильность. Далее он выводит цену за пределы флета, или ложным движением и возвратом в флет , или с продолжением - без возврата. Что сносит стопы и тех, чьим контрагентом он был и тех, кто стоял против его ордеров. Он выходит с рынка - с прибылью, они - с убытком. Он, на данном шаге, не выходит с большой прибылью, он, так скажем - скальпер(на этом этапе). И его тейки, это стопы его контрагентов.
Но выводит он цену за границы флета не так резко, как она бы вылетала без него, а с возвратом к границам флета и отскоками, или с возвращением в флет...
Собственно... ММ и организует флет, вливая свою ликвидность и сдерживая движение цены.)))
Но, дело в том, что он торгует своей ликвидностью со всеми типами игроков.
Так вот, если узкие спреды и ликвидность привлекают мелкого спекулянта, которого потом и выбрасывают с рынка. То зачем нужен ММ?!
Какова, вообще, по вашему, его цель?
"Хоть это и не входит в обязанности маркет-мейкеров, но они часто тушат попытки устроить Pump&Dump в зародыше, когда цены только начинают разгонять нацеленные на мошенничество участники. В эти начальные фазы, маркет-мейкер закидывает игрока, который пытается "по рынку" взвинтить цены вверх, огромными долями лимитных ордеров. Это тушит спрос, и новички в деле пампа очень часто ломают зубы именно об маркет-мейкера. Но если памп хорошо спланирован и осуществляется по плану - наплыв множества рыночных ордеров, мощно двигающих ценник, вынуждает маркет-мейкера на время уйти с рынка."
И, вот, что помешает ММ самому устроить Pump&Dump, как и что-нибудь иное, дабы не быть, как минимум - в убытках, а как максимум - в нуле?! В тех случаях, когда ему нужно ту ликвидность, что они залили в рынок вывести в +.
Ведь, если твой контрагент ММ, то это означает, что он вошёл в рынок.
А если у него во флете образовался дисбаланс спроса и предложения, то он его компенсирует своей ликвидностью на размер дисбаланса - входит в рынок .
И угадай - куда цена пойдёт - против ММ, или в сторону его ордеров?
И вообще, если какая-то компания, или банк, или частное лицо является ММ, то из какой такой мотивации благотворительности?!
Не смешите тапочки ММ.
Функии ММ - делать привлекательной цену для мелкого спекулянта, путём сужения спреда.
Далее - обеспечивать ликвидность(что, в свою очередь, снижает волатильность ), в том числе и для мелкого спекулянта.
Далее - квантование цены(стабилизация цены) - выброс мелкого спекулянта с рынка.
Как ни странно, "выброс мелкого спекулянта" и есть "стабилизация цены". Ну, как раз, как в примере с флетом и дисбалансом в нём.
ММ использовал, на основании "сужения спреда" - "привлекательности цены", свою ликвидность в флете, с целью компенсировать дисбаланс. Если бы не использовал, то цена бы вышла из флета - была бы более волатильна. То есть, он сдержал свой ликвидностью волатильность. Далее он выводит цену за пределы флета, или ложным движением и возвратом в флет , или с продолжением - без возврата. Что сносит стопы и тех, чьим контрагентом он был и тех, кто стоял против его ордеров. Он выходит с рынка - с прибылью, они - с убытком. Он, на данном шаге, не выходит с большой прибылью, он, так скажем - скальпер(на этом этапе). И его тейки, это стопы его контрагентов.
Но выводит он цену за границы флета не так резко, как она бы вылетала без него, а с возвратом к границам флета и отскоками, или с возвращением в флет...
Собственно... ММ и организует флет, вливая свою ликвидность и сдерживая движение цены.)))
Но, дело в том, что он торгует своей ликвидностью со всеми типами игроков.
Так вот, если узкие спреды и ликвидность привлекают мелкого спекулянта, которого потом и выбрасывают с рынка. То зачем нужен ММ?!
Какова, вообще, по вашему, его цель?
Да, цена пойдет в его сторону. Но резкие пампы и дампы ему тоже не нужны. Попробуйте сами быть ММ на DEX, и увидите, как капитал резко дергается на резких пампах и дампах. Намного выгоднее стабильный флет устраивать, и рубить на спреде, разве нет?