SniperGold_ML/ml/diag_hmm.py

50 lines
1.6 KiB
Python

# -*- coding: utf-8 -*-
"""Uji cepat HMM 2-state pada log(RV24) & log(1+|z|) — cari regime yg tidak kolaps."""
import os
import sys
import math
import numpy as np
import datetime as dt
HERE = os.path.dirname(os.path.abspath(__file__))
SRC = os.path.normpath(os.path.join(HERE, "..", "..", "SniperGold_ML"))
sys.path.insert(0, SRC)
import train_regime as TR
import build_features as BF
BASE = os.path.normpath(os.path.join(HERE, "..", "..", "..", "Files", "AlgoForge", "Data"))
z = np.load(os.path.join(BASE, "XAUUSD_M15.npz"))
t = z["time"].astype(np.int64)
c = z["close"].astype(np.float64)
n = len(c)
r = np.zeros(n)
r[1:] = np.log(np.maximum(c[1:], 1e-12) / np.maximum(c[:-1], 1e-12))
rw = np.clip(r, -BF.WINSOR, BF.WINSOR)
w, a, b, nu = BF.fit_garch_t_bounded(rw[1490:148471])
sig = BF.garch_sigma_causal(rw, w, a, b)
zz = rw / np.maximum(sig, 1e-12)
ztr = zz[1490:148471]
zm, zs = float(ztr.mean()), float(ztr.std())
z_std = (zz - zm) / zs
r2 = r ** 2
rv = np.zeros(n)
for i in range(23, n):
rv[i] = math.sqrt(float(r2[i - 23:i + 1].mean()))
rv = np.maximum(rv, 1e-9)
lo, hi = 1490, 148471
for tag, series in [
("log(rv24)", np.log(rv)),
("log(1+|z_std|)", np.log1p(np.abs(z_std))),
("rv24", rv),
]:
A, pi, mu, var, ll = TR.hmm_em(series[lo:hi], K=2)
filt = TR.hmm_filter(series, A, pi, mu, var)
order = np.argsort(mu)
p_hi = filt[:, order[-1]]
p_lo = filt[:, order[0]]
print(f"--- {tag}: mu={mu[order]} var={var[order]} loglik={ll:.1f}")
print(f" P(high): mean={p_hi.mean():.3f} std={p_hi.std():.3f} "
f"min={p_hi.min():.3f} max={p_hi.max():.3f} "
f"test-mean={p_hi[hi:].mean():.3f}")