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.

Une stratégie ne peut déclarer qu’un seul bloc [backtest].

Voir la page « Exchanges, Symboles et Timeframes » pour l’interprétation des symboles et des timeframes.

La logique de marge, de levier, d’équité, de prix de sizing, de prix d’exécution et de liquidation est décrite dans la page « Marges et leviers ». Le bloc [backtest] expose uniquement les paramètres nécessaires à cette logique.

Les règles d’assemblage des plages .start, .stop et .step avec celles des indicateurs sont expliquées dans la page « Combinaisons d’hyperparamètres ».

Déclaration du bloc

Une stratégie ne peut contenir qu’un seul bloc [backtest].

Exemples

Les exemples suivants montrent des configurations complètes que vous pouvez adapter à vos propres stratégies. Pour la signification détaillée de default_qty_type, de default_qty_value, des paramètres margin_* et des multiplicateurs de taille, reportez-vous à la page « Marges et leviers ». Les combinaisons générées par les plages sont comptées et validées selon les règles décrites dans « Combinaisons d’hyperparamètres ».

Configuration minimale

Cette configuration 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 = 1000

Backtest sans levier explicite au sens de l’exposition

Ce bloc configure un backtest avec une taille d’ordre exprimée en pourcentage de l’équité. Les paramètres de marge conservent leurs valeurs par défaut, et l’allocation reste en dessous de 100% pour garder une marge de sécurité face aux frais et aux écarts entre prix de sizing et prix d’exécution dans le cadre 1x par défaut.

[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 = 95

Backtest avec marge et multiplicateurs asymétriques

Ce bloc 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 shorts

Optimiser 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  = 5

Explorer 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 longues. 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.5

Optimiser 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 est surtout pertinent pour les stratégies capables d’ouvrir des positions longues et courtes. Dans ce cas, default_qty_value définit une base commune, tandis que long_size_multiplier et short_size_multiplier permettent d’ajuster l’exposition de chaque côté séparément. Sur une stratégie unidirectionnelle, ces paramètres se confondent largement sur le côté actif et l’intérêt de cette optimisation conjointe devient beaucoup plus limité.

[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.5

Paramè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ètreDescription
start_date
 Date‑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 :
  • Si start_date et end_date contiennent le même décalage explicite (par exemple +02:00), ce décalage est utilisé.
  • Si une seule des deux dates contient un décalage explicite, l’autre date est interprétée avec ce même décalage.
  • Si aucune des deux dates ne contient de décalage explicite, les deux dates sont interprétées en UTC.
  • Si start_date et end_date contiennent des décalages explicites différents, la configuration est rejetée.

Formats acceptés :
  • Chaîne ISO 8601 avec Z (UTC) ou avec un décalage ±HH:MM (par exemple "2024-06-01T12:30:45Z", "2024-06-01T12:30:45+02:00").
  • Chaîne ISO 8601 sans décalage, séparée par un espace (par exemple "2024-06-01 12:30:45").
  • Chaîne date ISO 8601 sans heure (par exemple "2024-06-01"), interprétée à minuit.
  • Types TOML offset-date-time, local-date-time ou local-date avec la même logique d’interprétation.
Les fuseaux nommés ne sont pas pris en charge et le décalage reste fixe pendant tout le backtest.
end_date
 Date‑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_date
 Date‑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.
symbol
 Texte
 ou Tableau
 Obligatoire
Symbole principal de la simulation. Peut être une chaîne unique (par exemple "BINANCE:BTCUSDT") ou un tableau de symboles. Le préfixe d’exchange est obligatoire au format EXCHANGE:SYMBOL. Lorsque plusieurs symboles sont fournis, Whale‑E construit une grille pour chaque combinaison symbole/timeframe. Pour la description complète des formats et de la projection entre symboles, voir la page « Exchanges, Symboles et Timeframes ».
timeframe
 Texte
 ou Tableau
 Obligatoire
Timeframe principal du backtest. Peut être une chaîne unique (par exemple "60", "240", "D", "W") ou un tableau de timeframes. Lorsque plusieurs timeframes ou symboles sont indiqués, Whale‑E crée une grille distincte pour chaque combinaison symbole/timeframe. Le comportement des indicateurs qui surchargent leur timeframe est décrit dans la page « Exchanges, Symboles et Timeframes ».
auto_slippage_enabled
 Boolé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_ratio
 Décimal
 Optionnel
Ratio appliqué à la fourchette highlow de la bougie d’une minute pour calculer le slippage automatique. Ignoré si auto_slippage_enabled est false.
Valeur par défaut : 0.25.
slippage
 Entier
 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_assumption
 Entier
 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_magnifier
 Boolé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_close
 Boolé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_candle
 Entier
 Optionnel
Nombre maximal de blocs executes sur une meme bougie sans avancee de bougie. Permet de detecter et stopper les boucles infinies. La valeur 0 desactive la detection.
Valeur par defaut : 1024.
commission_value
 Dé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_type
 Texte
 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_capital
 Décimal
 Optionnel
Capital initial du backtest, exprimé dans la devise de cotation du symbole principal.
Valeur par défaut : 1000000.
default_qty_type
 Texte
 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_value
 Dé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_long
 Décimal
 Optionnel
Pourcentage de marge appliqué aux positions longues. 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 longues. Ce paramètre accepte aussi une plage via les suffixes .start, .stop et .step. 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_short
 Décimal
 Optionnel
Pourcentage de marge appliqué aux positions courtes. 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 courtes. Comme pour margin_long, des variantes .start, .stop et .step peuvent être utilisées pour la grid‑search.
Valeur par défaut : 100.
long_size_multiplier
 Dé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_multiplier
 Dé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.
pyramiding
 Entier
 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_rule
 Texte
 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_end
 Boolé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 highlow 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.