Размер позиции решает всё: Монте-Карло, где честно меняется ровно одна переменная
Дисклеймер о конфликте интересов.
Я делаю бесплатные калькуляторы риск-менеджмента для крипто-трейдинга. Чтобы это не выглядело как реклама в каждом абзаце, ссылка на проект в статье ровно одна — в самом конце. Всё остальное здесь — код, математика и числа, которые вы можете воспроизвести у себя за минуту.
И сразу к делу — с вопроса, на который у большинства есть «очевидный», но неверный ответ.
Вопрос
Два трейдера торгуют одну и ту же стратегию. Винрейт 55%, выплата 1:1 (выигрыш равен риску). Они получают буквально одну и ту же серию из 500 сделок — те же победы на тех же местах, те же поражения. Отличается только одно: первый рискует 10% депозита на сделку, второй — 35%.
У стратегии положительное матожидание. Второй рискует больше, значит и зарабатывать должен больше — так подсказывает интуиция.
Прогон 10 000 таких «карьер» на каждый размер ставки даёт:
ставка 10% → медианный итог $122 336 (старт был $10 000);
ставка 35% → медианный итог $0.006. Полцента.
Те же подбрасывания монеты. Отличается только размер ставки. Ниже — полный код, по которому это получено, таблица, графики и разбор, почему так.
Модель
Одна сделка меняет депозит на множитель:
выигрыш →
× (1 + f)проигрыш →
× (1 − f)
где f — риск на сделку: доля депозита, которую вы теряете на стопе. Это не номинал позиции и не плечо, а именно «сколько денег от счёта сгорает, если сделка против вас». Выплата симметричная (1:1), то есть выигрыш приносит ровно то же f, что отнимает проигрыш.
Параметры:
p = 0.55— доля выигрышных сделок, одинаковая для всех размеров ставки;START = $10 000— стартовый депозит;N_TRADES = 500— сделок в одной «карьере»;N_RUNS = 10 000— «карьер» на каждый размер ставки;RISKS = 1%, 2%, 5%, 10%, 20%, 35%— то, что мы перебираем;«слив» — депозит хотя бы раз опускался ниже 10% от старта.
Как обеспечена честность сравнения
Это главное, ради чего стоит читать дальше. Подогнать такую симуляцию — нечего делать: достаточно тайком занизить винрейт «плохой» стратегии или прогнать каждый размер ставки на своей серии случайностей. Поэтому конструкция построена так, чтобы подгонку было невозможно спрятать:
Меняется ровно одна переменная — размер ставки. Винрейт у всех одинаковый:
p = 0.55.Все размеры ставки прогоняются на ОДНОЙ И ТОЙ ЖЕ матрице исходов. Сначала генерируется матрица побед/поражений
10 000 × 500, и затем каждыйfприменяется к ней же. Сид зафиксирован (SEED = 7).Код опубликован целиком (ниже). Скопируйте, запустите — получите те же числа до цента.
Медиана из симуляции сверяется с аналитической формулой прямо в таблице. Если бы код врал, столбцы «медиана» и «теория» разошлись бы. Они совпадают.
Каждое число в статье — из реального прогона. Сначала прогон, потом текст. Ничего «по памяти» и ничего «по теории» под видом результата симуляции.
Код
Это и есть весь скрипт целиком — он печатает таблицу из следующего раздела. Сохраните его в файл habr_sim.py и запустите python3 habr_sim.py: таблица воспроизводится один в один.
import numpy as np
SEED = 7
START = 10_000 # стартовый депозит, $
P_WIN = 0.55 # доля выигрышных сделок — одинаковая у всех
N_TRADES = 500 # сделок в одной «карьере»
N_RUNS = 10_000 # «карьер» на каждый размер ставки
RISKS = [0.01, 0.02, 0.05, 0.10, 0.20, 0.35] # риск на сделку, доля депозита
RUIN = 0.10 # «слив»: депозит хотя бы раз опускался ниже 10% от старта
rng = np.random.default_rng(SEED)
# Честность конструкции: ОДНИ И ТЕ ЖЕ последовательности побед/поражений
# для всех размеров ставки. Меняется ровно одна переменная — размер.
wins = rng.random((N_RUNS, N_TRADES)) < P_WIN
k_med = round(P_WIN * N_TRADES) # медианное число побед: 275 из 500
print(f"{'ставка':>7} | {'медиана, $':>14} | {'теория, $':>14} | "
f"{'P(итог<старта)':>14} | {'P(слив)':>8} | {'P(DD>50%)':>9}")
for f in RISKS:
mult = np.where(wins, 1 + f, 1 - f) # множитель депозита за сделку
paths = START * np.cumprod(mult, axis=1) # траектории депозита
full = np.concatenate([np.full((N_RUNS, 1), START), paths], axis=1)
drawdown = 1 - full / np.maximum.accumulate(full, axis=1)
med = np.median(paths[:, -1])
theory = START * (1 + f)**k_med * (1 - f)**(N_TRADES - k_med)
p_loss = (paths[:, -1] < START).mean()
p_ruin = (full.min(axis=1) < START * RUIN).mean()
p_dd = (drawdown.max(axis=1) > 0.50).mean()
print(f"{f:>6.0%} | {med:>14,.2f} | {theory:>14,.2f} | "
f"{p_loss:>13.1%} | {p_ruin:>7.1%} | {p_dd:>8.1%}")
Результаты
Ставка | Медиана итога | Теория (медианы) | P(итог < старта) | P(слив) | P(DD > 50%) |
|---|---|---|---|---|---|
1% | $16 080.39 | $16 080.39 | 1.8% | 0.0% | 0.0% |
2% | $24 598.82 | $24 598.82 | 2.3% | 0.0% | 0.9% |
5% | $65 293.27 | $65 293.27 | 5.1% | 0.1% | 60.9% |
10% | $122 335.65 | $122 335.65 | 13.5% | 6.5% | 99.9% |
20% | $9 334.47 | $9 334.47 | 51.4% | 59.4% | 100.0% |
35% | $0.01 * | $0.01 * | 96.3% | 98.6% | 100.0% |
* При формате с двумя знаками после запятой значение для 35% округляется до $0.01; точная медиана ≈ $0.0056. Это видно на графике 1 и подтверждается формулой лог-роста ниже.
Два наблюдения, на которые стоит обратить внимание сразу.
Столбцы «медиана» и «теория» совпадают до цента во всех строках — и это не подгонка, а свойство задачи. Итоговый капитал зависит только от числа побед, а не от их порядка: умножение коммутативно, (1+f) и (1−f) можно переставлять как угодно. Поэтому итог однозначно определяется счётчиком побед k, а медианному итогу соответствует медианное число побед. Для Binomial(500, 0.55) медиана числа побед — ровно 275, и формула START · (1+f)²⁷⁵ · (1−f)²²⁵ бьёт с симуляцией один в один. Если бы в коде была ошибка в логике компаундинга, эти два столбца разъехались бы. Они не разъехались.
Столбцы «слив» и «DD > 50%» аналитически не считаются — их даёт только прогон. Они путезависимые: важно не только сколько побед, но и когда пришли поражения. Здесь и прячется главная ловушка крупной ставки: уже при 5% риска у 60.9% «карьер» хоть раз была просадка глубже 50% — при том что медианный итог отличный ($65k). При ставке Келли (10%) такую просадку переживают 99.9%, а 6.5% «карьер» хоть раз падали ниже 10% от старта.

График 1. Медиана растёт до ставки Келли (10%, $122k), а затем рушится: 20% даёт уже $9.3k (ниже старта), 35% — полцента. Положительное матожидание не спасает.
Почему так: критерий Келли и лог-рост
При мультипликативном компаундинге важна не арифметическая прибавка за сделку, а средний логарифмический рост:
g(f) = p · ln(1 + f) + q · ln(1 − f), где q = 1 − pg(f) — это скорость, с которой растёт логарифм капитала за сделку. Медианный итог за N сделок ≈ START · e^(N · g(f)). Максимум g(f) достигается при ставке Келли; для выплаты 1:1 она равна:
f* = 2p − 1 = 2·0.55 − 1 = 0.10 → 10%Подставляем реальные g(f) из прогона (та же формула, тот же p):
Ставка | g(f) за сделку | START · e^(500·g) |
|---|---|---|
1% | +0.000950 | $16 080 |
2% | +0.001800 | $24 599 |
5% | +0.003753 | $65 293 |
10% | +0.005008 (максимум) | $122 336 |
20% | −0.000138 (≈ 0) | $9 334 |
35% | −0.028795 (< 0) | $0.0056 |
Три зоны:
f < 10% —
g > 0, и чем ближе к Келли, тем быстрее растём.f = 20% (это 2× Келли) —
g ≈ 0. Рост логарифма капитала обнуляется: медиана возвращается примерно к старту. Удвоить ставку Келли — значит обнулить ожидаемый рост, а не удвоить прибыль.f = 35% —
g < 0. Матожидание положительное, но лог-рост отрицательный → медианное разорение. Капитал почти каждой отдельной «карьеры» съёживается до нуля, хотя «в среднем по больнице» (см. ниже) всё прекрасно.
Это и есть контринтуитивная суть: у функции g(f) есть пик, за которым больше риска = меньше денег, а дальше — гарантированный путь в ноль, несмотря на положительный матожидание каждой сделки.

График 2. Те же 60 серий побед/поражений, отличается только размер ставки. Слева (10%) траектории разлетаются вверх с большим разбросом, но большинство — выше старта. Справа (35%) тот же набор серий схлопывается ко дну ($0.01 — это пол визуализации, чтобы лог-шкала не уходила в −∞), редкие выжившие погоды не делают.
Среднее против медианы: откуда берётся иллюзия
Если посчитать не медиану, а среднее (арифметическое), картина переворачивается. Среднее добавляется к скрипту двумя строками на той же матрице:
terminal = paths[:, -1]
mean_sample = terminal.mean() # выборочное среднее
mean_theory = START * (1 + f * (2 * P_WIN - 1)) ** N_TRADES # теоретическое среднееСтавка | Медиана | Среднее (выборка) | Среднее (теория) |
|---|---|---|---|
1% | $16 080 | $16 472 | $16 483 |
2% | $24 599 | $27 116 | $27 156 |
5% | $65 293 | $120 326 | $121 068 |
10% | $122 336 | $1 443 930 | $1 447 728 |
20% | $9 334 | $111 697 574 | $199 565 691 |
35% | ≈$0.006 | $60 856 483 | $295 239 795 928 |
При ставке 35% медиана — полцента, а теоретическое среднее — почти $295 млрд. Это не опечатка. Среднее тащат вверх единичные траектории, где почти все 500 сделок оказались выигрышными — астрономически богатые, но исчезающе редкие. Если ваша стратегия — «занести крупно и надеяться», математически вы ставите на то, что окажетесь именно на такой траектории. Почти наверняка — нет.
Честная оговорка про среднее. Обратите внимание: выборочное среднее при больших f систематически ниже теоретического (на 35%: $60.9 млн против $295 млрд). Это не ошибка кода. Основной вклад в теоретическое среднее дают редчайшие траектории, которых в 10 000 прогонов попросту нет — распределение итогов имеет чудовищно тяжёлый правый хвост. Поэтому столбец «среднее (выборка)» нужно читать как нижнюю оценку истинного среднего, а не как само среднее. Это честное свойство конечной выборки из распределения с экстремальным хвостом, и его важно проговаривать, а не прятать.

График 3. Чем выше ставка, тем чаще боль. Даже на «разумных» 5% риска у 60.9% «карьер» хоть раз случалась просадка глубже 50%. На 35% почти всё идёт не так одновременно.
А если вы ошиблись в оценке винрейта?
До сих пор мы считали, что p = 0.55 известно точно. В реальности винрейт — это оценка по конечной истории сделок, и она шумит.
Стандартное отклонение оценки винрейта по 500 сделкам:
σ = sqrt( p·(1−p) / n ) = sqrt( 0.55·0.45 / 500 ) ≈ 0.022 → 2.2 процентных пунктаТо есть на дистанции в 500 сделок вы не можете статистически отличить винрейт 52% от 55% — они лежат внутри полутора сигм друг от друга. А разница для размера ставки — огромная:
Вы думаете, что
p = 0.55→ считаете Келлиf* = 10%.На самом деле
p = 0.52→ настоящий Келлиf* = 2·0.52 − 1 = 4%.
Что происходит, если ставить 10% при истинном p = 0.52:
g(10%) при p=0.52 = 0.52·ln(1.10) + 0.48·ln(0.90) = −0.001012 → g < 0
START · e^(500·g) ≈ $6 030g отрицательный — медиана падает ниже старта за 500 сделок. Вы были уверены, что играете по Келли с положительным ростом, а на деле медленно сливаетесь, потому что переоценили свой эдж на 3 пункта — на те самые 3 пункта, которые невозможно увидеть в данных.
Вывод не «Келли плохой», а ровно обратный по духу: поскольку истинный эдж измерить точно нельзя, ставить долю от Келли (дробный Келли) или учебные 1–2% риска — это не трусость и не «для слабаков». Это рациональное поведение под неопределённостью. Запас по размеру ставки — это плата за то, что вы не знаете свой винрейт с точностью до процента. И вы его действительно не знаете.
Честные оговорки
Это модель, а не реальность. Все упрощения перечислены явно — и почти все они в пользу трейдера, то есть реальность ещё суровее модели:
Винрейт фиксирован и известен. В жизни он неизвестен и плавает (что усугубляет проблему — см. раздел выше). Знать свой эдж идеально — это подарок, которого у вас нет.
Выплата ровно 1:1. Никакого разброса в R-мультипликаторах сделок.
Нет комиссий, проскальзывания, спреда и funding. Любые реальные издержки сдвигают всё только в худшую сторону.
Сделки независимы. Нет автокорреляции, смены режимов рынка, серий и тильта.
«Карьера» не останавливается на просадке. Симулированный трейдер не закрывает счёт после −80%, его не выносит по марже, у него нет эмоций. Реальные люди останавливаются — иногда спасая остаток, иногда фиксируя худшее в панике.
Все перечисленные упрощения играют ЗА трейдера — и всё равно переставка размера ставки разоряет его. На реальном рынке преимущество модели исчезает, а проблема остаётся.
Выборочное среднее при больших
fнедосэмплит теоретическое (см. оговорку про среднее) — это ограничение конечной выборки, а не свойство стратегии.Это не финансовый совет. Рынок — не подбрасывание монеты с известной вероятностью. Это иллюстрация одного конкретного механизма, не модель торговли.
Выводы
Размер позиции — не второстепенная ручка, а главная. При полностью зафиксированных винрейте, выплате и серии сделок именно размер ставки решает, компаундитесь вы или идёте в ноль.
Есть оптимум (Келли), за которым больше риска = меньше денег. А дальше — практически гарантированное разорение, несмотря на положительное матожидание каждой сделки.
Среднее ≠ медиана, когда доходности перемножаются. «Средняя» доходность — это иллюзия выжившего: её формируют траектории, на которых вас почти наверняка не будет.
Свой эдж точно измерить нельзя, поэтому дробный Келли и учебные 1–2% риска — это математически обоснованный ответ на неопределённость, а не робость.
Скучный, маленький размер позиции — это не отсутствие смелости. Это единственный размер, который защищён математикой.
Я делаю бесплатные калькуляторы риск-менеджмента для крипто-трейдинга, в том числе симулятор Монте-Карло вроде этого, но интерактивный — riskdesks.com. Это единственная ссылка в статье.
P.S. Код и сид открыты, симуляцию можно повторить за минуту. Если найдёте ошибку в построении, в математике или сможете показать, что честность сравнения где-то нарушена — напишите в комментариях, поправлю прямо в статье и укажу автора правки. Это ровно тот peer-review, ради которого пост и написан: ломайте методологию, а не верьте на слово.






















