chore(reset): v2.0.0 — storico certificato Deribit mainnet, ripartenza pulita
Reset del progetto su fondamenta verificate dopo la scoperta che l'intera libreria "validata OOS" era artefatto di feed contaminato (print fantasma del feed Cerbero TESTNET + storico Binance/USDT). - Storico ricostruito da Deribit MAINNET (ccxt pubblico, tokenless) e CERTIFICATO (certify_feed.py): BTC/ETH puliti su TUTTA la storia (mediana 2-6 bps vs Coinbase USD), integrita' OHLC + coerenza resample (maxΔ 0.00) + cross-venue OK. Alt esclusi (illiquidi/divergenti: LTC/DOGE 50-82% barre flat; XRP/BNB non certificabili). - Verdetto sul feed pulito: FADE / PAIRS / XS01 / TSM01 morti (ogni portafoglio Sharpe -2.3..-3.0, DD ~40%); solo SH01 e frammenti HONEST con segnale residuo, da ri-validare in isolamento. - Cleanup "restart pulito": strategie, stack live (src/live, src/portfolio, runner/executor, yml, docker), ~100 script ricerca/gate, waste/games/ portfolios, dati non certificati + cache e 60+ diari -> archiviati in Old/ (preservati, non cancellati). Diario consolidato in un unico documento. - Skeleton ricerca tenuto: Strategy ABC + indicatori + src/fractal + src/backtest/engine + load_data; tool dati certificati (rebuild_history, certify_feed, audit_feed, multi_source_check). - Universo dati ATTIVO: solo BTC/ETH (5m/15m/1h); guardrail fisico (load_data su alt -> FileNotFoundError). Esecuzione DISABILITATA, conto flat. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,443 @@
|
||||
"""SHAPE_TEMPLATE_RESEARCH — edge nella FORMA del prezzo: distanze alternative e template canonici.
|
||||
|
||||
Due filoni, sull'harness ONESTO condiviso (shape_lab + explore_lab), netto-fee e OOS:
|
||||
|
||||
1. ANALOG con distanza di FORMA alternativa (DTW warping-invariant, correlazione/coseno)
|
||||
confrontata HEAD-TO-HEAD con l'euclidea a PARITA' di selettivita' (stessa libreria,
|
||||
stesso K, stessa soglia di accordo). DTW e' O(W^2): si usa una libreria SOTTOCAMPIONATA
|
||||
(uno start ogni `step` barre) + W ridotto + banda di Sakoe-Chiba.
|
||||
|
||||
2. TEMPLATE di forma canonici (doppio top/bottom, testa-spalle, V-reversal, salita/discesa
|
||||
lineare, U). A ogni i misuro la similarita' (correlazione di Pearson sulla finestra
|
||||
z-normalizzata) fra forma recente e ogni template; se supera soglia, entro a close[i]
|
||||
nella DIREZIONE ATTESA del template stimata SOLO sul passato (esito medio causale delle
|
||||
occorrenze gia' concluse di quel template), exit H barre o tp/sl ATR.
|
||||
|
||||
VINCOLI anti-look-ahead (verificati esplicitamente):
|
||||
- la forma/match a i usa SOLO close fino a i (z-norm causale);
|
||||
- la direzione attesa di ogni template e la libreria analog usano SOLO occorrenze il cui
|
||||
esito a H barre e' gia' realizzato PRIMA di i (end + H <= i-1);
|
||||
- ingresso eseguibile a close[i]; exit TP/SL intrabar o time-limit H.
|
||||
|
||||
Netto fee 0.10% RT baseline + sweep fino a 0.20%. Leva 3x, pos 0.15. OOS ultimo 30%.
|
||||
|
||||
Run riproducibile: uv run python scripts/analysis/shape_template_research.py
|
||||
DTW e' costoso: usa run_in_background per gli sweep larghi (vedi --sweep).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
from numpy.lib.stride_tricks import sliding_window_view
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from scripts.analysis.explore_lab import get_df, evaluate, robust, simulate, atr, ema, OOS_FRAC # noqa: E402
|
||||
from scripts.analysis.shape_lab import znorm_windows, fwd_return # noqa: E402
|
||||
|
||||
RNG_SEED = 7
|
||||
SUBC_ASSETS = ["BTC", "ETH", "SOL"]
|
||||
|
||||
|
||||
# =========================================================================================
|
||||
# DISTANZE DI FORMA
|
||||
# =========================================================================================
|
||||
def _euclid(q: np.ndarray, lib: np.ndarray) -> np.ndarray:
|
||||
"""Distanza euclidea fra q (W,) e ogni riga di lib (M,W). Forme gia' z-normalizzate."""
|
||||
return np.sqrt(((lib - q) ** 2).sum(axis=1))
|
||||
|
||||
|
||||
def _corr_dist(q: np.ndarray, lib: np.ndarray) -> np.ndarray:
|
||||
"""Distanza = 1 - correlazione di Pearson (q,lib gia' z-norm: corr = q.lib / W)."""
|
||||
# forme z-norm hanno media 0 std 1 -> dot/W e' la correlazione di Pearson
|
||||
corr = (lib @ q) / q.shape[0]
|
||||
return 1.0 - corr
|
||||
|
||||
|
||||
def _cosine_dist(q: np.ndarray, lib: np.ndarray) -> np.ndarray:
|
||||
"""Distanza = 1 - coseno fra q e ogni riga di lib."""
|
||||
qn = q / (np.linalg.norm(q) + 1e-12)
|
||||
ln = lib / (np.linalg.norm(lib, axis=1, keepdims=True) + 1e-12)
|
||||
return 1.0 - (ln @ qn)
|
||||
|
||||
|
||||
def _dtw_one(a: np.ndarray, b: np.ndarray, band: int) -> float:
|
||||
"""DTW 1D con banda di Sakoe-Chiba (|i-j|<=band). a,b stessa lunghezza W."""
|
||||
n = len(a)
|
||||
INF = 1e18
|
||||
prev = np.full(n + 1, INF)
|
||||
prev[0] = 0.0
|
||||
for i in range(1, n + 1):
|
||||
cur = np.full(n + 1, INF)
|
||||
jlo = max(1, i - band)
|
||||
jhi = min(n, i + band)
|
||||
ai = a[i - 1]
|
||||
for j in range(jlo, jhi + 1):
|
||||
cost = abs(ai - b[j - 1])
|
||||
m = prev[j]
|
||||
if prev[j - 1] < m:
|
||||
m = prev[j - 1]
|
||||
if cur[j - 1] < m:
|
||||
m = cur[j - 1]
|
||||
cur[j] = cost + m
|
||||
prev = cur
|
||||
return float(prev[n])
|
||||
|
||||
|
||||
def _dtw_dist(q: np.ndarray, lib: np.ndarray, band: int) -> np.ndarray:
|
||||
"""DTW di q contro ogni riga di lib. O(M * W * band)."""
|
||||
out = np.empty(lib.shape[0])
|
||||
for k in range(lib.shape[0]):
|
||||
out[k] = _dtw_one(q, lib[k], band)
|
||||
return out
|
||||
|
||||
|
||||
DIST_FUNCS = {"euclid": _euclid, "corr": _corr_dist, "cosine": _cosine_dist}
|
||||
|
||||
|
||||
# =========================================================================================
|
||||
# FILONE 1 — ANALOG con distanza configurabile (libreria sottocampionata, causale)
|
||||
# =========================================================================================
|
||||
def analog_dist_entries(df, dist="euclid", W=24, H=12, K=40, step=5, rebuild=500,
|
||||
min_lib=2000, agree=0.62, dtw_band=4, dtw_prefilter=200,
|
||||
decide_step=1, tp_atr=None, sl_atr=None,
|
||||
trend_max=None, ema_long=200) -> list[dict]:
|
||||
"""Analog kNN sulla FORMA con metrica `dist` ('euclid'|'corr'|'cosine'|'dtw').
|
||||
|
||||
Libreria SOTTOCAMPIONATA: si considerano solo finestre che terminano a indici
|
||||
multipli di `step` (riduce N e rende DTW trattabile). Causalita': la libreria a
|
||||
decisione i contiene solo finestre con end<=i-1-H (esito gia' realizzato).
|
||||
Ricostruita ogni `rebuild` barre. Stessa firma per tutte le metriche -> confronto
|
||||
head-to-head a parita' di selettivita' (stesso W,H,K,agree).
|
||||
|
||||
DTW (costoso, O(W*band) per coppia in Python): si PREFILTRA con la correlazione ai
|
||||
`dtw_prefilter` candidati piu' simili, poi si fa DTW-rerank solo su quelli (approccio
|
||||
standard lower-bound/rerank). `decide_step`>1 valuta una barra ogni decide_step (non
|
||||
cambia la causalita', riduce solo il numero di query DTW).
|
||||
"""
|
||||
close = df["close"].values
|
||||
n = len(close)
|
||||
a = atr(df, 14)
|
||||
M, ends = znorm_windows(close, W)
|
||||
end_pos = {int(e): k for k, e in enumerate(ends)}
|
||||
fr = fwd_return(close, H)
|
||||
el = ema(close, ema_long) if trend_max is not None else None
|
||||
|
||||
# candidati di libreria: solo end multipli di step (sottocampionamento causale fisso)
|
||||
base_ends = ends[(ends % step == 0)]
|
||||
|
||||
entries: list[dict] = []
|
||||
lib_M = None
|
||||
lib_idx = None
|
||||
next_rebuild = 0
|
||||
|
||||
for i in range(min_lib, n - 1):
|
||||
if i % decide_step != 0:
|
||||
continue
|
||||
if lib_M is None or i >= next_rebuild:
|
||||
elig = base_ends[(base_ends <= i - 1 - H) & (base_ends >= W - 1)]
|
||||
elig = elig[~np.isnan(fr[elig])]
|
||||
if len(elig) < max(K * 3, 200):
|
||||
next_rebuild = i + rebuild
|
||||
continue
|
||||
lib_M = M[[end_pos[int(e)] for e in elig]]
|
||||
lib_idx = elig
|
||||
next_rebuild = i + rebuild
|
||||
|
||||
if lib_M is None:
|
||||
continue
|
||||
q = M[end_pos[i]]
|
||||
if not np.isfinite(q).all():
|
||||
continue
|
||||
if trend_max is not None and a[i] > 0 and abs(close[i] - el[i]) / a[i] > trend_max:
|
||||
continue
|
||||
|
||||
if dist == "dtw":
|
||||
# prefiltro corr (cheap, vettoriale) -> DTW-rerank solo sui top dtw_prefilter
|
||||
pre = _corr_dist(q, lib_M)
|
||||
npre = min(dtw_prefilter, len(lib_idx))
|
||||
cand = np.argpartition(pre, npre - 1)[:npre]
|
||||
dd_cand = _dtw_dist(q, lib_M[cand], dtw_band)
|
||||
kk = min(K, len(cand))
|
||||
sub = np.argpartition(dd_cand, kk - 1)[:kk]
|
||||
nn = cand[sub]
|
||||
outs = fr[lib_idx[nn]]
|
||||
outs = outs[~np.isnan(outs)]
|
||||
if len(outs) < 5:
|
||||
continue
|
||||
mean_out = float(outs.mean())
|
||||
d = 1 if mean_out > 0 else -1
|
||||
frac = float(np.mean(np.sign(outs) == d))
|
||||
if frac < agree:
|
||||
continue
|
||||
e = {"i": i, "d": d, "max_bars": H}
|
||||
if tp_atr is not None and a[i] > 0:
|
||||
e["tp"] = close[i] + d * tp_atr * a[i]
|
||||
if sl_atr is not None and a[i] > 0:
|
||||
e["sl"] = close[i] - d * sl_atr * a[i]
|
||||
entries.append(e)
|
||||
continue
|
||||
|
||||
dd = DIST_FUNCS[dist](q, lib_M)
|
||||
kk = min(K, len(lib_idx))
|
||||
nn = np.argpartition(dd, kk - 1)[:kk]
|
||||
outs = fr[lib_idx[nn]]
|
||||
outs = outs[~np.isnan(outs)]
|
||||
if len(outs) < 5:
|
||||
continue
|
||||
mean_out = float(outs.mean())
|
||||
d = 1 if mean_out > 0 else -1
|
||||
frac = float(np.mean(np.sign(outs) == d))
|
||||
if frac < agree:
|
||||
continue
|
||||
e = {"i": i, "d": d, "max_bars": H}
|
||||
if tp_atr is not None and a[i] > 0:
|
||||
e["tp"] = close[i] + d * tp_atr * a[i]
|
||||
if sl_atr is not None and a[i] > 0:
|
||||
e["sl"] = close[i] - d * sl_atr * a[i]
|
||||
entries.append(e)
|
||||
return entries
|
||||
|
||||
|
||||
# =========================================================================================
|
||||
# FILONE 2 — TEMPLATE di forma canonici
|
||||
# =========================================================================================
|
||||
def make_templates(W: int) -> dict[str, np.ndarray]:
|
||||
"""Template parametrici z-normalizzati di lunghezza W (forma pura, no scala/livello).
|
||||
|
||||
Sono solo descrittori di FORMA recente (gli ultimi W close). La direzione attesa NON
|
||||
e' decisa a priori: viene stimata causalmente sul passato (vedi template_entries).
|
||||
"""
|
||||
t = np.linspace(0, 1, W)
|
||||
s = 0.012 # ampiezza gaussiana scalata sulla finestra (W-indipendente in t in [0,1])
|
||||
g = lambda c: np.exp(-((t - c) ** 2) / s)
|
||||
raw = {
|
||||
# estremi di reversione a DOPPIO picco (due massimi / minimi simmetrici)
|
||||
"double_top": g(0.25) + g(0.75), # M: due cime
|
||||
"double_bottom": -(g(0.25) + g(0.75)), # W: due fondi
|
||||
# testa-spalle: spalla-testa-spalla (centro piu' alto)
|
||||
"head_shoulders": g(0.2) + 1.7 * g(0.5) + g(0.8),
|
||||
"inv_head_shoulders": -(g(0.2) + 1.7 * g(0.5) + g(0.8)),
|
||||
# singola reversione
|
||||
"v_bottom": np.abs(t - 0.5),
|
||||
"inv_v_top": -np.abs(t - 0.5),
|
||||
"u_bottom": (t - 0.5) ** 2,
|
||||
"arch_top": -((t - 0.5) ** 2),
|
||||
# trend lineari
|
||||
"ramp_up": t,
|
||||
"ramp_down": -t,
|
||||
}
|
||||
out = {}
|
||||
for k, v in raw.items():
|
||||
v = np.asarray(v, dtype=float)
|
||||
sd = v.std()
|
||||
out[k] = (v - v.mean()) / (sd if sd > 0 else 1.0)
|
||||
return out
|
||||
|
||||
|
||||
def template_entries(df, W=24, H=12, corr_min=0.85, dir_min=0.10, min_lib=2000,
|
||||
rebuild=300, tp_atr=None, sl_atr=None, trend_max=None, ema_long=200,
|
||||
templates=None) -> list[dict]:
|
||||
"""Entries da match con template canonici, DIREZIONE stimata SOLO sul passato.
|
||||
|
||||
A ogni i, per ogni template calcolo la correlazione di Pearson fra la forma recente
|
||||
z-norm (close[i-W+1..i]) e il template. Prendo il template a correlazione massima; se
|
||||
>= corr_min lo considero "attivo". La DIREZIONE in cui entrare e' il segno del rendimento
|
||||
forward MEDIO storico delle occorrenze gia' concluse (end+H<=i-1) di quel template
|
||||
(stesso criterio di match), purche' |media| in barre-equivalenti superi dir_min*media_atr-ish
|
||||
-> qui dir_min e' una soglia sulla |media forward| relativa (frazione). NIENTE direzione a
|
||||
priori: se il passato non e' coerente (occorrenze<min o segno debole) si salta.
|
||||
"""
|
||||
close = df["close"].values
|
||||
n = len(close)
|
||||
a = atr(df, 14)
|
||||
M, ends = znorm_windows(close, W)
|
||||
end_pos = {int(e): k for k, e in enumerate(ends)}
|
||||
fr = fwd_return(close, H)
|
||||
el = ema(close, ema_long) if trend_max is not None else None
|
||||
tps = templates if templates is not None else make_templates(W)
|
||||
names = list(tps.keys())
|
||||
T = np.stack([tps[k] for k in names]) # (NT, W), gia' z-norm
|
||||
|
||||
# match-history: per ogni end di libreria, quale template e con che corr
|
||||
# (precalcolo causale: per ogni end, corr con ogni template)
|
||||
# corr Pearson fra forme z-norm = dot/W
|
||||
lib_ends = ends[ends >= W - 1]
|
||||
lib_M = M[[end_pos[int(e)] for e in lib_ends]] # (L, W)
|
||||
corr_mat = (lib_M @ T.T) / W # (L, NT)
|
||||
best_tpl = np.argmax(corr_mat, axis=1)
|
||||
best_corr = corr_mat[np.arange(len(lib_ends)), best_tpl]
|
||||
lib_fr = fr[lib_ends]
|
||||
lib_end_arr = lib_ends
|
||||
|
||||
entries: list[dict] = []
|
||||
# cache direzione per template, ricostruita ogni rebuild barre
|
||||
dir_cache: dict[int, int] = {}
|
||||
next_rebuild = 0
|
||||
|
||||
for i in range(min_lib, n - 1):
|
||||
q = M[end_pos[i]]
|
||||
if not np.isfinite(q).all():
|
||||
continue
|
||||
cq = (T @ q) / W # corr con ogni template
|
||||
bt = int(np.argmax(cq))
|
||||
if cq[bt] < corr_min:
|
||||
continue
|
||||
if trend_max is not None and a[i] > 0 and abs(close[i] - el[i]) / a[i] > trend_max:
|
||||
continue
|
||||
|
||||
# direzione attesa: media forward causale delle occorrenze concluse dello stesso template
|
||||
if i >= next_rebuild:
|
||||
dir_cache = {}
|
||||
next_rebuild = i + rebuild
|
||||
if bt not in dir_cache:
|
||||
mask = (lib_end_arr <= i - 1 - H) & (best_tpl == bt) & (best_corr >= corr_min) & (~np.isnan(lib_fr))
|
||||
outs = lib_fr[mask]
|
||||
if len(outs) < 30:
|
||||
dir_cache[bt] = 0
|
||||
else:
|
||||
m = float(outs.mean())
|
||||
# soglia: |media| forward deve superare dir_min volte la std forward (edge vs rumore)
|
||||
sd = float(outs.std()) + 1e-12
|
||||
dir_cache[bt] = (1 if m > 0 else -1) if abs(m) / sd >= dir_min else 0
|
||||
d = dir_cache[bt]
|
||||
if d == 0:
|
||||
continue
|
||||
e = {"i": i, "d": d, "max_bars": H}
|
||||
if tp_atr is not None and a[i] > 0:
|
||||
e["tp"] = close[i] + d * tp_atr * a[i]
|
||||
if sl_atr is not None and a[i] > 0:
|
||||
e["sl"] = close[i] - d * sl_atr * a[i]
|
||||
entries.append(e)
|
||||
return entries
|
||||
|
||||
|
||||
# =========================================================================================
|
||||
# CHECK CAUSALITA' espliciti
|
||||
# =========================================================================================
|
||||
def check_causality_analog(df, **kw) -> bool:
|
||||
"""Le entries non devono cambiare se perturbo il FUTURO oltre l'ultima barra usata.
|
||||
Tronco il df a una certa lunghezza L e verifico che le entries con i<L-H-1 siano
|
||||
identiche a quelle calcolate sul df completo (la coda futura non le tocca)."""
|
||||
L = int(len(df) * 0.55)
|
||||
H = kw.get("H", 12)
|
||||
full = analog_dist_entries(df, **kw)
|
||||
trunc = analog_dist_entries(df.iloc[:L].reset_index(drop=True), **kw)
|
||||
horizon = L - H - 2
|
||||
f = {e["i"]: e["d"] for e in full if e["i"] < horizon}
|
||||
t = {e["i"]: e["d"] for e in trunc if e["i"] < horizon}
|
||||
ok = (f == t)
|
||||
print(f" causalita' analog ({kw.get('dist','euclid')}): {'OK' if ok else 'VIOLATO'} "
|
||||
f"({len(f)} entries confrontate <{horizon})")
|
||||
return ok
|
||||
|
||||
|
||||
def check_causality_template(df, **kw) -> bool:
|
||||
L = int(len(df) * 0.55)
|
||||
H = kw.get("H", 12)
|
||||
full = template_entries(df, **kw)
|
||||
trunc = template_entries(df.iloc[:L].reset_index(drop=True), **kw)
|
||||
horizon = L - H - 2
|
||||
f = {e["i"]: e["d"] for e in full if e["i"] < horizon}
|
||||
t = {e["i"]: e["d"] for e in trunc if e["i"] < horizon}
|
||||
ok = (f == t)
|
||||
print(f" causalita' template: {'OK' if ok else 'VIOLATO'} "
|
||||
f"({len(f)} entries confrontate <{horizon})")
|
||||
return ok
|
||||
|
||||
|
||||
# =========================================================================================
|
||||
# RUN
|
||||
# =========================================================================================
|
||||
def run_head_to_head(assets=SUBC_ASSETS, W=16, H=12, K=40, step=6, agree=0.62,
|
||||
decide_step=4, dtw_prefilter=120):
|
||||
"""Confronto HEAD-TO-HEAD delle metriche di forma a PARITA' di selettivita'.
|
||||
|
||||
Tutte le metriche valutano le STESSE barre-decisione (decide_step) con lo STESSO
|
||||
W/H/K/agree: l'unica variabile e' la distanza. decide_step>1 serve a rendere DTW
|
||||
trattabile (pura Python ~9ms/query); applicato a tutte per equita'.
|
||||
"""
|
||||
print("=" * 100)
|
||||
print(f" FILONE 1 — ANALOG head-to-head metriche (W{W} H{H} K{K} step{step} "
|
||||
f"agree{agree} decide_step{decide_step}) | netto fee, OOS")
|
||||
print("=" * 100)
|
||||
results = {}
|
||||
for asset in assets:
|
||||
df = get_df(asset, "1h")
|
||||
print(f"\n --- {asset} 1h (n={len(df)}) ---", flush=True)
|
||||
for dist in ["euclid", "corr", "cosine", "dtw"]:
|
||||
t0 = time.time()
|
||||
ents = analog_dist_entries(df, dist=dist, W=W, H=H, K=K, step=step, agree=agree,
|
||||
dtw_band=max(2, W // 5), dtw_prefilter=dtw_prefilter,
|
||||
decide_step=decide_step)
|
||||
dt = time.time() - t0
|
||||
res = evaluate(f"{dist:<7s}", ents, df)
|
||||
results[(asset, dist)] = res
|
||||
print(f" ^ time={dt:>5.1f}s robust={'YES' if robust(res) else 'no '}", flush=True)
|
||||
return results
|
||||
|
||||
|
||||
def run_templates(assets=SUBC_ASSETS, W=20, H=12, corr_min=0.85, dir_min=0.10):
|
||||
print("=" * 100)
|
||||
print(f" FILONE 2 — TEMPLATE canonici (W{W} H{H} corr>={corr_min} dir>={dir_min}) | netto fee, OOS")
|
||||
print("=" * 100)
|
||||
results = {}
|
||||
for asset in assets:
|
||||
df = get_df(asset, "1h")
|
||||
print(f"\n --- {asset} 1h (n={len(df)}) ---")
|
||||
for cm in [0.80, 0.85, 0.90]:
|
||||
ents = template_entries(df, W=W, H=H, corr_min=cm, dir_min=dir_min)
|
||||
res = evaluate(f"corr_min={cm}", ents, df)
|
||||
results[(asset, cm)] = res
|
||||
print(f" ^ robust={'YES' if robust(res) else 'no '}")
|
||||
return results
|
||||
|
||||
|
||||
def run_sweep():
|
||||
"""Sweep largo (lento per via di DTW). Usa run_in_background."""
|
||||
print("=" * 100)
|
||||
print(" SWEEP LARGO — analog griglia W/H/K/step x metriche + template griglia")
|
||||
print("=" * 100)
|
||||
for W in [16, 20, 28]:
|
||||
for H in [8, 12, 24]:
|
||||
print(f"\n##### W={W} H={H} #####")
|
||||
run_head_to_head(W=W, H=H, K=40, step=6, agree=0.62)
|
||||
for W in [16, 20, 28]:
|
||||
for H in [8, 12, 24]:
|
||||
print(f"\n##### TEMPLATE W={W} H={H} #####")
|
||||
run_templates(W=W, H=H, corr_min=0.85, dir_min=0.10)
|
||||
|
||||
|
||||
def run():
|
||||
np.random.seed(RNG_SEED)
|
||||
print("#" * 100)
|
||||
print(" SHAPE_TEMPLATE_RESEARCH — distanze di forma alternative + template canonici")
|
||||
print("#" * 100)
|
||||
# 1) check causalita' espliciti
|
||||
print("\n[CAUSALITA']")
|
||||
dfb = get_df("BTC", "1h")
|
||||
check_causality_analog(dfb, dist="euclid", W=20, H=12, K=40, step=6, min_lib=2000)
|
||||
check_causality_analog(dfb, dist="dtw", W=16, H=12, K=40, step=8, min_lib=2000,
|
||||
dtw_band=3, decide_step=20)
|
||||
check_causality_template(dfb, W=20, H=12, corr_min=0.85)
|
||||
# 2) head-to-head metriche
|
||||
print()
|
||||
run_head_to_head()
|
||||
# 3) template
|
||||
print()
|
||||
run_templates()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "--sweep" in sys.argv:
|
||||
run_sweep()
|
||||
elif "--templates" in sys.argv:
|
||||
run_templates()
|
||||
elif "--h2h" in sys.argv:
|
||||
run_head_to_head()
|
||||
else:
|
||||
run()
|
||||
Reference in New Issue
Block a user