Réutilisation des stratégies et backtests
Les cellules de recherche restent du code Rust ordinaire et modifiable. Ces fonctions utilitaires facilitent la réutilisation du code des stratégies et des résultats enregistrés ; elles ne remplacent pas vos analyses personnalisées et n’introduisent pas de moteur de trading distinct.
Commencer dans le panneau de session
Section intitulée « Commencer dans le panneau de session »Dans Strategy code & backtests :
- Load research tools charge la bibliothèque et les composants publics de votre stratégie sous
project::, leurs dépendances habituelles et les outils de backtest et de recherche. Cette action ne connecte aucun flux de données et ne lance aucune stratégie. - Add discovery cell répertorie les backtests terminés du projet et les identifiants des paramètres du graphe.
- Choisissez une exécution de référence et une exécution candidate, puis Add comparison cell.
- Refresh saved runs actualise les sélecteurs après une expérience sans réinitialiser les variables.
- Add signal chart & heatmap crée un exemple modifiable pour l’exécution sélectionnée.
- Add isolated backtest cell utilise les instantanés historiques déjà chargés dans le notebook.
Les boutons Add… cell insèrent du code sans l’exécuter. Load research tools compile et initialise l’environnement d’exécution, mais n’exécute jamais les cellules enregistrées du notebook. Si la même révision du projet est déjà importée dans une session active, cette session est réutilisée sans recompilation, réinitialisation des variables ni marquage des résultats comme périmés. Les imports nouveaux ou modifiés réinitialisent les variables de session et marquent les résultats précédents comme périmés.
Les bougies déjà chargées et leurs paramètres de date et d’heure d’origine sont restaurés au chargement des outils. Modifier les dates de la session ne change pas la période associée à un instantané existant : rechargez les données pour utiliser une autre période.
Compilation et mise en cache
Section intitulée « Compilation et mise en cache »Le premier import résout les dépendances du projet, compile AQE, Polars et les modules exportés du projet, puis lie les fonctions utilitaires du notebook et restaure les instantanés chargés. Le panneau de session affiche l’étape de préparation ou de compilation et le temps écoulé ; Stop/reset annule l’opération. Les dépendances compilées sont conservées dans un cache propre à chaque notebook, y compris après une réinitialisation ou un redémarrage de l’application. Une compilation à froid du notebook est distincte de celle de l’application de bureau ou de l’exécutable de stratégie et peut elle aussi prendre plusieurs minutes.
Les cellules du notebook et les dépendances importées utilisent un profil de développement à compilation rapide : niveau d’optimisation 0, 256 unités de génération de code, compilation incrémentale, sans symboles de débogage ni optimisation à l’édition de liens. Les assertions de débogage, les vérifications de dépassement de capacité et le déroulement de pile en cas de panique restent activés. Ce profil privilégie la réduction du temps de compilation à la vitesse d’exécution ; les temps mesurés dans le notebook ne constituent pas des mesures de performance de stratégie compilée en mode release. Ces réglages ne concernent que la compilation du notebook, pas les compilations de stratégies en direct, les backtests ordinaires ni les sous-processus d’expériences isolées.
Après une mise à jour d’AQS, redémarrez la session du notebook pour appliquer les changements de configuration du compilateur. Cargo peut recompiler les dépendances une fois lorsque le profil change, puis réutiliser ce cache aux chargements suivants. Il n’est pas nécessaire de supprimer le cache de compilation.
Conservez le même notebook et son cache de compilation lorsque vous reprenez vos travaux. Utilisez Refresh saved runs pour actualiser les sélecteurs de backtests sans compilation. Après avoir modifié les sources ou le manifeste de ce projet, cliquez à nouveau sur Load research tools. Après avoir modifié AQE ou une autre dépendance externe référencée par un chemin, utilisez Stop/reset, puis Load research tools pour forcer une nouvelle vérification des imports. La réinitialisation efface les variables, pas le cache des dépendances ; réexécutez ensuite vos cellules de préparation personnalisées.
Réutiliser un alpha, un indicateur ou une étape de pipeline
Section intitulée « Réutiliser un alpha, un indicateur ou une étape de pipeline »Par exemple, un projet Three Amigo qui exporte un module openingrange peut utiliser l’implémentation de son propre alpha :
use project::openingrange::Openingrange;
let alpha: Openingrange = Openingrange::new( 45, "07:00".to_string(), 14, 2.0, 1.5, false,);let study: AqsBacktest = aqs_run_alpha(alpha, &research_snapshot).await?;let btc = study.bars("BTCUSD", "5m")?;let signals = study.signals("BTCUSD")?;aqs_chart(&btc).candles().signals(&signals)?.show()?;Utilisez le nom de module et le constructeur effectifs de votre composant. aqs_run_alpha effectue un rejeu historique AQE avec le cycle de vie de l’alpha et un historique filtré dans le temps. Il s’agit d’une étude de signaux uniquement, sans étape de soumission des ordres d’entrée ; ce n’est pas un backtest des rendements d’une stratégie. Testez plutôt dans une stratégie complète les alphas qui nécessitent une configuration personnalisée du cycle de vie, des unités de temps supplémentaires, des variables partagées ou un état d’exécution.
Indiquez explicitement les types des variables à l’interface avec le code importé, comme ci-dessus. L’analyse incrémentale des types du notebook Rust peut exiger une annotation même lorsqu’une compilation Cargo ordinaire déduirait le type. Si une cellule signale qu’elle ne peut pas déterminer le type d’une variable, annotez-le, par exemple let btc: DataFrame = ...;, puis rechargez la session ou la préparation si le diagnostic demande une réinitialisation.
Un indicateur importé peut travailler directement sur data.bars(symbol)?. Les étapes de pipeline d’insights importées nécessitent un contexte de stratégie et les états d’insight appropriés. Enregistrez-les dans votre Strategy AQE personnalisée, puis exécutez cette stratégie :
// my_strategy implements AQE's existing Strategy interface.let run = aqs_run_strategy( my_strategy, &research_snapshot, 100_000.0, 10,).await?;aqs_table(&run.trades()?, 20)?;Ce rejeu personnalisé utilise les frais par défaut de PaperBroker et les arguments explicites de capital et de levier. Il n’hérite ni des composants de cycle de vie enregistrés dans le graphe ni de ses paramètres de frais. Utilisez l’expérience à partir du graphe enregistré décrite ci-dessous pour les conserver. Vous pouvez également définir des fonctions, des indicateurs, des modèles et des stratégies directement dans les cellules Rust.
Lire les backtests existants
Section intitulée « Lire les backtests existants »aqs_table(&backtests.list()?, 100)?;let run = backtests.load("backtests/your-run-id")?;run.metrics()La liste comprend les exécutions terminées du répertoire backtests/ du projet lié et celles de research/experiments/. Utilisez l’identifiant renvoyé ; les chemins absolus bruts et la traversée des répertoires parents sont refusés. Les métriques et backtest.db doivent tous deux exister.
let equity = run.equity()?;let trades = run.trades()?; // Closed round tripslet insights = run.insights()?; // Full saved insight recordslet btc = run.bars("BTCUSD", "5m")?;let fills = run.table("trade_log")?;let monthly = run.table("monthly_returns")?;
aqs_table(&insights, 20)?;aqs_plot(&equity, "equity")?;bars sélectionne exactement le symbole, l’unité de temps et le flux principal enregistrés, à l’exclusion des flux de contexte. Il ajoute une colonne timestamp Int64 en millisecondes UTC. equity ajoute cet horodatage ainsi que return_pct, la variation de la valeur nette du compte depuis sa première observation, et drawdown_pct, le repli par rapport au plus haut observé jusqu’alors. Ces rendements ne sont pas ajustés des flux de trésorerie.
table(name) conserve les noms de colonnes et les données enregistrées. Les tables disponibles comprennent les bougies, l’historique du compte, les insights, le journal des transactions, les opérations complètes d’ouverture et de clôture de positions, les rendements mensuels, les performances temporelles, les séries de repli (drawdown), les performances par stratégie ou régime, les expositions factorielles, les corrélations, la concentration des positions, le glissement de prix, l’excursion adverse maximale (MAE) des transactions, les performances des configurations, le ratio de Sharpe glissant, les balayages de paramètres et les résultats walk-forward. Certaines tables peuvent manquer dans les anciennes exécutions : une erreur est alors renvoyée au lieu d’inventer des données.
Les lectures complètes sont limitées à 250 000 lignes et 64 MiB par requête. Un dépassement produit une erreur, pas un résultat tronqué silencieusement. Pour les exécutions plus volumineuses, utilisez explicitement la pagination :
let (page, has_more) = run.table_page("insights", 10_000, 0)?;// Next page: run.table_page("insights", 10_000, 10_000)?Comparer les stratégies et les signaux
Section intitulée « Comparer les stratégies et les signaux »let baseline = backtests.load("backtests/baseline-id")?;let candidate = backtests.load("backtests/candidate-id")?;
aqs_compare_backtests(&[&baseline, &candidate])?;aqs_returns_heatmap(&[&baseline, &candidate])?;let differences = aqs_compare_insights(&baseline, &candidate)?;aqs_table(&differences, 30)?;

Comparez les exécutions enregistrées à l’aide d’un récapitulatif du compte et de courbes de variation de sa valeur et de drawdown. Afficher la comparaison en taille réelleAfficher la comparaison en taille réelle.
aqs_compare_backtests accepte 2 à 6 exécutions et produit une synthèse ainsi que des courbes superposées de variation de la valeur nette du compte et de repli (drawdown). Les statistiques utilisent toutes les observations de compte chargées ; les courbes sont échantillonnées pour l’affichage. Chaque exécution conserve ses horaires UTC observés. Aucun remplissage par propagation de la dernière valeur ni recalage sur une observation commune inventée n’est effectué.
Vérifiez la concordance des périodes de test, du capital initial, des flux de trésorerie, de la révision des sources, du jeu de données, de la phase d’initialisation, des spécifications des actifs et des frais avant d’attribuer une différence à un changement de modèle. L’outil affiche des périodes différentes sans prétendre qu’il s’agit d’expériences contrôlées. Les métriques enregistrées restent accessibles avec metrics().
aqs_compare_insights rapproche les signaux générés selon le symbole, l’heure exacte de création, l’alpha, le sens, l’unité de temps et le statut parent ou enfant, et non selon les UUID aléatoires des insights. Les signaux dupliqués sont comptés. La fonction renvoie les nombres de signaux de référence et candidats, les correspondances et les signaux propres à chaque exécution. Elle ne garantit pas des exécutions d’ordres ni un P&L identiques ; examinez les tables complètes d’insights et de transactions pour ces éléments.
L’ancienne fonction aqs_compare(&data, symbols, "close") compare des prix de marché, pas les performances de backtests.
Marquer les signaux générés ou les entrées exécutées
Section intitulée « Marquer les signaux générés ou les entrées exécutées »let candles = baseline.bars("BTCUSD", "5m")?;let generated = baseline.signals("BTCUSD")?;aqs_chart(&candles).candles().signals(&generated)?.show()?;
let executed = baseline.fills("BTCUSD")?;aqs_chart(&candles).candles().signals(&executed)?.show()?;Les marqueurs générés utilisent created_at ; les marqueurs d’entrées exécutées utilisent filled_at. Un signal généré ne prouve pas qu’un ordre a été exécuté. Les DataFrames de marqueurs personnalisés nécessitent timestamp en millisecondes UTC, side avec Buy ou Sell, sans distinction de casse, et éventuellement label. Filtrez vous-même les marqueurs sur le symbole du graphique, avec un maximum de 500 marqueurs.
Le graphique interactif place chaque marqueur sur la bougie affichée qui précède l’événement et conserve l’heure exacte de celui-ci dans son texte. Les marqueurs hors de la période ne sont pas affichés. Le sous-échantillonnage peut modifier le placement visuel, jamais l’horodatage enregistré. Les instantanés d’articles AQI utilisent le même moteur de rendu interactif pour les graphiques temporels enregistrés et conservent un rendu SVG statique de secours avec des légendes indiquant l’heure des événements.
Lancer une expérience isolée à partir du graphe enregistré
Section intitulée « Lancer une expérience isolée à partir du graphe enregistré »Enregistrez le graphe et chargez les données historiques, puis examinez les véritables identifiants de nœuds et noms d’entrées :
project_parameterslet baseline = aqs_backtest() .name("Baseline") .snapshot(&research_snapshot) .run()?;
let candidate = aqs_backtest() .name("Candidate") .snapshot(&research_snapshot) .parameter("actual-node-id", "actual-input-name", 45) .run()?;
aqs_compare_backtests(&[&baseline, &candidate])?;L’outil crée un instantané des sources du projet et du graphe enregistré, vérifie les empreintes des données historiques Parquet, crée les entrées CSV et utilise la génération de code AQE habituelle avec PaperBroker. Il conserve les paramètres de dimensionnement, de risque, d’ordre des étapes du pipeline, de cycle de vie et de frais du graphe. Les valeurs de remplacement ne s’appliquent qu’à cette expérience ; le fichier .aqmeta, les sources et le manifeste d’origine ne sont pas réécrits. Les modifications non enregistrées du graphe de l’éditeur ne sont pas incluses. Résolvez d’abord les valeurs par défaut des hyperparamètres ; aucun balayage combinatoire implicite n’est lancé.
Chaque expérience se trouve dans research/experiments/<id>/, avec l’instantané des sources et de la configuration, provenance.json, execution.log et les fichiers de résultats habituels d’un backtest AQE. Les compilations réutilisent research/experiment-target/. Stop/reset termine l’arborescence des processus du notebook, y compris une expérience active. Les exécutions en échec conservent leurs diagnostics et ne figurent pas parmi les exécutions terminées.
Les dépendances externes référencées par un chemin pointent toujours vers leurs répertoires sources existants ; elles ne sont pas copiées dans l’expérience. Gardez ces dépendances stables lors des comparaisons. Le fichier de verrouillage du projet sert de point de départ, mais Cargo peut résoudre les changements nécessaires à la compilation de recherche ; examinez le Cargo.lock final de l’expérience pour reproduire les résultats.
Limites du modèle de données : le rejeu CSV utilise des actifs synthétiques, pas les spécifications de contrats MT5. L’unité de temps chargée doit correspondre exactement à celle de l’exécution du graphe ; aucun flux manquant n’est remplacé ni complété par propagation de la dernière valeur. Le chargement d’une seule unité de temps ne fournit ni unités de temps de contexte supplémentaires ni historique d’initialisation antérieur à la période. Examinez la couverture et les journaux pour les modèles qui nécessitent ces flux. Ces résultats ne sont pas automatiquement équivalents à ceux des backtests alimentés par les données d’un courtier ni à ceux d’une exécution en direct. Les projets ayant des scripts de compilation personnalisés ne sont pas encore pris en charge par l’outil d’exécution isolée du graphe.
Partager un résultat
Section intitulée « Partager un résultat »Le code sélectionné, les graphiques de comparaison, les graphiques à marqueurs, les cartes thermiques et les aperçus de tableaux peuvent être inclus dans un bloc de notebook AQI. Les lecteurs n’exécutent rien. Le partage n’envoie pas automatiquement les arborescences sources du projet, les bases de données brutes, les jeux de données ni les identifiants de connexion. Vérifiez le code, les chemins affichés et les aperçus de données avant d’enregistrer ou de publier un article.
Nous utilisons des cookies et un stockage essentiels pour la connexion, la sécurité du compte, les préférences de thème, cet avis et les mesures internes PostHog nécessaires au suivi de l’utilisation, de la qualité des sessions et de la fiabilité. Nous n’utilisons pas de cookies publicitaires.
