research(wave-0822): GROWTH-POLICY — il libro gira al 7% di Kelly, e ogni gate del progetto e' cieco alla scala
This commit is contained in:
@@ -375,11 +375,9 @@ def main() -> None:
|
||||
print(" su GTAA/ADJUSTED_LAST). NON l'ho inseguito: tutte le mie conclusioni sono confronti")
|
||||
print(" RELATIVI dentro UNA lente. Ma tocca un numero pubblicato e il gate del 23/10.")
|
||||
print(f" XSR01 dal 25/07 a oggi (forward, {len(xsr_fwd)} barre, stessa lente): "
|
||||
f"ritorno {(np.prod(1+xsr_fwd.values)-1)*100:+.2f}% "
|
||||
f"Sharpe {sh(xsr_fwd) if len(xsr_fwd) > 30 else float('nan'):.2f} "
|
||||
f"{'(campione troppo corto per uno Sharpe: si legge il ritorno)' if len(xsr_fwd) <= 30 else ''}")
|
||||
print(" ^ la differenza fra 1.82 e il numero FULL di oggi NON e' una lente diversa (le repliche")
|
||||
print(" sono bit-exact): e' un mese in piu' di dati. Il gate pre-registrato resta il 23/10.")
|
||||
f"ritorno {(np.prod(1+xsr_fwd.values)-1)*100:+.2f}%"
|
||||
+ (" (campione troppo corto per uno Sharpe: si legge il ritorno)"
|
||||
if len(xsr_fwd) <= 30 else f" Sharpe {sh(xsr_fwd):.2f}"))
|
||||
print(f" finestra MAJ19: {C19.index[0].date()} -> {C19.index[-1].date()} ({len(C19)} barre); "
|
||||
f"in-sample = pre {HOLDOUT.date()} = {int((C19.index < HOLDOUT).sum())} barre")
|
||||
cov51 = np.isfinite(C51.values).sum(axis=1)
|
||||
@@ -535,24 +533,42 @@ def main() -> None:
|
||||
f"{dg['med_ticket']:>11.0f}{dg['orders_py']:>10.0f}"
|
||||
f"{trk:>12.2f}{' ⚠' if trk < 0.8 else ' '}")
|
||||
print()
|
||||
print(f" {'cella':<13}{'|dw| mediano al ribil.':>24}{'capitale sleeve minimo':>25}{' = book al 15%':>17}")
|
||||
print(f" {'cella':<13}{'|dw| RIBILANCIO':>18}{'|dw| deriva':>14}{'cap sleeve min':>17}"
|
||||
f"{'= book al 15%':>16}")
|
||||
capmin_k5 = None
|
||||
for nm in ("MAJ19 k=1", "MAJ19 k=2", "MAJ19 k=3", "MAJ19 k=5*"):
|
||||
cell = xs_cells[nm]
|
||||
Weff = xs_effective_weights(cell["W"], cell["scale"])
|
||||
chg = np.abs(np.diff(cell["W"], axis=0)).sum(axis=1) > 1e-12 # giorni di ribilanciamento
|
||||
rows = np.where(chg)[0] + 1
|
||||
d = np.abs(np.diff(Weff, axis=0))[rows - 1]
|
||||
med = float(np.median(d[d > 1e-9])) if np.any(d > 1e-9) else float("nan")
|
||||
capmin = MIN_ORDER_HL / med if med > 0 else float("nan")
|
||||
print(f" {'XS ' + nm.split()[1]:<13}{med:>24.4f}{capmin:>24.0f}$"
|
||||
f"{capmin/0.15:>16.0f}$")
|
||||
print(" ^ ARITMETICA: il ticket di un ribilanciamento e' |dw|*capitale_sleeve. Il min-order")
|
||||
print(" morde sotto il 'capitale sleeve minimo'. Per il CANONICO k=5 quel numero e' ~150$")
|
||||
print(" di sleeve = ~1.000$ di book al 15%, non 20.000$. La soglia dichiarata dal progetto")
|
||||
print(" veniva da una diagnostica di TURNOVER (quota di turnover sopra il min-order), che a")
|
||||
print(" capitale piccolo e' bassa perche' salta la deriva GIORNALIERA del vol-target — la")
|
||||
print(" quale non porta segnale. Stessa lezione gia' imparata su TP01 ('a $600 il min-order")
|
||||
print(" $5 e' GIA' la banda ottimale'), non applicata a XS01.")
|
||||
W = cell["W"]
|
||||
Weff = xs_effective_weights(W, cell["scale"])
|
||||
dW = np.abs(np.diff(W, axis=0)) # W cambia alla riga j+1
|
||||
dE = np.abs(np.diff(Weff, axis=0)) # Weff[j+1]-Weff[j], Weff[i]=W[i-1]*scale[i]
|
||||
# il cambio di W alla riga j+1 si vede su Weff alla riga j+2 -> confine da rispettare
|
||||
rb, dr = [], []
|
||||
for j in range(len(dW)):
|
||||
if j + 1 >= len(dE):
|
||||
break
|
||||
m = dW[j] > 1e-12
|
||||
if m.any():
|
||||
rb.extend(dE[j + 1][m].tolist()) # gambe DAVVERO ribilanciate
|
||||
dr.extend(dE[j + 1][~m][dE[j + 1][~m] > 1e-12].tolist())
|
||||
else:
|
||||
dr.extend(dE[j + 1][dE[j + 1] > 1e-12].tolist())
|
||||
med_rb = float(np.median(rb)) if rb else float("nan")
|
||||
med_dr = float(np.median(dr)) if dr else float("nan")
|
||||
capmin = MIN_ORDER_HL / med_rb if med_rb > 0 else float("nan")
|
||||
if nm.startswith("MAJ19 k=5"):
|
||||
capmin_k5 = capmin
|
||||
print(f" {'XS ' + nm.split()[1]:<13}{med_rb:>18.4f}{med_dr:>14.4f}{capmin:>16.0f}$"
|
||||
f"{capmin/0.15:>15.0f}$")
|
||||
print(" ^ ARITMETICA: il ticket vale |dw|*capitale_sleeve, e le due colonne |dw| sono ordini")
|
||||
print(" di grandezza diversi: il RIBILANCIO (ogni 10 giorni, porta il segnale) e la DERIVA")
|
||||
print(" giornaliera del vol-target (non porta segnale). Il min-order taglia la seconda molto")
|
||||
print(" prima della prima, ed e' per questo che la quota di turnover eseguito puo' essere del")
|
||||
print(f" 4% con haircut ~0. Per il CANONICO k=5 il ribilancio smette di passare sotto "
|
||||
f"~{capmin_k5:.0f}$")
|
||||
print(f" di sleeve = ~{capmin_k5/0.15:.0f}$ di book al 15%. La soglia '$20k' del progetto viene da")
|
||||
print(" una diagnostica di TURNOVER, non di Sharpe — stessa lezione gia' imparata su TP01")
|
||||
print(" ('a $600 il min-order $5 e' GIA' la banda ottimale'), mai applicata a XS01.")
|
||||
print()
|
||||
print(" 'gambe eseg' = quota delle VARIAZIONI di posizione sopra il min-order (la diagnostica")
|
||||
print(" su cui si basa la soglia '$20k'). 'haircut' = quanto ne costa in Sharpe. Sono cose")
|
||||
|
||||
Reference in New Issue
Block a user