Skip to main content

Spécifications des Scénarios de Workflow - Swing Positions

🎯 Vue d’ensemble

Ce document définit tous les scénarios de workflow possibles pour les positions swing, permettant de vérifier le bon comportement de l’implémentation centralisée dans processBuy2.

📝 TERMINOLOGIE

”Montant” = Quantité (Amount)

Quand on parle de “montant” dans ce document, cela fait référence à la quantité de tokens, pas au prix :
  • buy1Amount = quantité de tokens achetés avec BUY1
  • buy2Amount = quantité de tokens achetés avec BUY2
  • tp1Amount = quantité de tokens à vendre avec TP1
  • tp2Amount = quantité de tokens à vendre avec TP2
  • relativeAmount = quantité totale de tokens (buy1 + buy2)

Prix vs Quantité

  • Prix : buy1Price, buy2Price, tp1Price, tp2Price (en USDT par token)
  • Quantité : buy1Amount, buy2Amount, tp1Amount, tp2Amount (en tokens)

Logique TP1/TP2

  • TP1 a un prix plus bas que TP2 (pour LONG)
  • TP1 est donc toujours fermé avant TP2
  • TP2 ne peut jamais être fermé avant TP1

💰 ÉVOLUTION DES PRIX ET CALCULS FINANCIERS

Calcul des Prix TP1/TP2

Les prix TP1 et TP2 sont recalculés à chaque fois que relativeEntryPrice change :
// Formule de calcul des prix TP
const avgMaxPnl = position.avgMaxPnlForPair || 2.0; // PnL maximum historique

// Pour LONG (achat)
tp1Price = relativeEntryPrice * (1 + (0.5 * avgMaxPnl / 100))   // 50% du PnL max
tp2Price = relativeEntryPrice * (1 + (0.95 * avgMaxPnl / 100))  // 95% du PnL max

// Pour SHORT (vente)
tp1Price = relativeEntryPrice * (1 - (0.5 * avgMaxPnl / 100))   // 50% du PnL max
tp2Price = relativeEntryPrice * (1 - (0.95 * avgMaxPnl / 100))  // 95% du PnL max

Évolution de relativeEntryPrice

Le prix d’entrée relatif est recalculé à chaque BUY2 fermé :
// Calcul du prix d'entrée pondéré
const totalBuy1Cost = buy1Amount * buy1Price;
const totalBuy2Cost = buy2Amount * buy2Price;
relativeEntryPrice = (totalBuy1Cost + totalBuy2Cost) / (buy1Amount + buy2Amount);

Calcul des Quantités TP

Les quantités TP sont toujours basées sur relativeAmount :
// Quantités fixes basées sur le total
tp1Amount = relativeAmount * 0.7;  // 70% du total
tp2Amount = relativeAmount * 0.3;  // 30% du total

Évolution des Frais

Les frais sont cumulés dans totalTpFees :
// Frais d'achat (BUY1 + BUY2)
const buyFees = (buy1Order.fee?.cost || 0) + (buy2Order.fee?.cost || 0);

// Frais de vente (TP1 + TP2 archivés)
const tpFees = position.totalTpFees || 0;

// Frais totaux
const totalFees = buyFees + tpFees;

Calcul du PnL

Le PnL est calculé pour chaque ordre TP fermé :
// PnL d'un ordre TP
const orderProfit = (tpAmount * tpPrice) - (tpFee || 0);

// PnL total cumulé
const totalTp1Profit = sum(archivedTp1Orders.map(o => o.profit));
const totalTp2Profit = sum(archivedTp2Orders.map(o => o.profit));
const totalProfit = totalTp1Profit + totalTp2Profit;

📋 SCÉNARIOS DE BASE

S1: Workflow Standard (Sans BUY2)

BUY1 (market) → TP1 (70%) → TP2 (30%) → CLOSE (reserveAmount)
État final: Position fermée avec profit complet

S2: Workflow Standard avec BUY2

BUY1 (market) → BUY2 (limit) → TP1 (70% total) → TP2 (30% total) → CLOSE (reserveAmount)
État final: Position fermée avec profit complet

🔄 SCÉNARIOS DE CYCLES MULTIPLES

S3: TP1 fermé avant BUY2

BUY1 → TP1 fermé → BUY2 amount += TP1 amount → BUY2 fermé → Nouveaux TP1/TP2
Vérifications:
  • TP1 archivé dans archivedTp1Orders
  • buy2Amount ajusté avec tp1Amount
  • BUY2 ordre remplacé avec nouveau montant
  • Nouveaux TP1/TP2 créés avec montants recalculés

S4: TP1 et TP2 fermés avant BUY2

BUY1 → TP1 fermé → TP2 fermé → BUY2 amount += (TP1 + TP2) amounts → BUY2 fermé → Nouveaux TP1/TP2
Vérifications:
  • TP1 et TP2 archivés
  • buy2Amount ajusté avec somme des deux
  • BUY2 ordre remplacé avec nouveau montant
  • Nouveaux TP1/TP2 créés

S6: BUY2 fermé avant TP1/TP2

BUY1 → BUY2 fermé → TP1 fermé → TP2 fermé → CLOSE
Vérifications:
  • relativeEntryPrice recalculé (moyenne pondérée)
  • Nouveaux TP1/TP2 avec montants basés sur relativeAmount
  • TP1/TP2 archivés quand fermés

🔀 SCÉNARIOS MIXTES COMPLEXES

S7: TP1 fermé → BUY2 fermé → TP2 fermé

BUY1 → TP1 fermé → BUY2 amount += TP1 → BUY2 fermé → TP2 fermé
Vérifications:
  • TP1 archivé immédiatement
  • BUY2 ajusté et fermé
  • Nouveaux TP1/TP2 créés
  • TP2 archivé quand fermé

S8: TP1 fermé → BUY2 fermé → TP2 fermé

BUY1 → TP1 fermé → BUY2 amount += TP1 → BUY2 fermé → TP2 fermé
Vérifications:
  • TP1 archivé immédiatement
  • BUY2 ajusté et fermé
  • Nouveaux TP1/TP2 créés
  • TP2 archivé quand fermé

S9: BUY2 fermé → TP1 fermé → TP2 fermé

BUY1 → BUY2 fermé → TP1 fermé → TP2 fermé
Vérifications:
  • relativeEntryPrice recalculé
  • Nouveaux TP1/TP2 créés
  • TP1 et TP2 archivés séquentiellement

🔁 SCÉNARIOS DE CYCLES MULTIPLES

S10: Cycle complet multiple

BUY1 → BUY2 fermé → TP1 fermé → TP2 fermé → Nouveau BUY2 → Nouveaux TP1/TP2
Vérifications:
  • Premier cycle archivé correctement
  • Nouveaux ordres créés avec montants corrects
  • totalTp1Profit, totalTp2Profit cumulés

S11: TP1 fermé en parallèle avec BUY2

BUY1 → BUY2 ouvert → TP1 fermé → BUY2 amount += TP1 → BUY2 fermé → TP2 fermé
Vérifications:
  • TP1 archivé immédiatement
  • BUY2 ajusté avec TP1 amount
  • BUY2 fermé et nouveaux TP créés
  • TP2 fermé ensuite

⚠️ SCÉNARIOS D’ERREUR

S12: BUY2 échec après TP fermé

BUY1 → TP1 fermé → BUY2 amount ajusté → BUY2 échec → Retry BUY2
Vérifications:
  • TP1 archivé même si BUY2 échoue
  • buy2Amount reste ajusté
  • Retry BUY2 avec montant correct

S13: TP fermé après BUY2 fermé

BUY1 → BUY2 fermé → TP1 fermé → TP2 fermé
Vérifications:
  • Pas de double archivage
  • TP archivés correctement
  • Nouveaux TP créés après BUY2

🧪 SCÉNARIOS DE TEST SPÉCIFIQUES

S14: Test de calculs financiers détaillés

Données de test:
  • BUY1: 100 tokens @ 1.00 USDT = 100 USDT
  • BUY2: 50 tokens @ 0.95 USDT = 47.5 USDT
  • avgMaxPnlForPair = 2.0%
  • Frais BUY1: 0.1 USDT, Frais BUY2: 0.05 USDT
Calculs attendus:
  • relativeEntryPrice = (100 + 47.5) / (100 + 50) = 0.983 USDT
  • relativeAmount = 100 + 50 = 150 tokens
  • tp1Amount = 150 * 0.7 = 105 tokens
  • tp2Amount = 150 * 0.3 = 45 tokens
  • tp1Price = 0.983 * (1 + 0.5 * 2.0 / 100) = 0.983 * 1.01 = 0.993 USDT
  • tp2Price = 0.983 * (1 + 0.95 * 2.0 / 100) = 0.983 * 1.019 = 1.002 USDT
Vérifications:
  • Prix TP1 < Prix TP2 ✅
  • Quantités TP cohérentes avec relativeAmount ✅
  • Prix basés sur relativeEntryPrice et avgMaxPnlForPair ✅

S15: Test d’archivage multiple

Séquence: TP1 fermé → TP2 fermé → BUY2 fermé → Nouveaux TP1/TP2 fermés Vérifications:
  • archivedTp1Orders.length = 2
  • archivedTp2Orders.length = 2
  • totalTp1Profit = somme des 2 cycles
  • totalTp2Profit = somme des 2 cycles
  • cycleNumber incrémenté correctement

S16: Test d’évolution des frais et PnL

Séquence: BUY1 → BUY2 fermé → TP1 fermé → TP2 fermé Données de test:
  • BUY1: 100 tokens @ 1.00 USDT, frais: 0.1 USDT
  • BUY2: 50 tokens @ 0.95 USDT, frais: 0.05 USDT
  • TP1: 105 tokens @ 0.993 USDT, frais: 0.08 USDT
  • TP2: 45 tokens @ 1.002 USDT, frais: 0.04 USDT
Calculs attendus:
  • Frais d’achat: 0.1 + 0.05 = 0.15 USDT
  • totalTpFees: 0.08 + 0.04 = 0.12 USDT
  • totalTp1Profit: (105 * 0.993) - 0.08 = 104.245 USDT
  • totalTp2Profit: (45 * 1.002) - 0.04 = 45.05 USDT
  • Profit total: 104.245 + 45.05 = 149.295 USDT
Vérifications:
  • totalTpFees cumule correctement ✅
  • PnL calculé avec frais déduits ✅
  • Totaux cohérents avec archives ✅

📊 MÉTRIQUES DE VÉRIFICATION

Données à vérifier pour chaque scénario:

  1. État des ordres: buy1Order, buy2Order, tp1Order, tp2Order
  2. Quantités (Amounts): buy1Amount, buy2Amount, tp1Amount, tp2Amount (en tokens)
  3. Prix: buy1Price, buy2Price, tp1Price, tp2Price (en USDT/token)
  4. Calculs: relativeEntryPrice, relativeAmount
  5. Archives: archivedTp1Orders, archivedTp2Orders
  6. Totaux: totalTp1Profit, totalTp2Profit, totalTpFees
  7. Activités: Logs d’activité pour chaque action

Vérifications Financières Spécifiques:

  1. Prix TP cohérents:
    • tp1Price < tp2Price (pour LONG)
    • Prix basés sur relativeEntryPrice et avgMaxPnlForPair
    • Formules: TP1 = 50% PnL max, TP2 = 95% PnL max
  2. Calculs de PnL:
    • orderProfit = (amount * price) - fee pour chaque TP fermé
    • totalTp1Profit et totalTp2Profit cumulés correctement
    • Pas de double comptage des profits
  3. Évolution des frais:
    • totalTpFees cumule tous les frais de vente TP
    • Frais d’achat séparés (BUY1 + BUY2)
    • Frais totaux = frais achat + frais vente
  4. Cohérence des montants:
    • relativeAmount = buy1Amount + buy2Amount
    • tp1Amount = relativeAmount * 0.7
    • tp2Amount = relativeAmount * 0.3
    • buy2Amount ajusté après TP fermés

Assertions critiques:

  • buy2Amount toujours cohérent avec les TP fermés
  • relativeEntryPrice toujours calculé correctement
  • ✅ TP1 archivé immédiatement quand fermé
  • ✅ TP2 ne peut jamais être fermé avant TP1
  • ✅ Nouveaux TP créés avec quantités correctes
  • ✅ Totaux cumulés correctement
  • ✅ Pas de double archivage
  • ✅ Cycle numbers incrémentés

🎯 PRIORITÉS DE TEST

Critique (Doit fonctionner):

  • S1, S2, S3, S4, S6, S14, S16

Important (Doit fonctionner):

  • S7, S8, S9, S15

Nice to have:

  • S10, S11, S12, S13

📝 NOTES D’IMPLÉMENTATION

Points d’attention:

  1. Race conditions: TP1 et TP2 peuvent fermer simultanément
  2. Calculs de prix: Vérifier la cohérence des calculs de relativeEntryPrice
  3. Gestion d’erreurs: BUY2 peut échouer après ajustement
  4. Performance: Éviter les requêtes DB multiples
  5. Logs: Traçabilité complète des actions

Tests unitaires recommandés:

  • Test de archiveTpOrder() avec différents types
  • Test de calculs de relativeEntryPrice
  • Test de mise à jour des totaux cumulés
  • Test de gestion des erreurs BUY2