feat(live): portafoglio REALE-only — i 2000EUR ai soli 14 sleeve eseguiti, paper fuori dal pool

Decisione utente: il conto reale deve mostrare il risultato puro. I 2000 si dividono
SOLO tra i 14 sleeve reali (6 fade + DIP01 + 5 pairs + SH01). I 3 multi-asset
(TR01/ROT02/TSM01), non eseguibili in reale, escono da pool/pesi/ledger e girano solo
per statistica.

- portfolios.yml: paper_sleeves [TR01,ROT02,TSM01].
- runner: live_specs (pool/ledger) vs paper_specs (capitale nozionale fisso = total/N,
  data/portfolio_paper_stats/, ticcati ma MAI in update_equity).
- hourly_report: sezione PAPER da portfolio_paper_stats, etichettata 'fuori dal conto reale'.

Pesi reale-only (14, cap): non-cappati 0.087, PAIRS 0.33, SHAPE 0.0588. Costo misurato
e accettato: FULL DD 3.96->5.34%, OOS DD 1.36->1.70% (perde i diversificatori PAPER,
corr 0.07); Sharpe ~invariato. Test 93/93. Diario docs/diary/2026-06-08-real-only-portfolio.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-08 11:29:00 +00:00
parent 3d3ebd85d2
commit 0e8ad9c5f0
4 changed files with 86 additions and 10 deletions
+7 -6
View File
@@ -22,6 +22,7 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
PAPER = ROOT / "data" / "portfolio_paper"
PAPER_STATS = ROOT / "data" / "portfolio_paper_stats" # sleeve PAPER fuori dal conto reale
PORT_STATUS = ROOT / "data" / "portfolios" / "PORT06" / "status.json"
@@ -130,13 +131,13 @@ def collect():
def multi_asset_section() -> str:
"""Worker multi-asset (TR01/ROT02/TSM01): book corrente + eta' dell'ultimo flip
+ freschezza dello status. Prima erano INVISIBILI nel report (collect() filtra
su event/in_position che non emettevano): impossibile distinguere 'flat in
chop / risk-off by-design' da 'wiring rotto' (improvement-sweep 2026-06-06)."""
"""Sleeve PAPER (TR01/ROT02/TSM01): SOLO statistica, FUORI dal conto reale dei
€2000 (2026-06-08). Vivono in data/portfolio_paper_stats/ con capitale nozionale
fisso, raccolti per eventuali future implementazioni reali. Book corrente + eta'
ultimo flip + freschezza."""
now = datetime.now(timezone.utc)
rows = []
for sp in sorted(glob.glob(str(PAPER / "*" / "status.json"))):
for sp in sorted(glob.glob(str(PAPER_STATS / "*" / "status.json"))):
d = Path(sp).parent
st = json.loads(Path(sp).read_text())
book = st.get("positions") if "positions" in st else st.get("weights")
@@ -162,7 +163,7 @@ def multi_asset_section() -> str:
rows.append(f"{code:<7}{hb:<26}{flip:>8} {fresh}")
if not rows:
return ""
return ("📈 <b>MULTI-ASSET</b> (book | ultimo flip | status)\n<pre>"
return ("📈 <b>PAPER — solo statistica, FUORI dal conto reale</b> (book | ultimo flip | status)\n<pre>"
+ "\n".join(rows) + "</pre>")