research(wave-0822): lo scettico conferma il gradino di leva ma corregge due contorni — e la lente close-only e' cieca solo sulle regole a UN giorno
This commit is contained in:
@@ -638,8 +638,10 @@ def stats(daily: pd.Series) -> dict:
|
||||
cagr = float(eq.iloc[-1] ** (1 / yrs) - 1) if yrs > 0.5 and eq.iloc[-1] > 0 else float("nan")
|
||||
ho = r[r.index >= HOLDOUT]
|
||||
sho = float(ho.mean() / ho.std() * math.sqrt(365.25)) if len(ho) > 30 and ho.std() > 0 else float("nan")
|
||||
yrs_ = max(len(r) / 365.25, 1e-9)
|
||||
return dict(sharpe=sh, holdout=sho, maxdd=dd, cagr=cagr, n=len(r),
|
||||
vol=float(r.std() * math.sqrt(365.25)))
|
||||
vol=float(r.std() * math.sqrt(365.25)),
|
||||
se_ann=float(r.std() * math.sqrt(365.25) / math.sqrt(yrs_)))
|
||||
|
||||
|
||||
def delevering_null(cand: pd.Series, base: pd.Series) -> dict:
|
||||
@@ -737,7 +739,7 @@ def main() -> None:
|
||||
# ---------------- STEP 4: griglia ----------------
|
||||
print("\n[4] GRIGLIA — dichiarata PRIMA, contata AL RIALZO")
|
||||
FAM = {"CAL": ["static_long", "static_short", "zrev", "zmom"],
|
||||
"FvP": ["carry", "static_long", "zrev", "zmom"]}
|
||||
"FvP": ["carry", "static_long", "static_short", "zrev", "zmom"]}
|
||||
WINS = [720, 2160, 4320] # 30 / 90 / 180 giorni in ore
|
||||
ROLLS = [7, 21]
|
||||
THRS = [0.0, 1.0]
|
||||
@@ -794,7 +796,7 @@ def main() -> None:
|
||||
print("\n LE CELLE CANONICHE (quelle che un lettore chiede per nome), roll=7g:")
|
||||
for fam, sig, lab in [
|
||||
("FvP", "carry", "vendi il datato quando e' in CONTANGO / compra perp (il carry classico)"),
|
||||
("FvP", "static_short", "SEMPRE corto il datato / lungo perp"),
|
||||
("FvP", "static_short", "SEMPRE corto il datato / lungo perp = LA RACCOLTA DEL CONTANGO"),
|
||||
("FvP", "static_long", "SEMPRE lungo il datato / corto perp (il contrario)"),
|
||||
("CAL", "static_long", "calendar: lungo back / corto front"),
|
||||
("CAL", "static_short", "calendar: corto back / lungo front")]:
|
||||
@@ -802,8 +804,8 @@ def main() -> None:
|
||||
if len(sub):
|
||||
r = G.loc[sub.index[0]]
|
||||
print(f" {fam}/{sig:12s} Sh {r.sharpe:+6.2f} hold {r.holdout:+6.2f} "
|
||||
f"CAGR {r.cagr*100:+6.2f}% DD {r.maxdd*100:5.2f}% vol {r.vol*100:5.2f}%"
|
||||
f" <- {lab}")
|
||||
f"CAGR {r.cagr*100:+6.2f}% (+-{r.se_ann*100:.2f} SE) DD {r.maxdd*100:5.2f}% "
|
||||
f"vol {r.vol*100:5.2f}% <- {lab}")
|
||||
|
||||
print("\n migliori 8 celle per Sharpe FULL (NON e' la selezione — solo panorama):")
|
||||
for i in G.sharpe.nlargest(8).index:
|
||||
@@ -826,7 +828,11 @@ def main() -> None:
|
||||
print(f" cella scelta AL BUIO: {b.family} {b.sig} W={int(b.win)}h roll={int(b.roll)}g thr={b.thr}")
|
||||
print(f" Sharpe in-sample {ins[best_i]:+.2f} -> FULL {bs['sharpe']:+.2f} "
|
||||
f"HOLD-OUT {bs['holdout']:+.2f} maxDD {bs['maxdd']*100:.2f}% "
|
||||
f"CAGR {bs['cagr']*100:+.2f}% vol {bs['vol']*100:.2f}%")
|
||||
f"CAGR {bs['cagr']*100:+.2f}% (+-{bs['se_ann']*100:.2f} SE annuo) "
|
||||
f"vol {bs['vol']*100:.2f}%")
|
||||
print(f" NB con {bs['n']/365.25:.1f} anni e vol {bs['vol']*100:.1f}% l'errore standard del "
|
||||
f"rendimento annuo e' {bs['se_ann']*100:.2f}pp: sotto ~{2*bs['se_ann']*100:.1f}pp/anno "
|
||||
f"NIENTE e' distinguibile da zero, ne' in un verso ne' nell'altro.")
|
||||
best_full = G.sharpe.idxmax()
|
||||
print(f" (per confronto, la cella col miglior FULL sarebbe stata "
|
||||
f"{G.loc[best_full,'family']} {G.loc[best_full,'sig']} "
|
||||
|
||||
Reference in New Issue
Block a user