103: EMC Perps: propagate Phoenix TWAP warnings through the tree to Perpetual Contracts

This commit is contained in:
2026-10-26 06:38:53 +01:00
parent e71a8daa8d
commit cfb49ed896
22 changed files with 797 additions and 7696 deletions
+35 -5
View File
@@ -444,9 +444,11 @@ og alarmer beholder deres afhængigheder og cache.
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, én mark price pr.
unikt åbent marked, ét TWAP-opslag, når der er positioner, og et risikolæs pr. synlig
konto. Lokal trader-adresseafledning bruger den eksisterende Solana-afhængighed.
ét REST-opslag pr. wallet. Phoenix bruger trader-state og ét TWAP-opslag for wallets
med eksisterende subaccounts, også uden åbne positioner. Metadata hentes ved positioner eller fyldte
TWAP-ordrer med resterende delordrer; én mark price hentes pr. unikt åbent marked,
og der foretages et risikolæs pr. synlig konto. Lokal trader-adresseafledning bruger
den eksisterende Solana-afhængighed.
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.
@@ -463,7 +465,7 @@ EMC viser **Position | Risk | Direction | Margin | Collateral | Leverage | Expos
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
hidtidige konfiguration med Jupiter før Phoenix. En venue uden positioner, Cross-konti eller TWAP-advarsler
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
@@ -471,7 +473,7 @@ rækkeobjekter bevares; kun ændrede rækkeværdier eller børn opdateres, også
ældes i et ellers uændret snapshot. Vinduesstart er 1100 × 600,
og smallere vinduer kan scrolle vandret, når kolonnernes minimumsbredder kræver det.
TWAP vises kun på en eksisterende Phoenix-position, når ordren selv har et faktisk
TWAP-progress vises på en eksisterende Phoenix-position, når ordren selv har et faktisk
fill og resterende delordrer. Ufyldte ordrer opretter ingen rækker og vises heller
ikke på en position, som allerede fandtes. Progressbaren måler udførte delordrer;
teksten er estimeret resterende tid fra seneste TWAP-observation, fx `≈ 28:32:10`
@@ -519,6 +521,34 @@ EMC spørger hver miljøservice straks ved åbning og hvert tredje sekund uden a
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.
### TWAP-advarsler
En fyldt Phoenix-TWAP med resterende delordrer, som mangler markedsmetadata eller
ikke matcher en åben position, bevares som en advarsel. TWAP-cellen viser en lille
orange trekant med udråbstegn og kort tekst. Advarslen står på positionen, når
ordren sikkert kan tilknyttes den; ellers på den ejende Cross-gruppe. Gruppen
bevares også uden kapital eller positioner. En umatchet isoleret ordre står på
Phoenix med sit korrekte subaccount i tooltip, aldrig på en opdigtet Cross-konto.
En matchet ordre uden brugbart estimat for næste udførelse viser en timing-advarsel
sammen med sin progressbar; det er ikke bevis på, at udførelsen er stoppet.
Advarsler samles op gennem **position → Cross → Phoenix → wallet → Perpetual
Contracts**, eller den faktiske isolerede gren uden Cross. Hvert niveau tæller
hver underliggende ordre én gang, også når undergrene er foldet sammen. Flere
ordrer vises med antal. Tooltip kan rulles og bliver stående, mens markøren er over
cellen eller detaljerne. Det identificerer wallet, konto/position, årsag,
TWAP-adresse, asset/subaccount, rå tællere/fills og oprindeligt observationstidspunkt.
Ukendte symboler, enheder, dollarværdier og tider opfindes ikke. Marginrisiko og
kapitaltotaler ændres ikke af advarslerne.
Ordren skal stadig selv have faktiske fills og resterende delordrer. Ufyldte og
færdige ordrer er skjult, også i gruppeoptællinger. Succesfulde opslag rydder løste
advarsler helt op gennem træet og bevarer de øvrige. Fejl bevarer tidligere data og
markerer berørte advarsler og opsummeringer `retained`; efter fem minutter eller ved
fremtidigt tidsstempel markeres de `stale`. Originale tider bevares, også ved fejl i
EMC's snapshot-læsning. Alderskontrol bruger eksisterende UI-polling; fem minutter
er en datakvalitetsgrænse, ikke en udførelsesfrist. Se [Phoenix-læsningen](PhoenixPerps.md#twap-observations).
### Risiko i Perps
Risk står ved positionsnavnet og bruger tekst og en statusprik, mens Long/Short-
+32 -18
View File
@@ -1,6 +1,6 @@
# Phoenix Perps read-only integration
`PhoenixPerpsService`, `PhoenixPerpsAccount`, `PhoenixPerpsPosition`, `PhoenixAccountRisk` and `PhoenixTwapOrder` live in
`PhoenixPerpsService`, `PhoenixPerpsAccount`, `PhoenixPerpsPosition`, `PhoenixAccountRisk`, `PhoenixTwapOrder` and `PhoenixTwapWarning` live in
`com.r35157.libs.phoenix.perps`; the REST implementation is in `impl.ref`.
They contain no Evelyn/UI types or signing/trading operations. NenjimHub creates
one adapter without a portfolio cache as `phoenix.perps.default` and injects it into both Evelyn
@@ -31,19 +31,21 @@ The implementation uses these official endpoints at `https://perp-api.phoenix.tr
position remains visible with unknown price-dependent metrics when the mark is absent.
A present nonpositive or malformed price still fails the lookup.
4. [`GET /v1/trader/{authority}/twap?traderPdaIndex=0`](https://github.com/Ellipsis-Labs/rise-public/blob/master/ts/src/api/traders/client.ts)
supplies active TWAP snapshots when the wallet has held positions. Only filled orders
with remaining children on matching existing positions are returned; see [TWAP observations](#twap-observations).
supplies TWAP snapshots for every wallet with existing subaccounts, including accounts
without positions. Filled outstanding orders become matched progress or warning observations;
zero-fill and completed orders remain invisible. See [TWAP observations](#twap-observations).
5. [`GET /v1/view/trader/{pubkey}`](https://docs.phoenix.trade/api/trader/get-trader)
supplies risk for each visible account, including funded empty Cross accounts.
Its key is the derived trader account, not the wallet or a TWAP key. See
[venue-reported account risk](#venue-reported-account-risk).
An empty trader state with no visible funded account needs only the first request.
A funded empty Cross account additionally needs its risk read, without market/TWAP reads.
Otherwise metadata is fetched once
and each active symbol's price once per wallet lookup, including when that symbol is
held in several subaccounts, followed by one TWAP read and each visible account's
risk read. Request starts are spaced at least one second apart across both environments to avoid
A trader state with no subaccounts needs only the first request. Otherwise TWAP is
read immediately after state, with its original response receipt time preserved.
Metadata is fetched once if there are held positions or filled outstanding TWAPs;
marks are fetched only for distinct held symbols, followed by each visible account's
risk read. Registered empty accounts without relevant TWAPs need no metadata or
marks; funded or warning-only empty Cross accounts also receive their risk read.
Request starts are spaced at least one second apart across both environments to avoid
bursts of per-market reads. Each HTTP request has a 10-second timeout and uses the
Hub's existing HTTP client (no redirects by default). On HTTP 429 the adapter respects
`Retry-After` (seconds or HTTP date; 60 seconds if missing/invalid). Further calls
@@ -93,9 +95,9 @@ following each completed cycle. Jupiter and Phoenix are attempted independently
each configured wallet. Successful results replace only that wallet/venue; failures
log wallet and venue and retain its last successful result. A valid empty result
replaces that venue's positions and account balances. EMC hides the venue heading
when it has neither position rows nor Cross accounts; its read status remains in
when it has neither position rows, Cross accounts nor TWAP warnings; its read status remains in
the wallet tooltip and the scope still contributes to snapshot totals.
Funded Cross accounts remain visible when they no longer hold positions. Snapshot reads never fetch
Funded Cross accounts and Cross accounts with eligible warnings remain visible when they no longer hold positions. Snapshot reads never fetch
external data; EMC's three-second polling remains unchanged.
Positions and prices are separate REST reads and can belong to different slots.
@@ -147,13 +149,25 @@ neutral isolated distance, venue tier colors and group summaries.
## TWAP observations
TWAP data is matched by requested authority, PDA index, subaccount and market `assetId`
using Phoenix metadata. Only an existing nonzero position can carry a TWAP, and the
order itself must have `baseLotsFilled > 0` and remaining children. A new order without
fills stays invisible even if the market already has a position. No TWAP-only row or
group total is created. A successful snapshot without that active order clears its
TWAP data. A failed or invalid TWAP read fails the whole wallet/venue observation,
using Phoenix metadata. Only an existing nonzero position carries a progressbar, but
an eligible order that cannot be matched is preserved in its account's immutable
warning list. The order itself must have `baseLotsFilled > 0` and remaining children.
A new order without fills stays invisible everywhere, even if the market already
has a position; completed orders also create no warning. No synthetic position or
monetary group total is created. A successful snapshot without that active order
clears its progress and warning data. A failed or invalid TWAP read fails the whole wallet/venue observation,
retaining the previous complete snapshot and its original timestamps as `(retained)`.
Warnings retain the TWAP address/order sequence, asset and subaccount IDs, raw
execution/fill counters and original receipt time. Missing market metadata or no
matching open position is an observed mismatch, not proof of delisting, cancellation
or stopped execution. Missing conversion data is shown as raw lots/unknown values;
warning-only markets do not trigger mark-price requests. A matched order with no
usable future next-execution estimate keeps its progress plus a timing warning.
Account/schema/counter mismatches still fail the read; valid missing-market warnings
do not discard independent positions or account risk. See the [EMC warning presentation](Evelyn.md#twap-advarsler)
for exact placement, ancestor propagation and retained/stale qualifications.
The [SDK snapshot](https://github.com/Ellipsis-Labs/rise-public/blob/master/ts/src/api/traders/twap.ts)
reports `nChildOrders` as the total execution count including dust. With explicit
`nDustOrders > 0`, regular count is total minus dust count. Legacy zero/omitted dust
@@ -184,8 +198,8 @@ EMC appends **TWAP** after uPnL. Its progressbar overlays a snapshot duration wi
unbounded total hours, such as `≈ 28:32:10` or `≈ 128:32:10`. It updates only with new
snapshots and is explicitly as of the tooltip's `Updated` time. Due/unavailable
timing shows `Due / unknown`; a failed venue shows `Retained` instead of a fresh
countdown. Other venues, positions without a relevant order and all groups have
empty TWAP cells. Tooltips show progress, `Estimated completion`, total/next/fill
countdown. Cells without relevant progress or warnings stay empty. Groups show warning
summaries when applicable, never aggregated progressbars. Tooltips show progress, `Estimated completion`, total/next/fill
quantities, different dust sizes where relevant, observation time and limitations.
Total and next-child USD values reuse that position's already fetched Phoenix mark,