État CLOSED - Fermeture de Position
📊 Statut des Tests
Tests Frontend (Checkly)
Tests Backend (Vitest)
🎯 Vue d’ensemble
L’état CLOSED correspond à une position fermée. Une position peut être fermée pour deux raisons principales : changement de tendance ou Stop Loss touché.🔄 Transition RUNNING → CLOSED
Conditions de fermeture
-
Changement de tendance :
- LONG :
candle.wma50 < wma50_htf - SHORT :
candle.wma50 > wma50_htf
- LONG :
-
Stop Loss touché :
- SL de BUY2 touché (BUY2 fermé) → Fermeture complète
- Note : SL de BUY1 touché (BUY2 non fermé) → Position reste en RUNNING
sharkModeCron.ts qui surveille les bougies 1m et met à jour le SL de manière agressive basé sur le Heikin Ashi. La fermeture par SL est gérée directement via processClose() qui crée l’ordre Close, puis la position passe en CLOSED après l’exécution de l’ordre.
Actions lors de la fermeture
- Annulation des ordres TP1/TP2 ouverts
- Création d’un ordre de fermeture (market)
- Après l’exécution de l’ordre Close :
status = CLOSED - Calcul des coûts finaux (
finalBuyCost,finalSellCost) - Calcul des frais finaux (
finalBuyFee,finalSellFee) - Notification envoyée
Ordre de fermeture (processClose)
Calcul du montant à fermer selon le contexte :-
SL touché + BUY2 non fermé :
-
SL touché + BUY2 fermé :
-
Fermeture normale (changement de tendance) :
- Si
relativeAmount <= 0: Ne pas créer d’ordre Close, passer directement en CLOSED
📋 Variantes de Fermeture
Variante 1 : Fermeture par changement de tendance
Séquence :- Détection du changement de tendance (WMA50)
- Annulation des ordres TP1/TP2 ouverts
- Création d’un ordre Close (market) pour vendre
relativeAmount + reserveAmount - totalBaseAssetFees - Après exécution de l’ordre Close :
status = CLOSED,closedReason = TREND_CHANGED - Calcul des coûts et frais finaux
- Notification envoyée
Variante 2 : Fermeture par Stop Loss (SL_BUY2)
Séquence :- SL de BUY2 touché (BUY2 fermé)
slMode = SL_BUY2défini- Création d’un ordre Close pour vendre
relativeAmount + reserveAmount - Après exécution de l’ordre Close :
status = CLOSED,closedReason = REACHED_STOP_LOSS - Fermeture complète de la position
- Calcul des coûts et frais finaux
- Notification envoyée
Variante 3 : SL de BUY1 touché (position reste RUNNING)
Séquence :- SL de BUY1 touché (BUY2 non fermé)
slMode = SL_BUY1défini- Création d’un ordre Close pour vendre seulement
relativeAmount(pasreserveAmount) - Après exécution de l’ordre Close : Position reste en RUNNING (pas CLOSED)
relativeAmountmis à jour à 0- La position continue d’être traitée pour permettre l’exécution future de BUY2
- La position ne sera fermée que si :
- BUY2 est exécuté puis son SL est touché (passage en SL_BUY2)
- La tendance change (création d’un ordre Close)
🔍 Logique de Fermeture Détaillée
Après exécution de l’ordre Close
La fermeture de la position après l’exécution de l’ordre Close est déterminée parslMode et le status, pas par calculatedRelativeAmount.
Cas 1 : SL_BUY2 (SL de BUY2 touché)
- Condition :
slMode === 'SL_BUY2'ETcloseOrder.status === 'closed' - Comportement :
- ✅ Fermeture complète de la position (l’ordre Close a vendu
relativeAmount + reserveAmount) - ✅
status = CLOSED - ✅
closedReason = REACHED_STOP_LOSS - ✅
closedAt = new Date() - ✅
relativeAmount = 0 - ✅ Calcul des coûts finaux (
finalBuyCost,finalSellCost) - ✅ Calcul des frais finaux (
finalBuyFee,finalSellFee) - ✅ Notification envoyée
- ✅ Fermeture complète de la position (l’ordre Close a vendu
Cas 2 : SL_BUY1 (SL de BUY1 touché, BUY2 non fermé)
- Condition :
slMode === 'SL_BUY1'ETbuy2IsClosed === falseETcloseOrder.status === 'closed' - Comportement :
- ✅ La position reste en RUNNING même après l’exécution de l’ordre Close
- ✅ L’ordre Close a vendu seulement
relativeAmount(pasreserveAmount) - ✅
relativeAmountest mis à jour à 0 - ✅ La position continue d’être traitée par
swingPositionspour permettre l’exécution future de BUY2 - ✅ La position ne sera fermée que si :
- BUY2 est exécuté puis son SL est touché (passage en SL_BUY2)
- La tendance change (création d’un ordre Close)
Cas 3 : Fermeture normale (changement de tendance)
- Condition :
closeOrder.status === 'closed'ETslMode !== 'SL_BUY1'(ouslMode === null) - Comportement :
- ✅
status = CLOSED - ✅
closedReason = TREND_CHANGED - ✅
closedAt = new Date() - ✅ Calcul des coûts finaux (
finalBuyCost,finalSellCost) - ✅ Calcul des frais finaux (
finalBuyFee,finalSellFee) - ✅ Notification envoyée
- ✅
📊 Calculs Finaux
Coûts finaux
Frais finaux
PnL final
🧪 Tests
Tests Frontend
Les tests frontend vérifient l’affichage des positions fermées et l’historique. Fichiers de tests :features/positions/closed-position.spec.ts
Configuration Checkly :
Tests Backend
Les tests backend valident la logique de fermeture et les différents scénarios. Fichiers de tests :packages/functions/src/tests/positions/closed-state.test.ts
Exécution :
🔗 Navigation
- Vue d’ensemble : Retour à la vue d’ensemble
- État NEW : Création de position
- État RUNNING : Gestion des ordres