Backtest
[backtest] définit le cadre global dans lequel votre stratégie est exécutée. Il indique la période de test, les symboles et timeframes à charger, le capital initial, les frais, le slippage, les règles de dimensionnement des entrées et les paramètres liés à la marge, au levier et au pyramidage.
Déclaration du bloc
Une stratégie ne peut contenir qu’un seul bloc [backtest].
Exemples
Configuration minimale
Cet exemple définit un symbole unique, un timeframe unique et une période de test. Tous les autres paramètres prennent leurs valeurs par défaut.
[backtest]
symbol = "BINANCE:BTCUSDT"
timeframe = "240"
start_date = 2024-01-01
end_date = 2025-01-01
initial_capital = 1000Plusieurs marchés et timeframes
Cet exemple compare la stratégie sur plusieurs marchés et plusieurs timeframes. Un backtest distinct est lancé pour chaque combinaison marché/timeframe : avec 2 marchés et 2 timeframes, 4 backtests sont exécutés. Le classement permet ensuite d’identifier les combinaisons où la stratégie obtient les meilleurs scores.
[backtest]
symbol = ["BINANCE:BTCUSDT", "BINANCE:ETHUSDT"]
timeframe = ["60", "240"]
start_date = 2024-01-01
end_date = 2025-01-01
initial_capital = 1000Backtest sans levier explicite au sens de l’exposition
Cet exemple configure un backtest où la taille d’ordre est exprimée en pourcentage de l’équité. Les paramètres de marge restent à leurs valeurs par défaut, et l’allocation reste sous 100% pour garder une marge de sécurité face aux frais et aux écarts entre prix de sizing et prix d’exécution.
[backtest]
symbol = "BINANCE:BTCUSDT"
timeframe = "240"
start_date = 2024-01-01
end_date = 2025-01-01
initial_capital = 1000
default_qty_type = "percent_of_equity"
default_qty_value = 95Backtest avec marge et multiplicateurs asymétriques
Cet exemple illustre une configuration où les positions sont ouvertes avec un pourcentage limité d’équité, une marge inférieure à 100 % et des multiplicateurs différents pour le long et le short. La dynamique exacte de la marge et du levier est décrite dans « Marges et leviers ».
[backtest]
symbol = "BINANCE:BTCUSDT"
timeframe = "240"
start_date = 2024-01-01
end_date = 2025-01-01
initial_capital = 1000
default_qty_type = "percent_of_equity"
default_qty_value = 30
margin_long = 50 # Marge 50 % côté long
margin_short = 50 # Marge 50 % côté short
long_size_multiplier = 5 # Multiplicateur de taille ×5 pour les longs
short_size_multiplier = 2 # Multiplicateur de taille ×2 pour les shortsOptimiser l’allocation de capital
La plage default_qty_value définit différentes allocations d’équité, de 10 % à 95 % par pas de 5 %. Avec default_qty_type = "percent_of_equity", cette clé représente la base globale d’exposition avant application éventuelle des multiplicateurs de côté.
[backtest]
symbol = "BINANCE:BTCUSDT"
timeframe = "240"
start_date = 2024-01-01
end_date = 2025-01-01
initial_capital = 1000
default_qty_type = "percent_of_equity"
long_size_multiplier = 4
default_qty_value.start = 10
default_qty_value.stop = 95
default_qty_value.step = 5Explorer le multiplicateur long avec allocation fixe
L’allocation de capital est fixée à 40 % de l’équité avec default_qty_value = 40. La plage long_size_multiplier définit ensuite une série de multiplicateurs de taille pour les positions long. Ce pattern est utile pour la grid-search, car il garde une base commune et fait varier seulement l’exposition du côté long.
[backtest]
symbol = "BINANCE:BTCUSDT"
timeframe = "240"
start_date = 2024-01-01
end_date = 2025-01-01
initial_capital = 1000
default_qty_type = "percent_of_equity"
default_qty_value = 40
long_size_multiplier.start = 1
long_size_multiplier.stop = 10
long_size_multiplier.step = 0.5Optimiser allocation et multiplicateurs de taille
Les allocations d’équité et les multiplicateurs de taille long et short sont simultanément explorés. Chaque combinaison de ces paramètres donne lieu à un backtest distinct.
Cet exemple prend tout son sens avec une stratégie capable d’ouvrir des positions long et short. default_qty_value fixe alors la taille de base des ordres, puis long_size_multiplier et short_size_multiplier ajustent cette taille séparément pour chaque direction. Si la stratégie ne trade que dans un seul sens, le multiplicateur de l’autre direction n’est jamais utilisé et ne peut donc pas influencer les résultats du backtest.
[backtest]
symbol = "BINANCE:BTCUSDT"
timeframe = "240"
start_date = 2024-01-01
end_date = 2025-01-01
initial_capital = 1000
default_qty_type = "percent_of_equity"
# Plage d’allocation d’équité
default_qty_value.start = 10
default_qty_value.stop = 50
default_qty_value.step = 5
# Plage multiplicateurs LONG
long_size_multiplier.start = 1
long_size_multiplier.stop = 10
long_size_multiplier.step = 0.5
# Plage multiplicateurs SHORT
short_size_multiplier.start = 1
short_size_multiplier.stop = 10
short_size_multiplier.step = 0.5Paramètres du bloc [backtest]
Le tableau suivant récapitule les paramètres disponibles dans le bloc [backtest]. Lorsque la colonne de description fait référence à d’autres pages de documentation, ces pages contiennent les explications détaillées. Pour tout ce qui touche au sizing, aux marges et aux multiplicateurs, la page de référence reste « Marges et leviers ».
| Paramètre | Description |
|---|---|
start_dateDate‑Heure Obligatoire | Date de début du backtest. Les dates peuvent inclure un décalage horaire numérique. Le moteur exécute strictement en UTC, mais il interprète les dates de début et de fin à l’aide d’un décalage fixe inféré avant conversion en UTC. Règles d’inférence et de validation du décalage :
Formats acceptés :
|
end_dateDate‑Heure Obligatoire | Date de fin du backtest. Les mêmes formats et règles d’inférence de décalage que pour start_date s’appliquent. |
price_history_start_dateDate‑Heure Optionnel | Date de début explicite de l’historique de prix à charger. Cette clé contrôle uniquement la profondeur de données récupérées en amont et ne modifie pas la période métier du backtest (start_date/end_date). Les formats et règles de décalage sont identiques à start_date et end_date.Si la clé est absente, Whale‑E utilise le calcul automatique basé sur le lookback des indicateurs. Si la date fournie est trop récente pour couvrir le lookback minimal, Whale‑E la recule automatiquement à la borne minimale requise et émet un warning. Valeur par défaut : calcul automatique. |
symbolTexte ou Tableau Obligatoire | Symbole principal de la simulation. Peut être une chaîne unique (par exemple "BINANCE:BTCUSDT") ou un tableau de symboles (par exemple ["BINANCE:BTCUSDT", "BINANCE:ETHUSDT"]).Lorsque plusieurs symboles sont fournis, une grille distincte est créée pour chaque combinaison symbole/timeframe. Pour la description complète des formats et de la projection entre symboles, voir Exchanges, symboles, sources et timeframes. |
timeframeTexte ou Tableau Obligatoire | Timeframe principal du backtest. Peut être une chaîne unique (par exemple "240") ou un tableau de timeframes (par exemple ["60", "240"]).Lorsque plusieurs timeframes sont fournis, une grille distincte est créée pour chaque combinaison symbole/timeframe. Le comportement des indicateurs qui surchargent leur timeframe est décrit dans Exchanges, symboles, sources et timeframes. |
auto_slippage_enabledBooléen Optionnel | Active le slippage automatique basé sur la bougie d’une minute. Si la valeur est false, le slippage est défini uniquement par slippage.Valeur par défaut : false. |
auto_slippage_ratioDécimal Optionnel | Ratio appliqué à la fourchette high‑low de la bougie d’une minute pour calculer le slippage automatique. Ignoré si auto_slippage_enabled est false.Valeur par défaut : 0.25. |
slippageEntier Optionnel | Nombre de ticks de slippage ajoutés manuellement au prix d’exécution. Utilisé uniquement lorsque auto_slippage_enabled est false.Valeur par défaut : 0. |
backtest_fill_limits_assumptionEntier Optionnel | Nombre minimal de ticks de dépassement exigé pour considérer un ordre LIMIT comme exécuté. La valeur 0 équivaut à un simple « touch ». Ce paramètre s’applique aux entrées LIMIT et à la jambe LIMIT des entrées STOP_LIMIT.Valeur par défaut : 0. |
use_bar_magnifierBooléen Optionnel | Active l’inspection intrabar à l’aide d’un timeframe inférieur pour déterminer l’ordre des événements à l’intérieur d’une bougie agrégée (par exemple « entrée puis stop » sur la même barre). Lorsque cette option est désactivée, l’ordre intrabar est déduit uniquement à partir des données OHLC du timeframe principal. Valeur par défaut : false. |
process_orders_on_closeBooléen Optionnel | Contrôle le moment où les ordres soumis à la clôture d’une bougie deviennent éligibles à l’exécution. Lorsque false, un ordre créé à la clôture ne peut être exécuté qu’à partir de l’ouverture de la bougie suivante (premier tick disponible en backtest historique). Lorsque true, les ordres peuvent être traités sur le tick de clôture de la bougie courante.Valeur par défaut : false. |
max_blocks_on_same_candleEntier Optionnel | Nombre maximal de blocs exécutés sur une même bougie sans avancée de bougie. Permet de détecter et stopper les boucles infinies. La valeur 0 désactive la détection.Valeur par défaut : 1024. |
commission_valueDécimal Optionnel | Valeur de la commission, interprétée selon commission_type. En mode percent, la valeur représente un pourcentage et doit rester strictement inférieure à 100. En modes cash_per_contract ou cash_per_order, elle représente un montant fixe en devise.Valeur par défaut : 0.1. |
commission_typeTexte Optionnel | Mode d’application de la commission. Les valeurs possibles sont percent, cash_per_contract et cash_per_order.Valeur par défaut : "percent". |
initial_capitalDécimal Optionnel | Capital initial du backtest, exprimé dans la devise de cotation du symbole principal. Valeur par défaut : 1000000. |
default_qty_typeTexte Optionnel | Mode global de calcul de la quantité pour les ordres d’entrée : fixed, cash ou percent_of_equity.Valeur par défaut : "percent_of_equity". |
default_qty_valueDécimal ou Plage Optionnel | Valeur publique de sizing global utilisée par les blocs d’entrée lorsque le bloc ne définit pas qty ni qty_percent. En mode fixed, cette valeur représente une quantité absolue. En mode cash, elle représente un budget monétaire. En mode percent_of_equity, elle représente la base globale en pourcentage avant application éventuelle de long_size_multiplier ou short_size_multiplier. Une valeur simple est acceptée dans tous les modes. Les variantes .start, .stop et .step sont acceptées uniquement en percent_of_equity pour la grid-search.Valeur par défaut : 100 en percent_of_equity. En fixed et cash, si default_qty_value est absent et qu’aucun qty ni qty_percent local n’est fourni, l’ordre est rejeté. |
margin_longDécimal Optionnel | Pourcentage de marge appliqué aux positions long. La valeur doit être supérieure ou égale à 0 et peut dépasser 100, comme dans TradingView. La marge requise pour un long est égale à la valeur notionnelle multipliée par margin_long / 100. Une valeur de 0 désactive la logique de marge pour les positions long. La logique complète de marge et de liquidation est détaillée dans la page « Marges et leviers ».Valeur par défaut : 100. |
margin_shortDécimal Optionnel | Pourcentage de marge appliqué aux positions short. La valeur doit être supérieure ou égale à 0 et peut dépasser 100, comme dans TradingView. La marge requise pour un short est égale à la valeur notionnelle multipliée par margin_short / 100. Une valeur de 0 désactive la logique de marge pour les positions short. La logique complète de marge et de liquidation est détaillée dans la page « Marges et leviers ».Valeur par défaut : 100. |
long_size_multiplierDécimal Optionnel | Multiplicateur appliqué à la base globale définie par default_qty_value pour les ordres longs dans les modes de sizing en pourcentage. La valeur 1 laisse la taille inchangée. Ce paramètre peut être défini comme valeur unique ou comme plage (.start, .stop, .step) pour exploration par grid-search. Il est ignoré pour le sizing d’entrée en modes fixed et cash.Valeur par défaut : 1. |
short_size_multiplierDécimal Optionnel | Multiplicateur appliqué à la base globale définie par default_qty_value pour les ordres courts dans les modes de sizing en pourcentage. La valeur 1 laisse la taille inchangée. Des variantes .start, .stop, .step sont possibles pour la grid-search. Il est ignoré pour le sizing d’entrée en modes fixed et cash.Valeur par défaut : 1. |
pyramidingEntier Optionnel | Nombre maximal d’entrées autorisées dans la même direction pour une position. Une valeur de 1 désactive le pyramidage et limite la position à une seule entrée. Une valeur N autorise jusqu’à N entrées cumulées avant d’ignorer les signaux supplémentaires.Valeur par défaut : 1. |
close_entries_ruleTexte Optionnel | Règle utilisée lorsqu’un bloc [[close]] consomme des entrées déjà ouvertes. Dans ce contexte, order_id référence toujours la valeur order_id d’un bloc [[entry]]. Avec fifo, le moteur ferme d’abord les entrées les plus anciennes, même si le bloc [[close]] vise une entrée précise via order_id. Avec any, il ferme d’abord l’entrée ciblée par order_id, puis revient aux entrées les plus anciennes s’il reste une quantité à clôturer.Valeur par défaut : "fifo". |
close_open_position_at_endBooléen Optionnel | Contrôle le traitement d’une position encore ouverte à end_date. Quand la valeur est true, Whale‑E clôture automatiquement la position à la fin du backtest afin de produire un résultat borné sur la fenêtre sélectionnée. Quand la valeur est false, la position reste ouverte dans le moteur et Whale‑E la valorise à end_date pour le calcul final. Aucune clôture explicite n’est alors ajoutée en fin de fenêtre. Valeur par défaut : true. |
Notes complémentaires
Slippage automatique et données 1 minute
Lorsque auto_slippage_enabled est activé, le moteur applique à chaque ordre un slippage calculé sur la bougie d’une minute dans laquelle l’exécution a lieu. Il récupère la fourchette high‑low de cette minute, en prend une fraction définie par auto_slippage_ratio, puis décale le prix d’exécution d’un montant défavorable au trader.
Les bougies d’une minute nécessaires à ce calcul sont chargées automatiquement, quel que soit le timeframe principal. Lorsque auto_slippage_enabled est désactivé, le slippage est défini uniquement par slippage et le moteur n’introduit pas de slippage intrabar.
Modes de taille d’ordre (default_qty_type)
Le couple default_qty_type / default_qty_value décrit la méthode globale de calcul de la taille d’entrée pour les blocs [[entry]] et [[order]], tant qu’aucun qty ou qty_percent local ne surcharge ce comportement.
En mode fixed, la taille d’entrée est une quantité absolue. En l’absence de qty ou de qty_percent local, Whale‑E utilise [backtest].default_qty_value. Si cette valeur est absente, l’ordre est rejeté.
En mode cash, la taille d’entrée est un budget monétaire. En l’absence de qty ou de qty_percent local, Whale‑E utilise [backtest].default_qty_value comme valeur globale de repli.
En mode percent_of_equity, la taille d’entrée est déterminée à partir d’un pourcentage d’équité. default_qty_value fixe cette base globale, puis les multiplicateurs de côté peuvent ajuster cette base. Dans ce mode, default_qty_value peut être fourni comme valeur simple ou comme plage.
Pour la sémantique exacte de chaque mode, la page de référence reste « Marges et leviers ».
Pyramidage
Le paramètre pyramiding fixe le nombre maximal d’entrées cumulables dans la même direction pour une position.
Une valeur de 1 désactive le pyramidage : une fois une entrée exécutée, aucune autre entrée ne peut renforcer la position tant qu’elle n’est pas entièrement clôturée ou inversée. Une valeur N > 1 autorise jusqu’à N entrées successives dans la même direction. Le compteur est remis à zéro lorsque la position est complètement fermée ou qu’elle change de signe (passage de long à short ou inversement).
Affichage et stockage des dates
Le moteur fonctionne en interne en UTC. L’interprétation de start_date et end_date, ainsi que l’affichage des horodatages dans les journaux et la base de données, utilisent le décalage fixe inféré à partir des dates fournies. Ce décalage reste constant pendant tout le backtest.
Les horodatages stockés dans la base de données incluent ce décalage sous forme de champ de contexte (par exemple UTC+02:00).
Fin de backtest et position ouverte (close_open_position_at_end)
Le paramètre close_open_position_at_end décide si une position encore ouverte à end_date est clôturée ou seulement valorisée.
Avec close_open_position_at_end = true, Whale‑E ferme automatiquement la position à la fin du backtest. Le résultat reste alors strictement borné par la fenêtre sélectionnée, ce qui est le comportement le plus simple pour analyser un backtest terminé.
Avec close_open_position_at_end = false, Whale‑E conserve la position ouverte dans le moteur et la valorise à end_date pour établir le résultat final. Ce mode garde visible l’exposition terminale, mais certaines valeurs finales changent puisqu’aucune clôture explicite n’est ajoutée à end_date.