量子コンピューティングと取引:価格予測への新たなアプローチ
取引における量子コンピューティング入門:主な概念と利点
すべての市場取引が、同時に存在し得る可能性の視点から分析される世界を想像してみてください。たとえば、有名なシュレーディンガーの猫が箱を開けるまでは生きても死んでもいるように。これが量子トレーディングの基本原理です。市場のあらゆる潜在的な状態を同時に考慮し、金融分析に新たな地平を開きます。
従来のコンピュータが情報をビット単位で逐次処理するのに対し、量子システムはミクロの世界の驚くべき特性、つまり、重ね合わせと量子もつれを利用して、複数のシナリオを並行して解析します。これは、経験豊富なトレーダーが複数のチャート、ニュース、指標を同時に頭の中で把握しているようなものですが、それを想像を絶する規模で実現します。
私たちはすでにアルゴリズム取引が一般化した時代に生きていますが、今、まさに次の革命の入り口に立っています。量子コンピューティングは単にデータ分析を高速化するだけでなく、市場プロセスの理解そのものに根本的な変化をもたらします。資産価格を線形的に予測する代わりに、最も微妙な市場相関を考慮した確率的なシナリオツリー全体を探索できるようになると想像してみてください。
本記事では、量子トレーディングの世界を探求します。量子コンピューティングの基本原理から取引システムの実践的な実装までを見ていきます。量子アルゴリズムがどのように従来の手法では見つけられなかったパターンを発見し、この優位性をリアルタイムの取引判断に応用できるかを考察します。
私たちの旅は量子コンピューティングの基礎から始まり、最終的には動作する市場予測システムの構築へとつながります。その過程で、複雑な概念をわかりやすい例で分解し、量子コンピューティングの理論的な利点がどのように実用的な取引ツールへと変換されるのかを確認していきます。
金融時系列分析における量子重ね合わせと量子もつれ
金融市場を分析する際、私たちは基本的な問題に直面します。それは、無限に存在する相互に影響し合う要因の存在です。あらゆる価格変動は、マクロ経済指標から個々のトレーダーのセンチメントに至るまでの、数千の変数が複雑に相互作用した結果として生じます。ここで量子コンピューティングは、その基本的な特性である重ね合わせと量子もつれを通じて、独自の解決策を提供します。
まず、重ね合わせを考えてみましょう。従来のコンピュータではビットは0または1のどちらかしか取れませんが、量子ビットは観測されるまで同時にすべての状態に存在します。数学的には、|ψ⟩ = α|0⟩ + β|1⟩と表され、αとβは複素数の確率振幅です。時系列分析に適用すると、この特性により、量子アルゴリズムはポートフォリオおよびリスク管理の問題において、多くの潜在的なシナリオを並列に解析し、効率的に解空間を探索できるようになります。
量子もつれは、さらにもう一段階の可能性をもたらします。量子ビットがもつれると、それらの状態は切り離せない関係になります。たとえば、|ψ⟩ = (|00⟩ + |11⟩)/√2という形で表されます。金融分析の文脈では、この特性は異なる市場指標間の複雑な相関関係をモデル化するために使用されます。たとえば、資産価格、取引量、市場ボラティリティの関係を同時に考慮するシステムを構築することができます。
これらの量子特性は、特に多次元データの処理速度が重要となる高頻度取引において有用です。重ね合わせにより複数の取引シナリオを同時に分析でき、もつれによって複雑な市場間の相関関係をリアルタイムで考慮できます。量子の優位性は、特に最適化や探索の問題において顕著であり、古典的なアルゴリズムが指数関数的な計算複雑性に直面する領域で際立ちます。
QPE(量子位相推定)を用いた量子予測アルゴリズムの開発
本システムの中心にあるのは、量子コンピューティングと古典的テクニカル分析の洗練された組み合わせです。8つの量子ビットからなる量子オーケストラを想像してみてください。それぞれの量子ビットが、自分のパートを演奏しながら、市場の動きという複雑な交響曲を奏でています。
すべてはデータの準備から始まります。私たちの量子予測器は、MetaTrader 5との統合を通じて市場データを受け取ります。これは、神経が感覚器官から情報を集めるようなものです。このデータは正規化プロセスを経ます。これは、まるでオーケストラのすべての楽器を同じ調に合わせているようなものです。
最も興味深い部分は、量子回路の作成時に始まります。まず、アダマールゲート(Hゲート、Hadamard Gate)を使って各量子ビットを重ね合わせ状態にします。この時点で、各量子ビットはすべての可能な状態に同時に存在しており、まるで各演奏者が自分のパートのあらゆる音符を同時に演奏しているかのようです。
次に、ryゲートを通じて市場データを量子状態にエンコードします。このとき、回転角は市場パラメータの値によって決定されます。これは、指揮者が各演奏者にテンポや演奏のニュアンスを指示するようなものです。特に現在価格には特別な注意が払われます。現在価格には独自の量子的な「ねじれ」が加えられ、オーケストラの中のソリストのようにシステム全体に影響を与えます。
本当の魔法は、量子もつれが生成されるときに起こります。cxゲート(CNOT)を使用して隣接する量子ビットを結合し、切り離すことのできない量子相関を作り出します。これは、演奏者たちの個々のパートが一つの調和した音に融合する瞬間のようなものです。
量子変換の後、私たちは測定をおこないます。これは、コンサートを録音するようなものです。しかし、ここにひとつの工夫があります。このプロセスを2000回(ショット)繰り返し、結果の統計分布を取得します。各次元はビット列を生成し、「1」の数が予測の方向を決定します。
最後の和音は結果の解釈です。このシステムは非常に慎重な予測を行い、価格変動の最大値を0.1%に制限しています。これは、経験豊富な指揮者がオーケストラの音が大きすぎたり小さすぎたりしないようにバランスを取るようなものです。
テスト結果はその性能を明確に示しています。予測精度はランダムな推測を上回り、EURUSD H1で54%に達しています。同時に、このシステムは予測に対して高い信頼度を示しており、それは「confidence」評価指標に反映されています。
この実装において、量子コンピューティングは単に古典的テクニカル分析を補完するものではありません。市場分析に新たな次元を創り出し、量子の重ね合わせの中で複数の可能なシナリオを同時に探索します。リチャード・ファインマンが言ったように、「自然は量子レベルでは私たちが通常考えるものとは非常に異なる振る舞いをする」のです。そしてどうやら、金融市場にも私たちがようやく理解し始めたばかりの量子的な本質が隠されているようです。
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()
量子トレーディングシステムのテストと検証:方法論と結果

主要な性能評価指標
- 正答率:55.00%。ボラティリティの高いEURUSD市場において、ランダム推測を中程度に上回る結果を示しています。
- 適合率:63.64%。システムが生成するシグナルの信頼性が高いことを示しています。予測のおよそ3分の2が正確であることを意味します。
- 再現率:14.58%。再現率が低いことは、システムが選択的であり、予測への信頼度が高い場合にのみシグナルを生成することを示しています。これにより、誤ったシグナルの発生を防ぐことができます。
- F1スコア:23.73%。F1スコアは適合率と再現率のバランスを反映しており、システムの保守的な戦略を裏付けています。
現在の市場予測
- 現在のEUR/USD価格:1.02903
- 予想価格:1.02905
- 確率分布:
- 上昇確率:38.95%
- 下落確率:61.05%
- 予測信頼度:99.98%
システムは、下落確率が優勢であるにもかかわらず、高い信頼度をもって緩やかな上昇を予測しています。これは、全体的な下降トレンドの中で短期的な修正局面が発生する可能性を示唆しています。
テクニカル指標
- RSI:49.13(中立ゾーンに近く、明確な買われ過ぎ・売られ過ぎの兆候はない)
- SMA:1.02904
- EMA:1.02909
- トレンド:中立(現在価格は移動平均レベル付近にある)
まとめ
本システムは、以下の主要な特徴を示しています。
- ランダム推測を上回る一貫した正解率
- シグナル生成における高い選択性(63.64%の精度)
- 異なるシナリオに対する信頼度および確率を定量化する能力
- テクニカル指標とより複雑なパターンの両方を考慮した包括的な市場分析
このように、シグナルの量よりも質を優先する保守的なアプローチは、実際の取引において有効なツールとなる可能性を示しています。
機械学習評価指標と量子アルゴリズムの統合:考察と最初の試み
量子コンピューティングと機械学習の組み合わせは、新たな地平を切り開きます。私たちの実験では、量子エンコーディングの前にデータを正規化するために、sklearnのMinMaxScalerを使用し、市場データを量子角度に変換しています。
このシステムは、機械学習の評価指標(正解率、適合率、再現率、F1スコア)を量子測定と組み合わせています。正解率60%という結果を示し、古典的アルゴリズムでは捉えられないパターンを検出します。これは、経験豊富なトレーダーのように慎重かつ選択的な動きを示しています。
このようなシステムの将来像は、オートエンコーダーやTransformerなどの高度な前処理手法を統合し、より深いデータ分析をおこなうことです。量子アルゴリズムは古典モデルのフィルターとなることも、逆に古典モデルが量子処理を補完することも可能であり、市場環境に適応します。
この実験は、量子と古典の手法の相乗効果が「どちらかを選ぶ」という問題ではなく、アルゴリズム取引における次のブレークスルーへの道であることを示しています。
私が最初の量子ニューラルネットワーク(分類器)を書き始めたとき
取引における量子コンピューティングの実験を始めたとき、私は単純な量子回路の枠を超えて、量子計算と古典的機械学習手法を組み合わせたハイブリッドシステムを作ろうと決めました。このアイデアは非常に有望に思えました。市場情報を量子状態にエンコードし、そのデータに対して従来型の分類器を学習させるつもりだったのです。
システムはかなり複雑なものになりました。8量子ビットの量子回路をベースとしており、市場データを一連の量子ゲートを通じて量子状態に変換します。価格履歴の各データポイントはryゲートの回転角としてエンコードされ、cxゲート(CNOT)によって量子ビット間のもつれが生成されます。これにより、データ内の複雑な非線形関係を捉えることができます。
予測能力を高めるために、私は一連の古典的なバイナリ指標を追加しました。価格方向、モメンタム、取引量、移動平均収束拡散(MACD)、ボラティリティ、RSI、そしてボリンジャーバンドです。各インジケーターはバイナリシグナルを生成し、それらが量子特徴量と組み合わされます。
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.")
最初の結果は厳しいものでした。EUR/USD H1において、システムの正解率はわずか42.13%であり、ランダム推測よりも悪い結果となりました。適合率は39.71%、再現率は27%であり、モデルが予測において大きく誤っていることを示しています。F1スコアは32.14%であり、予測全体の弱さを裏付けています。
特徴量の重要度分析は特に興味深いものでした。量子特徴量はモデル全体の予測力のうち27.63%しか寄与しておらず、一方でバイナリ特徴量は121.95%という高い重要度を示しました。これは、システムの量子部分がデータ中の重要なパターンを捉えられていないか、あるいは量子エンコーディング手法そのものに大幅な改良が必要であることを示唆しています。
しかし、これらの結果は落胆すべきものではありません。むしろ、改善すべき具体的な領域を明確に示しています。量子エンコーディング回路を変更したり、量子ビットの数を増減したり、別の量子ゲートを試したりする価値があるかもしれません。あるいは、問題は量子的特徴と古典的特徴の統合方法そのものにある可能性もあります。
この実験から、効率的な量子‐古典ハイブリッドシステムを構築することは、単に2つの手法を組み合わせるだけでは不十分であることが明らかになりました。それには、量子コンピューティングの深い理解と、金融市場の特性に対する洞察の両方が求められます。これは、研究と最適化という長い旅の最初の一歩にすぎません。
今後の反復実験では、システムの量子部分を大幅に改良し、より複雑な量子変換を追加したり、市場情報を量子状態にエンコードする方法を改善したりする予定です。また、量子的特徴と古典的特徴を組み合わせるさまざまな方法を試し、その最適なバランスを見つけることも重要であると考えています。

結論
量子コンピューティングとテクニカル分析を組み合わせるのは素晴らしいアイデアだと思っていました。映画のように、クールなテクノロジーに少し機械学習の魔法を加えれば、お金を生み出す装置の完成です。ただし、現実は、私の考えが間違っていたことを証明しました。
私の「天才的」な量子分類器は、かろうじて正解率42%を出すのが精一杯でした。コインを投げるより悪い結果です。そして一番おかしいのは何かというと、何週間もかけて作り上げたこの派手な量子特徴量がもたらした効果はたったの27%だったのです。ところが、「念のため」に追加した昔ながらのテクニカル指標は、なんと122%もの効果を示しました。
量子データエンコーディングの仕組みを理解し始めたときは、特に興奮しました。想像してみてください。普通の価格変動を量子状態に変換するのです。まるでSFのようですが、実際に動作します。もっとも、私が望むような動きをしてくれるわけではありませんでした。
私の量子分類器は、今のところ未来のトレーディングシステムというより、壊れかけの電卓のようなものです。でも、私は諦めません。なぜなら、この奇妙な量子状態と市場パターンの世界のどこかに、本当に価値のある何かが隠れているはずだからです。そして、たとえコードを最初からすべて書き直すことになっても、私はそれを見つけ出すつもりです。
その間に...私は再び自分の量子ビットたちのもとに戻ります。それでも、通常の「量子」スキームでも多少の成果は見られました。単なる推測よりはましです。ですが、このシステムを本当に動かすためのいくつかのアイデアがあります。そして、そのことについては必ずお話しします。
記事で使用されているプログラム
| ファイル | ファイルの内容 |
|---|---|
| Quant_Predict_p_1.py | 古典的な量子予測モデル(プロトタイプ探索の試みを含む) |
| Quant_Neural_Link.py | 量子ニューラルネットワークの草案版 |
| Quant_ML_Model.py | 量子機械学習モデルの草案版 |
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/16879
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
学習中にニューロンを活性化する関数:高速収束の鍵は?
取引所価格のバイナリコードの分析(第1回):テクニカル分析の新たな視点
アルゴリズム取引におけるニューロシンボリックシステム:シンボリックルールとニューラルネットワークを組み合わせる
市場シミュレーション(第3回):パフォーマンスの問題
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索