Guide de développement du SDK Ranger Finance
Un guide complet pour construire des applications Solana avec Ranger Finance - le premier agrégateur de contrats perpétuels sur Solana.
Vue d'ensemble
Ranger Finance est un Smart Order Router (SOR) qui agrège les échanges de contrats perpétuels sur plusieurs protocoles Solana :
- Drift Protocol : Principal DEX de contrats perpétuels sur Solana
- Flash Trade : Contrats perpétuels haute performance
- Adrena : Protocole de trading avec effet de levier
- Jupiter Perps : Plateforme de contrats perpétuels de Jupiter
Avantages clés
- Meilleure exécution : Route automatiquement les ordres vers les venues avec les meilleurs prix
- API unifiée : Interface unique pour tous les protocoles de contrats perpétuels supportés
- Agrégation de positions : Visualisez et gérez les positions sur tous les venues
- Support des agents IA : Serveur MCP intégré pour les agents de trading IA
Démarrage rapide
Installation (TypeScript)
# Clonez la démo du SDK
git clone https://github.com/ranger-finance/sor-ts-demo.git
cd sor-ts-demo
npm install
Configuration de l'environnement
Créez un fichier .env :
RANGER_API_KEY=your_api_key_here
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
WALLET_PRIVATE_KEY=your_base58_private_key # Optionnel, pour signer
Configuration de base
import { SorApi, TradeSide } from 'ranger-sor-sdk';
import dotenv from 'dotenv';
dotenv.config();
// Initialisez le client API SOR
const sorApi = new SorApi({
apiKey: process.env.RANGER_API_KEY!,
solanaRpcUrl: process.env.SOLANA_RPC_URL,
});
// Votre clé publique de portefeuille
const walletAddress = 'YOUR_WALLET_PUBLIC_KEY';
Concepts principaux
1. Côtés de trading
type TradeSide = 'Long' | 'Short';
2. Types d'ajustement
type AdjustmentType =
| 'Quote' // Obtenir une cotation uniquement
| 'Increase' // Ouvrir ou augmenter une position
| 'DecreaseFlash' // Diminuer via Flash
| 'DecreaseJupiter' // Diminuer via Jupiter
| 'DecreaseDrift' // Diminuer via Drift
| 'DecreaseAdrena' // Diminuer via Adrena
| 'CloseFlash' // Fermer via Flash
| 'CloseJupiter' // Fermer via Jupiter
| 'CloseDrift' // Fermer via Drift
| 'CloseAdrena' // Fermer via Adrena
| 'CloseAll'; // Fermer la position entière
3. Interface Position
interface Position {
id: string;
symbol: string;
side: TradeSide;
quantity: number;
entry_price: number;
liquidation_price: number;
position_leverage: number;
real_collateral: number;
unrealized_pnl: number;
borrow_fee: number;
funding_fee: number;
open_fee: number;
close_fee: number;
created_at: string;
opened_at: string;
platform: string; // 'DRIFT', 'FLASH', 'ADRENA', 'JUPITER'
}
4. Réponse de cotation
interface Quote {
base: number;
fee: number;
total: number;
fee_breakdown: {
base_fee: number;
spread_fee: number;
volatility_fee: number;
margin_fee: number;
close_fee: number;
other_fees: number;
};
}
interface VenueAllocation {
venue_name: string;
collateral: number;
size: number;
quote: Quote;
order_available_liquidity: number;
venue_available_liquidity: number;
}
interface OrderMetadataResponse {
venues: VenueAllocation[];
total_collateral: number;
total_size: number;
}
Opérations de trading
Obtenir une cotation
Avant d'exécuter un trade, obtenez une cotation pour voir les prix entre les venues :
import { SorApi, OrderMetadataRequest, TradeSide } from 'ranger-sor-sdk';
const sorApi = new SorApi({ apiKey: process.env.RANGER_API_KEY! });
async function getQuote() {
const request: OrderMetadataRequest = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
size: 1.0, // Taille de position 1 SOL
collateral: 10.0, // Collatéral 10 USDC (effet de levier 10x)
size_denomination: 'SOL',
collateral_denomination: 'USDC',
adjustment_type: 'Quote',
};
const quote = await sorApi.getOrderMetadata(request);
console.log('Venues disponibles :');
quote.venues.forEach(venue => {
console.log(` ${venue.venue_name}: ${venue.quote.total} USDC`);
});
return quote;
}
Ouvrir/Augmenter une position
async function openLongPosition() {
const request = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
size: 1.0,
collateral: 10.0,
size_denomination: 'SOL',
collateral_denomination: 'USDC',
adjustment_type: 'Increase' as const,
};
// Obtenez les instructions de transaction
const response = await sorApi.increasePosition(request);
console.log('Message de transaction (base64) :', response.message);
if (response.meta) {
console.log('Prix exécuté :', response.meta.executed_price);
console.log('Venues utilisées :', response.meta.venues_used);
}
return response;
}
// Ouvrir une position courte
async function openShortPosition() {
const request = {
fee_payer: walletAddress,
symbol: 'ETH',
side: 'Short' as TradeSide,
size: 0.5,
collateral: 100.0,
size_denomination: 'ETH',
collateral_denomination: 'USDC',
adjustment_type: 'Increase' as const,
};
return await sorApi.increasePosition(request);
}
Diminuer une position
async function decreasePosition() {
const request = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
size: 0.5, // Diminuer de 0,5 SOL
collateral: 5.0, // Retirer 5 USDC de collatéral
size_denomination: 'SOL',
collateral_denomination: 'USDC',
adjustment_type: 'DecreaseFlash' as const, // Router via Flash
};
return await sorApi.decreasePosition(request);
}
Fermer une position
// Fermer la position entière sur un venue spécifique
async function closePosition() {
const request = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
adjustment_type: 'CloseFlash' as const,
};
return await sorApi.closePosition(request);
}
// Fermer toutes les positions sur tous les venues
async function closeAllPositions() {
const request = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
adjustment_type: 'CloseAll' as const,
};
return await sorApi.closePosition(request);
}
Signer et exécuter une transaction
import { Keypair, VersionedTransaction } from '@solana/web3.js';
import bs58 from 'bs58';
async function executeTradeWithSigning() {
// Obtenez les instructions de transaction
const txResponse = await sorApi.increasePosition({
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long',
size: 1.0,
collateral: 10.0,
size_denomination: 'SOL',
collateral_denomination: 'USDC',
adjustment_type: 'Increase',
});
// Créez une paire de clés à partir de la clé privée
const privateKeyBytes = bs58.decode(process.env.WALLET_PRIVATE_KEY!);
const keypair = Keypair.fromSecretKey(privateKeyBytes);
// Définissez la fonction de signature
const signTransaction = async (tx: VersionedTransaction) => {
tx.sign([keypair]);
return tx;
};
// Exécutez la transaction
const result = await sorApi.executeTransaction(txResponse, signTransaction);
console.log('Signature de la transaction :', result.signature);
return result;
}
Gestion des positions
Récupérer toutes les positions
async function getAllPositions() {
const positions = await sorApi.getPositions(walletAddress);
positions.positions.forEach(pos => {
console.log(`${pos.symbol} ${pos.side}: ${pos.quantity} @ ${pos.entry_price}`);
console.log(` Plateforme : ${pos.platform}`);
console.log(` PnL : ${pos.unrealized_pnl}`);
console.log(` Liquidation : ${pos.liquidation_price}`);
});
return positions;
}
Filtrer les positions par plateforme
async function getDriftPositions() {
const positions = await sorApi.getPositions(walletAddress, {
platforms: ['DRIFT'],
});
return positions;
}
async function getFlashAndAdrenaPositions() {
const positions = await sorApi.getPositions(walletAddress, {
platforms: ['FLASH', 'ADRENA'],
});
return positions;
}
Filtrer les positions par symbole
async function getSolPositions() {
const positions = await sorApi.getPositions(walletAddress, {
symbols: ['SOL-PERP'],
});
return positions;
}
Intégration avec les agents IA
Ranger fournit un serveur MCP (Model Context Protocol) pour l'intégration avec les agents IA.
Installation (Python)
pip install mcp-agent numpy
Outils du serveur MCP
Le serveur MCP de Ranger expose ces outils :
Outils SOR :
sor_get_trade_quote- Obtenir des cotations de prixsor_increase_position- Ouvrir/augmenter des positionssor_decrease_position- Réduire des positionssor_close_position- Fermer des positions
Outils API de données :
data_get_positions- Récupérer les positions actuellesdata_get_trade_history- Historique de tradingdata_get_liquidations- Données de liquidation et signauxdata_get_funding_rates- Analyse des taux de financement
Exemple : Agent de réversion à la moyenne
import asyncio
from ranger_mcp_agent.examples.mean_reversion_agent import run_mean_reversion_agent
async def main():
# Exécutez une stratégie de trading de réversion à la moyenne
await run_mean_reversion_agent()
if __name__ == "__main__":
asyncio.run(main())
Démarrer le serveur MCP
cd ranger-agent-kit/perps-mcp
cp .env.example .env
# Modifiez .env avec vos identifiants API
python -m ranger_mcp
Référence API
Classe SorApi
class SorApi {
constructor(config: SorSdkConfig);
// Obtenir une cotation pour un trade
getOrderMetadata(request: OrderMetadataRequest): Promise<OrderMetadataResponse>;
// Ouvrir ou augmenter une position
increasePosition(request: IncreasePositionRequest): Promise<TransactionResponse>;
// Réduire une position
decreasePosition(request: DecreasePositionRequest): Promise<TransactionResponse>;
// Fermer une position
closePosition(request: ClosePositionRequest): Promise<TransactionResponse>;
// Obtenir les positions d'un portefeuille
getPositions(
publicKey: string,
options?: {
platforms?: string[];
symbols?: string[];
startDate?: string;
endDate?: string;
}
): Promise<PositionsResponse>;
// Exécuter une transaction signée
executeTransaction(
transactionResponse: TransactionResponse,
signTransaction: (tx: VersionedTransaction) => Promise<VersionedTransaction>
): Promise<{ signature: string }>;
// Obtenir la connexion Solana
getConnection(): Connection;
}
Configuration
interface SorSdkConfig {
apiKey: string;
sorApiBaseUrl?: string; // Par défaut : API SOR de Ranger
dataApiBaseUrl?: string; // Par défaut : API de données de Ranger
solanaRpcUrl?: string; // Par défaut : RPC Mainnet
}
Types de requête
interface BaseRequest {
fee_payer: string;
symbol: string;
side: TradeSide;
size_denomination?: string;
collateral_denomination?: string;
}
interface IncreasePositionRequest extends BaseRequest {
size: number;
collateral: number;
size_denomination: string;
collateral_denomination: string;
adjustment_type: 'Increase';
}
interface DecreasePositionRequest extends BaseRequest {
size: number;
collateral: number;
size_denomination: string;
collateral_denomination: string;
adjustment_type: 'DecreaseFlash' | 'DecreaseJupiter' | 'DecreaseDrift' | 'DecreaseAdrena';
}
interface ClosePositionRequest extends BaseRequest {
adjustment_type: 'CloseFlash' | 'CloseJupiter' | 'CloseDrift' | 'CloseAdrena' | 'CloseAll';
}
Types de réponse
interface TransactionResponse {
message: string; // Transaction encodée en base64
meta?: {
executed_price?: number;
executed_size?: number;
executed_collateral?: number;
venues_used?: string[];
};
}
interface PositionsResponse {
positions: Position[];
}
Marchés supportés
Ranger agrège les marchés de contrats perpétuels sur :
| Protocole | Marchés |
|---|---|
| Drift | SOL, BTC, ETH et 20+ actifs |
| Flash | SOL, BTC, ETH |
| Adrena | SOL, BTC, ETH |
| Jupiter | SOL, BTC, ETH |
Gestion des erreurs
try {
const response = await sorApi.increasePosition(request);
} catch (error) {
if (error.error_code) {
// Erreur API
console.error('Erreur API :', error.message);
console.error('Code d\'erreur :', error.error_code);
} else {
// Erreur de réseau ou autre
throw error;
}
}
Bonnes pratiques
-
Toujours obtenir les cotations en premier : Avant d'exécuter des trades, utilisez
getOrderMetadatapour comparer les prix entre les venues. -
Gérer la signature de transactions de manière sécurisée : Ne codez jamais en dur les clés privées. Utilisez des variables d'environnement ou une gestion sécurisée des clés.
-
Surveiller les positions : Récupérez régulièrement les positions pour suivre le PnL et les prix de liquidation.
-
Utiliser le venue approprié : Lors de la diminution/fermeture, choisissez le venue où votre position existe.
-
Définir un collatéral approprié : Considérez l'effet de levier lors de la définition du collatéral. Un collatéral plus élevé = risque de liquidation plus faible.
Ressources
Structure de compétence
ranger-finance/
├── SKILL.md # Ce fichier
├── resources/
│ ├── api-reference.md # Référence des endpoints API
│ └── types-reference.md # Types TypeScript complets
├── examples/
│ ├── basic/
│ │ └── example.ts # Opérations de trading basiques
│ ├── positions/
│ │ └── example.ts # Requêtes et gestion des positions
│ └── transactions/
│ └── example.ts # Flux de signature de transaction
├── templates/
│ └── setup.ts # Modèle de configuration prêt à l'emploi
└── docs/
├── troubleshooting.md # Problèmes courants et solutions
└── ai-agent-integration.md # Guide de configuration des agents IA
Vérification
- Un appel RPC/SDK réel a été effectué (mainnet, devnet ou validateur local) et la charge utile de réponse est capturée dans la transcription, non pas simplement paraphrasée
- Chaque transaction a été simulée (
simulateTransactionou équivalent) avant toute étape de signature/envoi ; les journaux de simulation sont joints - Pour toute transaction signée/envoyée, la signature résultante est enregistrée et confirmée sur la chaîne (statut retourné par
getSignatureStatusesou URL d'explorateur) - Le slippage, les frais de priorité et les limites d'unités de calcul ont été définis explicitement avec des valeurs numériques concrètes, non laissés aux défauts de bibliothèque
- Les adresses de compte, les mints et les ID de programme utilisés dans la exécution correspondent aux adresses ranger-perps documentées pour le cluster ciblé (pas de mélange mainnet/devnet)
- Le chemin d'échec a été exercé au moins une fois (solde insuffisant, oracle périmé, blockhash expiré, etc.) et la gestion des erreurs de l'agent a produit un message lisible par l'homme