Aller au contenu

Composants de cycle de vie

Les composants de cycle de vie permettent de sortir la logique de lifecycle d’une grande implementation Strategy inline et de la placer dans de petits composants AQE. Vous pouvez toujours ecrire toute cette logique directement dans on_start, init, on_teardown et universe; le modele de composants existe pour rendre les projets plus faciles a segmenter, tester, reutiliser et exposer dans AQS.

Utilisez ces composants quand un bloc de logique a sa propre responsabilite, sa propre configuration, sa politique d’echec ou une valeur de reutilisation.

AQE possede un StrategyState et execute la strategie dans un ordre previsible :

  1. on_start(ctx) pour le demarrage unique.
  2. universe(ctx) pour une selection de symboles statique ou inline.
  3. les universe models enregistres pour une selection modulaire.
  4. le chargement des metadonnees d’actifs pour l’univers final fusionne.
  5. init(ctx, asset) une fois par actif tradable.
  6. les mises a jour par barre, indicateurs, modeles alpha, callbacks de strategie et insight pipes.
  7. on_teardown(ctx) pour le nettoyage final.

Les blocs de logique de cycle de vie encadrent les methodes de strategie generees ou inline. Les universe models ajoutent des symboles a l’univers final.

AQE expose un trait par phase :

aq-engine/src/core/lifecycle/mod.rs
pub trait OnStartLogic {
fn version(&self) -> &str;
fn run(&mut self, ctx: &mut dyn StrategyContext) -> LifecycleResult;
}
pub trait OnInitLogic {
fn version(&self) -> &str;
fn run(&mut self, ctx: &mut dyn StrategyContext, asset: &Asset) -> LifecycleResult;
}
pub trait OnTeardownLogic {
fn version(&self) -> &str;
fn run(&mut self, ctx: &mut dyn StrategyContext) -> LifecycleResult;
}

Chaque methode run retourne LifecycleResult, qui enregistre le succes, un message optionnel et les metadonnees du composant. Un composant en echec avec can_fail(false) arrete le run; avec can_fail(true), AQE journalise l’echec et continue.

Politique par defaut :

  • OnStartLogic : strict par defaut.
  • OnInitLogic : strict par defaut.
  • OnTeardownLogic : tolerant par defaut, pour laisser le nettoyage continuer si possible.

Les wrappers lifecycle utilisent LifecycleTiming pour choisir ou ils s’executent autour du corps de la methode :

LifecycleTiming::BeforeGenerated
LifecycleTiming::AfterGenerated

Dans les projets AQS generes, “generated” designe le corps de methode genere depuis le graphe. Dans les projets AQE ecrits a la main, c’est le corps inline de votre implementation Strategy.

Utilisez BeforeGenerated pour la validation, la configuration d’environnement, l’initialisation d’etat et les dependances attendues par le corps de strategie. Utilisez AfterGenerated pour le suivi, les controles d’enregistrement et les metadonnees qui dependent du corps de strategie.

Les projets AQE directs enregistrent la logique lifecycle sur StrategyState avant de demarrer le run. Le moteur appelle les composants automatiquement; le code utilisateur ne doit pas appeler manuellement les helpers d’execution lifecycle.

state.add_on_start_logic(
OnStartLogicBuilder::new(Box::new(SeedRuntimeState::new()))
.timing(LifecycleTiming::BeforeGenerated)
.can_fail(false)
.build(),
);
state.add_on_init_logic(
OnInitLogicBuilder::new(Box::new(InitAssetState::new()))
.timing(LifecycleTiming::AfterGenerated)
.can_fail(false)
.build(),
);
state.add_on_teardown_logic(
OnTeardownLogicBuilder::new(Box::new(FlushRuntimeLogs::new()))
.timing(LifecycleTiming::AfterGenerated)
.can_fail(true)
.build(),
);

Un universe model est un selecteur de symboles modulaire. Il retourne des symboles via UniverseResult :

aq-engine/src/core/universe/mod.rs
pub trait UniverseModel {
fn version(&self) -> &str;
fn run(&mut self, ctx: &mut dyn StrategyContext) -> UniverseResult;
}

AQE fusionne les symboles retournes par Strategy::universe(ctx) et par chaque universe model enregistre. L’univers final est une union dedoublonnee. Cela permet de garder un univers statique inline et d’ajouter des symboles depuis des watchlists, filtres, regles de compte ou selections dependant de la date.

state.add_universe_model(
UniverseModelBuilder::new(Box::new(MyUniverseModel::new()))
.can_fail(false)
.build(),
);

Le code inline reste valide :

  • mettez la configuration simple dans Strategy::on_start;
  • mettez l’initialisation par actif dans Strategy::init;
  • retournez un ensemble fixe depuis Strategy::universe;
  • placez le nettoyage ponctuel dans Strategy::on_teardown.

Preferez les composants lifecycle et universe models quand le code a une frontiere de module claire, doit etre visible dans AQS, a sa propre configuration de constructeur ou doit etre reutilise entre strategies.

Les composants lifecycle recoivent le meme StrategyContext que les strategies, modeles alpha et insight pipes. Utilisez ctx.variables() pour l’etat runtime partage qui ne doit pas devenir de la configuration AQS.

Bons usages de ctx.variables() :

  • etat de modele alpha initialise au demarrage;
  • metadonnees par symbole initialisees dans OnInitLogic;
  • metadonnees d’univers mises en cache;
  • compteurs, timestamps et flags runtime;
  • diagnostics necessaires au teardown ou a l’analyse des resultats.

Gardez les entrees ajustables par l’utilisateur dans les arguments du constructeur. Gardez le bookkeeping mutable dans ctx.variables() afin que le panneau de proprietes AQS reste centre sur la vraie configuration.