English Русский 中文 Español Deutsch 日本語
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 |
222 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):  # Reduce the number of qubits for stability
        self.num_qubits = num_qubits
        self.simulator = AerSimulator()
        self.scaler = MinMaxScaler()
        
    def create_qpe_circuit(self, market_data, current_price):
        """Create a simplified quantum circuit"""
        qr = QuantumRegister(self.num_qubits, 'qr')
        cr = ClassicalRegister(self.num_qubits, 'cr')
        qc = QuantumCircuit(qr, cr)
        
        # Normalize data
        scaled_data = self.scaler.fit_transform(market_data.reshape(-1, 1)).flatten()
        
        # Create superposition
        for i in range(self.num_qubits):
            qc.h(qr[i])
        
        # Apply market data as phases
        for i in range(min(len(scaled_data), self.num_qubits)):
            angle = float(scaled_data[i] * np.pi)  # Convert to float
            qc.ry(angle, qr[i])
        
        # Create entanglement
        for i in range(self.num_qubits - 1):
            qc.cx(qr[i], qr[i + 1])
        
        # Apply the current price
        price_angle = float((current_price % 0.01) * 100 * np.pi)  # Use only the last 2 characters
        qc.ry(price_angle, qr[0])
        
        # Measure all qubits
        qc.measure(qr, cr)
        
        return qc
    
    def predict(self, market_data, current_price, features=None, shots=2000):
        """Simplified prediction"""
        # Trim the input data
        if market_data.shape[0] > self.num_qubits:
            market_data = market_data[-self.num_qubits:]
        
        # Create and execute the circuit
        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()
        
        # Analyze the results
        predictions = []
        total_shots = sum(counts.values())
        
        for bitstring, count in counts.items():
            # Use the number of ones in the bitstring to determine the direction
            ones = bitstring.count('1')
            direction = ones / self.num_qubits  # Normalized direction
            
            # Predict the change of no more than 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):
        """Prepare technical indicators"""
        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):
        # Get data
        df = self.data_loader.get_historical_data(self.window_size + 50)
        features = self.prepare_features(df)
        
        if len(features) < self.window_size:
            raise ValueError("Insufficient data")
        
        # Get the latest data for the forecast
        latest_features = features.iloc[-self.window_size:].values
        current_price = df['close'].iloc[-1]
        
        # Make a prediction, now pass features as DataFrame
        prediction = self.quantum_predictor.predict(
            market_data=latest_features,
            current_price=current_price,
            features=features.iloc[-self.window_size:]  # Pass the last entries
        )
        
        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):
    """Evaluation of model accuracy"""
    predictor = MarketPredictor(symbol, timeframe)
    predictions = []
    actual_movements = []
    
    # Get historical data
    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)
            
            # Get data for forecasting
            latest_features = features_temp.iloc[-predictor_temp.window_size:].values
            current_price = temp_df['close'].iloc[-1]
            
            # Make a forecast with the transfer of all necessary parameters
            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("\nTest the model...")
            metrics = evaluate_model(symbol, timeframe, test_periods=100)
            
            print("\nModel quality 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("\nCurrent forecast:")
            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()  # Now this method passes all parameters correctly
            
            print(f"Predicted price: {prediction['predicted_price']:.5f}")
            print(f"Growth probability: {prediction['up_probability']:.2%}")
            print(f"Fall probability: {prediction['down_probability']:.2%}")
            print(f"Forecast confidence: {prediction['confidence']:.2%}")
            print(f"Current price: {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)
        
        # Normalize data
        scaled_data = self.scaler.fit_transform(market_data.reshape(-1, 1)).flatten()
        
        # Create superposition
        for i in range(self.num_qubits):
            qc.h(qr[i])
        
        # Apply market data as phases
        for i in range(min(len(scaled_data), self.num_qubits)):
            angle = float(scaled_data[i] * np.pi)
            qc.ry(angle, qr[i])
        
        # Create entanglement
        for i in range(self.num_qubits - 1):
            qc.cx(qr[i], qr[i + 1])
        
        # Add the current price
        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()
        
        # Create a vector of quantum features
        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):
        """Prepare hybrid features"""
        pattern_generator = BinaryPatternGenerator(df, self.lookback)
        binary_patterns = pattern_generator.get_all_patterns()
        
        features = []
        labels = []
        
        # Fill NaN in binary patterns
        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:
                # Quantum features
                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 features
                binary_vector = []
                for key in binary_patterns:
                    window = binary_patterns[key].iloc[i-self.lookback:i].values
                    binary_vector.extend([
                        sum(window),  # Total number of signals
                        window[-1],   # Last signal
                        sum(window[-3:])  # Last 3 signals
                    ])
                
                # Technical indicators
                rsi = binary_patterns['rsi'].iloc[i]
                bollinger = binary_patterns['bollinger'].iloc[i]
                momentum = binary_patterns['momentum'].iloc[i]
                
                # Combine all features
                feature_vector = np.concatenate([
                    quantum_features,
                    binary_vector,
                    [rsi, bollinger, momentum]
                ])
                
                # Label: price movement direction
                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):
        """Train hybrid model"""
        print("Preparing features...")
        X, y = self.prepare_features(df)
        
        # Split into training and test samples
        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))
        
        # Model evaluation
        predictions = self.model.predict(X_test)
        probas = self.model.predict_proba(X_test)
        
        # Calculate metrics
        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 analysis
        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):
        """Next movement forecast"""
        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):
    """Full test of the hybrid model"""
    try:
        # MT5 initialization
        if not mt5.initialize():
            raise Exception("Failed to initialize MT5")
        
        # Download data
        print(f"Loading {periods} periods of {symbol} {timeframe} data...")
        loader = MT5DataLoader(symbol, timeframe)
        df = loader.get_historical_data(periods)
        
        # Create and train model
        print("Creating hybrid model...")
        model = HybridQuantumBinaryPredictor()
        
        # Training and assessment
        print("Training and evaluating model...")
        metrics = model.train(df)
        
        # Output results
        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%}")
        
        # Current forecast
        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 (11.58 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.