Este informe presenta un nuevo enfoque para el comercio de criptomonedas utilizando un agente de aprendizaje por refuerzo profundo (DRL) basado en Transformers. El sistema aprovecha las arquitecturas modernas inspiradas en el procesamiento del lenguaje natural (Transformers), Double DQN (DDQN), redes ruidosas y adaptación de bajo rango (LoRA) para el entrenamiento en tiempo de prueba (TTT). Al combinar estos componentes, el agente demuestra una mejor adaptabilidad, una formación de políticas estable y una rentabilidad significativamente mejorada en los datos históricos de BTC/USDT. Si bien son preliminares, estos resultados sugieren que el método se puede extender a conjuntos de datos más complejos (por ejemplo, a nivel de cartera de pedidos) y múltiples clases de activos, lo que proporciona una base escalable para estrategias comerciales de nivel institucional.
Nota del editor: este artículo es solo para fines informativos y no constituye asesoramiento de inversión. Las criptomonedas son especulativas, complejas e implican altos riesgos. Esto puede significar una alta volatilidad de precios y una posible pérdida de su inversión inicial. Debe considerar su situación financiera, sus propósitos de inversión y consultar con un asesor financiero antes de tomar cualquier decisión de inversión. El equipo editorial de HackerNoon solo ha verificado la historia en busca de precisión gramatical y no respalda ni garantiza la precisión, confiabilidad o integridad de la información expresada en este artículo. #DYOR
Por qué usar Transformers, por qué luces DRL y por qué debería importarte
Transformers: Nacidos en el mundo de la PNL, son expertos en descifrar secuencias. Los mercados son simplemente rompecabezas de series temporales. Los Transformers los leen como historias, anticipando giros de la trama (movimientos de precios) mucho antes de que un analista cuantitativo promedio pestañee.
Double DQN (DDQN): ya no se realizan estimaciones unilaterales del valor Q. DDQN reduce esas notorias sobreestimaciones, lo que le otorga a su política comercial la credibilidad que necesita para manejar trampas alcistas complicadas y ataques bajistas.
Las redes ruidosas fomentan la exploración agregando ruido parametrizado directamente a los pesos de la red.
LoRA permite el entrenamiento en tiempo de prueba (TTT) con una sobrecarga mínima, lo que permite que el modelo se adapte rápidamente a las nuevas condiciones del mercado sin un ciclo de reentrenamiento completo.
Entrenamiento en tiempo de prueba (TTT): los mercados cambian, evolucionan y sorprenden. El TTT permite que este modelo se adapte rápidamente y ajuste las estrategias sobre la marcha, como si estuviera leyendo hoy los titulares de mañana.
El código está activado
En este marco se crea un sistema en el que un agente de aprendizaje interactúa con un entorno de trading simulado, guiado por una arquitectura moderna basada en Transformers. En esencia, el sistema busca mejorar las decisiones de trading a lo largo del tiempo, refinando su estrategia a través del aprendizaje de refuerzo y adaptándose rápidamente a las nuevas condiciones del mercado.
Consideremos primero el modelo Transformer . Tradicionalmente, los Transformers han revolucionado campos como el procesamiento del lenguaje natural al interpretar secuencias de palabras o tokens. Aquí, los mismos principios se aplican a los datos de precios de series temporales. En lugar de palabras, el modelo ingiere características históricas del mercado (precios, volúmenes, indicadores técnicos) e intenta extraer dependencias temporales significativas. La clase TransformerNetwork
, definida en el código, ejemplifica este enfoque. Observe cómo el constructor proyecta características de entrada sin procesar en una representación de dimensiones superiores y luego las pasa a través de múltiples capas de codificador de 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
Este fragmento destaca el flujo: los estados sin procesar ingresan a través de input_fc
(una capa lineal mejorada con ruido y posibles adaptaciones de bajo rango), viajan a través de módulos apilados TransformerEncoderLayerRelative
que capturan información posicional temporal y relativa y, finalmente, se resumen en acciones mediante output_fc
. Este diseño permite que el modelo pondere los eventos en diferentes puntos del tiempo, identificando patrones recurrentes o anomalías que pueden sugerir oportunidades rentables.
Si el modelo Transformer proporciona los “ojos” y los “oídos” del agente, la clase TradingEnv simula el mundo con el que interactúa. Esta clase de entorno, denominada TradingEnv
, define lo que significa realizar una acción (como abrir o cerrar posiciones) y cómo se asignan las recompensas. Dentro del entorno, el agente observa los cambios de precios, los indicadores técnicos y sus tenencias actuales. El siguiente extracto muestra cómo el entorno construye estados a partir de los datos del mercado y las posiciones del agente:
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
Aquí, el entorno forma una rica incrustación de estados que incluye información de posición y una ventana histórica de características. Al proporcionar esta perspectiva en ventana, el Transformador puede modelar patrones temporales. Cada paso del entorno actualiza las posiciones, calcula las ganancias o pérdidas y devuelve un nuevo estado y una recompensa para el agente. Este intercambio cíclico fomenta un ciclo de retroalimentación, que permite al agente aprender qué funciona y qué no.
El motor de toma de decisiones reside en la clase DiscreteDDQNAgent , que implementa un enfoque Double DQN. Double DQN ayuda a abordar el conocido sesgo de sobreestimación en el aprendizaje Q mediante el uso de redes separadas para la selección de acciones y la estimación de valores. El agente mantiene instancias online_net
y target_net
del modelo basado en Transformer y utiliza un búfer de reproducción para muestrear experiencias pasadas. Durante el entrenamiento, actualiza sus parámetros minimizando la diferencia entre los valores Q predichos y los valores Q objetivo derivados de la red objetivo:
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()
Este código revela una rutina de entrenamiento cuidadosa: el agente toma muestras repetidas de minilotes de transiciones pasadas, calcula la pérdida de DDQN y actualiza online_net
. Periódicamente, realiza una actualización suave de target_net
para realizar un seguimiento lento de las mejoras. Al combinar las capacidades de reconocimiento de patrones de un transformador con la dinámica de aprendizaje estable de Double DQN, el agente gradualmente se vuelve más hábil para seleccionar transacciones rentables.
Sin embargo, las condiciones del mercado nunca se detienen. Los cambios en la volatilidad, los cambios regulatorios o los eventos repentinos de liquidez pueden convertir a los ganadores de ayer en los perdedores de hoy. Para manejar estos cambios, se introduce el concepto de entrenamiento en tiempo de prueba (TTT, por sus siglas en inglés) . En lugar de depender únicamente de las actualizaciones realizadas después de recopilar grandes cantidades de experiencia, TTT permite que ciertas partes de la red se adapten dinámicamente a medida que llegan nuevos estados, incluso durante la inferencia. Esta rápida adaptación permite al agente recalibrar sus estrategias sobre la marcha, ajustándose a circunstancias imprevistas sin esperar un ciclo de reentrenamiento completo.
En este código, la TTT se facilita entrenando selectivamente los parámetros durante la inferencia y centrándose en un pequeño subconjunto de parámetros. El agente puede, por ejemplo, modificar una parte de su red para absorber rápidamente nuevos patrones. Los métodos activate_lora()
y deactivate_lora()
(no se muestran ahora porque nos centramos en la lógica Transformer, Env, DDQN y TTT) activan y desactivan estos parámetros adaptativos. Si bien ese fragmento de código hace referencia específicamente a LoRA (adaptación de bajo rango), se aplica la misma filosofía: TTT significa permitir que ciertas partes del modelo aprendan en el momento de la prueba. Cuando el modo TTT está activo, un optimizador especializado actualiza estos parámetros en el momento:
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()
Esta rutina de actualización auxiliar, que se activa en el momento de la prueba, demuestra la adaptabilidad del sistema. El agente enmascara intencionalmente algunas características de entrada e intenta reconstruirlas, mejorando su representación interna del régimen de mercado actual. De este modo, puede reaccionar rápidamente a los cambios de datos y mantener estrategias rentables en un panorama en constante cambio.
En resumen, la interacción entre estos componentes crea una máquina de trading robusta y flexible. El modelo basado en Transformer proporciona una comprensión rica y sensible al contexto de las señales del mercado. TradingEnv simula condiciones realistas y ciclos de retroalimentación. El marco Double DQN asegura un aprendizaje estable de los valores de acción, refinando gradualmente las decisiones de trading. Finalmente, TTT permite al agente permanecer ágil, ajustando sus parámetros internos cuando se enfrenta a patrones nuevos. Juntos, estos elementos preparan el escenario para un sistema que es sofisticado en el reconocimiento de patrones y resistente frente a la incertidumbre del mercado, ofreciendo una visión convincente para las estrategias de trading de próxima generación.
¿Cual es el resultado?
Potencial de siguiente nivel
Comenta, interactúa, ofrece una oferta 🤯
No dejes que esto sea una curiosidad pasajera. Comenta, critica, haz preguntas. Si te preguntas cómo cambiar tu estrategia o cómo integrar una solución DRL flexible en tu conjunto de herramientas existente, deja un comentario.