diff --git a/CLAUDE.md b/CLAUDE.md index 3559ae5..106a535 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1136,6 +1136,29 @@ Prima ondata di ricerca onesta su BTC/ETH certificati (5 track, harness condivis ragione meccanica (small e mid USA correlano ~0.95 giornaliero, un TSMOM si accende negli stessi giorni). Non e' "validato": 6.5 anni non distinguono due gambe cosi' simili, ed e' esattamente perche' la scelta non conta. Se c'e' una linea Russell 2000, si usa quella. + (g) ✅ **DEGIRO HA TUTTE E SEI LE GAMBE — verificato sul conto reale (2026-07-27, screenshot + watchlist "Pythagoras").** Era **Revolut** a non avere R2US. Su Degiro: VUAA e XNAS su **Tradegate + in EUR**, R2US/IDTL/IGLN/IHYU su **LSE in USD**. ✅ Verifica indipendente che le linee EUR siano + gli stessi fondi (dai dati, non dallo screenshot): il rapporto prezzo-IB/prezzo-Degiro dev'essere + **un solo cambio** → VUAA 1.1341, XNAS 1.1315, **scarto 0.23%**; le altre 4 stanno a 0.993-0.998 + (gia' USD). Due fondi diversi non darebbero lo stesso cambio. + ⚠️ **ERRORE MIO, dello stesso tipo che avevo appena codificato:** per cercare le linee in euro + delle altre 4 gambe ho interrogato IB **per TICKER** sulle borse tedesche → "nessuna linea EUR" + su 4/4, **falso**. Cercando **per ISIN** ognuna ce l'ha: **ZPRR** (=R2US), **IS04** (=IDTL), + **EGLN** (=IGLN, Londra EUR), **IS0R** (=IHYU). **Un "assente" da una ricerca per ticker su una + borsa dove quel ticker non esiste NON significa "non esiste".** + **Turnover per gamba a $10k (21 ordini/anno):** **IDTL 9 ordini / $6.257 = 46%**, VUAA $2.289 + (17%), IGLN $1.695 (12%), XNAS $1.614 (12%), IHYU $958 (7%), R2US $843 (6%) → **il turnover e' + concentrato**, il 71% e' su gambe in USD (**$9.752/anno**, conversione **$24/a a 25bps**, $49 a + 50bps = 6-12% del CAGR). **Spostare la sola IDTL su IS04 copre il 64% del turnover convertibile.** + ⚠️ Non e' un risparmio netto (spread Xetra piu' larghi delle linee primarie di Londra + tariffa di + connettivita' per borsa) e su $10k parliamo di decine di dollari l'anno in entrambe le direzioni: + **non e' una decisione importante, ed e' piu' utile dirlo che costruire una precisione finta.** + ⚠️ Il prompt **W-8BEN** di Degiro ("aliquota ridotta della ritenuta USA") **non riguarda queste + sei**: sono fondi IRLANDESI, non titoli USA — la ritenuta 15% la subisce il fondo al proprio + interno e nessun modulo dell'investitore la cambia. + **Stato: PREPARAZIONE, non azione** (saldo Degiro €328,92; GTAA01 richiede ≥$3k e la decisione + venue tiene tutto su Deribit fino a $20k). **LEZIONE: una raccomandazione poggiata su un fatto non verificato sul conto reale vale quanto quel fatto** — due volte in due giorni un'assunzione sul conto ha cambiato la conclusione (prima la negoziabilita' PRIIPs, poi quale conto e' davvero operativo). diff --git a/docs/diary/2026-07-26-gtaa-ucits.md b/docs/diary/2026-07-26-gtaa-ucits.md index af913cf..1d705fe 100644 --- a/docs/diary/2026-07-26-gtaa-ucits.md +++ b/docs/diary/2026-07-26-gtaa-ucits.md @@ -525,3 +525,89 @@ Avevo dedotto "linea in EUR = costo in più" da un caso (conto in USD) e l'avevo generale; per il conto che l'operatore usa davvero il segno è invertito. È la terza volta in due giorni che un'assunzione non verificata sul conto reale cambia la conclusione — dopo la negoziabilità PRIIPs e quale conto è operativo. + +--- + +# Addendum 2026-07-27 (4) — DEGIRO ha tutte e sei + +Screenshot della watchlist "Pythagoras" su flatexDEGIRO: **le sei gambe ci sono tutte**, con i +ticker esatti raccomandati. (Era Revolut a non avere R2US.) + +| gamba | ticker | borsa | valuta | prezzo Degiro | +|---|---|---|---|---| +| SPY | VUAA | TDG | **EUR** | € 126,795 | +| QQQ | XNAS | TDG | **EUR** | € 58,10 | +| IWM | R2US | LSE | USD | $ 86,66 | +| TLT | IDTL | LSE | USD | $ 3,09987 | +| GLD | IGLN | LSE | USD | $ 79,585 | +| HYG | IHYU | LSE | USD | $ 94,32 | + +## Verifica indipendente che le linee in EUR siano gli stessi fondi + +Non dallo screenshot ma dai dati: il rapporto fra il prezzo IB (Londra USD) e il prezzo Degiro deve +essere **un solo cambio** per entrambe le linee EUR. + +| ticker | Degiro | IB (LSE USD) | rapporto | +|---|---|---|---| +| VUAA | 126,795 | 143,80 | **1.1341** | +| XNAS | 58,10 | 65,74 | **1.1315** | +| R2US / IDTL / IGLN / IHYU | — | — | 0.993-0.998 (già USD) | + +EURUSD implicito **1.1341 vs 1.1315, scarto 0.23%**. Due fondi diversi non darebbero lo stesso +cambio: sono le stesse quote, quotate in euro. + +## ⚠️ Un errore mio, dello stesso tipo che avevo appena codificato come regola + +Per cercare le linee in euro delle altre quattro gambe ho interrogato IB **per ticker** sulle borse +tedesche: risultato "nessuna linea EUR" su 4/4. **Falso.** Il ticker cambia da borsa a borsa — R2US +su Xetra si chiama ZPRR. Cercando **per ISIN**: + +| gamba | linea USD | **linea EUR** | ISIN | +|---|---|---|---| +| SPY | VUAA (LSE) | VUAA (Xetra/BIt) | `IE00BFMXXD54` | +| QQQ | XNAS (LSE) | XNAS (Xetra) | `IE00BMFKG444` | +| IWM | R2US (LSE) | **ZPRR** (Xetra) | `IE00BJ38QD84` | +| TLT | IDTL (LSE) | **IS04** (Xetra) | `IE00BSKRJZ44` | +| GLD | IGLN (LSE) | **EGLN** (Londra) | `IE00B4ND3602` | +| HYG | IHYU (LSE) | **IS0R** (Xetra) | `IE00B4PY7Y77` | + +**Ogni gamba ha una linea in euro.** Avevo scritto la regola "si cerca per ISIN, non per ticker" un +messaggio prima e poi ho costruito la sonda per ticker. *Un "assente" da una ricerca per ticker su +una borsa dove quel ticker non esiste non significa "non esiste".* + +## Quanto vale la conversione, e su quale gamba + +Turnover per gamba a $10.000 (banda 25%, 21 ordini/anno): + +| gamba | ticker | ordini/anno | turnover/anno | quota | +|---|---|---|---|---| +| **TLT** | **IDTL** | **9** | **$6.257** | **46%** | +| SPY | VUAA | 3 | $2.289 | 17% | +| GLD | IGLN | 3 | $1.695 | 12% | +| QQQ | XNAS | 3 | $1.614 | 12% | +| HYG | IHYU | 1 | $958 | 7% | +| IWM | R2US | 2 | $843 | 6% | + +- turnover su gambe in **USD** (da convertire): **$9.752/anno = 71%** +- costo conversione: **$24/anno a 25bps**, $49 a 50bps (0.24-0.49% del capitale, ~6-12% del CAGR) + +**IDTL da sola vale il 46% del turnover e 9 dei 21 ordini.** Se si vuole ridurre la conversione +senza cambiare sei strumenti, si sposta **quella** sulla linea in euro (IS04, `IE00BSKRJZ44`): da +sola copre il **64%** del turnover convertibile. + +⚠️ Il risparmio non è netto: le linee di Xetra possono avere spread più larghi delle linee di Londra +(che sono le primarie), e Degiro storicamente addebita una tariffa di connettività per borsa. Su +$10.000 parliamo di decine di dollari l'anno in entrambe le direzioni — **non è una decisione +importante**, e dirlo è più utile che costruire una precisione finta. + +## Cosa NON serve + +Il messaggio in cima allo screenshot — *"Richiedi un'aliquota ridotta della ritenuta alla fonte sugli +investimenti statunitensi"* (il W-8BEN) — **non riguarda queste sei posizioni**: sono fondi +irlandesi, non titoli USA. La ritenuta del 15% la subisce il fondo al proprio interno e nessun +modulo dell'investitore la cambia. Va compilato se un giorno si detengono azioni USA dirette. + +## Stato + +Saldo Degiro €328,92: questa è **preparazione, non azione**. GTAA01 richiede ≥$3.000 per reggere i +costi, e la decisione venue del 26/07 tiene tutto su Deribit fino a $20k. diff --git a/scripts/research/r0727_gtaa_broker.py b/scripts/research/r0727_gtaa_broker.py index bb99011..efabeae 100644 --- a/scripts/research/r0727_gtaa_broker.py +++ b/scripts/research/r0727_gtaa_broker.py @@ -46,10 +46,21 @@ ISIN = {"VUAA": ("IE00BFMXXD54", "Vanguard S&P 500 UCITS (Acc, USD)"), "IGLN": ("IE00B4ND3602", "iShares Physical Gold ETC"), "IHYU": ("IE00B4PY7Y77", "iShares $ High Yield Corp Bond UCITS")} -# Stesso fondo, ticker diverso su borse diverse. Verificato su contract details IB: se le ISIN -# coincidono e' la STESSA classe di quote, quindi lo stesso NAV — cambia solo dove si negozia e in -# che valuta. Serve perche' un broker puo' non quotare la linea di Londra e quotare quella di Xetra. -EQUIVALENZE = [("R2US", "ZPRR", "IE00BJ38QD84", "Xetra EUR")] +# Stesso fondo, ticker diverso su borse diverse. Verificato su contract details IB cercando **per +# ISIN**: se le ISIN coincidono e' la STESSA classe di quote, quindi lo stesso NAV — cambia solo +# dove si negozia e in che valuta. Serve perche' (a) un broker puo' non quotare la linea di Londra, +# (b) su un conto in EURO la linea in euro evita la conversione a ogni ordine. +# +# ⚠️ Queste righe vanno cercate PER ISIN e non per ticker, ed e' un errore che ho fatto io stesso +# costruendo la tabella: la prima sonda cercava il ticker "R2US" sulle borse tedesche e non trovava +# nulla, concludendo "nessuna linea EUR". La linea c'e' e si chiama ZPRR. Cercare un ticker su una +# borsa dove quel ticker non esiste da' sempre "assente", che NON significa "non esiste". +EQUIVALENZE = [("R2US", "ZPRR", "IE00BJ38QD84", "Xetra EUR"), + ("IDTL", "IS04", "IE00BSKRJZ44", "Xetra EUR"), + ("IGLN", "EGLN", "IE00B4ND3602", "Londra EUR"), + ("IHYU", "IS0R", "IE00B4PY7Y77", "Xetra EUR"), + ("VUAA", "VUAA", "IE00BFMXXD54", "Xetra/BIt EUR"), + ("XNAS", "XNAS", "IE00BMFKG444", "Xetra EUR")] # Ripiego misurato: se un broker non ha NESSUNA linea Russell 2000, l'S&P 400 mid cap e' l'unica # alternativa comune. NON e' lo stesso indice (mid, non small) — vedi sezione (6) per il costo. @@ -280,6 +291,23 @@ def main() -> None: print(" reale, ma piccolo rispetto alla soglia (${:.2f}/ordine a ${:,.0f}).".format( float(soglia_per_ordine(dep, cal, CAP, band_c, can_every)[1:]), int(CAP))) + print("\n ⚠️ E LA CONVERSIONE NON SI DISTRIBUISCE IN MODO UNIFORME: il turnover e' concentrato") + print(" in poche gambe, quindi conviene sapere QUALI conviene spostare su una linea in euro.") + print(f"\n {'gamba':7s}{'ticker':8s}{'ordini/anno':>13s}{'turnover/anno':>16s}{'quota':>8s}") + tv = {} + for s in U.US: + _, pos = U.leg_returns(dep[s], dep[s], cal, CAP / 6.0, band_c, can_every, + U.cost_form(fixed=1.0)) + tv[s] = (int((pos.diff().abs() > 1e-12).sum()) / (len(cal) / 252.0), + float(pos.diff().abs().sum()) * CAP / 6.0 / (len(cal) / 252.0)) + tot = sum(v for _, v in tv.values()) + for s, (n, v) in sorted(tv.items(), key=lambda kv: -kv[1][1]): + print(f" {s:7s}{U.SET_DEPLOY[s]:8s}{n:>13.0f}{'$'+format(v,',.0f'):>16s}{v/tot:>8.0%}") + top = max(tv.items(), key=lambda kv: kv[1][1]) + print(f"\n -> {U.SET_DEPLOY[top[0]]} da sola vale il {top[1][1]/tot:.0%} del turnover e " + f"{top[1][0]:.0f} dei {sum(n for n, _ in tv.values()):.0f} ordini: se si vuole ridurre la") + print(" conversione senza cambiare sei strumenti, si sposta QUELLA su una linea in euro.") + # ---------- (6) ripiego sulla gamba small cap ---------- print("\n" + "=" * 100) print(" (6) SE IL BROKER NON HA NESSUNA LINEA RUSSELL 2000") diff --git a/tests/test_gtaa_broker.py b/tests/test_gtaa_broker.py index 1f5890d..43c503e 100644 --- a/tests/test_gtaa_broker.py +++ b/tests/test_gtaa_broker.py @@ -126,11 +126,22 @@ def test_le_soglie_di_lettura_sono_dichiarate(): def test_le_equivalenze_dichiarate_condividono_la_isin_del_veicolo_scelto(): """ZPRR (Xetra EUR) e R2US (Londra USD) sono la stessa classe di quote: se le ISIN non coincidono l'equivalenza e' falsa e l'operatore comprerebbe un altro fondo.""" + assert {a for a, _, _, _ in B.EQUIVALENZE} == set(B.ISIN), \ + "ogni gamba deve avere una linea in euro dichiarata: su un conto in EUR e' cio' che evita la conversione" for a, b, isin, _ in B.EQUIVALENZE: assert a in B.ISIN, f"{a} non e' un veicolo del set DEPLOY" assert B.ISIN[a][0] == isin, f"{a}: la ISIN dell'equivalenza non e' quella del veicolo" assert re.fullmatch(r"IE00[A-Z0-9]{8}", isin) - assert b not in B.ISIN, f"{b} e' un ALIAS di {a}, non un veicolo distinto" + if b != a: + assert b not in B.ISIN, f"{b} e' un ALIAS di {a}, non un veicolo distinto" + + +def test_ogni_isin_compare_una_volta_sola_fra_le_equivalenze(): + """Due gambe con la stessa ISIN sarebbero lo stesso fondo comprato due volte: il vol-target + girerebbe su cinque esposizioni invece di sei senza che nulla lo segnali.""" + isins = [i for _, _, i, _ in B.EQUIVALENZE] + assert len(set(isins)) == len(isins) + assert len(set(B.ISIN[t][0] for t in B.ISIN)) == 6 def test_il_ripiego_smallcap_e_dichiarato_come_indice_DIVERSO():