Конфіг казав starting_capital: 100000, а вісь y на графіку казала USD. Кожне виконання в логу було числом у USDC. Одинадцять місяців того прогону ці два факти жили в одній комірці, і нікому не було причини їх розвести.
Потім збанкрутував Silicon Valley Bank, Circle заявила, що $3.3 мільярда резервів USDC застрягли там, і USDC торгувався по 87 центів. Наша «доларова» книга пішла вгору. BTC у ціні USDC рвонув. Перп друкував зелене. Кеш, який ми вважали безризиковими 100,000, і був тим, що зрушилося.
Я досі виловлюю дослідницькі пайплайни, які ставлять USDC, USDT і USD в одну колонку. Це той вікенд, розібраний у порядку, в якому його бачив леджер.
Рядок, який казав $100,000
Паперовий рахунок, BTC-перпетуал з маржею в USDC, скромний лонг. 30,000 USDC номіналу BTC, близько 1.5 BTC за п’ятничним марком біля $20,150. Інші 70,000 сиділи як забезпечення в USDC. Недонавантажено навмисно. Ми прогрівали стратегію. Решта стеку сиділа в кеші.
Функція NAV робила те, що роблять більшість із них. Вона додавала кеш у USDC до нереалізованого pnl у USDC і записувала суму в ряд з ім’ям equity_usd. У конфігу був коментар, який я написав сам:
stablecoins = 1 долар. не рахуй FX двічі.
Я мав на увазі: не перетворювати фандинговий платіж у USDT на другий доларовий рух, конвертуючи його двічі. Що я насправді зробив — заморозив курс FX на 1.0 для решти файлу.
quote_asset = "USDC"
Майданчик був майданчиком USDC. Виконання, маржа, фандинг, мітки ліквідації, розмір лота, мінімальний номінал — усе це. Hyperliquid, dYdX v3, Coinbase International, ще десяток інших, та сама форма. Дослідницький ноутбук імпортував свічку BTCUSDC і свічку BTCUSD, першу використовував для торгівлі, а другу ставив міткою на графік, бо графік виглядав професійніше в доларах.
І ось ця дрібна, дурна деталь, про яку я досі думаю в невідповідні години: стандартний заголовок осі в бібліотеці графіків — «USD». Я його ніколи не перевизначав. Люди проходили повз екран і читали одиницю, якої в ряді не було.
П’ятничний вечір, твіт Circle
10 березня 2023. SVB уже немає. Circle розкриває, що $3.3 мільярда з тодішніх ~$40 мільярдів резерву USDC лежали в збанкрутілому банку, близько 8%. Coinbase тієї ж ночі призупиняє конвертації USDC. Викуп, власне механізм прив’язки, закритий на вікенд.
У бектесті не було рядка ні для чого з цього. Жодного прапорця зупинки викупу, жодного поля резервів емітента, жодного «чи можу я отримати долари за цей токен до понеділка». Був close. П’ятничний close у нашому FX-файлі все ще був 1.0000, бо FX-файл був заглушкою, яка повертала 1.0 для всього, чий тікер починався з USD.
Раніше я вважав премію USDT класичним шумом — тим, що згадуєш у виносці й далі ігноруєш. Ми якось провели двадцять хвилин на кухні, сперечаючись, чи 1.03 «варто проводити в облік». Ми обоє нав’язували оцінку. Пара — це ряд. Зберігайте її. Припиніть за неї голосувати.
0.8789
Суботній ранок. Мінімум USDC на CoinGecko — $0.8789. Інші стрічки друкують $0.87. Кілька DEX-пулів проходять через $0.80. DAI, напханий USDC як забезпеченням, іде за ним униз. USDT іде в протилежний бік, $1.03 на деяких екранах, $1.06 на Kraken.
Заглушка FX-файлу все ще повертає 1.0. Годинник бектесту знає, що зараз субота. Він не знає, що одиниця книги тепер — проблемний токен.
Принт Kraken на 26,000
Bitstamp BTC/USD кружляє біля $20,200. Kraken BTC/USDC друкує вище $26,000. Це той самий біткоїн. Друге число — доларова ціна, поділена на зламану прив’язку, плюс те повітря, яке тонка книга USDC додає в суботу.
Наш майданчик маркував перпетуал у USDC. Візьмімо консервативну стрічку, BTC/USDC близько ~$23,000, тобто $20,200 / 0.88. Лонг на 1.5 BTC у плюсі приблизно на 4,300 USDC. Рахунок у нативних одиницях: 104,300 USDC. Рушій звітує $104,300, вікенд +4.3%, і зверху в тій самій одиниці сідає фандинговий платіж.
У доларах 70,000 USDC вільного забезпечення коштують близько $61,600. Усі 104,300 USDC коштують близько $91,800. Книга, яка «заробила» 4.3%, втратила 8% свого доларового капіталу, переважно сидячи в кеші.
Вікендова дохідність була зміною одиниці, а не зміною долі. Лонг BTC/USDC у день падіння USDC механічно є лонгом депегу. Цю ставку можна хотіти. Її не можна виявити заднім числом у ряді з міткою USD.
cash_usd = cash_usdc * 1.0
Саме цей рядок я лишаю. Він виконувався на кожному барі, включно з барами, де USDCUSD був 0.87. Множення на 1.0 відчувається як no-op, тому воно виживає на код-рев’ю. Це FX-мітка. Заморожена.
70,000 USDC забезпечення ніколи не запускали угоду, тож жодна модель прослизання на них не дивилася, жодна таблиця комісій, жоден фандинг. Кеш має бути нудною колонкою. На цій книзі це був найбільший ризик і єдиний, який ми не оцінювали.
Знижка maker на виконаннях BTC того вікенду становила 2 або 3 bps, якщо виконання взагалі було. Рух котирувального активу становив 1,300 bps. У нас цілий стек під 3 і заглушка під 1,300.
Зелений вікенд на графіку
Понеділок зранку в Slack, перш ніж хтось відкрив USDCUSD: ми надрукували 4% за ніч. Хтось запитав, чи не масштабувати паперовий розмір. Я подивився на графік, потім на Kraken, потім на заглушку.
| Стаття леджера | Що зберігав рушій | Субота, натив | Той самий момент, у доларах |
|---|---|---|---|
| Вільне забезпечення | 70,000 USDC × 1.00 | 70,000 USDC | ~$61,600 |
| Марк BTC-перпа | last BTCUSDC | ~23,000 USDC (26,000 на Kraken) | BTCUSD ~$20,200 |
| Нереалізоване на 1.5 BTC | +4,300 USDC | +4,300 USDC | здебільшого прив’язка, трохи біткоїна |
| Звітний NAV | 104,300 «USD» | 104,300 USDC | ~$91,800 |
У книгах USDT була протилежна карикатура. USDT торгувався з премією, тож плаский рахунок з маржею в USDT показував доларовий прибуток, якого він також не заробив, і марк BTCUSDT, який був занадто низьким відносно BTCUSD. Якщо ви ранжували два «ідентичні» BTC-перпи того вікенду, один на майданчику USDC і один на майданчику USDT, ви ранжували токени котирування і називали це alpha.
Паперовий рахунок, той, що реально тримав USDC, був ближчим до правди, ніж дослідницький дашборд. Він ніколи не претендував бути доларами. Це зробили ми в експорті.
Експорт, який ми відвантажили в понеділок
USDC повз назад до $1 після того, як Treasury, Fed і FDIC заявили, що вкладників SVB відшкодують повністю, і після того, як Circle заявила, що покриє дефіцит. До понеділка прив’язку здебільшого залатали. Заглушка FX-файлу, яка 48 годин була хибною, знову стала правильною.
Але денні бари це сховали. Вибірка 00:00 UTC 11 березня зловила USDC уже відхиленим або вже у відскоку, залежно від постачальника, а вибірка 12 березня була іншим кіно. Якщо ви зберігали лише NAV, а не марк котирування, ви не могли відновити, який саме варіант. Потворний вікенд згладився до бліпу, достатньо малого, щоб його ігнорувати, — що ми й зробили, бо семплювали денно.
Тепер на книзі ми завжди тримаємо три ряди, навіть коли вони місяцями лежать один на одному:
- NAV у котирувальному активі майданчика, одиниця, яку ви реально можете вивести.
- Котирувальний актив проти USD, реальна стрічка, включно з суботою, включно з 0.87, включно з годинами, коли Coinbase не конвертувала.
- NAV у доларах, як похідний ряд, щоб мітка USD на графіку мала батьківський ряд.
Якщо бектест пише агент, перевірка та сама. Запитайте в нього котирувальний актив кожної позиції і кешу. Якщо він відповідає USD на майданчику USDC, прогін — не доларовий прогін. Березень 2023 — це тиждень, який я програю, коли хтось каже мені, що ця відмінність не рухає Sharpe. Вона зрушила цей більше, ніж стратегія, а стратегія була тією частиною, на яку в нас були моделі.
← Усі статті


