4.3 KiB
phoenix-perps-service Specification
Purpose
Read actual Phoenix perpetual positions for a Solana authority without signing or modifying accounts, preserving precise current USD notional and subaccount identities.
Requirements
Requirement: Read every active position under the authority
The integration SHALL read official Phoenix REST trader state for the requested wallet authority at PDA index 0. It SHALL include nonzero positions from cross-margin and isolated subaccounts, preserve subaccount/symbol identity independently of sequence numbers, and return an immutable deterministically ordered result. No signing, trading or account activation SHALL occur.
Scenario: Cross and isolated positions share a symbol
- WHEN subaccounts 0 and 2 both have a nonzero SOL position
- THEN both positions are returned with distinct identities
- AND zero-sized positions are excluded
Requirement: Current USD notional uses documented market units
Position direction SHALL follow signed quantity. USD size SHALL be the absolute current notional, calculated using exact decimal arithmetic from base lots divided by 10 to the market's base-lot decimal exponent and multiplied by its current mark price. Collateral, entry value and raw lot counts SHALL NOT be used as USD size. Missing conversion data SHALL fail the read.
Scenario: Convert a short position
- WHEN a position has -125 base lots, base-lot exponent 2 and mark price 104.45 USD
- THEN it represents -1.25 base units, Short direction and 130.5625 USD notional
Requirement: Read failures cannot masquerade as empty portfolios
HTTP, authentication, malformed schema, identity mismatch and numeric conversion errors SHALL fail the read. Requests SHALL have bounded timeouts. Only a valid response with no nonzero positions SHALL produce an empty result. Required mark prices SHALL be positive and finite.
Scenario: Missing mark price or rejected access
- WHEN a required price is missing or an HTTP request is rejected
- THEN the read fails instead of returning an empty or partial portfolio
Scenario: Empty account
- WHEN a valid trader snapshot has no subaccounts or no nonzero positions
- THEN an empty result is returned without market-price requests
Scenario: Public API rate limit
- WHEN the shared adapter issues requests for PROD and TEST
- THEN request starts SHALL be spaced at least one second apart
- AND HTTP 429 SHALL fail the lookup and establish a shared cooldown from Retry-After (seconds or HTTP date, 60 seconds fallback)
- AND lookups during cooldown SHALL fail without external calls, with no immediate retry
Requirement: Separate account capital and precise position metrics
The reader SHALL return immutable account balances separately from positions, including funded empty Cross accounts. Quote lots SHALL convert at 1e-6 USD. Price PnL SHALL use precise virtual quote and signed base amounts at mark. Initial position margin SHALL follow size-dependent tiers including venue interpolation and rounding. Unsupported non-USDC collateral SHALL make affected valuations unavailable instead of being ignored.
Scenario: Size between margin tiers
- WHEN a position lies between two leverage tiers
- THEN its initial margin follows interpolated integer leverage and upward quote-lot rounding, rather than the market's maximum leverage
Scenario: Unsupported spot collateral
- WHEN an account has nonzero spot collateral that cannot be valued reliably
- THEN collateral, equity and closing Value are unavailable while independent exposure and price PnL remain available
Requirement: Estimated account and isolated closing proceeds
Equity SHALL include collateral, undiscounted price PnL and signed unsettled funding once. Estimated Value SHALL subtract estimated closing taker fees with account fee overrides. Settled fees/funding SHALL NOT be subtracted again. Isolated position leverage/ROI SHALL use actual collateral; Cross position leverage/ROI SHALL remain unavailable unless their venue convention is verified.
Scenario: Funding signs and fee override
- WHEN collateral is 100 USD, PnL 5 USD, unsettled funding -2 USD, and estimated exit fee 1 USD
- THEN equity is 103 USD and estimated Value 102 USD
- AND effective Cross leverage uses 103 USD as its denominator