forex/management/commands/ 配下の複数コマンドで、同じロジックが重複実装されている。
共通ユーティリティモジュール _predict_fx/_utils.py に集約し、保守性を向上させる。
| ファイル | サイズ | 用途 |
|---|---|---|
predict_fx.py |
54.9 KB | メイン予測コマンド |
tool_optimize_fx_direction.py |
32.0 KB | 方向パラメータ最適化 |
tool_optimize_fx_weights.py |
13.7 KB | アンサンブル重み最適化 |
confirm_fx_predictions.py |
13.5 KB | 実績確定・乖離計算 |
tool_analyze_fx_features.py |
12.2 KB | 特徴量重要度分析 |
tool_analyze_fx_features.py, tool_optimize_fx_direction.py, tool_optimize_fx_weights.py の3ファイルでほぼ同一の TIMEFRAME_CONFIG を定義。
TIMEFRAME_CONFIG = {
'15M': {'load_func': ..., 'feature_func': ..., 'min_samples': ...},
'30M': {...},
'H': {...},
'D': {...},
}
predict_fx.py, tool_optimize_fx_direction.py, tool_optimize_fx_weights.py で同一の config パッチ処理。
def _patch_config(self):
CRYPTO_CONFIG.update(FX_PREDICTION_CONFIG)
crypto_fe.TREND_FEATURES = FX_TREND_FEATURES
3ファイルで微妙に異なる実装。統一されていない。
predict_fx.py: 独自の抽出ロジックtool_optimize_fx_direction.py: _extract_column_safe() 使用tool_optimize_fx_weights.py: fillna().astype() パターンtool_optimize_fx_direction.py, tool_optimize_fx_weights.py で150行以上の重複:
- データロード → 特徴量適用 → カラム取得 → ターゲット作成 → 配列準備
confirm_fx_predictions.py: ローカル実装 (_get_atr())tool_optimize_fx_direction.py: crypto ユーティリティからインポートpredict_fx.py, tool_optimize_fx_direction.py で同様のオシレーター抽出処理。
_predict_fx/_utils.py を新規作成:
get_timeframe_config(timeframe) — TIMEFRAME_CONFIG の一元管理patch_fx_config() — config パッチ処理の共通化extract_regime_data(df) — レジーム抽出の統一extract_vol_regime_data(df) — ボラレジーム抽出の統一extract_shock_data(df) — ショック抽出の統一prepare_backtest_arrays(df_model, feature_cols, timeframe) — 配列準備の共通化build_oscillator_arrays(df_model) — オシレーター抽出の共通化問題: D足予測で、価格予測が close > open(上げ)なのに direction=-1(下げ)となる矛盾が発生。 clsモデル(方向)と回帰モデル(価格)が独立しており、整合性チェックがなかった。
実例: base=3/4, target=3/5 - predicted_close(157.440) > predicted_open(157.040) → 上げ - direction=-1(clsモデルが下げと判定) - 実績も上げだったが、direction基準で「外れ」と評価された
修正内容: predict_fx.py のライブ予測パス・バックテストパス両方に整合性チェックを追加。
# Direction-price consistency check
if direction != 0 and pred_close is not None and pred_open is not None:
price_dir = 1 if pred_close > pred_open else (-1 if pred_close < pred_open else 0)
if price_dir != 0 and direction != price_dir:
direction = price_dir
direction=0(レンジ)→ そのまま維持問題: 旧目付は (open + low) / 2(上げ)/ (open + high) / 2(下げ)で、open寄りの中間点。実際のエントリーポイントとしてはH/Lに近い方が有用。
修正内容: calculate_target に target_offset パラメータを追加。H/Lから固定pipsオフセットで目付を算出。
| TF | オフセット |
|---|---|
| 15M | 3 pips |
| 30M | 3 pips |
| H | 5 pips |
| 4H | 7.5 pips |
| D | 10 pips |
predict_fx.py: FX_TARGET_OFFSET 定数を定義、ライブ・バックテスト両パスで使用confirm_fx_predictions.py: 実績確定時も同じオフセットで目付計算direction_prediction.py: calculate_target にオプション引数追加(crypto既存動作は維持)問題: Yahoo Finance APIが返すタイムスタンプに秒が付いており(例: 21:45:04)、予測・OHLCVともに秒付きでDB保存されていた。ビューは丸めた時刻(21:45:00)で検索するため、予測ローソクが表示されない。またOHLCVにはスナップショット(O=H=L=Cの重複レコード)も混入。
修正内容:
- predict_fx.py: latest_dt を _round_to_period で保存前に丸めるよう修正
- views.py: チャートクエリで .exclude(high_price=F('low_price')) を追加(スナップショット除外)
- views.py: H=Lのローソク足スキップ処理を削除(本数減少の原因だった)
- 既存データクレンジング: OHLCV 1413件の秒付き重複を削除、予測870件のタイムスタンプを丸め・重複100件を削除、詳細1738件を丸め