<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
    <title>Notes &amp; Insights - high-risk</title>
    <subtitle>Блог об архитектуре систем, AI-агентах, распределенных системах и алгоритмическом трейдинге.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://xsa-dev.github.io/tags/high-risk/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://xsa-dev.github.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-10-09T00:00:00+00:00</updated>
    <id>https://xsa-dev.github.io/tags/high-risk/atom.xml</id>
    <entry xml:lang="ru">
        <title>Бюджет и риск-гейты для DCA-позиций: расчёт до запуска бота</title>
        <published>2026-10-09T00:00:00+00:00</published>
        <updated>2026-10-09T00:00:00+00:00</updated>
        
        <author>
          <name>Alexei Savin</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://xsa-dev.github.io/posts/dca-martingale-capital-budget-risk-gates/"/>
        <id>https://xsa-dev.github.io/posts/dca-martingale-capital-budget-risk-gates/</id>
        
        <content type="html" xml:base="https://xsa-dev.github.io/posts/dca-martingale-capital-budget-risk-gates/">&lt;p&gt;Усреднение снижает цену безубыточности, но одновременно увеличивает сумму под риском. &lt;strong&gt;Высокий риск · образовательный разбор.&lt;/strong&gt; Это не инвестиционная рекомендация и не инструкция к запуску торгового бота. Если в отчёте DCA-бота показан только процент прибыльных сделок, главный вопрос остаётся без ответа: &lt;strong&gt;сколько капитала потребует серия покупок, если отскока не будет?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Повод для разбора — видео &lt;a rel=&quot;external&quot; href=&quot;https://youtu.be/M1036x1Hobg&quot;&gt;DCA Martingale Trading Bot Explained&lt;/a&gt;. Рыночный бэктест в рамках этой статьи не проводился.&lt;/p&gt;
&lt;h2 id=&quot;dca-ne-obiazatel-no-martingeil&quot;&gt;DCA — не обязательно мартингейл&lt;/h2&gt;
&lt;p&gt;В этой статье DCA означает дополнительные покупки при снижении цены внутри одной сделки. Это не регулярное долгосрочное инвестирование фиксированной суммы.&lt;/p&gt;
&lt;p&gt;Различать стоит три независимых правила:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Триггер:&lt;/strong&gt; на каком снижении разрешена дополнительная покупка.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Размер:&lt;/strong&gt; сколько денег выделяется каждой покупке.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Остановка:&lt;/strong&gt; когда новые покупки запрещаются и что происходит с уже открытой позицией.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Постоянный размер покупки не является классическим мартингейлом. Геометрическое увеличение размера похоже на него по нагрузке на капитал, но само по себе не гарантирует компенсацию прошлых потерь. Термин «контролируемый» здесь не используется как оценка качества: он имеет смысл только вместе с явными лимитами.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Почему мартингейл опасен.&lt;/strong&gt; Увеличение каждой следующей покупки наращивает экспозицию именно тогда, когда цена движется против позиции. При удвоении номиналов серия 100 → 200 → 400 → 800 требует уже 1500 единиц капитала, а следующая покупка — ещё 1600; это без комиссий. Конечный бюджет не позволяет продолжать такую последовательность бесконечно, а восстановление цены не гарантировано. На споте без заёмных средств можно потерять почти всю стоимость позиции; с плечом ликвидация может наступить ещё до запланированного уровня усреднения. Лимит покупок ограничивает выделяемый капитал, но не делает стратегию прибыльной и не гарантирует выход по заданной цене при разрыве котировок или недостаточной ликвидности. Приведённые ниже расчёты служат для анализа этих ограничений, а не являются торговой идеей, призывом запускать бота или инвестиционной рекомендацией.&lt;/p&gt;
&lt;h2 id=&quot;snachala-biudzhet-zatem-signal&quot;&gt;Сначала бюджет, затем сигнал&lt;/h2&gt;
&lt;p&gt;Пусть B — сумма базовой покупки в валюте котировки, S — сумма первой дополнительной покупки, m — множитель следующих покупок, N — максимальное число дополнительных покупок. Плеча нет; все суммы — номиналы покупок без комиссий.&lt;/p&gt;
&lt;p&gt;$$
C = B + S\sum_{k=0}^{N-1}m^k
$$&lt;/p&gt;
&lt;p&gt;При m ≠ 1:&lt;/p&gt;
&lt;p&gt;$$
C = B + S\frac{m^N-1}{m-1}
$$&lt;/p&gt;
&lt;p&gt;При m = 1 бюджет равен B + NS. Нулевая величина N означает отсутствие дополнительных покупок.&lt;/p&gt;
&lt;p&gt;Например, B = 100, S = 100, m = 2 и N = 4 требуют &lt;strong&gt;1600 единиц капитала&lt;/strong&gt;, хотя стартовая покупка составляет только 100. Для пяти одновременно заполненных серий потребуется 8000 — до комиссий и запаса ликвидности. Это арифметический сценарий, не прогноз рынка.&lt;/p&gt;
&lt;p&gt;Если предполагается реинвестирование прибыли, план нужно пересчитывать при каждом изменении базового размера. Иначе однажды проверенный лимит перестанет соответствовать реальной экспозиции.&lt;/p&gt;
&lt;h3 id=&quot;tri-nezavisimykh-limita&quot;&gt;Три независимых лимита&lt;/h3&gt;
&lt;p&gt;Бюджет серии &lt;code&gt;C&lt;/code&gt; — только номинал покупок. Для рабочего риск-гейта нужны ещё два ограничения:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Лимит серии:&lt;/strong&gt; &lt;code&gt;C &amp;lt;= C_series&lt;/code&gt;, где &lt;code&gt;C_series&lt;/code&gt; включает все дополнительные покупки, разрешённые одной позиции.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Лимит портфеля:&lt;/strong&gt; &lt;code&gt;R_reserved = Σ C_j &amp;lt;= R_portfolio&lt;/code&gt; для всех серий &lt;code&gt;j&lt;/code&gt;, которые могут быть заполнены одновременно.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Лимит ликвидности:&lt;/strong&gt; каждая заявка должна удовлетворять минимальному размеру, шагу количества и доступной глубине; остаток &lt;code&gt;R_portfolio - R_reserved&lt;/code&gt; не следует считать свободным для другой стратегии без общего резервного реестра.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Если вероятность одновременного заполнения неизвестна, для консервативного гейта используют сумму полных бюджетов, а не среднее историческое заполнение. &lt;code&gt;R_reserved&lt;/code&gt; включает quote cash, зарезервированные под незаполненную часть активных заявок; фактически исполненный notional учитывается отдельно. При частичном исполнении резерв уменьшают только после отмены остатка и подтверждённого terminal status (&lt;code&gt;canceled&lt;/code&gt;/&lt;code&gt;closed&lt;/code&gt;), а не сразу после получения частичного fill. Таймаут или перезапуск процесса не являются основанием считать резерв свободным.&lt;/p&gt;
&lt;p&gt;Важно: &lt;code&gt;C&lt;/code&gt; — бюджет покупок в quote currency без комиссий, а не максимальный убыток. Фактический убыток зависит от цены выхода, комиссий, проскальзывания, гэпа и ликвидности; для деривативов добавляется риск ликвидации. Даже полностью зарезервированный бюджет не задаёт нижнюю границу потерь.&lt;/p&gt;
&lt;p&gt;Для оценки чувствительности удобно считать прирост очередного ордера отдельно: &lt;code&gt;ΔC_k = S m^k&lt;/code&gt;. При &lt;code&gt;m &amp;gt; 1&lt;/code&gt; последний разрешённый ордер доминирует в бюджете; поэтому изменение &lt;code&gt;N&lt;/code&gt; на единицу часто опаснее, чем небольшая поправка расстояния между уровнями. Этот расчёт не содержит предположений о вероятности отскока.&lt;/p&gt;
&lt;h2 id=&quot;pochemu-sredniaia-tsena-ne-srednee-tsen-orderov&quot;&gt;Почему средняя цена — не среднее цен ордеров&lt;/h2&gt;
&lt;p&gt;При расходах c и ценах исполнения p количество купленного актива равно расходам, делённым на цену. Поэтому средняя цена взвешивается количествами, а не числом заявок:&lt;/p&gt;
&lt;p&gt;$$
Q = \sum_{i=0}^{N}\frac{c_i}{p_i},\qquad
\bar{p}=\frac{\sum_{i=0}^{N}c_i}{Q}
$$&lt;/p&gt;
&lt;p&gt;Рассмотрим только три исполненные покупки, не весь максимальный план:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Покупка&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Расход&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Цена&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Количество&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Базовая&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Дополнительная 1&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;90&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1,111111&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Дополнительная 2&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;200&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;80&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2,5&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Всего потрачено 400, куплено примерно 4,611111 единицы, средняя цена — &lt;strong&gt;86,746988&lt;/strong&gt;. Чтобы вернуться от 80 к этой цене, нужен рост примерно на 8,43%. Без комиссий это цена безубыточности, а не целевая прибыль.&lt;/p&gt;
&lt;p&gt;Если комиссия каждой покупки уплачена дополнительно в валюте котировки с долей f, а при продаже удерживается такая же доля выручки, цена безубыточности будет:&lt;/p&gt;
&lt;p&gt;$$
p_{BE}=\bar{p}\frac{1+f}{1-f}
$$&lt;/p&gt;
&lt;p&gt;При f = 0,001 получаем около 86,920656. Если комиссия удерживается в базовом активе или отдельном токене, формула учёта меняется. Проскальзывание учитывается фактическими ценами исполнения, а не обещанными уровнями сетки.&lt;/p&gt;
&lt;p&gt;При падении до 60 стоимость позиции составит около 276,67, а нереализованный убыток — 123,33 без комиссий. Средняя цена действительно снизилась; абсолютный риск при этом вырос.&lt;/p&gt;
&lt;h2 id=&quot;proveriaemyi-kal-kuliator-na-python&quot;&gt;Проверяемый калькулятор на Python&lt;/h2&gt;
&lt;p&gt;Код ниже не отправляет заявки и не является стратегией Freqtrade. Он проверяет арифметику плана и трёх гипотетических исполнений. Нужен только Python 3 со стандартной библиотекой.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;from&lt;/span&gt;&lt;span&gt; decimal&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; import&lt;/span&gt;&lt;span&gt; Decimal&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; as&lt;/span&gt;&lt;span&gt; D&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;base&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; first&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; multiplier&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; count&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; type&lt;/span&gt;&lt;span&gt;(count)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; is not&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; int&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; or not&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span&gt; count&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;count must be an integer from 0 to 100&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    values&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; tuple&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt;str&lt;/span&gt;&lt;span&gt;(x))&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; (base&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; first&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; multiplier))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; any&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;not&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_finite&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; or&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; values)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;sizes and multiplier must be finite and positive&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    base&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; first&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; multiplier&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; values&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; base&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; sum&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (first&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; *&lt;/span&gt;&lt;span&gt; multiplier&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; **&lt;/span&gt;&lt;span&gt; k&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; k&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; range&lt;/span&gt;&lt;span&gt;(count))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1600&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;500&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;for&lt;/span&gt;&lt;span&gt; bad&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 1.5&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; True&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 101&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;        capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; bad)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    except&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        pass&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    else&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; AssertionError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;invalid count accepted&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; breakeven_price&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;average&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; fee&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    average&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; fee&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt;str&lt;/span&gt;&lt;span&gt;(average))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt;str&lt;/span&gt;&lt;span&gt;(fee))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; not&lt;/span&gt;&lt;span&gt; average&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_finite&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; or&lt;/span&gt;&lt;span&gt; average&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;average must be finite and positive&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; not&lt;/span&gt;&lt;span&gt; fee&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_finite&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; or not&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span&gt; fee&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;fee must be finite and in [0, 1)&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; average&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; *&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +&lt;/span&gt;&lt;span&gt; fee)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; /&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span&gt; fee)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; breakeven_price&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;100&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;100&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; breakeven_price&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;86.7469879518&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0.001&amp;quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;86.7469879518&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fills&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; [(&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;90&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;200&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;80&lt;/span&gt;&lt;span&gt;))]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cost&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; sum&lt;/span&gt;&lt;span&gt;((cash&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; cash&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; fills)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;quantity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; sum&lt;/span&gt;&lt;span&gt;((cash&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; /&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; cash&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; fills)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;average&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; cost&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; /&lt;/span&gt;&lt;span&gt; quantity&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fee&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0.001&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;breakeven&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; breakeven_price&lt;/span&gt;&lt;span&gt;(average&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; fee)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; abs&lt;/span&gt;&lt;span&gt;(average&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;86.7469879518&amp;quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0.000000001&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; abs&lt;/span&gt;&lt;span&gt;(breakeven&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;86.9206555953&amp;quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0.000000001&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F07178;&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;capital=&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F07178;&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;average=&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;{&lt;/span&gt;&lt;span&gt;average&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;:.6f&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;; breakeven=&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;{&lt;/span&gt;&lt;span&gt;breakeven&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;:.6f&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Этот тест не проверяет исторические котировки, ликвидность или доходность. Он нужен для более узкого инварианта: риск-менеджер и стратегия должны одинаково понимать размер запланированной серии.&lt;/p&gt;
&lt;h2 id=&quot;kontur-ispolneniia-limit-do-dopolnitel-noi-pokupki&quot;&gt;Контур исполнения: лимит — до дополнительной покупки&lt;/h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;flowchart&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    A&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Новый закрытый бар&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;] --&amp;gt;&lt;/span&gt;&lt;span&gt; B&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Сверка позиций и заявок&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    B &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; C&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Есть неопределённое исполнение?&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    C &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Да&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; D&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Пауза и повторная сверка&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    C &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Нет&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; E&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Проверка уровня и номера покупки&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    E &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; F&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Хватает лимита серии и портфеля?&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    F &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Нет&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; G&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Запрет увеличения позиции&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    F &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Да&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; H&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Резервирование бюджета и заявка&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    H &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; I&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Запись фактического исполнения&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Здесь нужны два лимита: на отдельную серию и на весь портфель. Остаток свободных денег сам по себе не заменяет резерв: несколько ботов могут одновременно считать одни и те же средства доступными.&lt;/p&gt;
&lt;p&gt;Минимальная запись состояния содержит идентификатор серии, номер дополнительной покупки, уже исполненный объём, зарезервированную сумму и идентификатор заявки. После таймаута сначала выясняют судьбу заявки, а не немедленно отправляют новую. Частичное исполнение учитывают по фактическому объёму; перезапуск процесса не должен обнулять счётчик покупок.&lt;/p&gt;
&lt;p&gt;В Freqtrade увеличение позиции реализуется через &lt;code&gt;adjust_trade_position()&lt;/code&gt;. Это callback именно для position adjustment; его частота вызовов и поведение в live/dry-run отличаются от бэктеста. Условие вроде «цена ниже уровня» остаётся истинным несколько итераций подряд: без проверки состояния оно способно породить повторные покупки. Возвращаемые значения (stake/amount), ограничения биржи и конфигурационные лимиты зависят от установленной версии Freqtrade, поэтому implementation contract нужно сверять с документацией конкретной версии, а не только со stable-ссылкой. Точные параметры callback и ограничения числа дополнительных входов проверяйте по документации установленной версии.&lt;/p&gt;
&lt;p&gt;Отказ от дальнейшего усреднения &lt;strong&gt;не закрывает существующий риск&lt;/strong&gt;. Отдельная политика должна описывать выход, максимальную длительность сделки и аварийное отключение. Стоп-заявка тоже не гарантирует цену исполнения при гэпе. Здесь рассматривается спот без плеча; для деривативов дополнительно необходимы модель маржи, funding и риск ликвидации.&lt;/p&gt;
&lt;h2 id=&quot;kak-proveriat-strategiiu-a-ne-krasivuiu-krivuiu&quot;&gt;Как проверять стратегию, а не красивую кривую&lt;/h2&gt;
&lt;p&gt;До перебора параметров задайте протокол:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Разделите время.&lt;/strong&gt; Подбор параметров — на тренировочном периоде; выбор варианта — на валидационном; финальная проверка — на отдельном, ранее не использованном периоде. Повторный подбор по финальному отчёту превращает его в тренировочный.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Сравните одинаковый капитал.&lt;/strong&gt; Покупка на 100 с резервом 1500 и buy-and-hold на 1600 — разные режимы экспозиции. Покажите доходность на весь выделенный капитал, а не только на первую покупку.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Проверьте открытые позиции.&lt;/strong&gt; Высокая доля выигрышных закрытых сделок может соседствовать с большой плавающей просадкой. Нужна equity с переоценкой открытых позиций, а не только баланс завершённых циклов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Учтите издержки.&lt;/strong&gt; Комиссии, спред, ограничения минимального ордера и шаг количества; отдельно — стрессовое проскальзывание и пропущенные исполнения.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Испытайте одновременное падение активов.&lt;/strong&gt; Число разных тикеров не гарантирует диверсификацию: в стрессовом режиме они могут одновременно запросить полный резерв.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Проверьте утечку будущего.&lt;/strong&gt; &lt;code&gt;lookahead-analysis&lt;/code&gt; в Freqtrade помогает обнаруживать часть подобных ошибок, но не доказывает прибыльность или отсутствие всех видов смещения. После него нужны обычный бэктест с реальными лимитами и dry-run.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Для итогового отчёта полезнее одного win rate четыре числа: максимальная просадка equity, максимальная занятость капитала, длительность самой долгой серии и результат на всём выделенном капитале после издержек. Добавьте число серий: редкие завершения дают мало независимых наблюдений.&lt;/p&gt;
&lt;h2 id=&quot;kliuchevye-vyvody&quot;&gt;Ключевые выводы&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Геометрическое увеличение покупок требует заранее посчитанного бюджета, даже если первая заявка мала.&lt;/li&gt;
&lt;li&gt;Снижение средней цены не означает снижения денежного риска.&lt;/li&gt;
&lt;li&gt;Ограничение количества покупок — не замена выходу и портфельному лимиту.&lt;/li&gt;
&lt;li&gt;Арифметический тест, исторический бэктест и dry-run отвечают на разные вопросы; ни один не гарантирует будущую прибыль.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Практический первый шаг — выписать B, S, m и N из своего исследовательского конфига и сравнить полный бюджет с доступным резервом при одновременном заполнении всех серий. Это материал об инженерной проверке рисков, а не рекомендация запускать усреднение на реальном счёте.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;pervoistochniki-i-materialy&quot;&gt;Первоисточники и материалы&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Оригинальное видео:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://youtu.be/M1036x1Hobg&quot;&gt;DCA Martingale Trading Bot Explained — Risk Controls + Out-of-Sample Backtest&lt;/a&gt;. Результаты стратегии независимо не воспроизводились.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Документация callback:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://www.freqtrade.io/en/stable/strategy-callbacks/#adjust-trade-position&quot;&gt;Freqtrade — Adjust trade position&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Проверка утечки будущего:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://www.freqtrade.io/en/stable/lookahead-analysis/&quot;&gt;Freqtrade — Lookahead analysis&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Инженерные наработки:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://github.com/xsa-dev&quot;&gt;github.com/xsa-dev&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
</feed>
