Leestijd: 10 min
Overzicht
Phoenix is een handelsplatform voor perpetual futures (ook wel ‘perps’ genoemd) op Solana via een openbare API informatie biedt over koersontwikkelingen, de diepte van het orderboek, transactiegegevens, candlesticks en de financieringsgeschiedenis. In deze handleiding wordt uitgelegd hoe je die API kunt gebruiken om een realtime dashboard te bouwen waarmee je live gegevens Solana kunt bekijken, inclusief een bijbehorende React-voorbeeldapp die je kunt klonen, uitvoeren en uitbreiden.
- Phoenix is een Solana handelsplatform voor eeuwigdurende futures dat realtime marktgegevens beschikbaar stelt via een gratis, alleen-lezen openbare API.
- In deze handleiding wordt uitgelegd wat perpetual futures zijn, wordt Phoenix geïntroduceerd en wordt een overzicht gegeven van de REST- en WebSocket-API’s ervan.
- Je zult de marktconfiguratie en historische kaarten via REST laden en vervolgens livegegevens via één WebSocket-verbinding streamen.
- Je zult de eigenaardigheden van de payload van Phoenix onder de knie krijgen, de verbinding netjes herstellen en de tijdframes van de grafieken wijzigen zonder de status te verliezen.
- Een bijbehorende React-voorbeeldapp brengt dit alles samen in een perps-dashboard dat je kunt klonen, uitvoeren en uitbreiden.
Wat je gaat doen
- Krijg een overzicht van perps en hoe Phoenix deze op Solana weergeeft.
- Kloon de bijbehorende voorbeeld-dashboard-app en voer deze uit.
- Abonneer je op alle zes Phoenix WebSocket-kanalen (
markt,orderboek,beroepen,kaarsen,financieringsrente,ruil) via één gedeelde verbinding. - Pak de eigenaardigheden van de Phoenix-payload (numerieke codering, variaties in de vorm van het orderboek, vermenging van tijdseenheden) op één grenspunt aan.
Wat je nodig hebt
- Een Quicknode als je van plan bent het dashboard uit te breiden met on-chain-opvragingen (optioneel voor de alleen-lezen Phoenix API).
- Node.js 22+
- Kennis van React en TypeScript
- Uitleg over het aanmaken van Solana -abonnementen
Wat zijn Perps?
Perps zijn derivaten die de koers van een onderliggende waarde volgen en geen vervaldatum hebben. Handelaren nemen long- of shortposities in met hefboomwerking, en het programma zorgt ervoor dat de koers van de positie in lijn blijft met de spotkoers door middel van een periodieke financieringsbetaling tussen long- en shortposities. Er is geen afwikkelingsdatum en er vindt geen doorrol plaats. Een positie kan voor onbepaalde tijd worden aangehouden, zolang deze solvabel blijft.
Vier factoren zijn bepalend voor de obligatiemarkten:
- De markprijs is de referentieprijs van het programma voor het contract. Dit is de prijs waarop ongerealiseerde winst en verlies, liquidaties en funding worden verrekend.
- De orakelprijs (of indexprijs) is de externe referentieprijs (meestal een orakelaggregaat van spotmarkten zoals Pyth). De marktprijs en de orakelprijs moeten elkaar nauw volgen. Een aanhoudende afwijking duidt op spanning of illiquiditeit.
- Het fundingpercentage is de periodieke betaling tussen long- en shortposities die ervoor zorgt dat de markprijs dicht bij de oracleprijs blijft. De conventie die in deze handleiding en in de responsberichten van Phoenix wordt gehanteerd: een positieve funding betekent dat longposities aan shortposities betalen, een negatieve funding betekent dat shortposities aan longposities betalen.
- De open interest is de totale nominale waarde van alle openstaande posities, dat wil zeggen de som van de hefboomomvang van alle open long- en shortposities, en niet het in het protocol vastgezette onderpand, wat de TVL is. Het geeft een indicatie van de mate waarin de markt gepositioneerd is.
Wat is Phoenix?
Phoenix is een gedecentraliseerde beurs Solana. Het platform is gelanceerd als een on-chain limietorderboek voor spothandel en heeft sindsdien een product voor perpetual futures geïntroduceerd, dat centraal staat in deze handleiding. Het matchen vindt volledig plaats in een Solana op mainnet off-chain matching-engine.
Voor elke toepassing die alleen marktgegevens hoeft te lezen (een dashboard, een prijsfeed, een analysetool), biedt Phoenix alles wat je nodig hebt op perp-api.phoenix.trade. Er is één REST-host voor snapshots en één WebSocket-host voor push-updates. Voor openbare lees-eindpunten zijn geen API-sleutel, geen ondertekende headers en geen wallet nodig. Het plaatsen van orders on-chain is een afzonderlijke integratie waarvoor een gekoppelde wallet vereist is en valt buiten het bestek van deze handleiding.
De Phoenix WebSocket-API
Phoenix stelt live marktgegevens beschikbaar via één endpoint wss://perp-api.phoenix.trade/v1/ws. Je opent één verbinding en abonneert je op de kanalen die je nodig hebt. Het dashboard in deze handleiding abonneert zich op alle zes.
Elk abonnement verloopt volgens hetzelfde patroon: stuur een JSON-bericht met een type van abonneren, een kanaal naam, en een symbool:
{
"type": "subscribe",
"subscription":
{
"channel": "<channel>",
"symbol": "SOL"
}
}
De zes kanalen die het dashboard gebruikt, en wat elk kanaal je biedt:
markt: Geeft de belangrijkste marktcijfers weer: marktprijs, orakelprijs, middenkoers, 24-uursvolume, openstaande posities en het huidige fundingpercentage.orderboek: Geeft bij elk bericht een volledig L2-overzicht van het orderboek weer, met alle bied- en laatkoersen, inclusief prijs en omvang.beroepen: Streams transacties Streams op het moment dat ze plaatsvinden: prijs, omvang, richting (kopen of verkopen) en tijdstempel.kaarsen: OHLCV-kaarsgegevens ( Streams ) voor een gekozen tijdsperiode (1m,5m,1h, enz.).financieringsrente: Geeft het huidige financieringspercentage weer telkens wanneer dit verandert.ruil: Geeft een overzicht van de algehele status van de exchange. Verstuurt bij het verbinden een momentopname en daarna delta-updates.
Phoenix biedt ook een volledige REST-API met eindpunten voor momentopnames van marktgegevens, de status van handelaren, registratie, authenticatie en het opstellen van transacties.
De bijbehorende voorbeeldapp is een alleen-lezen React-dashboard dat één WebSocket-verbinding met Phoenix tot stand brengt, zich abonneert op alle zes kanalen en de gegevens weergeeft in vijf panelen:
- Marktoverzicht: Kopbalk met daarin de markprijs, de oracleprijs, de verandering in de afgelopen 24 uur, het volume in de afgelopen 24 uur, de openstaande posities en het huidige fundingpercentage. Aangedreven door de
marktenfinancieringsrentekanalen. Bevat een badge met de verbindingsstatus van deruilkanaal. - Prijsgrafiek: Kaarsengrafiek met een tijdschaalkeuzeschakelaar (
1m,5m,15m,1h,4h,1d). Bij het laden en bij het opnieuw verbinden wordt de gegevensset vanuit REST geladen, waarna deze live wordt bijgewerkt vanuit dekaarsenkanaal. - Orderboek: Top 15 van bied- en laatkoersen met cumulatieve omvang en spread in basispunten. Wordt bij elke
orderboekbericht. - Handelsfeed: Live-uitzending van de meest recente transactie, per partij met een eigen kleur aangeduid. Wordt bij elke
beroepenbericht. - Marktinformatie: Statisch overzicht met informatie over vergoedingen, hefboomniveaus, margevereisten, tickgrootte en lotgrootte.

PhoenixProvider / usePhoenix() in src/ws/PhoenixWebSocket.tsx is verantwoordelijk voor de enige gedeelde WebSocket, het bijhouden van abonnementen, het verzenden van berichten, de logica voor het herstellen van de verbinding, het wisselen van tijdsbestekken en het blootgestelde statusobject.
Kloon het en voer het lokaal uit om de rest van de handleiding te kunnen volgen:
git clone https://github.com/quiknode-labs/qn-guide-examples.git
cd solana/phoenix-dashboard
npm install
npm run dev
Marktconfiguratie ophalen en kaarsen aansteken
Een dashboard dat via een WebSocket werkt, heeft nog steeds REST nodig. De socket sluit halverwege aan en verstuurt de volgende update, geen momentopname. Er moeten twee statusgegevens worden ingevuld voordat de live-updates binnenkomen: de statische marktconfiguratie (die de WebSocket nooit verstuurt) en de reeks historische candlesticks (zodat de grafiek meer dan één staafje bevat).
GET /exchange/market/{symbol} geeft één JSON-object terug met de statische marktparameters. Een ingekort voorbeeld van een antwoord:
{
"symbol": "SOL",
"assetId": 1,
"marketStatus": "active",
"marketPubkey": "...",
"tickSize": 0.01,
"baseLotsDecimals": 3,
"takerFee": 0.0005,
"makerFee": 0.0001,
"fundingIntervalSeconds": 3600,
"fundingPeriodSeconds": 86400,
"maxFundingRatePerIntervalPercentage": 0.05,
"openInterestCapBaseLots": "100000000",
"maxLiquidationSizeBaseLots": "5000000",
"isolatedOnly": false,
"leverageTiers": [
{ "maxLeverage": 20, "maxSizeBaseLots": 1000000, "limitOrderRiskFactor": 0.05 },
{ "maxLeverage": 10, "maxSizeBaseLots": 5000000, "limitOrderRiskFactor": 0.1 }
],
"riskFactors": {
"maintenance": 0.03,
"backstop": 0.01,
"highRisk": 0.05,
"upnl": 0.5,
"upnlForWithdrawals": 0.25,
"cancelOrder": 0.001
}
}
Het dashboard gebruikt deze gegevens voor het referentiepaneel ‘Marktinfo’ (maximale hefboom, niveautabel, margevereisten, kosten, tick-/lotgrootte). Geen van deze velden wordt via een WebSocket-kanaal verzonden, dus REST is de enige bron.
GET /candles?symbol=SOL&timeframe=1m&limit=500 geeft een array terug met candle-objecten met tijdstempels in milliseconden:
[
{
"time": 1747556400000,
"open": 170.21,
"high": 170.55,
"low": 170.14,
"close": 170.42,
"volume": 1284.5,
"volumeQuote": 218842.71,
"tradeCount": 42,
"markOpen": 170.20,
"markHigh": 170.54,
"markLow": 170.13,
"markClose": 170.41
}
]
Abonneer je op de Phoenix WebSocket
const ws = new WebSocket('wss://perp-api.phoenix.trade/v1/ws');
const subscriptions = [
{ type: 'subscribe', subscription: { channel: 'market', symbol: 'SOL' } },
{ type: 'subscribe', subscription: { channel: 'orderbook', symbol: 'SOL' } },
{ type: 'subscribe', subscription: { channel: 'trades', symbol: 'SOL' } },
{ type: 'subscribe', subscription: { channel: 'candles', symbol: 'SOL', timeframe: '1m' } },
{ type: 'subscribe', subscription: { channel: 'fundingRate', symbol: 'SOL' } },
{ type: 'subscribe', subscription: { channel: 'exchange', encoding: 'json' } },
];
ws.onopen = () => {
for (const msg of subscriptions) ws.send(JSON.stringify(msg));
};
Twee dingen om op te letten: kaarsen draagt de tijdsbestek, en ruil draagt codering: 'json' (zonder symbool).
Elke payload heeft ofwel een kanaal of een type veld. Verwerk op basis van wat aanwezig is:
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
const key = msg.channel ?? msg.type;
switch (key) {
case 'market': return onMarketStats(msg);
case 'orderbook': return onOrderbook(msg);
case 'trades': return onTrades(msg);
case 'candles': return onCandle(msg);
case 'fundingRate': return onFundingRate(msg);
case 'exchange': return onExchange(msg);
case 'subscriptionConfirmed': return;
case 'subscriptionError':
case 'error':
console.error('Phoenix error', msg);
return;
}
};
Zodra de verbinding tot stand is gebracht en de abonnementen zijn verzonden, begint de server met het versturen van berichten. Hieronder volgt een overzicht van de inhoud van elk van de zes kanalen:
Markt
Marktstatistieken-update past de kopnummers aan:
{
"channel": "market",
"markPx": 170.42,
"oraclePx": 170.41,
"midPx": 170.42,
"prevDayPx": 168.15,
"dayNtlVlm": 218842710.42,
"openInterest": 4521234.5,
"funding": 0.00012
}
Vervang de in-memory MarketStats groothandelsprijs per bericht. Bereken de procentuele verandering over 24 uur ten opzichte van markPx en prevDayPx. Het dashboard maakt gebruik van financiering zowel voor het embleem in de koptekst als voor een reeks sessiegebonden geschiedenisgegevens die naast de grafiek worden weergegeven.
Orderboek
L2BookUpdate is een volledige L2-snapshot, geen delta. Vervang het boek in het geheugen bij elk bericht. Phoenix verstuurt deze payload in twee vormen (zie Omgaan met de eigenaardigheden van de Phoenix-payload). Als Marktstatistieken-update is nog niet aangekomen, afleiden midPx uit de koptekst: (beste biedprijs + beste laatprijs) / 2.
{
"channel": "orderbook",
"symbol": "SOL",
"orderbook": {
"bids": [[170.41, 42.5], [170.40, 118.0], [170.38, 75.2]],
"asks": [[170.42, 30.1], [170.43, 95.0], [170.45, 210.3]],
"mid": 170.415
},
"bypassExecutionBand": false
}
Vakgebieden
TradesMessage wordt via de verbinding uitsluitend aangevuld. Het dashboard voegt gegevens toe aan het begin en beperkt het aantal rijen tot 100. Belangrijke velden:
{
"channel": "trades",
"trades": [
{
"tradeSequenceNumber": 482113,
"slot": 281234567,
"slotIndex": 3,
"timestamp": "1747556421",
"time": 1747556421000,
"side": "b",
"price": 170.42,
"size": 12.5,
"notional": 2130.25,
"numFills": 1
}
]
}
Kaarsen
CandleData streams huidige kaars streams terwijl deze wordt bijgewerkt, en de gesloten kaars wanneer het interval afloopt. De tijdseenheid op dit kanaal is seconden (REST is milliseconden). Het dashboard voegt gegevens toe of vervangt ze door tijd: als een kaars met dezelfde tijd als het al bestaat, vervang het dan; anders voeg het toe.
{
"channel": "candles",
"symbol": "SOL",
"timeframe": "1m",
"candle": {
"time": 1747556460,
"open": 170.42,
"high": 170.50,
"low": 170.38,
"close": 170.45,
"volume": 92.1,
"volumeQuote": 15710.2
}
}
Financieringsrente
Update financieringsrente vervangt het huidige financieringspercentage. Het dashboard stuurt ook een { timestamp: Date.now(), rate } opname in een sessie-specifieke array, zodat de financieringsgeschiedenis samen met de koers in een grafiek kan worden weergegeven. Er is geen permanente opslag nodig.
{
"channel": "fundingRate",
"funding": 0.00012,
"fundingTime": 1747556400
}
Wisselkantoor
De ruil Het kanaal geeft de algemene toestand van de beurs weer. Het verzendt een momentopname eenmaal bij het aanmelden, en vervolgens delta berichten. Elk delta heeft een op; het enige waarop dit dashboard reageert, is exchangeStatusChanged. Andere delta-operaties op marktniveau worden bewust buiten beschouwing gelaten.
{
"channel": "exchange",
"type": "snapshot",
"active": true,
"gated": false
}
Tot slot
Je beschikt nu over een volledig op push-berichten gebaseerde SOL-perps-terminal die volledig wordt aangestuurd door de openbare API van Phoenix. Je weet van welke REST-eindpunten je gegevens moet ophalen, op welke zes WebSocket-kanalen je je moet abonneren en hoe je de eigenaardigheden van de payload van Phoenix (numerieke codering, vorm van het orderboek, tijdseenheden) op één punt kunt afvlakken, zodat de rest van je code overzichtelijk blijft. De logica voor het opnieuw verbinden, opnieuw abonneren en het wisselen van tijdsbestek is allemaal zo geïntegreerd dat het dashboard een verbroken verbinding overleeft zonder verouderd te raken. Van hieruit kun je het op elke Phoenix-markt richten, on-chain-context toevoegen via een Quicknode endpoint, of de gebruikersinterface opnieuw opbouwen in het framework van jouw voorkeur.
Veelgestelde vragen
Wordt het gebruik van Phoenix WebSocket beperkt of is er authenticatie vereist?
Voor de hier beschreven openbare feeds die alleen-lezen zijn, is geen API-sleutel, geen ondertekende headers en geen wallet nodig. Raadpleeg de Phoenix-documentatie voor de huidige limieten, aangezien de limieten van de openbare infrastructuur kunnen veranderen.
Wat is het verschil tussen de markprijs en de oracleprijs?
De markprijs is de referentieprijs van het protocol voor het eeuwigdurende contract en wordt gebruikt voor de afwikkeling van ongerealiseerde winst en verlies, liquidaties en funding. De oracleprijs (of indexprijs) is een externe referentie (meestal een gemiddelde van spotmarkten). Deze twee prijzen zouden elkaar nauw moeten volgen; een aanhoudende afwijking is een stresssignaal dat door het dashboard wordt weergegeven als een overlay op de grafiek.
Kan ik dit ook gebruiken voor andere Phoenix-markten, zoals BTC of ETH?
Ja. De REST- en WebSocket-interface van Phoenix is in alle markten identiek. Stel het symbool voor de hele provider in als parameter, zet de status in het geheugen om naar een map per symbool, en dezelfde zes kanalen leveren alle gegevens die op het dashboard worden weergegeven.
Kan ik vanuit dit dashboard transacties uitvoeren?
Nee. Handelen valt buiten het bestek van deze handleiding. Het plaatsen van orders op Phoenix is een on-chain interactie Solana waarvoor een gekoppelde wallet en ondertekende transacties nodig zijn; beide worden niet ondersteund door de hier gebruikte, alleen-lezen openbare API.
