73 lines
3.1 KiB
Python
73 lines
3.1 KiB
Python
"""Check indicator values + signal conditions at 2025-01-02 01:50 vs 15:45.
|
|||
|
|
|
||
|
|
MT5 first trade fired 2025.01.02 01:55 LONG @ 2624.05
|
||
|
|
→ signal bar 01:50 close=2623.84, fill at 01:55 open=2623.84
|
||
|
|
Python first trade fired 2025-01-02 15:50 LONG @ 2642.57
|
||
|
|
→ signal bar 15:45 close=2642.54, fill at 15:50 open=2642.54
|
||
|
|
|
||
|
|
Both engines should fire same signals on same bars. Why do they differ?
|
||
|
|
"""
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
PROJECT = Path(__file__).resolve().parent.parent
|
||
|
|
sys.path.insert(0, str(PROJECT))
|
||
|
|
|
||
|
|
import numpy as np
|
||
|
|
import pandas as pd
|
||
|
|
|
||
|
|
from shared.indicators.base import atr, ema, rsi
|
||
|
|
from shared.data.loaders import load_bars
|
||
|
|
from strategies.gold_scalper_pro.search_space import FROZEN_BASELINE
|
||
|
|
import optuna
|
||
|
|
|
||
|
|
# Load finalist #1 params
|
||
|
|
db = PROJECT / "studies" / "optuna" / "gold_scalper_pro_is2025.db"
|
||
|
|
study = optuna.load_study(
|
||
|
|
study_name="gold_scalper_pro_is2025",
|
||
|
|
storage=f"sqlite:///{db}",
|
||
|
|
)
|
||
|
|
from shared.optimizer.selector import select_diverse_topn
|
||
|
|
from strategies.gold_scalper_pro.search_space import SEARCH_SPACE
|
||
|
|
finalists = select_diverse_topn(study, n=3, ranges=SEARCH_SPACE)
|
||
|
|
params = {**FROZEN_BASELINE, **finalists[0].params}
|
||
|
|
|
||
|
|
print(f"InpFastEmaPeriod={params['InpFastEmaPeriod']}, "
|
||
|
|
f"InpSlowEmaPeriod={params['InpSlowEmaPeriod']}, "
|
||
|
|
f"InpRsiPeriod={params['InpRsiPeriod']}, "
|
||
|
|
f"InpAtrPeriod={params['InpAtrPeriod']}")
|
||
|
|
print(f"InpRsiBuyLevel={params['InpRsiBuyLevel']}, "
|
||
|
|
f"InpPullbackAtrMult={params['InpPullbackAtrMult']}")
|
||
|
|
|
||
|
|
m5 = load_bars(PROJECT / "data" / "XAUUSD_M5_2024-06-26_2026-06-26.parquet")
|
||
|
|
window = m5[(m5["timestamp"] >= "2024-12-01 00:00:00") & (m5["timestamp"] < "2025-01-03 00:00:00")].reset_index(drop=True)
|
||
|
|
|
||
|
|
close = window["close"].to_numpy(dtype=float)
|
||
|
|
high = window["high"].to_numpy(dtype=float)
|
||
|
|
low = window["low"].to_numpy(dtype=float)
|
||
|
|
|
||
|
|
fast = ema(close, int(params["InpFastEmaPeriod"]))
|
||
|
|
slow = ema(close, int(params["InpSlowEmaPeriod"]))
|
||
|
|
rsi_arr = rsi(close, int(params["InpRsiPeriod"]))
|
||
|
|
atr_arr = atr(high, low, close, int(params["InpAtrPeriod"]))
|
||
|
|
|
||
|
|
# Find rows on 2025-01-02 around 01:50 and 15:45
|
||
|
|
window["fast"] = fast
|
||
|
|
window["slow"] = slow
|
||
|
|
window["rsi"] = rsi_arr
|
||
|
|
window["atr"] = atr_arr
|
||
|
|
window["trend_up"] = (fast > slow) & (close > slow)
|
||
|
|
window["near_fast"] = np.abs(close - fast) <= (params["InpPullbackAtrMult"] * atr_arr)
|
||
|
|
window["rsi_prev"] = np.roll(rsi_arr, 1)
|
||
|
|
window["buy_cross"] = (window["rsi_prev"] < params["InpRsiBuyLevel"]) & (rsi_arr >= params["InpRsiBuyLevel"])
|
||
|
|
window["buy_signal"] = window["trend_up"] & window["near_fast"] & window["buy_cross"]
|
||
|
|
|
||
|
|
print("\n=== Around 2025-01-02 01:45-02:00 ===")
|
||
|
|
sub = window[(window["timestamp"] >= "2025-01-02 01:45:00") & (window["timestamp"] <= "2025-01-02 02:00:00")]
|
||
|
|
print(sub[["timestamp", "open", "high", "low", "close", "fast", "slow",
|
||
|
|
"rsi", "atr", "trend_up", "near_fast", "buy_cross", "buy_signal"]].to_string())
|
||
|
|
|
||
|
|
print("\n=== Around 2025-01-02 15:40-15:55 ===")
|
||
|
|
sub = window[(window["timestamp"] >= "2025-01-02 15:40:00") & (window["timestamp"] <= "2025-01-02 15:55:00")]
|
||
|
|
print(sub[["timestamp", "open", "high", "low", "close", "fast", "slow",
|
||
|
|
"rsi", "atr", "trend_up", "near_fast", "buy_cross", "buy_signal"]].to_string())
|