Ce rapport présente une nouvelle approche du trading de crypto-monnaies à l'aide d'un agent d'apprentissage par renforcement profond (DRL) basé sur Transformer. Le système exploite des architectures modernes inspirées du NLP (Transformers), Double DQN (DDQN), Noisy Networks et Low-Rank Adaptation (LoRA) pour la formation au temps de test (TTT). En combinant ces composants, l'agent démontre une adaptabilité améliorée, une formation de politique stable et une rentabilité considérablement améliorée sur les données historiques BTC/USDT. Bien que préliminaires, ces résultats suggèrent que la méthode peut être étendue à des ensembles de données plus complexes (par exemple, au niveau du carnet d'ordres) et à plusieurs classes d'actifs, offrant une base évolutive pour les stratégies de trading de niveau institutionnel.
Note de l'éditeur : cet article est fourni à titre informatif uniquement et ne constitue pas un conseil en investissement. Les crypto-monnaies sont spéculatives, complexes et comportent des risques élevés. Cela peut signifier une forte volatilité des prix et une perte potentielle de votre investissement initial. Vous devez tenir compte de votre situation financière, de vos objectifs d'investissement et consulter un conseiller financier avant de prendre toute décision d'investissement. L'équipe éditoriale de HackerNoon n'a vérifié l'exactitude grammaticale de l'article et n'approuve ni ne garantit l'exactitude, la fiabilité ou l'exhaustivité des informations énoncées dans cet article. #DYOR
Pourquoi Transformers, pourquoi DRL et pourquoi vous devriez vous en soucier
Les Transformers : nés dans le monde de la PNL, ils excellent dans le déchiffrement des séquences. Les marchés ne sont que des énigmes chronologiques. Les Transformers les lisent comme des histoires, anticipant les rebondissements (les mouvements de prix) bien avant que votre quant moyen ne cligne des yeux.
Double DQN (DDQN) : plus d'estimation unilatérale de la valeur Q. DDQN réduit ces surestimations notoires, donnant à votre politique de trading la crédibilité dont elle a besoin pour gérer les pièges haussiers et les raids baissiers délicats.
Les réseaux bruyants encouragent l’exploration en ajoutant du bruit paramétré directement aux pondérations du réseau.
LoRA permet une formation au moment des tests (TTT) avec une surcharge minimale, permettant au modèle de s'adapter rapidement aux nouvelles conditions du marché sans cycle de recyclage complet.
Entraînement au temps de test (TTT) : les marchés changent, évoluent, surprennent. TTT permet à ce modèle de s'adapter rapidement, en ajustant les stratégies en cours de route comme s'il lisait aujourd'hui les gros titres de demain.
Le code est activé
Dans ce cadre, un système est créé dans lequel un agent d'apprentissage interagit avec un environnement de trading simulé, guidé par une architecture moderne basée sur Transformer. À la base, le système cherche à améliorer les décisions de trading au fil du temps, en affinant sa stratégie grâce à l'apprentissage par renforcement et en s'adaptant rapidement aux nouvelles conditions du marché.
Considérons d’abord le modèle Transformer . Traditionnellement, les Transformers ont révolutionné des domaines comme le traitement du langage naturel en interprétant des séquences de mots ou de jetons. Ici, les mêmes principes sont appliqués aux données de prix de séries chronologiques. Au lieu de mots, le modèle ingère des caractéristiques historiques du marché (prix, volumes, indicateurs techniques) et tente d’extraire des dépendances temporelles significatives. La classe TransformerNetwork
, définie dans le code, illustre cette approche. Notez comment le constructeur projette les caractéristiques d’entrée brutes dans une représentation de dimension supérieure, puis les transmet à travers plusieurs couches d’encodeur Transformer :
class TransformerNetwork(nn.Module): def __init__(self, state_dim, output_dim, lookback, nhead=8, num_layers=4, model_dim=512, lora_r=8, lora_alpha=1.0, lora_active=False, sigma_init=hyperparameters['SIGMA_INIT']): super(TransformerNetwork, self).__init__() self.model_dim = model_dim self.lookback = lookback self.lora_active = lora_active self.input_fc = NoisyLoRALinear(state_dim, self.model_dim, r=lora_r, alpha=lora_alpha, lora_active=lora_active, sigma_init=sigma_init) encoder_layer = TransformerEncoderLayerRelative(d_model=model_dim, nhead=nhead, lora_r=lora_r, alpha=lora_alpha, lora_active=lora_active, sigma_init=sigma_init) self.transformer = TransformerEncoderRelative(encoder_layer, num_layers=num_layers) self.output_fc = NoisyLoRALinear(self.model_dim, output_dim, r=lora_r, alpha=lora_alpha, lora_active=lora_active, sigma_init=sigma_init) self._initialize_weights() def forward(self, x): x = self.input_fc(x) x = x.permute(1, 0, 2) x = self.transformer(x) x = x.mean(dim=0) output = self.output_fc(x) return output
Cet extrait met en évidence le flux : les états bruts entrent par input_fc
(une couche linéaire enrichie de bruit et d'adaptations potentielles de faible rang), circulent à travers des modules TransformerEncoderLayerRelative
empilés qui capturent les informations de position temporelles et relatives, et sont finalement résumés en actions par output_fc
. Cette conception permet au modèle de peser les événements à différents moments dans le temps, en identifiant des modèles récurrents ou des anomalies qui peuvent suggérer des opportunités rentables.
Si le modèle Transformer fournit les « yeux » et les « oreilles » de l'agent, la classe TradingEnv simule le monde avec lequel il interagit. Cette classe d'environnement, nommée TradingEnv
, définit ce que signifie effectuer une action (comme ouvrir ou fermer des positions) et comment les récompenses sont attribuées. Au sein de l'environnement, l'agent observe les variations de prix, les indicateurs techniques et ses avoirs actuels. L'extrait suivant montre comment l'environnement construit des états à partir des données de marché et des positions de l'agent :
def get_state(self): states = [] current_timestamp = self.tech_array.iloc[self.time]['timestamp'] weight_long = float(self.stocks_long * self.current_price / self.total_asset) if self.total_asset > 0 else 0.0 weight_short = float(self.stocks_short * self.current_price / self.total_asset) if self.total_asset > 0 else 0.0 for _ in range(self.lookback): row = self.precomputed_tech.get(current_timestamp) if row is not None: features = row.drop(['timestamp', 'date']).astype(np.float32).values state_row = np.concatenate(([weight_long, weight_short], features)).astype(np.float32) else: state_row = np.zeros(self.state_dim, dtype=np.float32) states.append(state_row) current_timestamp -= self.get_timeframe_in_seconds() states = states[::-1] # ensure chronological order state = torch.tensor(np.array(states, dtype=np.float32), dtype=torch.float32).unsqueeze(0).to(self.device) return state
Ici, l'environnement forme un riche état intégré qui comprend des informations de position et une fenêtre historique de fonctionnalités. En fournissant cette perspective fenêtrée, le transformateur peut modéliser des modèles temporels. Chaque étape de l'environnement met à jour les positions, calcule les profits ou les pertes et renvoie un nouvel état et une récompense pour l'agent. Cet échange cyclique favorise une boucle de rétroaction, permettant à l'agent d'apprendre ce qui fonctionne et ce qui ne fonctionne pas.
Le moteur de prise de décision réside dans la classe DiscreteDDQNAgent , qui implémente une approche Double DQN. Double DQN permet de remédier au biais de surestimation bien connu dans l'apprentissage Q en utilisant des réseaux distincts pour la sélection des actions et l'estimation des valeurs. L'agent conserve les instances online_net
et target_net
du modèle basé sur Transformer et utilise un tampon de relecture pour échantillonner les expériences passées. Pendant l'entraînement, il met à jour ses paramètres en minimisant la différence entre les valeurs Q prédites et les valeurs Q cibles dérivées du réseau cible :
def update(self): self.online_net.train() if len(self.memory) < self.batch_size: return None states, actions, rewards, next_states, dones = self.memory.sample(self.batch_size) q_values = self.online_net(states).gather(1, actions.unsqueeze(1)).squeeze(1) with torch.no_grad(): next_q_values = self.target_net(next_states).gather(1, self.online_net(next_states).argmax(dim=1).unsqueeze(1)).squeeze(1) target_q_values = rewards + self.gamma * next_q_values * (1 - dones) ddqn_loss = self.loss_fn(q_values, target_q_values.detach()) self.optimizer.zero_grad() ddqn_loss.backward() torch.nn.utils.clip_grad_norm_(self.online_net.parameters(), max_norm=1.0) self.optimizer.step() self.soft_update() return ddqn_loss.item()
Ce code révèle une routine de formation minutieuse : l'agent échantillonne à plusieurs reprises des mini-lots de transitions passées, calcule la perte DDQN et met à jour le online_net
. Périodiquement, il effectue une mise à jour logicielle de target_net
pour suivre lentement les améliorations. En combinant les capacités de reconnaissance de formes d'un transformateur avec la dynamique d'apprentissage stable de Double DQN, l'agent devient progressivement plus apte à sélectionner des transactions rentables.
Les conditions du marché ne sont toutefois jamais statiques. Les variations de volatilité, les changements réglementaires ou les événements soudains de liquidité peuvent transformer les gagnants d'hier en perdants d'aujourd'hui. Pour gérer ces changements, le concept de Test-Time Training (TTT) est introduit. Plutôt que de s'appuyer uniquement sur des mises à jour effectuées après avoir collecté de grandes quantités d'expérience, le TTT permet à certaines parties du réseau de s'adapter de manière dynamique à l'arrivée de nouveaux états, même pendant l'inférence. Cette adaptation rapide permet à l'agent de recalibrer ses stratégies à la volée, en s'adaptant à des circonstances imprévues sans attendre un cycle de recyclage complet.
Dans ce code, le TTT est facilité par l'entraînement sélectif des paramètres pendant l'inférence et en se concentrant sur un petit sous-ensemble de paramètres. L'agent peut, par exemple, modifier une partie de son réseau pour absorber rapidement de nouveaux modèles. Les méthodes activate_lora()
et deactivate_lora()
(non présentées maintenant car nous nous concentrons sur Transformer, Env, DDQN et la logique TTT) activent et désactivent ces paramètres adaptatifs. Bien que cet extrait de code fasse spécifiquement référence à LoRA (adaptation de bas rang), la même philosophie s'applique : TTT signifie permettre à certaines parties du modèle d'apprendre au moment du test. Lorsque le mode TTT est actif, un optimiseur spécialisé met à jour ces paramètres sur place :
def update_auxiliary(self, state): self.autoencoder.train() self.online_net.train() # Ensure noise and adaptive params are active masked_state, target_state = self.mask_input(state) masked_state_flat = masked_state.view(state.size(0), -1) target_state_flat = target_state.view(state.size(0), -1) reconstructed = self.autoencoder(masked_state_flat) aux_loss = F.mse_loss(reconstructed, target_state_flat) self.autoencoder_optimizer.zero_grad() self.ttt_optimizer.zero_grad() aux_loss.backward() torch.nn.utils.clip_grad_norm_(self.autoencoder.parameters(), max_norm=1.0) torch.nn.utils.clip_grad_norm_(filter(lambda p: p.requires_grad, self.online_net.parameters()), max_norm=1.0) self.autoencoder_optimizer.step() self.ttt_optimizer.step() self.autoencoder.eval() return aux_loss.item()
Cette routine de mise à jour auxiliaire, déclenchée au moment du test, démontre l'adaptabilité du système. L'agent masque intentionnellement certaines caractéristiques d'entrée et tente de les reconstruire, améliorant ainsi sa représentation interne du régime de marché actuel. Ce faisant, il peut réagir rapidement aux changements de données et maintenir des stratégies rentables dans un paysage en constante évolution.
En résumé, l'interaction entre ces composants crée une machine de trading robuste et flexible. Le modèle basé sur Transformer fournit une compréhension riche et contextuelle des signaux du marché. TradingEnv simule des conditions réalistes et des boucles de rétroaction. Le cadre Double DQN assure un apprentissage stable des valeurs d'action, affinant progressivement les décisions de trading. Enfin, TTT permet à l'agent de rester agile, en ajustant ses paramètres internes lorsqu'il est confronté à de nouveaux modèles. Ensemble, ces éléments ouvrent la voie à un système à la fois sophistiqué en matière de reconnaissance de modèles et résilient face à l'incertitude du marché, offrant une vision convaincante des stratégies de trading de nouvelle génération.
Quel est le résultat ?
Potentiel de niveau supérieur
Commentez, impliquez-vous, proposez une offre 🤯
Ne laissez pas cela devenir une curiosité passagère. Commentez, critiquez, posez des questions. Si vous vous demandez comment faire évoluer votre stratégie ou comment intégrer une solution DRL flexible dans votre pile existante, laissez un commentaire.