Traefik auto-upgrade (latest+Watchtower -> 3.7.7) ha scartato il resolver ACME per acme.json a 660 (3.x pretende 600) -> cert self-signed su tutto il VPS -> DeribitRead SSLError -> book online=False. Zero trade persi (target flat, gate di sicurezza OK). Fix: chmod 600 acme.json + restart; pin traefik:3.7 nel compose. Diario con diagnosi, verifica end-to-end e runbook. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PythagorasGoal
Sistema di riconoscimento pattern frattali e predizione per il trading di criptovalute (BTC, ETH), ispirato al framework teorico di Serleto & Malanga (Pythagoras Trading Prediction).
Obiettivo
Partendo da un capitale iniziale di €1.000, raggiungere un profitto medio di €50 al giorno entro 6–8 mesi, tramite un portafoglio di strategie algoritmiche poco correlate fra loro — mean-reversion, trend/rotazione e spread market-neutral — validate out-of-sample e fee-aware.
Risultati
⚠️ Revisione 2026-05-28. La famiglia squeeze-breakout (SQ/MT/ML/AD/CM/PD, con accuracy storiche dichiarate 76-82%) è stata scartata: quei numeri erano un artefatto di look-ahead. I backtest decidevano la direzione dalla candela di breakout
close[i]ma entravano aclose[i-1]— impossibile dal vivo. Sotto ingresso onesto (close[i]) e fee reali, l'edge sparisce e tutte perdono, anche a fee zero. Dettagli e prove:scripts/analysis/oos_validation.py.
Dopo una validazione out-of-sample, fee-aware di molte famiglie di strategie, emergono cinque famiglie con edge netto reale, tutte radicate nella stessa lezione (in cripto la mean-reversion funziona, la continuazione no) o nella diversificazione:
| Famiglia | Meccanismo | Strategie | Profilo (netto OOS) |
|---|---|---|---|
| FADE | mean-reversion intraday 1h (long/short, BTC/ETH) | MR01 Bollinger, MR02 Donchian, MR07 Return-reversal | Acc 52-55%, DD 18-34% |
| HONEST | long-only multi-regime multi-crypto | DIP01 dip-buy, TR01 EMA-trend, ROT02 dual-momentum | CAGR 31-56%, DD 15-27% |
| PAIRS | spread reversion market-neutral (2 gambe) | PR01 ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL | Sharpe 2.0-4.4, corr col mercato ~0.05 |
| TSMOM | time-series momentum multi-orizzonte | TSM01 (3/6/12m + risk-off) | diversificatore, DD 15-22% |
| SHAPE | ML walk-forward su feature di forma del prezzo | SH01 (LogisticRegression, orizzonte 12 barre) | diversificatore, corr +0.08 col resto |
Tutti i numeri sono netti dopo fee realistiche (Deribit 0.10% RT single-leg, 0.20% RT/coppia sui pairs), leva 3x, su finestra held-out. Le strategie sono robuste su griglia parametri, sweep fee 0.00-0.20% RT e — per i pairs — validate con walk-forward e config universale (niente cherry-picking).
Portafoglio combinato (la vera leva anti-drawdown)
Le famiglie sono quasi scorrelate fra loro (~0.05). Combinandole in un unico portafoglio equipesato il drawdown crolla sotto quello di ogni singola sleeve:
| Portafoglio | CAGR | Max DD | Sharpe |
|---|---|---|---|
| FADE (6 sleeve) | ~46% | 8% | 3.9 |
| HONEST (3 sleeve) | ~46% | 13% | 2.2 |
| MASTER (FADE + HONEST, 9) | ~47% | 5% | 4.2 |
| MASTER + PAIRS + TSM01 (15) | ~67% | ~5% | ~6 |
| PORT06 live (17 sleeve, cap pairs 33%, leva 2×, config EXIT-16) | ~79% | 2.6% | 7.8 (FULL) / 10.1 (OOS) |
🔎 Numeri sobri (anti-overfit). L'OOS singolo cade nel regime favorevole 2024-25: i valori di Sharpe/DD sopra sono ottimistici di circa il 50%. Da pianificare per le decisioni: Sharpe atteso ~5, worst-drawdown su 90 giorni ~6%, profilo che regge a leva 2x con slippage raddoppiato. Configurazione raccomandata: equal-weight, leva 2x, con un cap sull'allocazione ai pairs (~30-35%, poiché concentrano ~57% del rischio). Tutto resta da confermare nel paper trading live.
Come funziona
MR01 — Bollinger Fade (mean-reversion)
La strategia attiva sfrutta il fatto, emerso dai dati, che su BTC/ETH a 1h gli estremi di prezzo rientrano verso la media più di quanto proseguano:
- Bollinger Bands (window
n,kdeviazioni standard) sul close. - Entry — quando il close esce sotto la banda inferiore → long (o sopra la superiore → short). Ingresso a
close[i], eseguibile dal vivo. - Take-profit alla media mobile (il rientro atteso).
- Stop-loss a
sl_atr × ATRoltre l'estremo; time-limit amax_bars.
Nessun look-ahead: direzione e livelli sono calcolati con dati fino a close[i].
Le altre famiglie
- FADE (oltre MR01): MR02 fada la rottura del canale Donchian verso il centro; MR07 fada il movimento di barra estremo misurato in deviazioni standard dei rendimenti. Stessa logica di reversione, indicatori indipendenti.
- HONEST (long-only, multi-crypto): DIP01 compra i dip estremi e rivende al recupero; TR01 segue il trend con incrocio di EMA su un paniere; ROT02 ruota ogni giorno sui tre asset col momentum più forte, andando in cash quando BTC è sotto la sua media (risk-off). Coprono i regimi di trend e rotazione, complementari alle fade.
- PAIRS (market-neutral): scommette sul rientro verso la media del log-ratio fra due cripto (z-score). Long su una, short sull'altra: l'esposizione netta al mercato è quasi nulla (correlazione ~0.02), il che la rende un diversificatore eccellente.
- TSMOM: tiene gli asset con momentum positivo persistente su più orizzonti (3/6/12 mesi), con overlay risk-off. Rende meno ma è poco correlato, utile in ensemble.
Perché lo squeeze breakout è stato abbandonato
L'ipotesi originale era opposta — continuazione dopo la compressione di volatilità
(Bollinger dentro Keltner → breakout direzionale). Su dati storici sembrava dare
76-82% di accuracy, ma era un artefatto di look-ahead: il backtest entrava a
close[i-1] con direzione decisa da close[i]. Replicando l'esecuzione reale
(ingresso a close[i]) l'edge collassa al ~47% (lancio di moneta) e i costi fanno
il resto. Il test sui breakout intra-barra a 5m conferma che il movimento rientra
subito (mean-reversion), giustificando MR01. Tutta la famiglia squeeze è in scripts/waste/.
Lezione metodologica
Ogni nuova strategia deve passare: (1) ingresso eseguibile senza look-ahead,
(2) backtest netto dopo fee realistiche (0.10% RT Deribit), (3) validazione
out-of-sample + robustezza su griglia parametri + sweep fee. Strumenti in
scripts/analysis/ (strategy_research.py, oos_validation.py, intrabar_test.py).
Struttura progetto
PythagorasGoal/
├── src/
│ ├── data/ # Download e gestione dati (Cerbero MCP + Binance)
│ ├── fractal/ # Indicatori frattali: Hurst, Higuchi FD, self-similarity
│ ├── backtest/ # Motore di backtesting con fee e metriche
│ ├── strategies/ # Classe base Strategy ABC + indicatori condivisi
│ │ ├── base.py # Strategy, Signal, BacktestResult, YearlyStats
│ │ └── indicators.py # keltner_ratio, detect_squeezes, ema, atr, rv, corr
│ ├── live/ # Paper trading live su Deribit testnet
│ │ ├── multi_runner.py # Orchestratore multi-strategia (strategie + pairs)
│ │ ├── strategy_worker.py # Worker single-leg con stato persistente
│ │ ├── pairs_worker.py # Worker a 2 gambe per i pairs (market-neutral)
│ │ ├── strategy_loader.py # Import dinamico classi Strategy
│ │ ├── cerbero_client.py # Client HTTP per Cerbero MCP
│ │ ├── signal_engine.py # Squeeze + ML real-time (legacy) + validazione OOS
│ │ └── telegram_notifier.py
│ └── portfolio/ # Portafogli di prima classe (capitale condiviso, backtest + live)
│ ├── base.py # SleeveSpec, Portfolio (.backtest), load_active_portfolio
│ ├── weighting.py # Schemi di ponderazione: equal, cap, inverse_vol, cluster_rp, manual
│ ├── sleeves.py # Builder unificato equity-per-sleeve (fonte unica, parità report)
│ ├── ledger.py # PortfolioLedger: PnL/DD aggregati, persistenza e resume
│ └── runner.py # PortfolioRunner live (Cerbero v2, sizing, ribilancio giornaliero)
├── scripts/
│ ├── strategies/ # Strategie con edge validato OOS (FADE, HONEST, PAIRS, TSMOM + portafogli)
│ ├── portfolios/ # Definizioni PORT01-06 e report run() dei portafogli di prima classe
│ ├── waste/ # Strategie scartate (squeeze SQ/MT/ML/AD/CM/PD, MR03, ROT01, W01-W28)
│ └── analysis/ # Ricerca/validazione OOS fee-aware, gestione rischio, report
├── strategies.yml # Config multi-strategy paper trader
├── data/
│ ├── raw/ # Parquet OHLCV (gitignored, ~70 MB)
│ └── regime/ # DVOL + funding (Deribit mainnet) + cache feature regime (gitignored)
├── VERSION # versione semver (cotta nell'immagine, mostrata nei msg Telegram)
├── docs/
│ ├── diary/ # Diario di ricerca giornaliero
│ └── specs/ # Specifiche di design
├── Dockerfile
├── docker-compose.yml
└── pyproject.toml
Strategie attive
Le strategie single-asset estendono src.strategies.base.Strategy
(generate_signals() → backtest()); i pairs hanno un worker dedicato a 2 gambe.
| Codice | Script | Famiglia | Descrizione |
|---|---|---|---|
| MR01 | MR01_bollinger_fade.py |
FADE | Fada la banda di Bollinger, TP alla media, SL ad ATR |
| MR02 | MR02_donchian_fade.py |
FADE | Fada la rottura del canale Donchian, TP al centro |
| MR07 | MR07_return_reversal.py |
FADE | Fada il movimento di barra estremo (z dei rendimenti) |
| DIP01 | DIP01_dip_reversion.py |
HONEST | Dip-buy long-only su z-score estremo |
| TR01 | TR01_ema_trend.py |
HONEST | EMA 20/100 trend-following su paniere cripto (4h) |
| ROT02 | ROT02_dual_momentum.py |
HONEST | Rotazione cross-sectional top-3 + risk-off (1d) |
| PR01 | PR01_pairs_reversion.py |
PAIRS | Spread reversion market-neutral su 5 coppie |
| TSM01 | tsmom_research.py |
TSMOM | Time-series momentum multi-orizzonte + risk-off |
| SH01 | SH01_shape_ml.py |
SHAPE | LogisticRegression walk-forward su 17 feature di forma, orizzonte 12 barre (diversificatore) |
Le fade applicano tre protezioni live: un filtro trend (trend_max/ema_long,
salta i segnali col prezzo troppo esteso rispetto alla EMA200), un loss-guard Hurst
(hurst_max=0.55, salta i segnali in regime persistente/trending dove si concentrano gli stop-loss
— dimezza il drawdown del portafoglio, calcolato dalle sole close) e l'EXIT-16 close-confirm SL
(sl_confirm_atr=0.5, 2026-06-04: lo stop scatta solo se la barra chiude oltre sl ∓ 0.5·ATR14 —
gli stop intrabar da wick erano falsi negativi, l'overshoot che buca lo stop è proprio il movimento
che la fade fada; a livello PORT06 porta l'OOS Sharpe da 8.82 a 10.06). Più un filtro min_tp_frac
che scarta i micro-scalp col take-profit entro il costo delle fee. Le tre protezioni sono
complementari: Hurst toglie il regime tossico, il trend-filter gli ingressi sovra-estesi, il
close-confirm i falsi stop. Portafogli pronti: PORT01
(honest), PORT02 (fade), PORT03 (master fade+honest), PORT06 (master esteso, default live).
Scartate (in scripts/waste/): la famiglia squeeze (SQ01-04, ML01, MT01, PD01,
CM01, AD01 — artefatto di look-ahead), MR03 Keltner (debole/ridondante con MR01) e
ROT01 (dominata da ROT02).
Comandi utili
# Backtest di una strategia
uv run python scripts/strategies/MR01_bollinger_fade.py
uv run python scripts/strategies/PR01_pairs_reversion.py
# Ricerca e validazione fee-aware out-of-sample
uv run python scripts/analysis/strategy_research.py # screening famiglie + deep-dive fade
uv run python scripts/analysis/strategy_research_v2.py # MR02 / MR03 / MR07
uv run python scripts/analysis/oos_validation.py # perche' la famiglia squeeze e' scartata
uv run python scripts/analysis/pairs_research.py # ricerca + verifica no-look-ahead dei pairs
# Gestione rischio, combinazione, report
uv run python scripts/analysis/risk_management.py # filtro trend + portafoglio fade
uv run python scripts/analysis/combine_portfolio.py # combinare fade + honest
uv run python scripts/analysis/combine_v2.py # master esteso con pairs + TSM01
uv run python scripts/analysis/report_families.py # report per anno di tutte le famiglie
# Validazione dei worker live (replay == backtest)
uv run python scripts/analysis/validate_worker_mr01.py # worker single-leg su MR01
uv run python scripts/analysis/validate_worker_pairs.py # worker a 2 gambe sui pairs
uv run python scripts/analysis/live_smoke_pairs.py # smoke test feed live reale dei pairs
Paper Trading Live
Il multi-strategy runner esegue N strategie in parallelo su dati live da Cerbero MCP, ognuna con €1000 USDC virtuali indipendenti. Gestisce due tipi di worker:
- Single-leg (
strategy_worker.py): per le strategie direzionali. Se unSignalportatp/sl/max_barsinmetadata(come le fade), chiude su take-profit / stop-loss / time-limit; altrimenti usa il fallbackhold_bars/stop -2%. - Due gambe (
pairs_worker.py): per i pairs market-neutral. Apre long su una gamba e short sull'altra, esce sul rientro dello z-score o per time-limit, conta le fee su entrambe le gambe. Validato: il replay storico coincide esattamente col backtest.
Avvio
# Locale
uv run python -m src.live.multi_runner
# Docker
docker compose up -d
Configurazione
Le strategie attive sono definite in strategies.yml:
defaults:
capital: 1000
position_size: 0.15
leverage: 3
strategies: # strategie single-leg
- name: MR01_bollinger_fade
asset: BTC
tf: 1h
enabled: true
params: { bb_window: 50, k: 2.5, sl_atr: 2.0, max_bars: 24, trend_max: 3.0, ema_long: 200 }
pairs: # strategie a 2 gambe (market-neutral)
- name: PR01_pairs_reversion
a: ETH
b: BTC
tf: 1h
enabled: true
params: { n: 50, z_in: 2.0, z_exit: 0.75, max_bars: 72, jump_max: 0.08 }
Per aggiungere una strategia: nuova riga in strategies.yml (sezione strategies o
pairs), poi docker compose restart. Lo storico delle strategie esistenti rimane intatto.
Persistenza
Ogni strategia ha la sua directory in data/paper_trades/:
data/paper_trades/
MR01_bollinger_fade__BTC__1h/
trades.jsonl # Storico trade append-only
status.json # Stato corrente (resume al restart, include tp/sl/max_bars)
Notifiche Telegram per ogni trade (richiede TELEGRAM_BOT_TOKEN e TELEGRAM_CHAT_ID in .env).
Paper Trading a Portafoglio
Accanto al multi-strategy runner originale — in cui ogni strategia gestisce autonomamente il proprio conto virtuale da €1.000 — il progetto dispone ora di un paper trader a portafoglio (src/portfolio/) che tratta l'insieme delle strategie come un unico organismo con un capitale condiviso.
Come funziona
La definizione di un portafoglio (SleeveSpec + schema di peso) ha due facce sulla stessa sorgente dati:
- Backtest (
.backtest()): ricostruisce le equity-curve di ogni sleeve tramite il builder unificato insleeves.py, le pondera secondo lo schema scelto e calcola le metriche aggregate (CAGR, Sharpe, max DD). La parità con i report prodotti dareport_families.pyè garantita dalla fonte unica. - Live (
PortfolioRunner): ogni ora il runner scarica le candele aggiornate via Cerbero v2, calcola i pesi correnti, avvia i worker appropriati per ogni sleeve attiva e registra il PnL aggregato nel ledger (data/portfolios/{code}/). Il ledger persiste tra i riavvii.
Schemi di ponderazione
Il modulo weighting.py mette a disposizione cinque schemi: equal (default), cap (tetto per famiglia — p.es. pairs: 0.33 per limitare la concentrazione), inverse_vol (pesi inversamente proporzionali alla volatilità storica), cluster_rp (equal tra cluster naturali poi inverse-vol all'interno del cluster) e manual (pesi liberi). Lo schema si specifica in portfolios.yml insieme al codice portafoglio e alla leva.
Portafoglio di default: PORT06
La configurazione raccomandata è PORT06 (scripts/portfolios/PORT06_master_shape.py): portafoglio master esteso che include tutte e sei le famiglie (FADE, HONEST, PAIRS, TSMOM, SHAPE), con schema cap che limita i pairs al 33% del capitale per moderare la loro concentrazione di rischio. Backtest canonico (dati al 2026-05-28): Sharpe 6.47 (FULL) / 8.82 (OOS), drawdown massimo 4.10% (FULL) / 1.30% (OOS), leva 2×; con la config live attuale (EXIT-16 close-confirm): Sharpe 7.84 / 10.06, DD 2.60% / 1.15%.
Scope live
Il runner esegue tutti e 17 gli sleeve di PORT06: fade (MR01, MR02, MR07 × BTC/ETH),
honest (DIP01, TR01-basket 4h, ROT02-rotation 1d), pairs (PR01, cinque coppie),
TSMOM (TSM01 1d) e shape (SH01 × BTC/ETH). Worker dedicati: StrategyWorker (single-leg, fade/
dip/shape), PairsWorker (2 gambe), BasketTrendWorker, RotationWorker, TsmomWorker. Il runner
fetcha 1h da Cerbero v2 e resampla a 4h/1d; il pool di capitale, il ribilancio giornaliero e il ledger
sono validati == backtest.
SH01 (2026-06-01): gira come
StrategyWorkernormale (il walk-forward è interno agenerate_signals). Il vecchioMLWorkerWrapperusava ilSignalEnginesqueeze scartato — rimosso. Loss-guard Hurst (2026-06-02): le fade saltano i segnali in regime persistente (rolling-Hurst ≥ 0.55), dove si concentrano gli stop-loss — dimezza il drawdown del portafoglio (FULL 4.1%→2.4%; stop-loss fade −67% in numero, perdite totali −68%). Calcolato dalle sole close, attivo live (hurst_maxnei params). Il report orario su Telegram monitora lo stop-rate fade prima/dopo l'attivazione e dà il verdetto automatico quando il campione è sufficiente.
Esecuzione reale (shadow, Deribit testnet)
Sette sleeve single-leg — le 6 fade (MR01/MR02/MR07 × BTC/ETH) e DIP01 (dal 2026-06-04) — eseguono ordini reali su Deribit testnet accanto al fill simulato (shadow: il sim resta la verità che guida le decisioni; il reale misura la fattibilità). Punti chiave:
- Strumenti lineari USDC (
BTC_USDC/ETH_USDC-PERPETUAL): payoff lineare = matematica del backtest; fee e PnL in USDC. QuantizzazioneDecimaldi amount (step) e prezzi (tick). - Take-profit reale = limit reduce-only AL livello (v1.0.7): piazzato all'apertura, copre la
sola quota del worker (gli strumenti sono condivisi fra worker e nettati per conto); alla
chiusura il worker cancella il resting, riconcilia i fill dal trade history per
order_ide chiude a market solo il residuo. Fix della divergenza misurata: il market-on-poll usciva +235 bps oltre il livello TP. Fill da resting = fee maker (~0%). - Stop-loss close-confirm (v1.1.0): uscita al close che sfonda il livello → market reduce-only al poll (nessun ordine stop sul book, per scelta: i trigger Deribit generano un nuovo order_id allo scatto, non verificabile, e i wick non devono stoppare).
- Verifica sul trade (order_id in
get_trade_history), fee reali daitrades[], ledger reale parallelo persistito (real_capital), eventiREAL_OPEN/REAL_TP_RESTING/REAL_CLOSEnel log + alert Telegram (REAL_EXEC_LIVE,REAL_OPEN_FAIL). - Config in
portfolios.yml→overrides.execution {enabled, sleeves, instruments}. Pairs/rotation/TSMOM/shape restano simulati: i pairs richiedono un executor a 2 gambe (leg-risk), i multi-asset un rebalance-to-target; roadmap nel diario.
Versione & deploy
Ogni deploy ha una versione (file VERSION, semver) che compare nei messaggi Telegram (notifiche
trade + report orario), così correli ogni messaggio al codice che l'ha generato. Il sorgente è cotto
nell'immagine → per aggiornare il live serve un rebuild, non un semplice restart:
./scripts/deploy.sh # bump patch (1.0.0 → 1.0.1) + commit + rebuild + ricrea container
./scripts/deploy.sh minor # 1.0.x → 1.1.0
Il volume data/ persiste tra i deploy → i worker fanno RESUME dello stato (capitale, posizioni aperte).
Avvio del paper trader a portafoglio
# Backtest del portafoglio di default (PORT06)
uv run python scripts/portfolios/PORT06_master_shape.py
# Paper trading live a portafoglio
uv run python -m src.portfolio.runner
# Report orario su Telegram (stato + stop-rate fade prima/dopo loss-guard) — via cron
uv run python scripts/portfolios/hourly_report.py
# Smoke test del data layer Cerbero v2
uv run python scripts/analysis/smoke_portfolio.py
Setup
# Clona e installa
git clone <repo-url> && cd PythagorasGoal
uv sync
# Scarica dati storici (~70 MB)
uv run python -m src.data.downloader
# Backtest strategia attiva
uv run python scripts/strategies/MR01_bollinger_fade.py
# Paper trading live
uv run python -m src.live.multi_runner
Requisiti
- Python ≥ 3.11
- uv come package manager
- Accesso a Cerbero MCP (
cerbero-mcp.tielogic.xyz) per dati Deribit live - Docker (opzionale, per deploy su VPS)
Dati
| Asset | Timeframe | Copertura |
|---|---|---|
| BTC, ETH | 5m / 15m / 1h | 2018-01 → oggi |
| SOL, LTC, ADA, XRP, BNB, DOGE | 15m / 1h | 2019-2022 → oggi (variabile per asset) |
Fonte primaria: perpetual Deribit via Cerbero MCP. Fallback: Binance spot via ccxt.
Formato: Apache Parquet (in data/raw/, gitignored).
Nota sul naming Deribit (per il feed live). I major sono perpetui inverse (
BTC-PERPETUAL,ETH-PERPETUAL); gli altcoin sono perpetui lineari USDC (SOL_USDC-PERPETUAL,LTC_USDC-PERPETUAL, …) con storia dal 2022. Attenzione:LTC-PERPETUAL/ADA-PERPETUALnon esistono eSOL-PERPETUALrestituisce dati errati — per gli altcoin usare sempre la forma_USDC-PERPETUAL.
Discovery & validazione strumenti
src/data/instruments.py scopre e valida gli strumenti disponibili sugli
exchange implementati — Deribit e Hyperliquid (esclusi Alpaca/stocks e
Bybit, feed testnet inaffidabile). Ogni perpetuo viene testato sui dati
storici realmente raccoglibili: esistenza, congruenza OHLC, contratto non-morto,
liquidità e congruenza prezzo cross-exchange (mediana per base-coin, tolleranza
5%) — così feed farlocchi e contratti sbagliati (es. SOL-PERPETUAL=9.6) vengono
scartati. Il risultato è data/instruments_registry.json (strumenti validi +
timeframe + data d'inizio).
Solo gli strumenti validati possono essere scaricati: il downloader ha un gate
(_download_cerbero_range) che rifiuta quelli non nel registry. Rigenera con:
uv run python -m src.data.instruments
Simboli Deribit: BTC/ETH = <COIN>-PERPETUAL (inverse); altcoin =
<COIN>_USDC-PERPETUAL (lineari USDC). Registry attuale (testnet): Deribit 18/106
validi (major liquidi, BTC dal 2018), Hyperliquid 66/74.
Riferimenti
- Serleto, L. & Malanga, C. — Pythagoras Trading Prediction (2024)
- Serleto, L. & Malanga, C. — Libro dei Frattali (2024)
Licenza
Uso privato. Non destinato alla distribuzione.