Repository navigation
v0.4.1
[0.4.1] - 2026-09-19
Влияние: торговая логика (бот 1) · P&L · UI · настройки/данные - бот 1 перестал
считать удар по рынку плоской константой 0.1% и берёт измеренную кривую глубины GMX. Константа
берёт 10 базисных пунктов, а измеренная величина на тикете $2500 это медиана 0.001 бп (ровно ноль
у 57 наблюдений из 126) при максимуме 13.38: константа выше измеренного в 125 наблюдениях из 126,
и вместе с ней завышен круг издержек, из-за чего правило отказывалось от рынков,
которые окупались бы: замер на 63 рынках при капитале $2500 даёт $840.30 нетто за год против
$775.84, то есть +$64.46. Круг сделки при $2500 стал около $6.3-6.9 вместо $8.75. Заодно
леджер перестал списывать своё число и книжит ровно тот круг, на котором принято решение.
Что увидит владелец открытой сделки при обновлении. Уже открытая позиция не трогается: её круг
списан и заморожен в момент входа. Изменится СЛЕДУЮЩЕЕ решение: круг подешевеет, и в состав
кандидатов вернутся рынки, которые прежний круг отсекал. В карточке издержек статья
«проскальзывание GMX» получила пометку, что правило входа и леджер её больше не берут, когда у
рынка есть измеренная кривая; само поле осталось редактируемым.
Клиенту, который стоит на 0.3.1. Обновление приведёт сразу сюда, минуя промежуточные версии,
поэтому для него действуют ЧЕТЫРЕ секции: 0.3.2 и 0.3.3 (они так и не публиковались), 0.4.0 и эта.
Главное из пропущенного: бот 1 перестал считать по пяти зашитым рынкам и собирает вселенную живым
отбором, плюс аудит механики 18.09 и починка его находок. Полный текст всех секций лежит в
CHANGELOG.md.
Проверено живьём на боевой машине 18.09 в 21:14Z: первое решение с кривой вошло в рынок,
которого в снимке нет вовсе (Avalanche, запасная кривая по ярусу ликвидности), круг сделки $6.32
вместо $8.75, и три числа сошлись между собой - круг правила в записи решения, списание позиции и
статьи в паспорте сделки.
Исправлено
-
[Funding-Arb] Кривая удара GMX дошла до живого тракта.
slice.jsподавал в правило
impact: { gmxNodes: [] }, и пустые узлы означали НЕ ноль издержки, а плоскую константу
gmxImpact0.1% изcosts.js: пустая кривая выключает веткуhasGmxCurveвcostAtSize, и круг
считается по константе. Константа берёт 10 базисных пунктов, а измеренная величина на тикете
$2500 это медиана 0.001 бп (ровно ноль у 57 наблюдений из 126) при максимуме 13.38, то есть
константа завышала круг издержек почти везде. Цена, названная отчётом
фазы 3: -$64.46 нетто за год на 63 рынках при капитале $2500 ($840.30 против $775.84), и она
РОСЛА С ЧИСЛОМ РЫНКОВ, потому что завышенный круг отсекает ровно те рынки, где нетто и круг
сопоставимы, - а вселенная как раз выкачена на полусотню.Измеренный снимок глубины (
impact-gmx.json.gz, 63 рынка Arbitrum, 623 256 наблюдений за год)
лёг в данные приложенияsrc/engine/fa/data/, откуда его пакуетelectron-builderбез правки
конфигурации (files: ["src/**/*"]). Узлы приносит новый читательfa/impact-curve.js, файл
открываетmain/impact-load.js: срез остаётся ЧИСТЫМ, как и был. Знак приводится в одном
месте (Math.max(0, -(adverseBps ?? 0)), образецexit-lib.mjsloadCapacity): приведение
дважды дало бы отрицательную издержку, то есть премию за собственный вход.Правила движка не тронуты ни строкой, и это проверено суммами: все шесть книг снялись ПОБИТОВО
теми же (сверка прогонов до и после правки, sha256 совпали у каждой). Это и есть доказательство,
что правка живёт в срезе, а не в правиле. Замер эффекта на трёх годовых фикстурах книгой правила
входа против её же контроля--drop-rule impact-off: нетто $1354.79 против $1297.52 (+$57.27),
круг издержек $240.84 против $283.28, профинансировано 16 решений из 33 против 14. Два рынка
(ETH блок 3, BTC блок 9) плоская константа отвергала кодомbelow_fund_ratio, а с измеренной
кривой они проходят. -
[Funding-Arb] Рынок, которого в снимке нет, получил НАЗВАННЫЙ запасной путь вместо молчаливой
подстановки. Это не краевой случай: на живом составе фикстуры 16.09 снимок не покрывает
16 инструментов из 51 (31%) - четыре рынка Avalanche (снимок снят по Arbitrum, и глубина рынка
ETH на Avalanche это не глубина ETH на Arbitrum) и двенадцать листингов Arbitrum новее периода
снимка (VVV, XMR, ZEC, XPL, SKY, AERO, HBAR, MET, PUMP, ICP, LIT, CC). Источник кривой каждой
строки едет вlive.gmxCurveSrc(market,tier,pooled,none), и молчаливого источника
нет ни у одной.Обе ветки замерены методом исключения по очереди на тех 63 рынках, где правда известна
(тикет $2500, 126 наблюдений, |ошибка| в бп за круг): запасной путь по ярусу ликвидности даёт
медиану 0.07 (p95 2.58), по общему пулу 0.06 (p95 2.61), плоская константа - 10.00
(p95 10.00). Константа переоценивает удар в 125 наблюдениях из 126. Ветка ОТКАЗА (код
univ_no_impact_curve) отклонена замером: она сняла бы с вселенной те самые 31% инструментов,
включая все рынки Avalanche и каждый новый листинг навсегда, то есть отменила бы фазу 3 тем
незаметнее, чем дальше снимок от сегодняшнего дня. Веткаnoneоставлена достижимой и под тестом.Граница названа честно: запасная кривая это ЦЕНТР яруса, поэтому на тесных рынках она удар
НЕДООЦЕНИВАЕТ - в ярусеD_<200k15% наблюдений недооценены больше чем на 0.5 бп, худшее 13.22 бп;
в ярусах A и B недооценки нет (максимум 0.07 и 0.74 бп). Новый листинг почти всегда тесный, то
есть попадает ровно в тот ярус, где запас слабее всего. Это повод пересчитывать снимок, а не
считать его вечным. -
[Funding-Arb] У снимка глубины появился срок годности, а у записи решения дата снимка и
источник кривой каждого рынка. Возраст считается от КОНЦА ПЕРИОДА снимка, а не от дня съёмки:
снимок снят 30.08, но посчитан по истории до 20.06, то есть в день рождения уже отставал от рынка
на 71 сутки. Конец периода лежит в самом файле числом (meta.period), поэтому вбивать дату
константой и следить, чтобы она не разъехалась с файлом, не нужно. Срок 180 суток, для
нынешнего снимка это 17.12.2026. Он обоснован охватом: за 90 суток после конца периода живая
вселенная набрала 13 имён Arbitrum, которых снимок не знает, и при том же темпе своя кривая
рынка перестаёт покрывать хотя бы половину состава примерно на 170 сутки. Это ДОПУЩЕНИЕ: под ним
одна скорость на одном промежутке, продолженная прямой, а второй механизм старения, дрейф глубины
на покрытых рынках, не замерен ничем, потому что живьём удар не наблюдаем вовсе.После срока расчёт НЕ меняется, и это замер, а не смелость. Обе замены измерены и обе хуже:
плоская константа ошибается в медиане на 10.00 бп против 0.07 у яруса, отказ рынку без своей
кривой снимает 31% вселенной. Поэтому просрочка это сообщение: строка журнала на буте, флагst
в каждой записи решения и падение офлайн-смоукаnpm run smoke:impactкодом возврата. Неизвестный
возраст считается просроченным, а не свежим.Запись решения понесла три новых числа: блок
imс датой конца периода, возрастом снимка на
час решения и флагом просрочки, плюс полеimс именем источника кривой у каждого рынка и
каждого отказа. Без них круг издержекkв строке решения нечем объяснить задним числом: он
посчитан либо по своей измеренной кривой рынка, либо по подстановке по ярусу, а по числам эти два
решения неразличимы. Строка решения подорожала на 41 байт плюс 14 байт на рынок, решение одно в
сутки, поэтому в таблице объёма сдвинулась одна сотая в клетке «63 рынка, опрос 1 мин»
(35.66 МБ в сутки против 35.65). Правила движка снова не тронуты: шесть книг побитово те же. -
[Funding-Arb] Леджер бумажной сделки списывает круг ПРАВИЛА, а не свой. Правка кривой
развела решение и учёт, и до неё они сходились: правило считает круг по измеренным кривым (удар
GMX из снимка глубины и стакан Hyperliquid), аfaOpenFromIntentсписывал его по плоской модели.
Замер на живой записи: правило посчитало $7.36, леджер списал $8.75, из них $2.50 статьёй удара,
которую правило на том же рынке оценило в $0.00. На 27 кругах в год это до $67 издержек, которых
нет, то есть величина того же порядка, что и весь выигрыш кривой $64.46: бот зарабатывал бы
решениями, а отчитывался бы по другому числу.Теперь
openPositionполучаетintent.costUsd, то самое число, на котором принято решение.
Пересчёта здесь нет и быть не должно: вторая копия расчёта круга разошлась бы с первой на
следующей же правке. Статьи для леджера строит новыйbreakdownForTotal(costs.js): комиссии и
газ точные из модели, всё, что правило насчитало сверх них, это измеренное проскальзывание обеих
площадок одной строкой. Сумма статей сходится с кругом по построению (до ошибки округления
двоичной дроби, 9e-16 на круге $7.36), и это важно: интерфейс леджера показывает Σ детализации
рядом с кругом целиком. Круг ниже комиссий разбивки не даёт вовсе, чтобы не выдумывать
отрицательную статью: так честнее, чем смешивать два числа в одной строке.Заодно починено, что запись сделки ПЕРЕСЧИТЫВАЛА статьи из текущих настроек вместо того,
чтобы документировать списанное. Это врало и до кривой: модель издержек редактируема, и правка
между открытием и записью переписала бы историю. Теперь статьи берутся с позиции, где они
заморожены в момент входа. Проверено живьём: правило $6.57, позиция $6.57, запись $6.57, статья
проскальзывания $0.32 против плоских $2.50 до правки.Подпись статьи в леджере стала «проскальзывание обеих площадок»: она больше не про одну GMX.
Добавлено
-
[Funding-Arb] Статья «проскальзывание GMX» в карточке издержек помечена как не работающая
у правила входа. С появлением кривой эту статью берут не все потребители круга:costAtSize
при живой кривой зануляет её и подставляет измеренное, а кривая сегодня есть у всех 54
инструментов живого состава, то есть настроенное значение не влияет на выбор рынка ни разу. Круг
в той же карточке и леджер бумажной сделки считают по нему по-прежнему, поэтому написано «правило
входа не берёт», а не «не в силе»: статья в силе, но не у правила. Поле осталось редактируемым,
числа не тронуты, текст едет и вaria-label. -
[Funding-Arb] Офлайн-смоук
npm run smoke:impact(scripts/smoke-fa-impact.mjs): показывает
живой состав отбора со стороной ноги, источником кривой, ударом в базисных пунктах и кругом
издержек с кривой и без неё. Падает кодом возврата, если снимок не прочитан или своя кривая не
досталась никому. В сеть не ходит: кривая удара живьём не наблюдаема вовсе (в REST GMX нет ни
одного поля impact), поэтому проверять надо путь снимка до правила, а не путь сети до снимка.