Aller directement au contenu principal

Créer un tableau de bord en temps réel sur les contrats à terme perpétuels SOL grâce à l'API Phoenix

Mis à jour le
Aug 07, 2026

10 min de lecture

Présentation générale

Phoenix est une plateforme dédiée aux contrats à terme perpétuels (également appelés « perps ») sur Solana met à disposition, via une API publique, les fluctuations de cours, la profondeur du carnet d'ordres, les relevés de transactions, les graphiques en chandeliers et l'historique des funding rates. Ce guide vous explique comment utiliser cette API pour créer un tableau de bord en temps réel permettant de consulter les données en direct Solana , avec un exemple d'application React que vous pouvez cloner, exécuter et personnaliser.


En bref
  • Phoenix est une plateforme de contrats à terme perpétuels Solana qui met à disposition des données de marché en temps réel via une API publique gratuite en lecture seule.
  • Ce guide explique le fonctionnement des contrats à terme perpétuels, présente Phoenix et décrit ses API REST et WebSocket.
  • Vous devrez récupérer les données de configuration du marché et les chandeliers historiques via REST, puis diffuser les données en temps réel via une seule connexion WebSocket.
  • Vous saurez gérer les particularités de la charge utile de Phoenix, vous reconnecter sans problème et changer de période sur les graphiques sans perdre l'état actuel.
  • Une application React d'exemple associée rassemble tous ces éléments au sein d'un tableau de bord « perps » que vous pouvez cloner, exécuter et étendre.

Vos missions


  • Découvrez les perps et comment Phoenix les met en œuvre sur Solana.
  • Clonez et exécutez l'application de tableau de bord fournie à titre d'exemple.
  • Abonnez-vous aux six canaux WebSocket de Phoenix (marché, carnet d'ordres, métiers, bougies, taux de financement, échange) à partir d'une seule connexion partagée.
  • Gérer les particularités des données de Phoenix (encodage numérique, variation de la structure du carnet d'ordres, mélange d'unités de temps) à une seule interface.

Ce dont vous aurez besoin


  • Un Quicknode si vous prévoyez d'étendre le tableau de bord avec des lectures sur la chaîne (facultatif pour l'API Phoenix en lecture seule).
  • Node.js 22 et versions ultérieures
  • Maîtrise de React et de TypeScript
  • Comprendre comment créer des abonnements Solana

Que sont les « Perps » ?

Les Perps sont des produits dérivés qui répliquent le cours d'un actif sous-jacent et qui n'ont pas de date d'échéance. Les traders prennent des positions longues ou courtes à l'aide d'un effet de levier, et le programme maintient le prix de la position aligné sur le cours au comptant grâce à un paiement de financement périodique entre les positions longues et courtes. Il n'y a ni date de règlement ni renouvellement. Une position peut être détenue indéfiniment tant qu'elle reste solvable.

Quatre facteurs influencent les marchés des titres à revenu fixe :


  • Le « Mark Price » est le prix de référence du contrat dans le cadre du programme. C'est sur cette base que sont calculés le PnL non réalisé, les liquidations et le financement.
  • Le cours « oracle » (ou indice) correspond au cours de référence externe (généralement un agrégat « oracle » provenant de marchés au comptant tels que Pyth). Le cours de marché et le cours « oracle » doivent évoluer de manière très proche l'un de l'autre. Une divergence persistante est le signe d'une situation de tension ou d'illiquidité.
  • Le taux de financement correspond au paiement périodique entre les positions longues et courtes qui permet de maintenir le mark proche de l'oracle. Conformément à la convention utilisée dans ce guide et dans les charges utiles de réponse de Phoenix : un financement positif signifie que les positions longues paient les positions courtes, tandis qu'un financement négatif signifie que les positions courtes paient les positions longues.
  • L'« open interest » correspond à la valeur notionnelle totale de toutes les positions ouvertes, c'est-à-dire la somme des montants, effet de levier compris, de toutes les positions longues et courtes ouvertes ; il ne s'agit pas des garanties bloquées dans le protocole, qui constituent la TVL. Il s'agit d'un indicateur permettant d'évaluer le niveau de concentration des positions sur le marché.

Qu'est-ce que Phoenix ?

Phoenix est une bourse décentralisée Solana. Lancée à l'origine sous la forme d'un carnet d'ordres à cours limité sur la chaîne pour le trading au comptant, elle a depuis mis en place un produit de contrats à terme perpétuels, qui fait l'objet du présent guide. L'appariement s'effectue entièrement au sein d'un Solana sur mainnet moteur d'appariement hors chaîne.

Pour toute application qui a uniquement besoin de lire des données de marché (un tableau de bord, un flux de cours, un outil d'analyse), Phoenix met à votre disposition tout ce dont vous avez besoin à l'adresse perp-api.phoenix.trade. Il existe un hôte REST pour les instantanés et un hôte WebSocket pour les mises à jour push. Les points de terminaison publics en lecture ne nécessitent ni clé API, ni en-têtes signés, ni portefeuille. La passation d'ordres sur la blockchain est une intégration distincte qui nécessite un portefeuille connecté et ne relève pas du champ d'application de ce guide.

L'API WebSocket de Phoenix

Phoenix diffuse des données de marché en temps réel via un endpoint WebSocket unique endpoint wss://perp-api.phoenix.trade/v1/ws. Vous ouvrez une connexion et vous vous abonnez aux chaînes de votre choix. Le tableau de bord présenté dans ce guide vous permet de vous abonner aux six chaînes.

Chaque abonnement suit le même schéma : envoyer un message JSON contenant un type de s'abonner, un chaîne nom, et un symbole:

{
"type": "subscribe",
"subscription":
{
"channel": "<channel>",
"symbol": "SOL"
}
}

Les six canaux utilisés par le tableau de bord, et ce que chacun d'entre eux vous apporte :


  • marché: Affiche les principaux indicateurs du marché : le prix de référence, le prix Oracle, le prix moyen, le volume sur 24 heures, l'intérêt ouvert et le taux de financement actuel.
  • carnet d'ordres: Fournit, à chaque message, un instantané complet de niveau 2 du carnet d'ordres, comprenant tous les niveaux d'achat et de vente, avec le prix et le volume.
  • métiers: Streams les transactions Streams au fur et à mesure qu'elles se produisent : prix, volume, sens de la transaction (achat ou vente) et horodatage.
  • bougies: Données Streams chandeliers « ouverture/ Streams haut/plus Streams » (OHLCV) pour une période choisie (1m, 5m, 1h, etc.).
  • taux de financement: Affiche le taux de financement actuel à chaque fois qu'il change.
  • échange: Donne une vue d'ensemble de l'état de santé global de l'exchange. Envoie un instantané à la connexion, puis des mises à jour delta.

Phoenix propose également une API REST complète comprenant des points de terminaison pour les instantanés de données de marché, l'état des traders, l'inscription, l'authentification et la création de transactions.

L'application d'exemple associée est un tableau de bord React en lecture seule qui établit une connexion WebSocket unique avec Phoenix, s'abonne aux six canaux et affiche les données dans cinq panneaux :


  • Aperçu du marché: Barre d'en-tête affichant le prix de référence, le prix Oracle, la variation sur 24 heures, le volume sur 24 heures, l'intérêt ouvert et le taux de financement actuel. Alimentée par le marché et taux de financement canaux. Comprend un badge indiquant l'état de la connexion provenant du échange chaîne.
  • Tableau des prix: Graphique en chandeliers avec sélecteur de période (1m, 5m, 15m, 1h, 4h, 1d). Les données sont initialisées à partir de REST au chargement et à la reconnexion, puis mises à jour en temps réel à partir du bougies chaîne.
  • Carnet d'ordres: Les 15 principaux niveaux d'achat et de vente, avec leur volume cumulé et leur écart en points de base. Actualisé à chaque carnet d'ordres message.
  • Flux d'actualités commerciales: Diffusion en direct des dernières transactions, avec un code couleur par camp. Mise à jour à chaque métiers message.
  • Informations sur le marché: tableau de référence statique présentant les frais, les niveaux d'effet de levier, les exigences de marge, la taille du tick et celle du lot.

Capture d'écran du tableau de bord Phoenix Perps affichant tous les panneaux relatifs à SOL

PhoenixProvider / usePhoenix() dans src/ws/PhoenixWebSocket.tsx gère le WebSocket unique partagé, la gestion des abonnements, la diffusion des messages, la logique de reconnexion, le changement de plage horaire et l'objet d'état exposé.

Clonez-le et exécutez-le localement pour suivre le reste du guide :

git clone https://github.com/quiknode-labs/qn-guide-examples.git
cd solana/phoenix-dashboard
npm install
npm run dev

Récupérer la configuration du marché et allumer les bougies

Même un tableau de bord s'appuyant sur un WebSocket nécessite tout de même REST. Le socket se connecte en cours de transmission et envoie la mise à jour suivante, et non un instantané. Deux éléments d'état doivent être renseignés avant que les mises à jour en temps réel n'arrivent : la configuration statique du marché (que le WebSocket ne transmet jamais) et la série historique des chandeliers (afin que le graphique comporte plus d'une barre).

GET /exchange/market/{symbol} renvoie un seul objet JSON contenant les paramètres statiques du marché. Exemple de réponse abrégée :

{
"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
}
}

Le tableau de bord utilise ces données pour le panneau de référence « Informations sur le marché » (effet de levier maximal, tableau des niveaux, exigences de marge, frais, taille du tick/lot). Aucun de ces champs n'est transmis via un canal WebSocket ; REST est donc la seule source d'information.

GET /candles?symbol=SOL&timeframe=1m&limit=500 renvoie un tableau d'objets « candle » avec des horodatages en millisecondes :

[
{
"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
}
]

S'abonner au WebSocket Phoenix

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));
};

Deux points à noter : bougies porte le période, et échange comporte encodage : « json » (sans symbole).

Chaque charge utile comporte soit un chaîne ou un type champ. Envoyer en fonction de celui qui est présent :

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;
}
};

Une fois la connexion établie et les abonnements envoyés, le serveur commence à diffuser des messages. Vous trouverez ci-dessous le détail du contenu de chacun des six canaux :

Marché

Mise à jour des statistiques de marché affiche les numéros d'en-tête :

{
"channel": "market",
"markPx": 170.42,
"oraclePx": 170.41,
"midPx": 170.42,
"prevDayPx": 168.15,
"dayNtlVlm": 218842710.42,
"openInterest": 4521234.5,
"funding": 0.00012
}

Remplacer la mémoire interne MarketStats en gros pour chaque message. Calculer la variation en pourcentage sur 24 heures par rapport à markPx et prevDayPx. Le tableau de bord utilise financement tant pour le badge d'en-tête que pour la série d'historique local à la session affichée à côté du graphique.

Carnet d'ordres

Mise à jour de L2Book Il s'agit d'un instantané L2 complet, et non d'un delta. Remplacez le « book » en mémoire à chaque message. Phoenix envoie cette charge utile sous deux formes (voir Gérer les particularités de la charge utile de Phoenix). Si Mise à jour des statistiques de marché n'est pas encore arrivé, en déduire midPx Extrait de l'en-tête : (meilleur cours acheteur + meilleur cours vendeur) / 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
}

Métiers

TradesMessage est en mode « ajout uniquement » sur le réseau. Le tableau de bord ajoute les données au début et limite le nombre de lignes à 100. Champs clés :

{
"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
}
]
}

Bougies

CandleData streams bougie en cours à mesure qu'elle est mise à jour, ainsi que la bougie clôturée à la fin de l'intervalle. L'unité de temps sur ce canal est la seconde (celle de REST est la milliseconde). Le tableau de bord effectue des opérations « upsert » en temps: si une bougie présentant les mêmes temps s'il existe déjà, remplacez-le ; sinon, ajoutez-le à la fin.

{
"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
}
}

Taux de financement

Mise à jour du taux de financement remplace le taux de financement actuel. Le tableau de bord affiche également une { timestamp: Date.now(), rate } ajout dans un tableau local à la session afin que l'historique des financements puisse être représenté graphiquement parallèlement au cours. Aucune persistance n'est requise.

{
"channel": "fundingRate",
"funding": 0.00012,
"fundingTime": 1747556400
}

Échange

Le échange Ce canal décrit l'état général de la bourse. Il envoie un instantané une fois au moment de l'abonnement, puis delta messages. Chaque delta a un op; le seul élément auquel ce tableau de bord réagit est exchangeStatusChanged. Les autres opérations de delta au niveau du marché sont délibérément ignorées.

{
"channel": "exchange",
"type": "snapshot",
"active": true,
"gated": false
}

Pour conclure

Vous disposez désormais d’un terminal SOL Perps entièrement basé sur le modèle « push », piloté de bout en bout par l’API publique de Phoenix. Vous savez à partir de quels points de terminaison REST extraire les données, à quels six canaux WebSocket vous abonner, et comment harmoniser les particularités des données de Phoenix (encodage numérique, structure du carnet d’ordres, unités de temps) en un seul point de contrôle, afin que le reste de votre code reste épuré. Les logiques de reconnexion, de réabonnement et de changement de période sont toutes intégrées, ce qui permet au tableau de bord de résister à une perte de connexion sans devenir obsolète. À partir de là, vous pouvez le diriger vers n’importe quel marché Phoenix, y intégrer le contexte on-chain à partir d’un endpoint Quicknode , ou reconstruire l’interface utilisateur dans le framework de votre choix.

Foire aux questions

Le WebSocket Phoenix est-il soumis à une limitation de débit ou à une authentification ?

Les flux publics en lecture seule décrits ici ne nécessitent ni clé API, ni en-têtes signés, ni portefeuille. Consultez la documentation de Phoenix pour connaître les limites de débit actuelles, car les limites de l'infrastructure publique peuvent évoluer.

Quelle est la différence entre le « mark price » et l'« oracle price » ?

Le « prix de référence » correspond au prix de référence du protocole pour le contrat perpétuel ; il sert à régler les P&L latentes, les liquidations et le financement. Le « prix Oracle » (ou « prix de l'indice ») est une référence externe (généralement un agrégat des cours au comptant sur différentes plateformes). Ces deux prix doivent évoluer de manière très proche l'un de l'autre ; une divergence persistante constitue un signal d'alerte que le tableau de bord met en évidence sous la forme d'une superposition de graphiques.

Puis-je l'utiliser pour d'autres marchés Phoenix, comme le BTC ou l'ETH ?

Oui. L'interface REST et WebSocket de Phoenix est identique sur tous les marchés. Il suffit de paramétrer le symbole au niveau du fournisseur, de transférer l'état en mémoire vers une table de correspondance par symbole, et ces six mêmes canaux transmettent toutes les données affichées sur le tableau de bord.

Puis-je passer des ordres depuis ce tableau de bord ?

Non. Le trading n'entre pas dans le champ d'application de ce guide. La passation d'ordres sur Phoenix est une interaction Solana sur la chaîne qui nécessite un portefeuille connecté et des transactions signées, deux éléments que l'interface API publique en lecture seule utilisée ici ne prend pas en charge.

Ressources