Линия закрытия: часть 1

Линия закрытия: часть 1

Артём Gameleon

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

Итак, передо мной стоит цель: я должен побить линию закрытия. Зачем мне это нужно? Я хочу полностью изменить свою жизнь и перейти на новый финансовый уровень. Чем больше я путешествую по Европе и чем дольше здесь живу, тем выше становится уровень моих потребностей, появляется все больше серьезных и масштабных желаний. У меня в планах получение гражданства высокоразвитой европейской страны, покупка дорогого дома в Европе, а чуть позже – высококлассное образование для детей. Все эти вещи стоят очень дорого. Ставки по линии закрытия выводят финансовые возможности на абсолютно новый уровень, и на сегодняшний день именно в них я вижу возможность изменить жизнь и направить ее в нужное мне русло. В целом, думаю, понятно, зачем мне бить линию закрытия. Вопрос заключается в том, как именно это сделать. И для начала я сел и задумался: а что вообще такое “линия закрытия?”

Букмекерская линия на разных этапах своей жизни несет в себе абсолютно разную информацию. На первом этапе своего существования линия состоит из коэффициентов БК: контора создает линию, выдвигая свой прогноз на матч в вероятностях в виде коэффициентов. Этот отрезок называется линией открытия, и он очень, очень короткий. Уже в первые секунды с момента выхода букмекерского прогноза, то есть, сразу же после открытия линии, профессиональные бетторы делают ставки с помощью ботов, и линия тут же начинает резко и существенно меняться. Постепенно к ним присоединяются другие игроки, которые также начинают делать ставки, своими действиями двигая линию то в одну, то в другую сторону. Дима наглядно показывал в нашем курсе xCourse, как сильно двигает линию каждая ставка, особенно на ранних этапах жизни линии. Каждая ставка, по сути, является мнением отдельного индивида по поводу матча, которое он подкрепляет собственными деньгами. В результате линия к моменту своего закрытия состоит уже не из вероятностей, которые предлагала букмекерская контора – она состоит из вероятностей, которые были спрогнозированы огромным количеством игроков самого разного уровня. 

Мы же хотим побить линию после всех этих событий. Для этого нам необходимо находить такие команды и такие исходы, которые пул игроков в последнее время недооценивает или, наоборот, переоценивает. Любую условную команду, к примеру, Осасуну, пул игроков может в начале сезона недооценивать, в середине сезона – переоценивать, а в конце сезона вновь недооценивать. На протяжении сезона эти периоды недооценивания и переоценивания неоднократно сменяют друг друга. Игра команды улучшилась, а пул еще оценивает ее по прошлым результатам. А может быть, наоборот, показатели команды ухудшились, но пул игроков все еще оценивает ее по прошлому результату. Вот такие команды нас и интересуют.

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

  1. Узнать вероятности исходов линии закрытия, которые отображает мнение пула игроков.
  2. Определить реальные вероятности сыгранного матча.

Перевести оценки игроков в вероятности очень легко: нужно просто разделить единицу на коэффициент линии закрытия для каждого исхода, и мы получим вероятности с учетом маржи. Но это будут вероятности, которые определили сами игроки, нам же нужны еще и реальные вероятности исходов матча. Как рассчитать реальные вероятности исходов? Для этой задачи нам понадобится генератор Монте-Карло, который рассчитывает вероятности исходов на основе xG статистики каждого удара, нанесенного в матче. Я разработал его еще три года назад, поэтому читатели, которые следят за проектом с самого начала, смотрели 5 выпуск влога Триумфатор или проходили курс xCourse, сразу поймут, о чем идет речь. Кто не видел, обязательно посмотрите 5 выпуск Триумфатора (да и все остальные выпуски тоже).

Так вот, для того, чтобы определить реальные вероятности исходов матча, мы должны просто пропустить каждый матч через послематчевый генератор Монте-Карло. Для одного конкретного матча вероятности, разумеется, будут неточными, не стоит списывать со счетов дисперсию. Но вот дистанция из нескольких матчей будет уже более точной, и тогда мы сможем увидеть, какие команды и исходы игроки недооценили, а какие – переоценили. Для этой задачи можно также использовать хорошие статистические инструменты, но об этом мы поговорим уже в следующих постах, а сейчас я покажу вам, какой анализ мне удалось провести и какие результаты я получил на выходе.

На нашем сайте обработано 60 000 футбольных матчей, с которыми мы можем работать. Я написал свой собственный программный код с генератором Монте-Карло в программе Jupyter Notebook, реализовав его таким образом, чтобы в него можно было загрузить Excel файл с ударами каждого матча. Статистики из нашей команды создали для меня один общий файл, в который мы поместили данные для 41 чемпионата.

Он насчитывает 11 692 матча, состоящих из 280 000 ударов.

Процесс выглядит так: я добавляю файл в Jupyter Notebook, далее он берет эти 11 692 матча, прогоняет их через генератор Монте-Карло, рассчитывая вероятности для каждого матча, и объединяет результаты в одну общую базу. Преимущество этого процесса заключается в том, что мне не нужно просчитывать почти 12 000 матчей вручную – теперь у меня есть софт, который выполняет эту задачу. Файл будет обновляться и пополняться, сейчас мне собирают для него данные.

В итоге я получил вот такие результаты:

В первой строчке указан профит по факту, во второй – ROI по факту (оба по линии закрытия Pinnacle). В третьей строчке отмечен ROI, который рассчитал в этих матчах генератор Монте-Карло. Расчет происходит следующим образом: Монте-Карло генерирует матчи и рассчитывает вероятности, которые мы умножаем на коэффициент линии закрытия и получаем тем самым ROI по генератору Монте-Карло. В идеале ROI по факту и ROI по Монте-Карло должны составлять около -4,5% для основных исходов (П1, Ничья, П2) и примерно -3,8% для тоталов. Значения для разных рынков отличаются из-за разной маржи в этих рынках.

Как видите, ROI по факту не сильно отклоняется от значений -4,5% и -3,8%, а с увеличением дистанции цифры еще будут приближаться к нужным значениям. А вот с ROI по Монте-Карло все обстоит гораздо хуже. Давайте выясним, почему же так происходит и что с этим делать.

Почему мы не получили ожидаемых результатов с помощью генератора Монте-Карло? Почему фактический ROI и ROI, рассчитанный Монте-Карло, так сильно отличаются? Для начала давайте разберемся с тоталами.

В таблице вы видите, что ROI на Тотал Меньше вместо -3.8% оказался нулевым, а ROI на Тотал Больше, наоборот, упал до -8,3%. Я предполагаю, что на вероятности и на ROI тоталов очень сильно влияют автоголы, которые в Монте-Карло никак не учитываются, из-за чего вероятность Тотала Меньше относительно Тотала Больше немного увеличивается. Также я предполагаю, что проблема исчезнет после того, как мы добавим в Монте-Карло вероятность автогола в матче, поэтому планирую собрать информацию по автоголам и построить новый, отдельный Монте-Карло для тоталов, в котором будут учитываться автоголы. В следующем посте напишу об этом более подробно.

Теперь попробуем разобраться с вероятностями исходов. Для меня это не составило особого труда, единственное – здесь мне несколько сложнее объяснить вам причины расхождения, а вам, соответственно, сложнее будет эти причины понять. 

Мы уже неоднократно рассказывали, что в футболе есть особое свойство, которое отчетливее всего проявляется в матчах равных по силам команд. Чем ближе команды по силе, то есть, чем ближе вероятности победы этих команд друг к другу, тем сильнее проявляется это свойство. Что это за свойство? При равном счете команды играют более-менее стандартно. Но когда одна из команд начинает вести в счете, меняется ее тактика – она начинает играть в более защитный футбол, пытаясь удержать преимущество в счете. А вот соперник этой команды пытается играть более открыто, стараясь отыграться и сравнять счет. Из-за этого изменения в тактике происходит вот что: команда, которая ведет в счете, начинает набирать меньше xG, чем набирала бы при равном счете, потому что она начинает играть в защитный футбол. Команда, которая уступает в счете, набирает больше xG, чем набирала бы при равном счете, потому что она начинает идти в атаку, пытаясь отыграться.

Если бы вероятности команд на победу были равны, на дистанции обе команды набирали бы примерно равное количество xG за матч. Именно это и происходит при равном счете. Но при неравном счете мы получаем перекос: проигрывающая команда начинает набирать по xG больше, а выигрывающая – меньше. Из-за этой особенности мы получаем сразу два негативных для нас момента, которые генератор Монте-Карло в его нынешнем виде учесть не способен. 

Первый момент касается ничьих. Если счет в матче составляет, к примеру, 1-0, проигрывающая команда начинает набирать больше xG, а выигрывающая – меньше xG, из-за чего счет чаще будет становиться равным, чем превращаться в 2-0. Но в генератор Монте-Карло эта особенность не заложена, поэтому он считает все xG как xG при равном счете, не учитывая эту особенность в процессе вычисления. То есть, из-за особенностей, которые описаны выше, в реальности вероятность ничьей будет больше, чем рассчитывает нынешняя версия генератора Монте-Карло. Это мы и видим в таблице с результатами: ROI на ничьи по генератору Монте-Карло составляет -7%, а ROI на ничьи по факту на дистанции составляет -4,5% (средний размер маржи Pinnacle для исходов матчей). Это первая проблема.

Теперь давайте посмотрим на всю выборку в целом. Очевидно, что домашние команды чаще выступают фаворитами в матчах, и именно домашние команды будут чаще вести в счете. Из этой особенности вытекает вторая проблема: хозяева ведут в счете намного чаще, чем гости, следовательно, и садятся в оборону хозяева также чаще, чем гости. Получается, что из-за этой особенности хозяева набирают по xG меньше, чем набирали бы при неизменно равных счетах, а гости, соответственно, набирают по xG больше, чем набирали бы при неизменно равных счетах. Вот почему у нас возник перекос с ROI по генератору Монте-Карло на П2, и мы получили 3% вместо -4,5% ROI на П2, который существует по факту. Это произошло из-за того, что нынешняя версия генератора Монте-Карло не учитывает этой особенности. Поэтому я решил создать еще одну версию Монте-Карло, теперь уже для исходов.

Итак, сейчас передо мной стоят две задачи: создать новый генератор Монте-Карло для тоталов и новый генератор Монте-Карло для исходов. Сделать эту нужно с учетом всех особенностей, отмеченных мною выше. Как решить проблему с исходами в новой версии генератора Монте-Карло? В тех отрезках, где команда проигрывает, я планирую уменьшить вес ударов, для этого нужно будет умножить xG ударов на коэффициент, к примеру, 0,9 (это приблизительное значение, точную цифру мне еще предстоит рассчитать). А в отрезках, где команда выигрывает, я планирую добавить вес ударам, умножая для этого xG на коэффициент, скажем, 1,1 (это значение также необходимо рассчитать). Таким образом я смогу сгладить эффект смены тактики команд при изменении счета. Это будет базовая подстройка, которая позволит закрыть задачу на текущий момент. 

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

Report Page