目次
LSTMによる取引方向予測と最新価格予測手法
📊 概要
本ドキュメントでは、DavidCicoのGitHubリポジトリ「Forecasting-direction-of-trade-an-example-with-LSTM-neural-network」の手法を日本語で解説し、2024年の最新研究成果と組み合わせて、効果的な価格予測手法を包括的にまとめます。
🔍 DavidCicoの手法:LSTMによる取引方向予測
プロジェクト概要
- 目的: オーダーブックと取引データを使用してtickの方向を予測
- アプローチ: 線形回帰とLSTMニューラルネットワークの比較
- 主眼: より正確な予測のためのLSTMの活用
特徴量の計算
def compute_features(orderbook_data, trade_data):
"""オーダーブックから特徴量を計算"""
features = {}
# 1. Volume Order Imbalance(ボリューム注文不均衡)
bid_volume = orderbook_data['bid_volume'].sum()
ask_volume = orderbook_data['ask_volume'].sum()
features['volume_imbalance'] = (bid_volume - ask_volume) / (bid_volume + ask_volume)
# 2. Bid-Ask Spread(ビッド・アスク・スプレッド)
features['spread'] = orderbook_data['ask_price'][0] - orderbook_data['bid_price'][0]
features['spread_pct'] = features['spread'] / orderbook_data['mid_price']
# 3. Mid-price basis(中値ベース)
features['mid_price'] = (orderbook_data['ask_price'][0] + orderbook_data['bid_price'][0]) / 2
features['mid_price_change'] = features['mid_price'].diff()
return features
LSTMアーキテクチャ
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
def build_lstm_model(input_shape, lookback_period=50):
"""取引方向予測のためのLSTMモデル構築"""
model = Sequential([
LSTM(50, return_sequences=True, input_shape=(lookback_period, input_shape)),
Dropout(0.2),
LSTM(50, return_sequences=True),
Dropout(0.2),
LSTM(50),
Dropout(0.2),
Dense(1, activation='sigmoid') # 二値分類:上昇/下降
])
model.compile(
optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy']
)
return model
主要な実装ポイント
-
データ前処理
- 買い注文と売り注文の不均衡を捉える特徴量設計
- 時系列データの正規化とウィンドウ化 -
モデル評価
- 線形回帰との性能比較
- 異なるルックバック期間での検証 -
限界と注意点
- LSTMの可能性を示すデモンストレーション
- 実際の取引戦略としては追加の検証が必要
🚀 2024年最新の価格予測手法
1. Transformer モデルの台頭
Predictive Modeling of Stock Prices Using Transformer Model (2024)
import torch
from torch import nn
class StockTransformer(nn.Module):
def __init__(self, feature_dim, d_model=512, nhead=8, num_layers=6):
super().__init__()
# 時間エンコーディング(Time2Vec)
self.time_encoding = Time2Vec(1, d_model)
# 特徴量埋め込み
self.feature_embedding = nn.Linear(feature_dim, d_model)
# Transformerエンコーダ
encoder_layer = nn.TransformerEncoderLayer(
d_model=d_model,
nhead=nhead,
dim_feedforward=2048,
dropout=0.1
)
self.transformer = nn.TransformerEncoder(encoder_layer, num_layers)
# 出力層
self.output_layer = nn.Linear(d_model, 1)
def forward(self, features, timestamps):
# 時間エンコーディング
time_embed = self.time_encoding(timestamps)
# 特徴量埋め込み
feature_embed = self.feature_embedding(features)
# 結合
x = feature_embed + time_embed
# Transformer処理
x = self.transformer(x)
# 予測
return self.output_layer(x)
成果: LSTMやProphetモデルと比較して優れた性能を実証
2. DeepLOB アーキテクチャ
オーダーブックデータに特化した深層学習モデル。
class DeepLOB(nn.Module):
"""CNN-LSTMハイブリッドモデル for LOB分析"""
def __init__(self, num_features=40):
super().__init__()
# CNN層:空間的特徴抽出
self.conv1 = nn.Conv2d(1, 32, kernel_size=(1, 2), stride=(1, 2))
self.conv2 = nn.Conv2d(32, 32, kernel_size=(4, 1))
self.conv3 = nn.Conv2d(32, 32, kernel_size=(4, 1))
# Inception Module
self.inception = InceptionModule(32, 64)
# LSTM層:時系列パターン学習
self.lstm = nn.LSTM(
input_size=64 * num_features // 2,
hidden_size=64,
num_layers=1,
batch_first=True
)
# 出力層
self.fc = nn.Linear(64, 3) # 3クラス分類:上昇/横ばい/下降
def forward(self, x):
# CNN特徴抽出
x = torch.relu(self.conv1(x))
x = torch.relu(self.conv2(x))
x = torch.relu(self.conv3(x))
# Inception
x = self.inception(x)
# Reshape for LSTM
x = x.permute(0, 2, 1, 3)
x = x.reshape(x.shape[0], x.shape[1], -1)
# LSTM処理
x, _ = self.lstm(x)
# 最終予測
return self.fc(x[:, -1, :])
3. 高度なオーダーブック特徴量
2024年の研究で有効性が確認された特徴量:
class OrderBookFeatures:
"""最新研究に基づくオーダーブック特徴量"""
@staticmethod
def stationary_features(orderbook):
"""定常性を持つ特徴量の構築"""
features = {}
# 1. Order Flow Imbalance(注文フロー不均衡)
bid_volume_change = orderbook['bid_volume'].diff()
ask_volume_change = orderbook['ask_volume'].diff()
features['order_flow_imbalance'] = (
bid_volume_change - ask_volume_change
) / (bid_volume_change.abs() + ask_volume_change.abs() + 1e-8)
# 2. Relative Spread(相対スプレッド)
mid_price = (orderbook['bid_price'] + orderbook['ask_price']) / 2
features['relative_spread'] = (
orderbook['ask_price'] - orderbook['bid_price']
) / mid_price
# 3. Price Level Imbalance(価格レベル不均衡)
for level in range(5): # Top 5 levels
bid_vol = orderbook[f'bid_volume_{level}']
ask_vol = orderbook[f'ask_volume_{level}']
features[f'level_{level}_imbalance'] = (
bid_vol - ask_vol
) / (bid_vol + ask_vol + 1e-8)
# 4. Weighted Mid Price(加重中値)
total_bid_size = orderbook['bid_volume_0']
total_ask_size = orderbook['ask_volume_0']
features['weighted_mid_price'] = (
orderbook['bid_price_0'] * total_ask_size +
orderbook['ask_price_0'] * total_bid_size
) / (total_bid_size + total_ask_size + 1e-8)
return features
4. ハイブリッドモデル:PSO-LSTM
2024年に提案された粒子群最適化(PSO)とLSTMの組み合わせ。
import numpy as np
from pyswarm import pso
class PSO_LSTM:
"""粒子群最適化によるLSTMハイパーパラメータ調整"""
def __init__(self, input_shape):
self.input_shape = input_shape
self.best_params = None
def objective_function(self, params):
"""最適化対象の目的関数"""
# パラメータの解釈
units = int(params[0])
dropout_rate = params[1]
learning_rate = params[2]
# モデル構築
model = self.build_lstm(units, dropout_rate, learning_rate)
# 訓練と評価
history = model.fit(
self.X_train, self.y_train,
validation_data=(self.X_val, self.y_val),
epochs=50,
batch_size=32,
verbose=0
)
# 検証損失を返す
return min(history.history['val_loss'])
def optimize(self):
"""PSOによる最適化実行"""
# パラメータの範囲
lb = [10, 0.1, 0.0001] # 下限:units, dropout, lr
ub = [200, 0.5, 0.01] # 上限
# PSO実行
best_params, best_loss = pso(
self.objective_function,
lb, ub,
swarmsize=20,
maxiter=50
)
self.best_params = best_params
return best_params, best_loss
5. Multi-Feature Integration(マルチ特徴量統合)
VMD-TMFG-LSTMモデル:変分モード分解とトポロジカル特徴の統合。
class MultiFeatureLSTM:
"""複数の特徴量ソースを統合するLSTM"""
def __init__(self):
self.vmd_decomposer = VMD() # 変分モード分解
self.tmfg_extractor = TMFG() # トポロジカル特徴抽出
def extract_features(self, price_data, orderbook_data, news_sentiment):
"""マルチソース特徴量抽出"""
features = {}
# 1. 価格分解特徴
modes = self.vmd_decomposer.decompose(price_data)
features['vmd_features'] = modes
# 2. トポロジカル市場構造
market_graph = self.tmfg_extractor.build_graph(orderbook_data)
features['topology_features'] = market_graph.get_features()
# 3. センチメント統合
features['sentiment_scores'] = news_sentiment
# 4. テクニカル指標
features['technical'] = self.compute_technical_indicators(price_data)
return self.combine_features(features)
def build_model(self, feature_dim):
"""統合モデルの構築"""
inputs = []
embeddings = []
# 各特徴量タイプごとの埋め込み
for feature_type in ['vmd', 'topology', 'sentiment', 'technical']:
input_layer = Input(shape=(None, feature_dim[feature_type]))
embedding = LSTM(64, return_sequences=True)(input_layer)
inputs.append(input_layer)
embeddings.append(embedding)
# 特徴量の結合
combined = Concatenate()(embeddings)
# 最終LSTM層
lstm_out = LSTM(128)(combined)
output = Dense(1, activation='linear')(lstm_out)
model = Model(inputs=inputs, outputs=output)
return model
📈 実装のベストプラクティス(2024年版)
1. データ前処理の重要性
def preprocess_orderbook_data(orderbook_df):
"""2024年のベストプラクティスに基づく前処理"""
# 1. 定常性の確保
orderbook_df['price_returns'] = orderbook_df['mid_price'].pct_change()
# 2. 外れ値の処理
for col in orderbook_df.columns:
if 'volume' in col or 'price' in col:
# Winsorization(上下1%をクリップ)
lower = orderbook_df[col].quantile(0.01)
upper = orderbook_df[col].quantile(0.99)
orderbook_df[col] = orderbook_df[col].clip(lower, upper)
# 3. 特徴量スケーリング
from sklearn.preprocessing import RobustScaler
scaler = RobustScaler()
numeric_cols = orderbook_df.select_dtypes(include=[np.number]).columns
orderbook_df[numeric_cols] = scaler.fit_transform(orderbook_df[numeric_cols])
# 4. 時間特徴の追加
orderbook_df['hour'] = orderbook_df.index.hour
orderbook_df['minute'] = orderbook_df.index.minute
orderbook_df['day_of_week'] = orderbook_df.index.dayofweek
return orderbook_df
2. モデル評価とバックテスト
class ModelEvaluator:
"""包括的なモデル評価フレームワーク"""
@staticmethod
def walk_forward_validation(model, data, window_size=1000, step_size=100):
"""ウォークフォワード検証"""
results = []
for i in range(window_size, len(data) - step_size, step_size):
# 訓練データ
train_data = data[i-window_size:i]
# テストデータ
test_data = data[i:i+step_size]
# モデル訓練
model.fit(train_data)
# 予測と評価
predictions = model.predict(test_data)
metrics = calculate_metrics(test_data['target'], predictions)
results.append({
'period': i,
'metrics': metrics,
'predictions': predictions
})
return results
@staticmethod
def calculate_metrics(y_true, y_pred):
"""取引特化メトリクス"""
metrics = {}
# 方向予測精度
direction_true = np.sign(y_true)
direction_pred = np.sign(y_pred)
metrics['directional_accuracy'] = np.mean(direction_true == direction_pred)
# Sharpe比
returns = y_pred * y_true # 予測に基づく収益
metrics['sharpe_ratio'] = np.mean(returns) / (np.std(returns) + 1e-8) * np.sqrt(252)
# 最大ドローダウン
cumulative_returns = np.cumprod(1 + returns)
running_max = np.maximum.accumulate(cumulative_returns)
drawdown = (cumulative_returns - running_max) / running_max
metrics['max_drawdown'] = np.min(drawdown)
return metrics
3. リアルタイム予測パイプライン
class RealTimePredictionPipeline:
"""本番環境向けリアルタイム予測システム"""
def __init__(self, model, feature_extractor):
self.model = model
self.feature_extractor = feature_extractor
self.buffer = deque(maxlen=100) # 最新100ティックを保持
async def process_tick(self, tick_data):
"""新しいティックデータの処理"""
# バッファに追加
self.buffer.append(tick_data)
# 特徴量抽出
if len(self.buffer) >= 50: # 最小必要データ
features = self.feature_extractor.extract(list(self.buffer))
# 予測
prediction = await self.predict_async(features)
# 取引シグナル生成
signal = self.generate_trading_signal(prediction)
return signal
return None
async def predict_async(self, features):
"""非同期予測"""
# モデル推論を別スレッドで実行
loop = asyncio.get_event_loop()
prediction = await loop.run_in_executor(
None,
self.model.predict,
features
)
return prediction
def generate_trading_signal(self, prediction):
"""予測から取引シグナルへの変換"""
signal = {
'timestamp': datetime.now(),
'prediction': prediction,
'action': None,
'confidence': None
}
# 閾値ベースの判断
if prediction > 0.002: # 0.2%以上の上昇予測
signal['action'] = 'BUY'
signal['confidence'] = min(prediction * 100, 100)
elif prediction < -0.002: # 0.2%以上の下降予測
signal['action'] = 'SELL'
signal['confidence'] = min(abs(prediction) * 100, 100)
else:
signal['action'] = 'HOLD'
signal['confidence'] = 0
return signal
🎯 統合アプローチ:最良の実践
エンサンブルモデル
class EnsemblePredictor:
"""複数モデルの統合による頑健な予測"""
def __init__(self):
self.models = {
'lstm': LSTMModel(),
'transformer': TransformerModel(),
'deeplob': DeepLOBModel(),
'pso_lstm': PSO_LSTM()
}
self.weights = None
def train_ensemble(self, train_data, val_data):
"""各モデルの訓練と重み最適化"""
predictions = {}
# 各モデルを訓練
for name, model in self.models.items():
model.fit(train_data)
predictions[name] = model.predict(val_data)
# 最適な重みを見つける
self.weights = self.optimize_weights(predictions, val_data['target'])
def predict(self, data):
"""重み付きアンサンブル予測"""
predictions = []
for name, model in self.models.items():
pred = model.predict(data)
weighted_pred = pred * self.weights[name]
predictions.append(weighted_pred)
return sum(predictions)
まとめ
2024年の価格予測における主要トレンド
-
Transformerモデルの優位性
- LSTMを上回る性能(特に長期依存関係)
- Time2Vecエンコーディングによる時系列特徴の改善 -
オーダーブック特徴量の進化
- 定常性を持つ特徴量の構築
- マルチレベル情報の活用 -
ハイブリッドアプローチ
- CNN-LSTM(DeepLOB)
- PSO-LSTM(最適化統合)
- VMD-TMFG-LSTM(マルチ特徴量) -
実装上の改善
- ウォークフォワード検証の標準化
- リアルタイム処理の最適化
- アンサンブル手法の洗練
推奨事項
- データ: オーダーブックの全レベルデータを活用
- モデル: Transformer または DeepLOB から開始
- 特徴量: 定常性を確保した Order Flow Imbalance を必須に
- 評価: 方向予測精度とSharpe比の両方を重視
- 実装: リアルタイム処理を前提とした設計
これらの手法を組み合わせることで、2024年の最先端の価格予測システムを構築できます。