Русский
preview
Computação quântica e trading: Um novo olhar sobre as previsões de preços

Computação quântica e trading: Um novo olhar sobre as previsões de preços

MetaTrader 5Sistemas de negociação | 26 junho 2025, 15:09
79 0
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Introdução à computação quântica para trading: conceitos básicos e vantagens

Imagine um mundo onde cada operação de mercado é analisada através da lente das possibilidades que existem simultaneamente, como o famoso gato de Schrödinger, que está vivo e morto ao mesmo tempo até abrirmos a caixa. É exatamente assim que funciona o trading quântico: ele considera todos os possíveis estados do mercado ao mesmo tempo, abrindo novos horizontes para a análise financeira.

Enquanto os computadores clássicos processam informações de forma sequencial, bit por bit, os sistemas quânticos utilizam as incríveis propriedades do micromundo — superposição e entrelaçamento — para analisar muitos cenários em paralelo. Isso se assemelha a um trader experiente que mantém em mente dezenas de gráficos, notícias e indicadores ao mesmo tempo, mas numa escala impossível de alcançar com métodos convencionais.

Vivemos numa era em que o trading algorítmico já se tornou a norma, mas agora estamos prestes a entrar na próxima revolução. A computação quântica promete não apenas acelerar a análise de dados, mas também oferece uma abordagem totalmente nova para compreender os processos de mercado. Imagine que, em vez de prever linearmente o preço de um ativo, podemos explorar toda uma árvore de cenários probabilísticos, onde cada ramificação leva em conta as mais sutis correlações de mercado.

Neste artigo, vamos mergulhar no universo do trading quântico, desde os princípios básicos da computação quântica até a implementação prática de sistemas de negociação. Veremos como os algoritmos quânticos podem identificar padrões onde os métodos clássicos falham, e como essa vantagem pode ser aplicada para tomar decisões de negociação em tempo real.

Nossa jornada começará com os fundamentos da computação quântica e nos levará, passo a passo, à criação de um sistema funcional de previsão de mercado. Ao longo do caminho, vamos destrinchar conceitos complexos com exemplos simples e enxergar como as vantagens teóricas da computação quântica se transformam em ferramentas práticas para o trading.


Superposição quântica e entrelaçamento no contexto da análise de séries temporais financeiras

Ao analisar os mercados financeiros, nos deparamos com um problema fundamental: uma infinidade de fatores interdependentes. Cada movimento de preço é o resultado de uma interação complexa entre milhares de variáveis, desde indicadores macroeconômicos até o sentimento de traders individuais. É justamente aqui que a computação quântica oferece uma solução exclusiva, graças às suas propriedades fundamentais: superposição e entrelaçamento.

Vamos considerar a superposição. Em um computador clássico, um bit pode ser 0 ou 1. Já um qubit existe em todos os estados possíveis ao mesmo tempo, até que realizemos uma medição. Matematicamente, isso é descrito como o estado |ψ⟩ = α|0⟩ + β|1⟩, onde α e β são amplitudes complexas de probabilidade. Aplicado à análise de séries temporais, esse recurso permite que os algoritmos quânticos explorem de forma eficiente o espaço de soluções em tarefas de gestão de portfólio e gerenciamento de risco, analisando múltiplos cenários potenciais em paralelo.

O entrelaçamento quântico acrescenta outra camada de possibilidades. Quando qubits estão entrelaçados, seus estados tornam-se inseparavelmente conectados, como é descrito, por exemplo, pelo estado |ψ⟩ = (|00⟩ + |11⟩)/√2. No contexto da análise financeira, essa propriedade é usada por algoritmos quânticos para modelar correlações complexas entre diversos indicadores de mercado. Por exemplo, podemos criar sistemas que levam em conta a relação entre o preço de um ativo, o volume de negociação e a volatilidade do mercado.

Essas propriedades quânticas são especialmente úteis no trading de alta frequência, onde a velocidade no processamento de dados multidimensionais é crucial. A superposição permite analisar diversos cenários de negociação em paralelo, enquanto o entrelaçamento possibilita capturar correlações complexas entre mercados em tempo real. As vantagens quânticas se destacam particularmente em tarefas específicas de otimização e busca, onde algoritmos clássicos enfrentam crescimento exponencial na complexidade computacional.


Desenvolvimento de um algoritmo quântico de previsão usando QPE (Quantum Phase Estimation)

No coração do nosso sistema está uma combinação elegante entre computação quântica e análise técnica clássica. Imagine um orquestra quântica formada por oito qubits, onde cada qubit é como um músico tocando sua parte na complexa sinfonia dos movimentos de mercado.

Tudo começa com a preparação dos dados. Nosso preditor quântico recebe os dados de mercado por meio da integração com o MetaTrader 5, como se fossem neurônios coletando informações dos órgãos sensoriais. Esses dados passam por um processo de normalização. É como se estivéssemos afinando todos os instrumentos da orquestra para a mesma tonalidade.

A parte mais fascinante começa na criação do circuito quântico. Primeiro, colocamos cada qubit em estado de superposição utilizando os portões de Hadamard (H-gates). Nesse momento, cada qubit existe simultaneamente em todos os estados possíveis, como se cada músico estivesse tocando todas as notas da sua partitura ao mesmo tempo.

Depois, codificamos os dados de mercado nos estados quânticos por meio dos portões ry, onde o ângulo de rotação é determinado pelos valores dos parâmetros de mercado. Isso se assemelha ao maestro definindo o tempo e a expressividade de cada músico. A atenção especial vai para o preço atual, que recebe uma rotação quântica própria, influenciando todo o sistema, como um solista conduzindo o conjunto.

A verdadeira mágica acontece na criação do entrelaçamento quântico. Ao utilizar os portões cx (CNOT), conectamos qubits vizinhos, criando correlações quânticas inseparáveis. É como o momento em que as partes individuais dos músicos se fundem em uma única harmonia.

Após as transformações quânticas, realizamos medições, como se estivéssemos gravando o concerto. Mas há um detalhe: repetimos esse processo 2000 vezes (shots), obtendo uma distribuição estatística dos resultados. Cada medição nos fornece uma cadeia de bits, onde a quantidade de uns determina a direção da previsão.

O acorde final é a interpretação dos resultados. O sistema é muito conservador em seus prognósticos, limitando a variação máxima de preço a 0.1%. Isso se compara a um maestro experiente que não permite que a orquestra toque alto demais ou baixo demais, preservando o equilíbrio sonoro.

Os resultados dos testes falam por si. A precisão das previsões supera o mero palpite, alcançando 54% no timeframe de 1 hora para EUR/USD. Ao mesmo tempo, o sistema demonstra um alto nível de confiança em suas previsões, refletido na métrica de confidence.

Nesta implementação, a computação quântica não apenas complementa a análise técnica clássica, como também cria uma nova dimensão na análise de mercado, onde múltiplos cenários possíveis são explorados simultaneamente na superposição quântica. Como dizia Richard Feynman: "A natureza, no nível quântico, não se comporta da maneira que estamos acostumados a pensar". E ao que tudo indica, os mercados financeiros também escondem uma natureza quântica que estamos apenas começando a descobrir.

import numpy as np
import MetaTrader5 as mt5
import pandas as pd
from datetime import datetime, timedelta
from qiskit import QuantumCircuit, transpile, QuantumRegister, ClassicalRegister
from qiskit_aer import AerSimulator
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
import warnings
warnings.filterwarnings('ignore')

class MT5DataLoader:
    def __init__(self, symbol="EURUSD", timeframe=mt5.TIMEFRAME_H1):
        if not mt5.initialize():
            raise Exception("MetaTrader5 initialization failed")
        
        self.symbol = symbol
        self.timeframe = timeframe
    
    def get_historical_data(self, lookback_bars=1000):
        current_time = datetime.now()
        rates = mt5.copy_rates_from(self.symbol, self.timeframe, current_time, lookback_bars)
        
        if rates is None:
            raise Exception(f"Failed to get data for {self.symbol}")
            
        df = pd.DataFrame(rates)
        df['time'] = pd.to_datetime(df['time'], unit='s')
        return df

class EnhancedQuantumPredictor:
    def __init__(self, num_qubits=8):  # Уменьшаем число кубитов для стабильности
        self.num_qubits = num_qubits
        self.simulator = AerSimulator()
        self.scaler = MinMaxScaler()
        
    def create_qpe_circuit(self, market_data, current_price):
        """Создание упрощенной квантовой схемы"""
        qr = QuantumRegister(self.num_qubits, 'qr')
        cr = ClassicalRegister(self.num_qubits, 'cr')
        qc = QuantumCircuit(qr, cr)
        
        # Нормализуем данные
        scaled_data = self.scaler.fit_transform(market_data.reshape(-1, 1)).flatten()
        
        # Создаем суперпозицию
        for i in range(self.num_qubits):
            qc.h(qr[i])
        
        # Применяем рыночные данные как фазы
        for i in range(min(len(scaled_data), self.num_qubits)):
            angle = float(scaled_data[i] * np.pi)  # Преобразуем в float
            qc.ry(angle, qr[i])
        
        # Создаем запутанность
        for i in range(self.num_qubits - 1):
            qc.cx(qr[i], qr[i + 1])
        
        # Применяем текущую цену
        price_angle = float((current_price % 0.01) * 100 * np.pi)  # Используем только последние 2 знака
        qc.ry(price_angle, qr[0])
        
        # Измеряем все кубиты
        qc.measure(qr, cr)
        
        return qc
    
    def predict(self, market_data, current_price, features=None, shots=2000):
        """Упрощенное предсказание"""
        # Обрезаем входные данные
        if market_data.shape[0] > self.num_qubits:
            market_data = market_data[-self.num_qubits:]
        
        # Создаем и выполняем схему
        qc = self.create_qpe_circuit(market_data, current_price)
        compiled_circuit = transpile(qc, self.simulator, optimization_level=3)
        job = self.simulator.run(compiled_circuit, shots=shots)
        result = job.result()
        counts = result.get_counts()
        
        # Анализируем результаты
        predictions = []
        total_shots = sum(counts.values())
        
        for bitstring, count in counts.items():
            # Используем количество единиц в битстроке для определения направления
            ones = bitstring.count('1')
            direction = ones / self.num_qubits  # Нормализованное направление
            
            # Предсказываем изменение не более чем на 0.1%
            price_change = (direction - 0.5) * 0.001
            predicted_price = current_price * (1 + price_change)
            predictions.extend([predicted_price] * count)
        
        predicted_price = np.mean(predictions)
        up_probability = sum(1 for p in predictions if p > current_price) / len(predictions)
        
        confidence = 1 - np.std(predictions) / current_price
        

        
        return {
            'predicted_price': predicted_price,
            'up_probability': up_probability,
            'down_probability': 1 - up_probability,
            'confidence': confidence
        }

class MarketPredictor:
    def __init__(self, symbol="EURUSD", timeframe=mt5.TIMEFRAME_H1, window_size=14):
        self.symbol = symbol
        self.timeframe = timeframe
        self.window_size = window_size
        self.quantum_predictor = EnhancedQuantumPredictor()
        self.data_loader = MT5DataLoader(symbol, timeframe)
    
    def prepare_features(self, df):
        """Подготовка технических индикаторов"""
        df['sma'] = df['close'].rolling(window=self.window_size).mean()
        df['ema'] = df['close'].ewm(span=self.window_size).mean()
        df['std'] = df['close'].rolling(window=self.window_size).std()
        df['upper_band'] = df['sma'] + (df['std'] * 2)
        df['lower_band'] = df['sma'] - (df['std'] * 2)
        df['rsi'] = self.calculate_rsi(df['close'])
        df['momentum'] = df['close'] - df['close'].shift(self.window_size)
        df['rate_of_change'] = (df['close'] / df['close'].shift(1) - 1) * 100
        
        features = df[['sma', 'ema', 'std', 'upper_band', 'lower_band', 
                      'rsi', 'momentum', 'rate_of_change']].dropna()
        return features
    
    def calculate_rsi(self, prices, period=14):
        delta = prices.diff()
        gain = (delta.where(delta > 0, 0)).ewm(alpha=1/period).mean()
        loss = (-delta.where(delta < 0, 0)).ewm(alpha=1/period).mean()
        rs = gain / loss
        return 100 - (100 / (1 + rs))
    
    def predict(self):
        # Получаем данные
        df = self.data_loader.get_historical_data(self.window_size + 50)
        features = self.prepare_features(df)
        
        if len(features) < self.window_size:
            raise ValueError("Недостаточно данных")
        
        # Получаем последние данные для прогноза
        latest_features = features.iloc[-self.window_size:].values
        current_price = df['close'].iloc[-1]
        
        # Делаем прогноз, теперь передаем features как DataFrame
        prediction = self.quantum_predictor.predict(
            market_data=latest_features,
            current_price=current_price,
            features=features.iloc[-self.window_size:]  # Передаем последние записи
        )
        
        prediction.update({
            'timestamp': datetime.now(),
            'current_price': current_price,
            'rsi': features['rsi'].iloc[-1],
            'sma': features['sma'].iloc[-1],
            'ema': features['ema'].iloc[-1]
        })
        
        return prediction

def evaluate_model(symbol="EURUSD", timeframe=mt5.TIMEFRAME_H1, test_periods=100):
    """Оценка точности модели"""
    predictor = MarketPredictor(symbol, timeframe)
    predictions = []
    actual_movements = []
    
    # Получаем исторические данные
    df = predictor.data_loader.get_historical_data(test_periods + 50)
    
    for i in range(test_periods):
        try:
            temp_df = df.iloc[:-(test_periods-i)]
            predictor_temp = MarketPredictor(symbol, timeframe)
            features_temp = predictor_temp.prepare_features(temp_df)
            
            # Получаем данные для прогноза
            latest_features = features_temp.iloc[-predictor_temp.window_size:].values
            current_price = temp_df['close'].iloc[-1]
            
            # Делаем прогноз с передачей всех необходимых параметров
            prediction = predictor_temp.quantum_predictor.predict(
                market_data=latest_features,
                current_price=current_price,
                features=features_temp.iloc[-predictor_temp.window_size:]
            )
            
            predicted_movement = 1 if prediction['up_probability'] > 0.5 else 0
            predictions.append(predicted_movement)
            
            actual_price_next = df['close'].iloc[-(test_periods-i)]
            actual_price_current = df['close'].iloc[-(test_periods-i)-1]
            actual_movement = 1 if actual_price_next > actual_price_current else 0
            actual_movements.append(actual_movement)
            
        except Exception as e:
            print(f"Error in evaluation: {e}")
            continue
    
    if len(predictions) > 0:
        metrics = {
            'accuracy': accuracy_score(actual_movements, predictions),
            'precision': precision_score(actual_movements, predictions),
            'recall': recall_score(actual_movements, predictions),
            'f1': f1_score(actual_movements, predictions)
        }
    else:
        metrics = {
            'accuracy': 0,
            'precision': 0,
            'recall': 0,
            'f1': 0
        }
    
    return metrics

if __name__ == "__main__":
    if not mt5.initialize():
        print("MetaTrader5 initialization failed")
        mt5.shutdown()
    else:
        try:
            symbol = "EURUSD"
            timeframe = mt5.TIMEFRAME_H1
            
            print("\nТестирование модели...")
            metrics = evaluate_model(symbol, timeframe, test_periods=100)
            
            print("\nМетрики качества модели:")
            print(f"Точность (Accuracy): {metrics['accuracy']:.2%}")
            print(f"Точность прогнозов (Precision): {metrics['precision']:.2%}")
            print(f"Полнота (Recall): {metrics['recall']:.2%}")
            print(f"F1-мера: {metrics['f1']:.2%}")
            
            print("\nТекущий прогноз:")
            predictor = MarketPredictor(symbol, timeframe)
            df = predictor.data_loader.get_historical_data(predictor.window_size + 50)
            features = predictor.prepare_features(df)
            latest_features = features.iloc[-predictor.window_size:].values
            current_price = df['close'].iloc[-1]
            
            prediction = predictor.predict()  # Теперь этот метод правильно передает все параметры
            
            print(f"Предсказанная цена: {prediction['predicted_price']:.5f}")
            print(f"Вероятность роста: {prediction['up_probability']:.2%}")
            print(f"Вероятность падения: {prediction['down_probability']:.2%}")
            print(f"Уверенность в прогнозе: {prediction['confidence']:.2%}")
            print(f"Текущая цена: {prediction['current_price']:.5f}")
            print(f"RSI: {prediction['rsi']:.2f}")
            print(f"SMA: {prediction['sma']:.5f}")
            print(f"EMA: {prediction['ema']:.5f}")
            
        finally:
            mt5.shutdown()


Teste e validação do sistema de trading quântico: metodologia e resultados



Principais métricas de desempenho

  • Precisão geral (Accuracy): 55,00% — Supera moderadamente o acerto aleatório em um mercado volátil como o EURUSD.
  • Precisão dos prognósticos (Precision): 63,64% — Mostra boa confiabilidade dos sinais gerados pelo sistema; quase dois terços das previsões são corretas.
  • Revocação (Recall): 14,58% — Um valor baixo indica que o sistema é seletivo e só gera sinais quando tem alta confiança na previsão. Isso ajuda a evitar sinais falsos.
  • F1-score: 23,73% — Este valor expressa o equilíbrio entre precisão e revocação, confirmando a estratégia conservadora do sistema.

Previsão atual do mercado

  • Preço atual do euro-dólar EURUSD: 1.02903
  • Preço previsto: 1.02905
  • Distribuição probabilística:
    • Probabilidade de alta: 38,95%
    • Probabilidade de queda: 61,05%
  • Confiança na previsão: 99,98%

O sistema prevê um leve movimento de alta com alta confiança, apesar da probabilidade predominante de queda. Isso pode indicar um período de correção de curto prazo dentro de uma tendência de baixa mais ampla.

Indicadores técnicos

  • RSI: 49,13 (próximo da zona neutra, não indica sobrecompra nem sobrevenda)
  • SMA: 1.02904
  • EMA: 1.02909
  • Tendência: neutra (o preço atual está próximo das médias móveis)

Conclusões

O sistema apresenta as seguintes características principais:

  1. Precisão consistente acima do acerto aleatório
  2. Alta seletividade na geração de sinais (63,64% de previsões corretas)
  3. Capacidade de quantificar confiança e probabilidades de diferentes cenários
  4. Análise abrangente da situação de mercado, levando em conta tanto indicadores técnicos quanto padrões mais complexos

Essa abordagem conservadora, que prioriza a qualidade dos sinais em vez da quantidade, torna o sistema um potencial instrumento eficaz para trading real.


Integração de métricas de aprendizado de máquina e algoritmos quânticos: reflexões e primeiros testes

A união da computação quântica com o aprendizado de máquina abre novos horizontes. Em nosso experimento, o MinMaxScaler do sklearn é usado para normalizar os dados antes da codificação quântica, convertendo os dados de mercado em ângulos quânticos.

O sistema combina métricas de aprendizado de máquina (accuracy, precision, recall, F1-score) com medições quânticas. Com uma precisão de 60%, ele capta padrões inacessíveis aos algoritmos clássicos, demonstrando cautela e seletividade, como um trader experiente.

O futuro desses sistemas envolve a integração de métodos avançados de pré-processamento, como autocodificadores e transformadores, para uma análise de dados mais profunda. Os algoritmos quânticos podem atuar como filtros para modelos clássicos ou vice-versa, adaptando-se às condições do mercado.

Nosso experimento comprova que a sinergia entre métodos quânticos e clássicos não é uma escolha, mas sim o caminho rumo ao próximo avanço na negociação algorítmica.


Como comecei a desenvolver minha primeira rede neural quântica — um classificador

Quando iniciei os experimentos com computação quântica no trading, decidi ir além dos circuitos quânticos simples e criar um sistema híbrido, combinando computação quântica com métodos clássicos de aprendizado de máquina. A ideia parecia promissora: usar estados quânticos para codificar informações de mercado e, em seguida, treinar um classificador clássico com esses dados.

O sistema acabou ficando bastante complexo. Em sua base, há um circuito quântico com 8 qubits, que transforma os dados de mercado em estados quânticos por meio de uma série de portões quânticos. Cada fragmento do histórico de preços é codificado nos ângulos de rotação dos portões ry, e o entrelaçamento entre qubits é criado com os portões cx. Isso permite que o sistema capture interações não lineares complexas nos dados.

Para reforçar o poder de previsão, adicionei um conjunto de indicadores clássicos binários: direção do movimento do preço, momentum, volumes, cruzamento/divergência de médias móveis, volatilidade, RSI e bandas de Bollinger. Cada indicador gera sinais binários, que depois são combinados com os atributos quânticos.

import numpy as np
import MetaTrader5 as mt5
import pandas as pd
from datetime import datetime, timedelta
from qiskit import QuantumCircuit, transpile, QuantumRegister, ClassicalRegister
from qiskit_aer import AerSimulator
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.model_selection import train_test_split
from catboost import CatBoostClassifier
import warnings
warnings.filterwarnings('ignore')

class MT5DataLoader:
    def __init__(self, symbol="EURUSD", timeframe=mt5.TIMEFRAME_H1):
        if not mt5.initialize():
            raise Exception("MetaTrader5 initialization failed")
        
        self.symbol = symbol
        self.timeframe = timeframe
    
    def get_historical_data(self, lookback_bars=1000):
        current_time = datetime.now()
        rates = mt5.copy_rates_from(self.symbol, self.timeframe, current_time, lookback_bars)
        
        if rates is None:
            raise Exception(f"Failed to get data for {self.symbol}")
            
        df = pd.DataFrame(rates)
        df['time'] = pd.to_datetime(df['time'], unit='s')
        return df

class BinaryPatternGenerator:
    def __init__(self, df, lookback=10):
        self.df = df
        self.lookback = lookback
        
    def direction_encoding(self):
        return (self.df['close'] > self.df['close'].shift(1)).astype(int)
        
    def momentum_encoding(self, threshold=0.0001):
        returns = self.df['close'].pct_change()
        return (returns.abs() > threshold).astype(int)
        
    def volume_encoding(self):
        return (self.df['tick_volume'] > self.df['tick_volume'].rolling(self.lookback).mean()).astype(int)
        
    def convergence_encoding(self):
        ma_fast = self.df['close'].rolling(5).mean()
        ma_slow = self.df['close'].rolling(20).mean()
        return (ma_fast > ma_slow).astype(int)
        
    def volatility_encoding(self):
        volatility = self.df['high'] - self.df['low']
        avg_volatility = volatility.rolling(20).mean()
        return (volatility > avg_volatility).astype(int)
        
    def rsi_encoding(self, period=14, threshold=50):
        delta = self.df['close'].diff()
        gain = (delta.where(delta > 0, 0)).ewm(alpha=1/period).mean()
        loss = (-delta.where(delta < 0, 0)).ewm(alpha=1/period).mean()
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
        return (rsi > threshold).astype(int)
        
    def bollinger_encoding(self, window=20):
        ma = self.df['close'].rolling(window=window).mean()
        std = self.df['close'].rolling(window=window).std()
        upper = ma + (std * 2)
        lower = ma - (std * 2)
        return ((self.df['close'] - lower)/(upper - lower) > 0.5).astype(int)
        
    def get_all_patterns(self):
        patterns = {
            'direction': self.direction_encoding(),
            'momentum': self.momentum_encoding(),
            'volume': self.volume_encoding(),
            'convergence': self.convergence_encoding(),
            'volatility': self.volatility_encoding(),
            'rsi': self.rsi_encoding(),
            'bollinger': self.bollinger_encoding()
        }
        return patterns

class QuantumFeatureGenerator:
    def __init__(self, num_qubits=8):
        self.num_qubits = num_qubits
        self.simulator = AerSimulator()
        self.scaler = MinMaxScaler()
        
    def create_quantum_circuit(self, market_data, current_price):
        qr = QuantumRegister(self.num_qubits, 'qr')
        cr = ClassicalRegister(self.num_qubits, 'cr')
        qc = QuantumCircuit(qr, cr)
        
        # Нормализуем данные
        scaled_data = self.scaler.fit_transform(market_data.reshape(-1, 1)).flatten()
        
        # Создаем суперпозицию
        for i in range(self.num_qubits):
            qc.h(qr[i])
        
        # Применяем рыночные данные как фазы
        for i in range(min(len(scaled_data), self.num_qubits)):
            angle = float(scaled_data[i] * np.pi)
            qc.ry(angle, qr[i])
        
        # Создаем запутанность
        for i in range(self.num_qubits - 1):
            qc.cx(qr[i], qr[i + 1])
        
        # Добавляем текущую цену
        price_angle = float((current_price % 0.01) * 100 * np.pi)
        qc.ry(price_angle, qr[0])
        
        qc.measure(qr, cr)
        return qc
        
    def get_quantum_features(self, market_data, current_price):
        qc = self.create_quantum_circuit(market_data, current_price)
        compiled_circuit = transpile(qc, self.simulator, optimization_level=3)
        job = self.simulator.run(compiled_circuit, shots=2000)
        result = job.result()
        counts = result.get_counts()
        
        # Создаем вектор квантовых признаков
        feature_vector = np.zeros(2**self.num_qubits)
        total_shots = sum(counts.values())
        
        for bitstring, count in counts.items():
            index = int(bitstring, 2)
            feature_vector[index] = count / total_shots
            
        return feature_vector


class HybridQuantumBinaryPredictor:
    def __init__(self, num_qubits=8, lookback=10, forecast_window=5):
        self.num_qubits = num_qubits
        self.lookback = lookback
        self.forecast_window = forecast_window
        self.quantum_generator = QuantumFeatureGenerator(num_qubits)
        self.model = CatBoostClassifier(
            iterations=500,
            learning_rate=0.03,
            depth=6,
            loss_function='Logloss',
            verbose=False
        )
        
    def prepare_features(self, df):
        """Подготовка гибридных признаков"""
        pattern_generator = BinaryPatternGenerator(df, self.lookback)
        binary_patterns = pattern_generator.get_all_patterns()
        
        features = []
        labels = []
        
        # Заполняем NaN в бинарных паттернах
        for key in binary_patterns:
            binary_patterns[key] = binary_patterns[key].fillna(0)
        
        for i in range(self.lookback, len(df) - self.forecast_window):
            try:
                # Квантовые признаки
                market_data = df['close'].iloc[i-self.lookback:i].values
                current_price = df['close'].iloc[i]
                quantum_features = self.quantum_generator.get_quantum_features(market_data, current_price)
                
                # Бинарные признаки
                binary_vector = []
                for key in binary_patterns:
                    window = binary_patterns[key].iloc[i-self.lookback:i].values
                    binary_vector.extend([
                        sum(window),  # Общее количество сигналов
                        window[-1],   # Последний сигнал
                        sum(window[-3:])  # Последние 3 сигнала
                    ])
                
                # Технические индикаторы
                rsi = binary_patterns['rsi'].iloc[i]
                bollinger = binary_patterns['bollinger'].iloc[i]
                momentum = binary_patterns['momentum'].iloc[i]
                
                # Объединяем все признаки
                feature_vector = np.concatenate([
                    quantum_features,
                    binary_vector,
                    [rsi, bollinger, momentum]
                ])
                
                # Метка: направление движения цены
                future_price = df['close'].iloc[i + self.forecast_window]
                current_price = df['close'].iloc[i]
                label = 1 if future_price > current_price else 0
                
                features.append(feature_vector)
                labels.append(label)
                
            except Exception as e:
                print(f"Error at index {i}: {str(e)}")
                continue
        
        return np.array(features), np.array(labels)
    
    def train(self, df):
        """Обучение гибридной модели"""
        print("Preparing features...")
        X, y = self.prepare_features(df)
        
        # Разделение на обучающую и тестовую выборки
        split_point = int(len(X) * 0.8)
        X_train, X_test = X[:split_point], X[split_point:]
        y_train, y_test = y[:split_point], y[split_point:]
        
        print("Training model...")
        self.model.fit(X_train, y_train, eval_set=(X_test, y_test))
        
        # Оценка модели
        predictions = self.model.predict(X_test)
        probas = self.model.predict_proba(X_test)
        
        # Расчет метрик
        metrics = {
            'accuracy': accuracy_score(y_test, predictions),
            'precision': precision_score(y_test, predictions),
            'recall': recall_score(y_test, predictions),
            'f1': f1_score(y_test, predictions)
        }
        
        # Анализ важности признаков
        feature_importance = self.model.feature_importances_
        quantum_importance = np.mean(feature_importance[:2**self.num_qubits])
        binary_importance = np.mean(feature_importance[2**self.num_qubits:])
        
        metrics.update({
            'quantum_importance': quantum_importance,
            'binary_importance': binary_importance,
            'test_predictions': predictions,
            'test_probas': probas,
            'test_actual': y_test
        })
        
        return metrics
    
    def predict_next(self, df):
        """Прогноз следующего движения"""
        X, _ = self.prepare_features(df)
        if len(X) > 0:
            last_features = X[-1].reshape(1, -1)
            prediction_proba = self.model.predict_proba(last_features)[0]
            prediction = self.model.predict(last_features)[0]
            
            return {
                'direction': 'UP' if prediction == 1 else 'DOWN',
                'probability_up': prediction_proba[1],
                'probability_down': prediction_proba[0],
                'confidence': max(prediction_proba)
            }
        return None

def test_hybrid_model(symbol="EURUSD", timeframe=mt5.TIMEFRAME_H1, periods=1000):
    """Полное тестирование гибридной модели"""
    try:
        # Инициализация MT5
        if not mt5.initialize():
            raise Exception("Failed to initialize MT5")
        
        # Загрузка данных
        print(f"Loading {periods} periods of {symbol} {timeframe} data...")
        loader = MT5DataLoader(symbol, timeframe)
        df = loader.get_historical_data(periods)
        
        # Создание и обучение модели
        print("Creating hybrid model...")
        model = HybridQuantumBinaryPredictor()
        
        # Обучение и оценка
        print("Training and evaluating model...")
        metrics = model.train(df)
        
        # Вывод результатов
        print("\nModel Performance Metrics:")
        print(f"Accuracy: {metrics['accuracy']:.2%}")
        print(f"Precision: {metrics['precision']:.2%}")
        print(f"Recall: {metrics['recall']:.2%}")
        print(f"F1 Score: {metrics['f1']:.2%}")
        
        print("\nFeature Importance Analysis:")
        print(f"Quantum Features: {metrics['quantum_importance']:.2%}")
        print(f"Binary Features: {metrics['binary_importance']:.2%}")
        
        # Текущий прогноз
        print("\nCurrent Market Prediction:")
        prediction = model.predict_next(df)
        if prediction:
            print(f"Predicted Direction: {prediction['direction']}")
            print(f"Up Probability: {prediction['probability_up']:.2%}")
            print(f"Down Probability: {prediction['probability_down']:.2%}")
            print(f"Confidence: {prediction['confidence']:.2%}")
        
        return model, metrics
        
    finally:
        mt5.shutdown()

if __name__ == "__main__":
    print("Starting Quantum-Binary Hybrid Trading System...")
    model, metrics = test_hybrid_model()
    print("\nSystem test completed.")

Os primeiros resultados foram um balde de água fria. No timeframe de 1 hora do EURUSD, a precisão da sistema ficou em apenas 42,13%, pior do que o simples acaso. A precisão (precision) foi de 39,71% e a revocação (recall) de 27%, mostrando que o modelo falha bastante nas suas previsões. A F1-score de 32,14% confirma a fragilidade geral das predições.

A análise da importância dos atributos foi especialmente interessante. Os atributos quânticos contribuíram com apenas 27,63% para o poder preditivo do modelo, enquanto os atributos binários apresentaram uma relevância de 121,95%. Isso sugere que, ou a parte quântica do sistema não está captando os padrões relevantes nos dados, ou o método de codificação quântica precisa de uma revisão profunda.

Mas esses resultados não desanimam, pelo contrário, apontam direções concretas para melhorias. Talvez valha a pena mudar o esquema de codificação quântica, aumentar ou diminuir o número de qubits, ou experimentar com outros tipos de portões quânticos. Ou, quem sabe, o problema esteja na forma como os atributos quânticos e clássicos estão sendo integrados.

O experimento mostrou que criar um sistema híbrido quântico-clássico eficiente não é simplesmente uma questão de juntar duas abordagens. É preciso um entendimento profundo tanto da computação quântica quanto das particularidades dos mercados financeiros. Este é apenas o primeiro passo de uma longa jornada de pesquisa e otimização.

Nas próximas iterações, pretendo reformular significativamente a parte quântica do sistema, talvez adicionando transformações quânticas mais sofisticadas e melhorando a forma de codificar informações de mercado em estados quânticos. Também vale experimentar diferentes formas de combinar atributos quânticos e clássicos para encontrar o equilíbrio ideal entre eles.




Considerações finais

Eu achava que unir computação quântica com análise técnica era uma ideia genial. Sabe como é nos filmes: junta uma tecnologia de ponta, joga um pouco da mágica do aprendizado de máquina, e pronto, máquina de imprimir dinheiro! Mas na prática... não é bem assim.

Meu "brilhante" classificador quântico mal conseguiu alcançar 42% de precisão. Isso é pior do que jogar cara ou coroa! E quer saber a parte mais irônica? Todas aquelas firulas quânticas, nas quais eu mergulhei por semanas, contribuíram com meros 27% de utilidade. Já os bons e velhos indicadores técnicos, que eu coloquei "só por garantia", brilharam com 122%.

Fiquei especialmente empolgado quando comecei a mexer com a codificação quântica de dados. Pensa só: a gente pega movimentos normais de preços e os transforma em estados quânticos! Parece ficção científica, mas é real. Só que, por enquanto, ainda não funciona como eu gostaria.

Meu classificador quântico, por enquanto, está mais para calculadora quebrada do que para sistema de trading do futuro. Mas eu não vou desistir. Porque eu sinto que, em algum lugar nesse estranho mundo de estados quânticos e padrões de mercado, tem algo realmente valioso escondido. E eu estou determinado a encontrar, nem que tenha que reescrever todo o código do zero.

Por ora... estou voltando para meus qubits. Afinal, aquele circuito "quântico simples" mostrou algum resultado. Melhor que adivinhar no escuro — e isso já é alguma coisa, né? Mas tenho algumas ideias de como fazer esse negócio funcionar. E vou compartilhá-las em breve.


Programas utilizados no artigo

 Arquivo Conteúdo do arquivo
Quant_Predict_p_1.py
Previsão quântica clássica com tentativa de detectar precursores
Quant_Neural_Link.py
Versão preliminar da rede neural quântica
Quant_ML_Model.py
Versão preliminar do modelo quântico de aprendizado de máquina




Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/16879

Arquivos anexados |
Quant_ML_Model.py (12.51 KB)
Funções de ativação de neurônios durante o aprendizado: chave para uma convergência rápida? Funções de ativação de neurônios durante o aprendizado: chave para uma convergência rápida?
Este trabalho apresenta uma análise da interação entre diferentes funções de ativação e algoritmos de otimização no contexto do treinamento de redes neurais. A atenção principal está voltada para a comparação entre o ADAM clássico e sua versão populacional ao lidar com uma ampla gama de funções de ativação, incluindo as funções oscilatórias ACON e Snake. Mediante uma arquitetura MLP minimalista (1-1-1) e um único exemplo de treino, isola-se a influência das funções de ativação no processo de otimização, eliminando interferências de outros fatores. Propomos um método de controle dos pesos da rede por meio dos limites das funções de ativação e um mecanismo de reflexão de pesos, permitindo evitar problemas de saturação e estagnação no aprendizado.
Do básico ao intermediário: Objetos (III) Do básico ao intermediário: Objetos (III)
Neste artigo iremos ver como podemos implementar um sistema de interação muito bacana e bastante interessante. Ainda mais para quem esteja começando a praticar programação MQL5. Não se trata de algo realmente novo. Porém a forma como irei abordar o assunto, de fato, tornará tudo muito mais simples de entender. Já que iremos ver na prática uma programação estrutural sendo feita com um objetivo bastante divertido.
Redes neurais em trading: Sistema multiagente com validação conceitual (FinCon) Redes neurais em trading: Sistema multiagente com validação conceitual (FinCon)
Apresentamos o framework FinCon, que é um sistema multiagente baseado em grandes modelos de linguagem (LLM). O framework utiliza reforço verbal conceitual para melhorar a tomada de decisões e o gerenciamento de riscos, permitindo realizar diversas tarefas financeiras de forma eficiente.
Do básico ao intermediário: Eventos de mouse Do básico ao intermediário: Eventos de mouse
Este artigo, é uns dos que definitivamente, é necessário não apenas ver o código e o estudar para compreender o que estará acontecendo. É de fato, necessário, criar uma aplicação executável e a utilizar em um gráfico qualquer. Isto maneira a conseguir entender pequenos detalhes, que de outra forma são muito complicados de serem compreendidos. Como por exemplo, a combinação de teclado com o mouse, a fim de construir certos tipos de coisas.