100: Add Perps collateral, leverage, value, uPnL and gross-exposure totals in EMC

This commit is contained in:
2026-10-24 17:56:20 +02:00
parent 7e36b7ef95
commit 28640f3203
35 changed files with 9110 additions and 180 deletions
+62 -28
View File
@@ -435,38 +435,72 @@ Price Index beregnes og vises, mens de øvrige fem felter fortsat er nul. Legacy
## 12. Perps-service og Mission Control
`EvelynPerpsService` udleverer et immutable `PerpsSnapshot` gennem det parameterløse
`getPositionsSnapshot()`. Læsning foretager ingen integrationskald. Hub'en starter separate processer
`evelyn.perps.prod` og `evelyn.perps.test`, injicerer de tilsvarende eksisterende `JupiterPerpsService`-views
og en fælles `PhoenixPerpsService` uden positionscache registreret som `phoenix.perps.default`.
`PerpsWalletConfiguration` indeholder en `SolanaWalletId`-adresse, der også bruges som række-ID og label.
Hub'en ejer de hardcodede lister: seks PROD-adresser og én TEST-adresse fra issue #98.
Begge integrationer læser de samme wallets i det pågældende miljø.
`getPositionsSnapshot()`. Læsning foretager ingen integrationskald. Hub'en starter
separate processer `evelyn.perps.prod` og `evelyn.perps.test`, hver med sin eksisterende
wallet-liste: seks PROD-adresser og én TEST-adresse fra issue #98. Begge får en fælles
read-only `JupiterPerpsOverview` og en fælles `PhoenixPerpsService`; sidstnævnte er
registreret som `phoenix.perps.default`. De eksisterende Jupiter-services til handel
og alarmer beholder deres afhængigheder og cache.
Servicen henter åbne Jupiter- og Phoenix-positioner asynkront ved start og venter 60 sekunder efter hvert
fuldført gennemløb, så runder ikke overlapper. Den eksisterende Solana-cache med 60 sekunders TTL bevares
for Jupiter. Phoenix læses gennem REST med 10 sekunders timeout pr. request, mindst ét sekund mellem
request-start på tværs af miljøer og fælles cooldown ved HTTP 429. Data er periodiske snapshots.
Servicen læser asynkront ved start og venter 60 sekunder efter hvert fuldført gennemløb.
Runder overlapper ikke og afhænger ikke af EMC's synlighed. Jupiter-overblikket bruger
ét REST-opslag pr. wallet. Phoenix bruger trader-state, metadata og én mark price pr.
unikt åbent marked. Begge har 10 sekunders request-timeout; Phoenix bevarer fælles
pacing og 429-cooldown. En fuld opdatering tager opslagstid plus pausen, ikke nødvendigvis
ét minut. Implementeringens `close()` afbryder worker'en; consumer-API'et har kun læsning.
Jupiters positionskonto er stabilt ID; retning og `positionSize()` vises, kendte mints bliver
SOL-PERP/BTC-PERP/ETH-PERP, og ukendte mints vises som adressen. Positioner sorteres efter konto.
Phoenix bruger authority-wallet og trader PDA index 0 med alle returnerede cross/isolated-subaccounts.
Kun nonzero-positioner medtages. ID og sortering bygger på PDA-index, subaccount-index og markedssymbol;
sekvensnumre indgår ikke. Retningen kommer fra signed quantity, label er fx SOL-PERP, og USD-størrelsen er
absolut base-mængde gange mark price, beregnet med decimalpræcision. Se [Phoenix-integrationen](PhoenixPerps.md)
for dokumenterede enheder, endpoints og begrænsninger.
Snapshot'et adskiller isolerede positioner fra Cross-konti med egne balancer. Pengebeløb
er præcise USD-decimaler, og null betyder utilgængelig. Før første succes indeholder
hver konfigureret wallet/venue en ukendt scope, ingen syntetiske positioner. Succes
publiceres pr. wallet/venue; en fejl beholder den kombinations sidste observation og
oprindelige succes-tidspunkt. Andre wallets/venues forsøges stadig. Et gyldigt tomt svar
rydder den pågældende scope og kan totalisere nul; HTTP-/formatfejl kan ikke. En gyldig
Cross-konto med kapital bevares, selv om dens sidste position lukkes.
Før første vellykkede opslag er der ingen positioner. Succes publiceres i et nyt snapshot pr. wallet/venue;
fejl logges og bevarer netop den kombinations sidste data. De øvrige venues og wallets forsøges stadig.
Et vellykket tomt svar fjerner kun den pågældende venues positioner og bevarer gruppen.
Fejl i HTTP, authentication, svarformat eller konvertering er ikke tomme porteføljer.
Der vises ingen indikator for forældede data. Implementationens `close()` afbryder worker'en;
consumer-API'et indeholder kun læsning.
EMC viser **Position | Direction | Margin | Collateral | Leverage | Exposure | Value | uPnL**
under den synlige rod **Perpetual Contracts**. Isolerede positioner har wallet → venue →
position; Phoenix Cross har wallet → venue → Cross → position. Positionens konto-ID
bestemmer identitet og tilhørsforhold, aldrig instrumentteksten. Wallets følger den
hidtidige konfiguration med Jupiter før Phoenix. En venue uden positioner eller Cross-konti
skjules og vises igen, når der kommer indhold. Skjulte venues indgår fortsat i snapshot
og totaler; deres læsestatus findes på wallet-rækkens tooltip. En Cross-konto med kapital
holder derfor Phoenix synlig, selv uden åbne positioner. Eksisterende foldestatus, markering og
rækkeobjekter bevares; uændrede snapshots opdaterer ikke træet. Vinduesstart er 1100 × 600,
og smallere vinduer kan scrolle vandret, når kolonnernes minimumsbredder kræver det.
EMC spørger hver miljøservice straks ved åbning og hvert tredje sekund uden at blokere JavaFX-tråden.
Skjul/luk stopper kun EMC-polling; services fortsætter. Træet er wallet → venue → position med Jupiter før
Phoenix og uden et ekstra subaccount-niveau. Tre kolonner, farver, formatering, foldestatus og markering
bevares for eksisterende rækker. Nye/lukkede positioner afstemmes efter ID.
Der er ingen sample-data, Refresh-knap, handel, signering eller kontoaktivering i denne læsevej.
Exposure er brutto: 100 USD Long + 100 USD Short giver 200 USD. Dollar-uPnL summeres
med fortegn. Collateral/Value tæller hver isoleret position og hver delt Cross-konto én
gang, inklusive ubrugt kapital på de inkluderede Cross-konti. Cross-positionernes
marginkrav lægges ikke til faktisk kontokapital. Mangler en nødvendig del, er netop
feltets total utilgængelig; en delsum præsenteres aldrig som total. Ingen summering eller
gennemsnitsberegning af leverage eller PnL-procenter. Totalerne afhænger ikke af foldning.
Isoleret leverage er Exposure / positiv Collateral; uPnL-procent er 100 × pris-uPnL /
positiv Collateral. På Cross-positioner er Collateral et initialt marginkrav i USD,
ikke særskilt ejet kapital. Cross-gruppens leverage er bruttoeksponering / udiskonteret
equity før estimerede exitgebyrer. Cross-positionernes leverage og ROI-procent er
utilgængelige, fordi Phoenix-konventionerne ikke er verificeret; dollar-uPnL vises.
Cross-positioners Value er ikke entydigt defineret og vises som —. Kontoudnyttelse er
ikke implementeret.
Value er et estimat ved referencepriser, ikke et eksekverbart tilbud. Phoenix medregner
collateral, pris-uPnL og signed uafregnet funding og fratrækker estimerede takergebyrer
med kontoens fee override. Slippage, price impact, swaps, netværksgebyrer og kontorent
indgår ikke. Ukendt spot-collateral gør de berørte værdiansættelser utilgængelige.
**Jupiter Value er foreløbig utilgængelig**, fordi API'ets netværdi trækker åbningsgebyrer
fra igen, og collateral-/profitloft-semantikken ikke er fuldt verificeret. Se
[Jupiter-overblikket](JupiterPerpsOverview.md) og [Phoenix-integrationen](PhoenixPerps.md)
for datakilder, enheder og beregninger.
Beløb har tusindtalsseparator og to decimaler, leverage × og pris-uPnL et synligt fortegn.
Positiv uPnL er grøn, negativ rød, afrundet nul neutral uden negativt nul. De svage
Long/Short-baggrunde bevares; grupper har tydeligere skrift og ingen retningsfarve.
Tooltips forklarer definitioner, manglende værdier og sidste succesfulde læsetidspunkt.
Efter fejl markeres en synlig venue som retained; læsestatus for skjulte venues findes
på wallet-rækkens tooltip. Gamle tal beskrives ikke som nye.
EMC spørger hver miljøservice straks ved åbning og hvert tredje sekund uden at blokere
JavaFX-tråden. Skjul/luk stopper kun EMC-polling. Der er ingen sample-data, Refresh-knap,
handel, signering, kontoaktivering eller automatisk genstart af Hub'en i denne læsevej.
Den kanoniske systembeskrivelse findes i
[Evelyn: services og status](../../r35157_docs/projects/evelyn/README.md#evelynperpsservice).