În config scria starting_capital: 100000, iar axa y a graficului spunea USD. Fiecare execuție din log era un număr USDC. Timp de unsprezece luni ale acelui run, cele două fapte au locuit în aceeași celulă și nimeni nu avea un motiv să le despartă.
Apoi Silicon Valley Bank a dat faliment, Circle a spus că $3.3 miliarde din rezervele USDC erau blocate acolo, iar USDC s-a tranzacționat la 87 de cenți. Cartea noastră de „dolari” a urcat. BTC cotat în USDC a explodat. Perp-ul a ieșit pe verde. Cash-ul pe care îl tratasem ca pe un 100,000 fără risc a fost lucrul care s-a mișcat.
Încă mai prind pipeline-uri de research care marchează USDC, USDT și USD ca o singură coloană. Acesta e weekendul acela, desfăcut în ordinea în care l-a văzut registrul.
Linia care spunea $100,000
Cont paper, perpetual BTC cu marjă în USDC, long modest. 30,000 USDC noțional de BTC, circa 1.5 BTC la marca de vineri aproape de $20,150. Ceilalți 70,000 stăteau drept colateral USDC. Sub-alocați intenționat. Încălzeam o strategie. Restul stivei stătea în cash.
Funcția NAV a făcut ce fac cele mai multe. A adunat cash-ul USDC cu pnl-ul nerealizat USDC și a scris suma într-o serie numită equity_usd. Era un comentariu în config pe care l-am scris eu însumi:
stablecoins = 1 dolar. nu dubla numărarea FX.
Voiam să zic: nu transforma o plată de funding USDT într-o a doua mișcare în dolari convertind-o de două ori. Ceea ce făcusem de fapt a fost să îngheț rata FX la 1.0 pentru restul fișierului.
quote_asset = "USDC"
Venue-ul era un venue USDC. Execuții, marjă, funding, mărci de lichidare, dimensiunea lotului, noționalul minim, totul. Hyperliquid, dYdX v3, Coinbase International, o duzină de altele, aceeași formă. Notebook-ul de research a importat o lumânare BTCUSDC și o lumânare BTCUSD, a folosit-o pe prima pentru trading și a etichetat-o pe a doua pe grafic, pentru că graficul arăta mai profesional în dolari.
Și asta e partea mică și stupidă la care încă mă gândesc la ore ciudate: titlul implicit al axei din biblioteca de plotting este „USD”. Nu l-am suprascris niciodată. Oamenii treceau pe lângă ecran și citeau o unitate pe care seria nu o avea.
Vineri noaptea, tweet-ul Circle
10 martie 2023. SVB e deja dus. Circle dezvăluie că $3.3 miliarde din rezerva sa USDC de atunci de ~$40 miliarde stăteau la banca falimentară, circa 8%. Coinbase suspendă conversiile USDC în aceeași noapte. Răscumpărarea, mecanismul real al peg-ului, e închisă pentru weekend.
Backtestul nu avea niciun rând pentru nimic din toate astea. Niciun flag de oprire a răscumpărării, niciun câmp de rezervă a emitentului, niciun „pot obține dolari pentru acest token înainte de luni.” Avea un close. Close-ul de vineri era încă 1.0000 în fișierul nostru FX, pentru că fișierul FX era un stub care returna 1.0 pentru orice al cărui ticker începea cu USD.
Obișnuiam să tratez un premium USDT ca zgomot de manual, genul de lucru pe care îl menționezi într-o notă de subsol și apoi îl ignori. Am petrecut odată douăzeci de minute într-o bucătărie certându-ne dacă 1.03 merita „înregistrat.” Amândoi editorializam. Perechea este o serie. Stocheaz-o. Nu mai vota asupra ei.
0.8789
Sâmbătă dimineața. Minimul CoinGecko pe USDC este $0.8789. Alte benzi tipăresc $0.87. Câteva pool-uri DEX trec prin $0.80. DAI, îndesat cu USDC drept colateral, îl urmează în jos. USDT merge invers, $1.03 pe unele ecrane, $1.06 pe Kraken.
Fișierul FX stub tot returnează 1.0. Ceasul backtestului știe că e sâmbătă. Nu știe că unitatea cărții este acum un token în suferință.
Printul Kraken la 26,000
Bitstamp BTC/USD se învârte în jurul a $20,200. Kraken BTC/USDC tipărește peste $26,000. Este același bitcoin. Al doilea număr este un preț în dolari împărțit la un peg spart, plus orice aer adaugă o carte USDC subțire sâmbăta.
Venue-ul nostru marca perpetualul în USDC. Ia o bandă conservatoare, BTC/USDC la ~$23,000, adică $20,200 / 0.88. Long-ul de 1.5 BTC e sus cu circa 4,300 USDC. Contul în unități native: 104,300 USDC. Motorul raportează $104,300, un weekend de +4.3%, iar o plată de funding aterizează deasupra, în aceeași unitate.
În dolari, cei 70,000 USDC de colateral inactiv valorează circa $61,600. Întregul 104,300 USDC valorează circa $91,800. Cartea care „făcuse” 4.3% a pierdut 8% din capitalul în dolari în timp ce stătea în mare parte în cash.
Randamentul de weekend a fost o schimbare de unitate, nu o schimbare de soartă. O poziție long BTC/USDC într-o zi cu USDC în jos este mecanic long pe depeg. Poți vrea acel pariu. Nu îl poți descoperi ulterior într-o serie etichetată USD.
cash_usd = cash_usdc * 1.0
Linia aia e cea pe care o păstrez. A rulat pe fiecare bară, inclusiv pe barele unde USDCUSD era 0.87. Înmulțirea cu 1.0 pare un no-op, de aceea trece de code review. Este un mark FX. Unul înghețat.
Cei 70,000 USDC de colateral nu au declanșat niciodată un trade, deci niciun model de slippage nu s-a uitat la ei, nicio tabelă de comisioane, niciun funding. Cash-ul ar trebui să fie coloana plictisitoare. Pe cartea asta a fost cel mai mare risc, și singurul pe care nu l-am prețuit.
Un rebate maker pe execuțiile BTC din weekendul acela era de 2 sau 3 bps, dacă erai executat deloc. Mișcarea activului de cotație a fost de 1,300 bps. Avem o stivă întreagă pentru 3 și un stub pentru 1,300.
Weekendul verde de pe grafic
Luni dimineața pe Slack, înainte ca cineva să fi deschis USDCUSD: am tipărit 4% peste noapte. Cineva a întrebat dacă ar trebui să scalăm dimensiunea paper. M-am uitat la grafic, apoi la Kraken, apoi la stub.
| Element de registru | Ce a stocat motorul | Sâmbătă, nativ | Același moment, în dolari |
|---|---|---|---|
| Colateral inactiv | 70,000 USDC × 1.00 | 70,000 USDC | ~$61,600 |
| Marcă perp BTC | BTCUSDC last | ~23,000 USDC (26,000 pe Kraken) | BTCUSD ~$20,200 |
| Nerealizat pe 1.5 BTC | +4,300 USDC | +4,300 USDC | în mare parte peg-ul, ceva bitcoin |
| NAV raportat | 104,300 „USD” | 104,300 USDC | ~$91,800 |
Cărțile USDT aveau caricatura inversă. USDT se tranzacționa peste paritate, deci un cont flat cu marjă USDT arăta un câștig în dolari pe care nici el nu-l câștigase, și o marcă BTCUSDT prea joasă relativ la BTCUSD. Dacă clasificai două perp-uri BTC „identice” în weekendul acela, unul pe un venue USDC și unul pe un venue USDT, clasificai tokenurile de cotație și îi spuneai alpha.
Contul paper, cel care deținea de fapt USDC, era mai aproape de adevăr decât dashboard-ul de research. Nu a pretins niciodată că e dolari. Asta am făcut noi în export.
Exportul pe care l-am livrat luni
USDC s-a târât înapoi spre $1 după ce Treasury, Fed și FDIC au spus că deponenții SVB vor fi despăgubiți integral, și după ce Circle a spus că va acoperi un deficit. Până luni peg-ul era în mare parte peticit. Fișierul FX stub, care fusese greșit timp de 48 de ore, era din nou corect.
Dar barele zilnice l-au ascuns. Eșantionul de 00:00 UTC din 11 martie a prins USDC deja jos, sau deja revenind, în funcție de furnizor, iar eșantionul din 12 martie era un film diferit. Dacă stocai doar NAV și nu marca de cotație, nu puteai reconstitui care. Weekendul urât s-a aplatizat într-un blip suficient de mic ca să-l ignori, ceea ce am și făcut, pentru că eșantionam zilnic.
Ce ținem acum pe carte sunt trei serii, întotdeauna, chiar și când stau una peste alta luni de zile:
- NAV în activul de cotație al venue-ului, unitatea pe care o poți retrage efectiv.
- Activul de cotație versus USD, o bandă reală, inclusiv sâmbăta, inclusiv 0.87, inclusiv orele în care Coinbase nu făcea conversii.
- NAV în dolari, ca serie derivată, astfel încât o etichetă de grafic USD să aibă un părinte.
Dacă un agent scrie backtestul, verificarea e aceeași. Cere-i activul de cotație al fiecărei poziții și al cash-ului. Dacă răspunde USD pe un venue USDC, run-ul nu este un run în dolari. Martie 2023 este săptămâna pe care o reiau când cineva îmi spune că distincția nu mișcă Sharpe-ul. L-a mișcat pe acesta mai mult decât a făcut-o strategia, iar strategia era partea pentru care aveam modele.
← Toate articolele


