Один разработчик поделился, как создать торгового бота для Polymarket, который ловит ценовые колебания на рынке BTC с интервалом 15 минут и за несколько дней превращает 1 000 долларов в 1 869 долларов, при этом доходность по тестам составила 86%. В статье подробно описывается логика построения бота, методы бэктестирования и их ограничения.
(Предыстория: лидер предсказательных рынков Polymarket объявил о создании собственного L2, исчезла ли козырная карта Polygon?)
(Дополнительный фон: как с помощью арбитража на Polymarket добиться годовой доходности 40%?)
Содержание статьи
Несколько недель назад я решил создать собственного бота для Polymarket. Полная версия заняла у меня несколько недель.
Я готов вложить эти усилия, потому что на Polymarket действительно есть уязвимости в эффективности, хотя на рынке уже есть некоторые боты, использующие эти недостатки для получения прибыли, но их всё ещё недостаточно, и возможностей этого рынка гораздо больше, чем количество ботов.
Логика этого бота основана на моей ранее вручную реализованной стратегии. Для повышения эффективности я автоматизировал её. Бот работает на рынке «BTC 15 минут UP/DOWN».
Бот управляется программой мониторинга в реальном времени, которая автоматически переключается на текущий раунд BTC с интервалом 15 минут, передавая через WebSocket лучшие цены покупки/продажи (best bid/ask), отображая фиксированный интерфейс терминала и позволяя управлять им с помощью текстовых команд.
В ручном режиме можно размещать ордера напрямую.
buy up / buy down : покупка на определённую сумму в долларах.
buyshares up / buyshares down : покупка точного количества акций с использованием лимитных (LIMIT) + GTC (действителен до отмены) ордеров, по текущей лучшей цене продажи (best ask).
В автоматическом режиме реализован цикл из двух этапов (two-leg).
Первый этап — он наблюдает за ценой в течение windowMin минут после начала каждого раунда. Если одна из сторон падает достаточно быстро (за примерно 3 секунды снижение достигает movePct), запускается «первый этап (Leg 1)», при котором покупается падающая сторона.
После завершения Leg 1 бот больше не покупает ту же сторону. Он ждёт «второй этап (Leg 2, хеджирование)» и активирует его только при выполнении условия: leg1EntryPrice + oppositeAsk <= sumTarget.
Когда условие выполнено, он покупает противоположную сторону. После завершения Leg 2 цикл заканчивается, и бот возвращается в режим наблюдения, ожидая следующего сигнала о падении с теми же параметрами.
Если в процессе цикла меняется раунд, бот отменяет текущий цикл и при следующем запуске использует те же настройки.
Параметры автоматического режима: auto on [sum=0.95] [move=0.15] [windowMin=2]
Логика бота очень проста: ждёт сильного падения, покупает ту сторону, которая упала, затем ждёт стабилизации цены и хеджирует, покупая противоположную сторону, при этом гарантируя, что: priceUP + priceDOWN < 1.
Но эта логика требует проверки. Действительно ли она работает в долгосрочной перспективе? И важнее — у бота много параметров (количество акций, сумма, процент движения, длительность окна). Какая комбинация параметров оптимальна и максимизирует прибыль?
Моя первая идея — запустить бота в реальной торговле на неделю и наблюдать за результатами. Но это занимает много времени и позволяет протестировать только один набор параметров, а мне нужно проверить много.
Вторая идея — использовать исторические данные из Polymarket CLOB API для бэктестирования. К сожалению, для рынка BTC 15 минут UP/DOWN исторические данные постоянно возвращают пустой набор. Нет данных о ценовых движениях (ticks), и бэктест не может обнаружить «примерно 3-секундное падение», чтобы активировать Leg 1. В результате — ноль циклов и ROI 0%, независимо от параметров.
После дальнейших исследований я обнаружил, что другие пользователи сталкиваются с той же проблемой при получении исторических данных для некоторых рынков. Проверил рынки, которые действительно возвращают данные, и пришёл к выводу: для этого конкретного рынка исторические данные вообще не сохраняются.
Из-за этого единственный надёжный способ бэктестировать стратегию — во время работы бота записывать в реальном времени лучшие цены продажи (best-ask), создавая собственный набор данных.
Записчик делает снимки (snapshots), сохраняемые на диск, содержащие:
Затем «записанный бэктест (recorded backtest)» воспроизводит эти снимки и применяет ту же автоматическую логику, что и в реальности. Это обеспечивает получение высокочастотных данных, необходимых для обнаружения падений и условий хеджирования.
За 4 дня я собрал 6 ГБ данных. Можно было собрать больше, но этого достаточно для тестирования различных наборов параметров.
Я начал тестировать эти параметры:
Также я применил фиксированные комиссии 0.5% и спред 2%, чтобы оставить сценарий консервативным.
Результаты бэктеста — ROI 86%, за несколько дней начальный капитал вырос с $1,000 до $1,869.
Затем я протестировал более агрессивные параметры:
Результат: через 2 дня ROI составил -50%.
Это ясно показывает, что выбор параметров — ключевой фактор. Он может принести огромную прибыль или привести к серьёзным потерям.
Даже с учётом затрат и спредов, у бэктестирования есть свои ограничения:
Для более консервативной оценки я ввёл правило: если Leg 2 не исполнится до закрытия рынка, Leg 1 считается полностью убыточным (total loss).
Это очень осторожный подход, но он не всегда отражает реальность:
Хотя убытки могут быть переоценены, это даёт представление о «наихудшем сценарии».
Самое важное — бэктест не моделирует влияние крупных ордеров на книгу и привлечение других трейдеров. В реальности ваши ордера могут:
Бэктест предполагает, что вы — чистый поставщик ликвидности (price taker), без влияния на рынок.
Также он не моделирует лимиты скорости (rate limits), ошибки API, отказ ордеров, паузы, тайм-ауты, повторные подключения или пропуски сигналов из-за занятости бота.
Бэктест очень полезен для определения диапазона хороших параметров, но не даёт 100% гарантии, так как некоторые эффекты реального мира не моделируются.
Планирую запускать бота на Raspberry Pi, чтобы не нагружать основной компьютер и обеспечить работу 24/7.
Но есть возможности для улучшения:
Есть, вероятно, и другие оптимизации, которые я пока не обнаружил. Сейчас я учусь Rust, потому что он становится незаменимым языком в Web3-разработке.
#####