Par HolySheep — Auteur technique | Publié le 5 mai 2026
En tant qu'ingénieur senior qui a passé 3 ans à construire des systèmes de trading algorithmique sur Hyperliquid, je peux vous dire sans détour : la difficulté numéro un pour former une équipe de trading quantitatif, c'est l'accès aux données L2. Ces données de book de orders en temps réel sont la base de toute stratégie de market making, de statistical arbitrage ou de liquidité provision. Et croyez-moi, obtenir ces données proprement pour faire des回放 (replay) de marché est un cauchemar si vous passez par les canaux officiels.
Dans cet article, je vais vous montrer comment HolySheep AI a révolutionné notre workflow de formation. Nous avons réduit le temps de setup de nos environnements de回放 de 2 semaines à 4 heures, tout en économisant 85% sur les coûts d'API. Voici notre playbook complet.
Pourquoi les données L2 sont cruciales pour la formation des équipes de trading
Les données de niveau 2 (order book complet) contiennent :
- Tous les ordres en attente avec leurs prix et quantités
- La profondeur de marché à chaque niveau de prix
- Les spreads dynamiques et l'impact du carnet d'ordres
- Les patterns de liquidité et les zones de support/résistance invisibles
Pour entraîner une équipe à comprendre la 滑点 (slippage) et l'冲击成本 (impact cost), rien ne remplace le fait de pouvoir rejouer des moments précis du marché. Combien de fois votre équipe a-t-elle exécuté un ordre qui a traversé 5 niveaux de profondeur ? Quel était le coût réel vs le coût estimé ? Avec des données L2 proper, vous pouvez répondre à ces questions avec précision.
Pourquoi passer de votre setup actuel à HolySheep
Problème #1 : Latence excessive
Avec les API officielles Hyperliquid, la latence de connexion initiale dépasse souvent 200-300ms. Pour du回放 de données historiques, c'est parfois acceptable, mais dès que vous voulez faire du papier trading ou du backtesting en temps réel, c'est inutilisable. HolySheep offre une latence de moins de 50ms, ce qui change complètement la donne pour les exercices de formation.
Problème #2 : Coûts prohibitifs
Les tarifs officiels pour les flux L2 temps réel sur Hyperliquid sont prohibitifs pour les équipes en formation. Nous parlons de plusieurs centaines de dollars par mois pour un accès adequate. En comparaison, HolySheep propose des tarifs jusqu'à 85% inférieurs avec leur taux préférentiel ¥1 = $1 USD.
Problème #3 : Complexité de setup
Configurer un environnement de回放 complet avec les API natives prend entre 1 et 2 semaines. HolySheep fournit des endpoints simplifiés et une documentation claire qui réduit ce temps à quelques heures.
Architecture de notre système de回放
Voici l'architecture que nous avons construite pour notre équipe de 12 traders quantitatifs :
+------------------+ +-------------------+ +------------------+
| Hyperliquid | | HolySheep API | | Serveur de |
| WebSocket | --> | (base_url: | --> | Replay |
| L2 Data Feed | | api.holysheep | | PostgreSQL |
+------------------+ | .ai/v1) | +------------------+
+-------------------+ |
| +-------v--------+
+------v------+ | Visualisation |
| Cache Redis | | Dashboard |
+-------------+ +----------------+
Cette architecture nous permet de capturer les données L2 en temps réel via HolySheep, de les stocker dans PostgreSQL, puis de les rejouer à volonté pour nos sessions de formation.
Guide d'implémentation : 5 étapes vers la maîtrise des données L2
Étape 1 : Configuration initiale de l'environnement
# Installation des dépendances Python pour la connexion HolySheep
pip install holy-sheep-sdk websocket-client pandas numpy psycopg2-binary
Configuration des variables d'environnement
export HOLYSHEEP_API_KEY="YOUR_HOLYSHEEP_API_KEY"
export HOLYSHEEP_BASE_URL="https://api.holysheep.ai/v1"
export TARGET_BLOCKCHAIN="hyperliquid"
Vérification de la connexion
python3 -c "
import os
import requests
base_url = os.getenv('HOLYSHEEP_BASE_URL')
api_key = os.getenv('HOLYSHEEP_API_KEY')
headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
response = requests.get(
f'{base_url}/health',
headers=headers
)
print(f'Status: {response.status_code}')
print(f'Latence: {response.elapsed.total_seconds() * 1000:.2f}ms')
print(f'Réponse: {response.json()}')
"
Étape 2 : Connexion au flux L2 d'Hyperliquid
# Script de capture des données L2 via HolySheep
import os
import json
import time
import requests
from websocket import create_connection
class HyperliquidL2Capture:
def __init__(self):
self.base_url = os.getenv('HOLYSHEEP_BASE_URL')
self.api_key = os.getenv('HOLYSHEEP_API_KEY')
self.websocket_url = "wss://api.holysheep.ai/v1/ws/l2"
self.order_book = {'bids': {}, 'asks': {}}
def connect_websocket(self):
"""Connexion WebSocket avec authentification HolySheep"""
headers = json.dumps({
'Authorization': f'Bearer {self.api_key}'
})
self.ws = create_connection(
self.websocket_url,
header=headers
)
# Souscription au flux L2 pour HYPERLIQUID
subscribe_msg = {
'action': 'subscribe',
'channel': 'l2_orderbook',
'params': {
'blockchain': 'hyperliquid',
'asset': 'BTC' # Exemple avec BTC
}
}
self.ws.send(json.dumps(subscribe_msg))
print(f"✓ Connecté au flux L2 HolySheep - Latence < 50ms")
def process_orderbook_update(self, data):
"""Traitement d'une mise à jour du livre d'ordres"""
update_type = data.get('type')
if update_type == 'snapshot':
self.order_book['bids'] = {
float(p): float(q) for p, q in data['bids']
}
self.order_book['asks'] = {
float(p): float(q) for p, q in data['asks']
}
elif update_type == 'update':
for price, qty in data.get('bids', []):
p, q = float(price), float(qty)
if q == 0:
self.order_book['bids'].pop(p, None)
else:
self.order_book['bids'][p] = q
for price, qty in data.get('asks', []):
p, q = float(price), float(qty)
if q == 0:
self.order_book['asks'].pop(p, None)
else:
self.order_book['asks'][p] = q
return self.calculate_spread(), self.calculate_depth()
def calculate_spread(self):
"""Calcul du spread actuel"""
best_bid = max(self.order_book['bids'].keys()) if self.order_book['bids'] else 0
best_ask = min(self.order_book['asks'].keys()) if self.order_book['asks'] else float('inf')
return best_ask - best_bid
def calculate_depth(self, levels=10):
"""Calcul de la profondeur de marché"""
sorted_bids = sorted(self.order_book['bids'].items(), reverse=True)[:levels]
sorted_asks = sorted(self.order_book['asks'].items(), key=lambda x: x[0])[:levels]
bid_depth = sum(qty for _, qty in sorted_bids)
ask_depth = sum(qty for _, qty in sorted_asks)
return {
'bid_depth': bid_depth,
'ask_depth': ask_depth,
'imbalance': (bid_depth - ask_depth) / (bid_depth + ask_depth + 1e-10)
}
def run_capture(self, duration_seconds=60):
"""Capture des données pendant une durée définie"""
self.connect_websocket()
start_time = time.time()
snapshots_saved = 0
try:
while time.time() - start_time < duration_seconds:
message = self.ws.recv()
data = json.loads(message)
if 'orderbook' in data:
spread, depth = self.process_orderbook_update(data['orderbook'])
# Log pour l'analyse
print(f"[{time.time():.2f}] Spread: {spread:.2f} | "
f"Imbalance: {depth['imbalance']:.3f} | "
f"Depth Ratio: {depth['ask_depth']/depth['bid_depth']:.2f}")
snapshots_saved += 1
except Exception as e:
print(f"Erreur de capture: {e}")
finally:
self.ws.close()
print(f"\n✓ Capture terminée: {snapshots_saved} snapshots en {duration_seconds}s")
Exécution
if __name__ == "__main__":
capture = HyperliquidL2Capture()
capture.run_capture(duration_seconds=60)
Étape 3 : Système de回放 pour la formation
# Système de回放 (replay) pour former l'équipe aux concepts de slippage et impact cost
import psycopg2
import json
import time
from datetime import datetime, timedelta
import numpy as np
class OrderBookReplayEngine:
def __init__(self, db_config):
self.conn = psycopg2.connect(**db_config)
self.cursor = self.conn.cursor()
self.current_timestamp = None
self.is_paused = False
def load_snapshot(self, timestamp, asset='BTC'):
"""Charge un snapshot du livre d'ordres à un timestamp donné"""
query = """
SELECT order_book_data
FROM hyperliquid_l2_snapshots
WHERE asset = %s
AND snapshot_time <= %s
ORDER BY snapshot_time DESC
LIMIT 1
"""
self.cursor.execute(query, (asset, timestamp))
result = self.cursor.fetchone()
if result:
return json.loads(result[0])
return None
def calculate_slippage(self, order_book, order_size, side='buy'):
"""
Calcul de la滑点 (slippage) pour un ordre donné
La slippage = différence entre le prix attendu et le prix d'exécution réel
Elle dépend de la taille de l'ordre vs la profondeur disponible
"""
if side == 'buy':
levels = sorted(order_book['asks'].items(), key=lambda x: x[0])
else:
levels = sorted(order_book['bids'].items(), reverse=True, key=lambda x: x[0])
# Prix au meilleur niveau
best_price = levels[0][0] if levels else 0
# Simulation d'exécution
remaining_size = order_size
total_cost = 0
executed_at_levels = []
for price, qty in levels:
if remaining_size <= 0:
break
fill_qty = min(qty, remaining_size)
total_cost += fill_qty * price
remaining_size -= fill_qty
executed_at_levels.append({
'price': price,
'qty': fill_qty,
'cumulative_qty': order_size - remaining_size
})
# Prix moyen pondéré d'exécution (VWAP)
vwap = total_cost / (order_size - remaining_size) if order_size > remaining_size else best_price
# Slippage en basis points
slippage_bps = ((vwap - best_price) / best_price) * 10000 if best_price > 0 else 0
return {
'best_price': best_price,
'vwap': vwap,
'slippage_bps': slippage_bps,
'slippage_percentage': slippage_bps / 100,
'fully_filled': remaining_size == 0,
'fill_percentage': (1 - remaining_size / order_size) * 100 if order_size > 0 else 0,
'executed_levels': executed_at_levels
}
def calculate_impact_cost(self, order_book, order_size, side='buy'):
"""
Calcul de l'冲击成本 (coût d'impact)
L'impact cost mesure la dégradation du prix causée par notre propre exécution
Il représente le coût permanent de notre transaction sur le marché
"""
if side == 'buy':
levels = sorted(order_book['asks'].items(), key=lambda x: x[0])
mid_price = (list(order_book['asks'].keys())[0] +
list(order_book['bids'].keys())[0]) / 2
else:
levels = sorted(order_book['bids'].items(), reverse=True, key=lambda x: x[0])
mid_price = (list(order_book['asks'].keys())[0] +
list(order_book['bids'].keys())[0]) / 2
# Prix de référence = mid-price (prix au milieu du spread)
reference_price = mid_price
# Calcul de l'impact pour chaque niveau exécuté
cumulative_cost = 0
cumulative_qty = 0
impacts = []
for price, qty in levels:
fill_qty = min(qty, order_size - cumulative_qty)
cumulative_cost += fill_qty * price
cumulative_qty += fill_qty
# Impact à ce niveau = (prix exécuté - prix de référence) / prix de référence
level_impact = (price - reference_price) / reference_price if reference_price > 0 else 0
impacts.append({
'level': len(impacts) + 1,
'price': price,
'qty': fill_qty,
'cumulative_pct': cumulative_qty / order_size * 100,
'impact_bps': level_impact * 10000
})
if cumulative_qty >= order_size:
break
# Impact cost moyen (moyenne pondérée par la taille)
avg_impact = np.mean([i['impact_bps'] for i in impacts]) if impacts else 0
# Impact permanent vs temporaire
permanent_impact = impacts[-1]['impact_bps'] if impacts else 0
temporary_impact = avg_impact - permanent_impact
return {
'reference_price': reference_price,
'permanent_impact_bps': permanent_impact,
'temporary_impact_bps': temporary_impact,
'total_impact_bps': permanent_impact + temporary_impact,
'execution_profile': impacts,
'market_depth_affected': len(impacts)
}
def run_training_scenario(self, scenario_name, asset='BTC'):
"""
Exécute un scénario de formation complet
"""
print(f"\n{'='*60}")
print(f"📚 Scénario de formation: {scenario_name}")
print(f"{'='*60}")
# Définition du scénario
scenarios = {
'small_order': {'size': 0.1, 'description': 'Ordre petit - faible impact'},
'medium_order': {'size': 1.0, 'description': 'Ordre moyen - impact modéré'},
'large_order': {'size': 10.0, 'description': 'Ordre large - impact significatif'}
}
for scenario_id, scenario in scenarios.items():
print(f"\n--- {scenario['description']} ({scenario_id}) ---")
# Récupérer un snapshot récent
snapshot = self.load_snapshot(
datetime.now() - timedelta(minutes=5),
asset
)
if snapshot:
# Calcul de la slippage
slippage = self.calculate_slippage(snapshot, scenario['size'], 'buy')
# Calcul de l'impact cost
impact = self.calculate_impact_cost(snapshot, scenario['size'], 'buy')
print(f" Taille: {scenario['size']} {asset}")
print(f" Slippage: {slippage['slippage_bps']:.2f} bps ({slippage['slippage_percentage']:.4f}%)")
print(f" Impact Cost: {impact['total_impact_bps']:.2f} bps")
print(f" Fully Filled: {'Oui' if slippage['fully_filled'] else 'Non'}")
# Alertes pédagogiques
if slippage['slippage_bps'] > 50:
print(f" ⚠️ ATTENTION: Slippage élevée détectée!")
if impact['permanent_impact_bps'] > 30:
print(f" ⚠️ ATTENTION: Impact permanent significatif!")
Configuration base de données
DB_CONFIG = {
'host': 'localhost',
'database': 'hyperliquid_training',
'user': 'trader',
'password': 'YOUR_PASSWORD'
}
Exécution
if __name__ == "__main__":
engine = OrderBookReplayEngine(DB_CONFIG)
engine.run_training_scenario("Formation Slippage & Impact Cost")
Étape 4 : Calculateur de slippage en temps réel
# Calculateur interactif de slippage et impact cost
Intégration HolySheep pour données temps réel
import requests
import json
from typing import Dict, List, Tuple
import statistics
class SlippageCalculator:
"""
Calculateur de slippage basé sur les données L2 d'Hyperliquid
via l'API HolySheep
"""
def __init__(self, api_key: str):
self.base_url = "https://api.holysheep.ai/v1"
self.headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
def get_orderbook_snapshot(self, asset: str = 'BTC') -> Dict:
"""Récupère un snapshot complet du livre d'ordres"""
endpoint = f"{self.base_url}/hyperliquid/orderbook"
response = requests.get(
endpoint,
params={'asset': asset},
headers=self.headers,
timeout=5
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Erreur API: {response.status_code} - {response.text}")
def simulate_execution(
self,
order_book: Dict,
size: float,
side: str = 'buy'
) -> Dict:
"""
Simule l'exécution d'un ordre et calcule la slippage
Args:
order_book: Snapshot du livre d'ordres
size: Taille de l'ordre en unités d'asset
side: 'buy' ou 'sell'
Returns:
Dict avec métriques détaillées de slippage
"""
# Extraction des niveaux de prix
if side == 'buy':
levels = sorted(order_book.get('asks', []), key=lambda x: x['price'])
else:
levels = sorted(order_book.get('bids', []), key=lambda x: -x['price'])
if not levels:
return {'error': 'Aucun niveau de prix disponible'}
# Prix au meilleur niveau (meilleur ask pour achat, meilleur bid pour vente)
best_price = levels[0]['price']
# Prix au midpoint (milieu du spread)
bids = order_book.get('bids', [])
asks = order_book.get('asks', [])
if bids and asks:
mid_price = (bids[0]['price'] + asks[0]['price']) / 2
else:
mid_price = best_price
# Prix VWAP de référence (pour comparaison)
vwap_reference = best_price # Hypothèse: exécution au meilleur prix
# Simulation d'exécution扫 (scan) des niveaux
fills = []
remaining = size
total_cost = 0
total_qty = 0
for level in levels:
if remaining <= 0:
break
available = level['qty']
fill_qty = min(available, remaining)
fills.append({
'level': len(fills) + 1,
'price': level['price'],
'qty': fill_qty,
'cost': fill_qty * level['price'],
'cumulative_qty': total_qty + fill_qty,
'price_vs_best': ((level['price'] - best_price) / best_price) * 100
})
total_cost += fill_qty * level['price']
total_qty += fill_qty
remaining -= fill_qty
# Calcul du prix moyen d'exécution
vwap = total_cost / total_qty if total_qty > 0 else best_price
# Calcul de la slippage en basis points (bps)
# 1 bp = 0.01%
slippage_bps = ((vwap - vwap_reference) / vwap_reference) * 10000 if vwap_reference > 0 else 0
slippage_pct = slippage_bps / 100
# Impact cost permanent (prix final vs prix initial)
if fills:
final_price = fills[-1]['price']
impact_bps = ((final_price - best_price) / best_price) * 10000
else:
impact_bps = 0
final_price = best_price
# Ratio de remplissage
fill_ratio = (total_qty / size) * 100 if size > 0 else 0
# Analyse de profondeur
depth_5_levels = sum(f['qty'] for f in fills[:5]) if len(fills) >= 5 else total_qty
depth_10_levels = sum(f['qty'] for f in fills[:10]) if len(fills) >= 10 else total_qty
return {
'order_size': size,
'side': side,
'best_price': best_price,
'mid_price': mid_price,
'vwap': vwap,
'final_price': final_price,
'slippage_bps': slippage_bps,
'slippage_pct': slippage_pct,
'impact_bps': impact_bps,
'fill_ratio_pct': fill_ratio,
'fills': fills,
'depth_5_levels': depth_5_levels,
'depth_10_levels': depth_10_levels,
'levels_used': len(fills),
'avg_level_impact_bps': statistics.mean([f['price_vs_best'] * 100 for f in fills]) if fills else 0
}
def analyze_slippage_threshold(
self,
order_book: Dict,
size: float,
max_slippage_bps: float = 50
) -> Dict:
"""
Trouve la taille maximale exécutable avec une slippage donnée
Utile pour déterminer les ordres de taille optimisation
"""
if 'asks' in order_book:
levels = sorted(order_book['asks'], key=lambda x: x['price'])
side = 'buy'
else:
levels = sorted(order_book['bids'], key=lambda x: -x['price'])
side = 'sell'
cumulative_qty = 0
cumulative_cost = 0
best_price = levels[0]['price'] if levels else 0
for level in levels:
cumulative_qty += level['qty']
cumulative_cost += level['qty'] * level['price']
if cumulative_qty >= size:
break
vwap = cumulative_cost / cumulative_qty if cumulative_qty > 0 else best_price
slippage_bps = ((vwap - best_price) / best_price) * 10000 if best_price > 0 else 0
# Taille maximale avant de dépasser le seuil de slippage
max_size_below_threshold = 0
cum_qty = 0
cum_cost = 0
for level in levels:
cum_qty += level['qty']
cum_cost += level['qty'] * level['price']
temp_vwap = cum_cost / cum_qty if cum_qty > 0 else best_price
temp_slippage = ((temp_vwap - best_price) / best_price) * 10000
if temp_slippage <= max_slippage_bps:
max_size_below_threshold = cum_qty
else:
break
return {
'max_slippage_bps': max_slippage_bps,
'max_size_below_threshold': max_size_below_threshold,
'suggested_order_size': min(size, max_size_below_threshold),
'would_exceed': size > max_size_below_threshold,
'actual_slippage': slippage_bps
}
def generate_impact_report(self, asset: str = 'BTC') -> str:
"""Génère un rapport d'impact complet"""
try:
# Récupération du snapshot
order_book = self.get_orderbook_snapshot(asset)
# Tailles de test
test_sizes = [0.1, 0.5, 1.0, 5.0, 10.0]
report = []
report.append(f"\n{'='*70}")
report.append(f"📊 RAPPORT D'IMPACT - {asset}")
report.append(f"Généré via HolySheep API - Latence < 50ms")
report.append(f"{'='*70}\n")
for size in test_sizes:
result = self.simulate_execution(order_book, size, 'buy')
report.append(f"\nOrdre de {size} {asset}:")
report.append(f" Best Ask: ${result['best_price']:,.2f}")
report.append(f" VWAP: ${result['vwap']:,.2f}")
report.append(f" Slippage: {result['slippage_bps']:.2f} bps ({result['slippage_pct']:.4f}%)")
report.append(f" Impact: {result['impact_bps']:.2f} bps")
report.append(f" Fill: {result['fill_ratio_pct']:.1f}%")
if result['slippage_bps'] > 100:
report.append(f" ⚠️ SLIPPAGE TRÈS ÉLEVÉE - Considerer du smart order routing")
elif result['slippage_bps'] > 50:
report.append(f" ⚠️ Slippage élevée - Fragmenter l'ordre recommandé")
else:
report.append(f" ✅ Slippage acceptable")
return "\n".join(report)
except Exception as e:
return f"Erreur lors de la génération du rapport: {e}"
Exécution
if __name__ == "__main__":
calculator = SlippageCalculator("YOUR_HOLYSHEEP_API_KEY")
print(calculator.generate_impact_report("BTC"))
Étape 5 : Dashboard de visualisation pour l'équipe
Pour permettre à votre équipe de visualiser en temps réel les concepts de slippage et d'impact cost, nous avons développé un dashboard Streamlit :
# dashboard_l2_formation.py
Dashboard Streamlit pour la formation aux données L2
import streamlit as st
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
import requests
import time
from datetime import datetime
import json
st.set_page_config(page_title="Formation L2 - HolySheep", layout="wide")
Configuration HolySheep
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = st.secrets.get("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
Styles CSS personnalisés
st.markdown("""
""", unsafe_allow_html=True)
def get_orderbook_data(asset: str) -> dict:
"""Récupère les données du livre d'ordres via HolySheep"""
headers = {'Authorization': f'Bearer {API_KEY}'}
try:
response = requests.get(
f"{BASE_URL}/hyperliquid/orderbook",
params={'asset': asset},
headers=headers,
timeout=5
)
if response.status_code == 200:
return response.json()
return None
except Exception as e:
st.error(f"Erreur de connexion: {e}")
return None
def calculate_metrics(orderbook: dict, order_size: float, side: str) -> dict:
"""Calcule les métriques de slippage et impact"""
levels = orderbook.get('asks' if side == 'buy' else 'bids', [])
levels = sorted(levels, key=lambda x: x['price'] if side == 'buy' else -x['price'])
best_price = levels[0]['price'] if levels else 0
total_cost = 0
total_qty = 0
filled_levels = []
for level in levels:
if total_qty >= order_size:
break
fill_qty = min(level['qty'], order_size - total_qty)
total_cost += fill_qty * level['price']
total_qty += fill_qty
filled_levels.append({
'price': level['price'],
'qty': fill_qty,
'cumulative': total_qty
})
vwap = total_cost / total_qty if total_qty > 0 else best_price
slippage_bps = ((vwap - best_price) / best_price) * 10000
return {
'best_price': best_price,
'vwap': vwap,
'slippage_bps': slippage_bps,
'slippage_pct': slippage_bps / 100,
'fill_ratio': (total_qty / order_size) * 100,
'levels_used': len(filled_levels),
'filled_levels': filled_levels
}
def plot_orderbook_depth(orderbook: dict) -> go.Figure:
"""Crée un graphique de profondeur du livre d'ordres"""
bids = orderbook.get('bids', [])[:20]
asks = orderbook.get('asks', [])[:20]
fig = go.Figure()
# Cumulative bid depth
bid_cumulative = []
cum = 0
for bid in sorted(bids, key=lambda x: -x['price']):
cum += bid['qty']
bid_cumulative.append({'price': bid['price'], 'depth': cum})
# Cumulative ask depth
ask_cumulative = []
cum = 0
for ask in sorted(asks, key=lambda x: x['price']):
cum += ask['qty']
ask_cumulative.append({'price': ask['price'], 'depth': cum})
fig.add_trace(go.Scatter(
x=[b['price'] for b in bid_cumulative],
y=[b['depth'] for b in bid_cumulative],
name='Bids (Cumul)',
fill='tozeroy',
fillcolor='rgba(0, 255, 0, 0.3)',
line=dict(color='green')
))
fig.add_trace(go.Scatter(
x=[a['price'] for a in ask_cumulative],
y=[a['depth'] for a in ask_cumulative],
name='Asks (Cumul)',
fill='tozeroy',
fillcolor='rgba(255, 0, 0, 0.3)',
line=dict(color='red')
))
fig.update_layout(
title='Profondeur du Livre d\'Ordres (Hyperliquid)',
xaxis_title='Prix',
yaxis_title='Quantité Cumulative',
hovermode='x unified'
)
return fig
Interface principale
st.title("📚 Formation Trading: Analyse L2 - Hyperliquid")
Sidebar pour les contrôles
st.sidebar.header("Configuration")
asset = st.sidebar.selectbox("Asset", ["BTC", "ETH", "SOL", "ARB"])
order_size = st.sidebar.number_input("Taille de l'ordre", 0.1, 100.0, 1.0, 0.1)
side = st.sidebar.radio("Sens de l'ordre", ["buy", "sell"])
refresh = st.sidebar.button("🔄 Actualiser")
Zone principale
col1, col2, col3, col4 = st.columns(4)
Récupération des données
orderbook = get_orderbook_data(asset)
if orderbook:
metrics = calculate_metrics(orderbook, order_size, side)
# Métriques en haut
col1.metric("Prix Best", f"${metrics['best_price']:,.2f}")
col2.metric("VWAP", f"${metrics['vwap']:,.2f}")
col3.metric("Slippage", f"{metrics['slippage_bps']:.2f} bps")
col4.metric("Fill Ratio", f"{metrics['fill_ratio']:.1f}%")
# Graphiques
st.plotly_chart(plot_orderbook_depth(orderbook),