research(gtaa): l'assenza di API DEGIRO vale -0.02 di Sharpe, non e' squalificante
Domanda dell'operatore: "degiro ha api?". Fatto: no, non ufficiale; Revolut nemmeno (la sua e' per pagamenti); IB si'. I wrapper non ufficiali girano su credenziali + seed 2FA e si rompono IN SILENZIO a ogni cambio di front-end — e il progetto ha gia' pagato quel prezzo con fresh_5m il 26/07. Un esecutore che puo' rompersi senza dirlo e' peggio dell'esecuzione manuale. Misurato il costo di NON automatizzare invece di discuterlo: carico operativo: 15 settimane/anno con >=1 ordine (29% dei controlli, 1.4 per volta) ritardo 1g -0.02 Sharpe (peggiora in 6/11 anni = moneta) ritardo 3g -0.13 ritardo 10g -0.27 Il costo non e' il ritardo tipico ma la coda: il rischio dell'operativita' manuale e' la dimenticanza, e si copre con un allarme, non con una API (gtaa_rebalance_plan esiste gia' in produzione ed e' nato per un esecutore). Nota di metodo: sulla finestra UCITS di 3.2 anni la curva del ritardo NON e' monotona (5g -0.26, 10g -0.13) -> il campione corto non risolve differenze di questa taglia, quindi il numero si legge sulla finestra lunga a 10 anni, dove lo e'. Book, pesi, cron, config INVARIATI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XBbYmiXqbUNuGpK9sfbsGp
This commit is contained in:
@@ -1120,6 +1120,22 @@ Prima ondata di ricerca onesta su BTC/ETH certificati (5 track, harness condivis
|
||||
**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).
|
||||
(e) **"degiro ha api?" — NO, e costa −0.02 di Sharpe.** DEGIRO non espone una API di trading
|
||||
ufficiale al retail; Revolut nemmeno (la sua e' per pagamenti); IB si'. I wrapper NON ufficiali
|
||||
degli endpoint interni girano su credenziali + seed 2FA e **si rompono in silenzio** a ogni cambio
|
||||
di front-end — e il progetto ha gia' pagato quel prezzo (`fresh_5m`, 26/07): **un esecutore
|
||||
automatico che puo' rompersi senza dirlo e' peggio dell'esecuzione manuale.** Misurato invece il
|
||||
costo di NON automatizzare: carico operativo **15 settimane/anno con ≥1 ordine** (29% dei
|
||||
controlli, 1.4 ordini per volta); costo del ritardo su 10 anni **1g −0.02 (peggiora in 6/11 anni
|
||||
= moneta), 3g −0.13, 10g −0.27**. ⚠️ Sulla finestra UCITS di 3.2 anni la curva NON e' monotona
|
||||
(5g −0.26, 10g −0.13) → il campione corto non risolve differenze di questa taglia, si legge la
|
||||
finestra lunga. **Il costo non e' il ritardo tipico ma la CODA: il rischio e' la dimenticanza, e
|
||||
si copre con un ALLARME non con una API** (`gtaa_rebalance_plan` esiste gia' in produzione, nato
|
||||
per un esecutore; l'allerta Telegram c'e' gia' sul book live). ⚠️ Lato opposto, vero: il resto del
|
||||
book e' automatico, una gamba manuale aggiunge un modo di fallire che oggi non c'e' — argomento
|
||||
reale a favore di IB, che pero' richiede un secondo venue e quindi cade sotto la decisione venue
|
||||
($20k). **REGOLA: una capacita' mancante si valuta sul costo di non averla, non sulla sua
|
||||
assenza.**
|
||||
- ⚠️ **IL FEED EQUITY NON AVEVA UN CROSS-CHECK — buco trovato e chiuso (2026-07-26).**
|
||||
`src/data/eq_crosscheck.py`. Nel crypto la certificazione incrocia sempre piu' venue
|
||||
(`certify_feed.py` vs Coinbase USD); il feed equity aveva **solo controlli locali** (integrita',
|
||||
|
||||
@@ -394,3 +394,67 @@ guardando i due conti** — non sono cose che posso misurare da questo lato.
|
||||
Ieri ho consigliato IB in parte perché "il conto esiste già": era un'assunzione, e per la seconda
|
||||
volta in due giorni un'assunzione sul conto reale ha cambiato la conclusione. La prima volta era la
|
||||
negoziabilità (PRIIPs), questa volta quale conto è davvero operativo.
|
||||
|
||||
---
|
||||
|
||||
# Addendum 2026-07-27 (2) — "degiro ha api?"
|
||||
|
||||
**Fatto:** DEGIRO **non** espone una API di trading ufficiale per il retail. Revolut nemmeno (la sua
|
||||
API è per pagamenti, non per il portafoglio titoli). IB sì, documentata e supportata — è quella che
|
||||
il progetto già usa per i dati.
|
||||
|
||||
Esistono wrapper **non ufficiali** degli endpoint interni del web trader DEGIRO. Girano su
|
||||
credenziali + seed 2FA depositati sulla macchina, sono fuori dai termini di servizio, e si rompono
|
||||
**in silenzio** a ogni cambio di front-end. Questo progetto ha già pagato una volta il prezzo di un
|
||||
guasto silenzioso (`fresh_5m`, 26/07: fallimento muto → latenza d'uscita di SKH01 da ~1h a ~1 giorno
|
||||
senza che nulla lo segnalasse). **Un esecutore automatico che può rompersi senza dirlo è peggio
|
||||
dell'esecuzione manuale.**
|
||||
|
||||
Quindi la domanda utile non è "si può automatizzare" ma **"quanto costa non farlo"**.
|
||||
|
||||
## Carico operativo (banda 25%, controllo settimanale, $10.000)
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| controlli/anno | 50 |
|
||||
| **settimane con ≥1 ordine** | **15** (29% dei controlli) |
|
||||
| ordini per settimana attiva | 1.4 (max 5) |
|
||||
|
||||
Nel 71% dei controlli non c'è nulla da fare.
|
||||
|
||||
## Costo del ritardo di esecuzione
|
||||
|
||||
Veicoli USA, 10 anni. ⚠️ Sulla finestra UCITS di 3.2 anni la curva **non risulta monotona** (5
|
||||
giorni −0.26, 10 giorni −0.13): il campione corto non risolve differenze di questa taglia, quindi
|
||||
il numero si legge sulla finestra lunga.
|
||||
|
||||
| ritardo | Sharpe | ΔSharpe | stabilità |
|
||||
|---|---|---|---|
|
||||
| 0 giorni | 0.90 | — | — |
|
||||
| **1 giorno** | 0.89 | **−0.02** | peggiora in 6/11 anni = **moneta** |
|
||||
| 2 giorni | 0.83 | −0.07 | 7/11 |
|
||||
| 3 giorni | 0.78 | −0.13 | 7/11 |
|
||||
| 5 giorni | 0.73 | −0.18 | 7/11 |
|
||||
| **10 giorni** | 0.63 | **−0.27** | 6/11 |
|
||||
|
||||
**Il costo non è il ritardo tipico, è la coda.** Eseguire il giorno stesso o il giorno dopo costa
|
||||
nulla; dieci giorni valgono quasi un terzo dello sleeve.
|
||||
|
||||
## Conseguenza
|
||||
|
||||
Il rischio dell'operatività manuale non è la lentezza, è la **dimenticanza** — e quella si compra
|
||||
con un **allarme**, non con una API. `gtaa_rebalance_plan(held, capital)` esiste già in produzione
|
||||
ed è nato esattamente per un esecutore; il progetto ha già l'allerta Telegram sul book live. Un cron
|
||||
settimanale che calcola il piano e notifica quando c'è da agire copre il caso 15 volte l'anno.
|
||||
|
||||
⚠️ **L'altro lato, che resta vero:** il resto del book è automatico (TP01 e SKH01 mandano ordini
|
||||
veri su cron). Aggiungere una gamba manuale introduce un modo di fallire che il sistema oggi non ha.
|
||||
È un argomento reale a favore di IB — che l'API ce l'ha — ma richiede finanziare un secondo venue, e
|
||||
la decisione venue del 26/07 tiene tutto su Deribit fino a $20k. **La scelta è quindi rimandata al
|
||||
punto in cui la si riaprirebbe comunque.**
|
||||
|
||||
## Lezione
|
||||
|
||||
**Una capacità mancante si valuta sul costo di non averla, non sulla sua assenza.** Qui l'assenza di
|
||||
API sembra squalificante e vale −0.02 di Sharpe se si esegue entro un giorno; ciò che vale davvero
|
||||
(−0.27) è un rischio operativo che si copre con una notifica.
|
||||
|
||||
@@ -174,6 +174,61 @@ def main() -> None:
|
||||
print(" controllo (2) su 10 anni e veicoli diversi, ma GTAA01 non e' deployabile prima dei")
|
||||
print(" $20k (decisione venue 26/07): c'e' tempo per validarla come si deve.")
|
||||
|
||||
# ---------- (5-bis) l'esecuzione MANUALE e' sostenibile? ----------
|
||||
print("\n" + "=" * 100)
|
||||
print(" (5-bis) SE IL BROKER NON HA UNA API — quanto costa eseguire a mano")
|
||||
print("=" * 100)
|
||||
print(" DEGIRO non espone una API di trading ufficiale; Revolut nemmeno (la sua API e' per")
|
||||
print(" pagamenti). Esistono wrapper non ufficiali degli endpoint interni, ma girano su")
|
||||
print(" credenziali + seed 2FA e si rompono in SILENZIO a ogni cambio di front-end — e questo")
|
||||
print(" progetto ha gia' pagato una volta il prezzo di un guasto silenzioso (fresh_5m, 26/07).")
|
||||
print(" Quindi la domanda giusta non e' 'si puo' automatizzare' ma 'quanto costa NON farlo'.")
|
||||
per_bar = None
|
||||
band_c = BAND_FRAC * CAP / 6.0
|
||||
for k in dep:
|
||||
_, pos = U.leg_returns(dep[k], dep[k], cal, CAP / 6.0, band_c, can_every,
|
||||
U.cost_form(fixed=1.0))
|
||||
o = (pos.diff().abs() > 1e-12).astype(int)
|
||||
per_bar = o if per_bar is None else per_bar + o
|
||||
anni = len(cal) / 252.0
|
||||
att = int((per_bar > 0).sum())
|
||||
print(f"\n Carico operativo a ${CAP:,.0f} (banda {BAND_FRAC:.0%}, controllo settimanale):")
|
||||
print(f" controlli/anno {len(cal)/5/anni:.0f}")
|
||||
print(f" settimane con >=1 ordine/anno {att/anni:.0f} ({att/(len(cal)/5):.0%} dei controlli)")
|
||||
print(f" ordini per settimana attiva {per_bar[per_bar > 0].mean():.1f} "
|
||||
f"(max {int(per_bar.max())})")
|
||||
|
||||
print("\n Costo del RITARDO di esecuzione — veicoli USA, finestra lunga "
|
||||
f"({len(cal_us)/252:.0f} anni), perche' su 3.2 anni la curva non risulta monotona")
|
||||
print(" (cioe' il campione corto non risolve differenze di questa taglia):")
|
||||
print(f"\n {'ritardo':>10s}{'Sharpe':>9s}{'CAGR':>9s}{'dSharpe':>10s} stabilita' per anno")
|
||||
base_sh, base_s = None, None
|
||||
for d in (0, 1, 2, 3, 5, 10):
|
||||
cols = {}
|
||||
for k in us:
|
||||
_, pos = U.leg_returns(us[k], us[k], cal_us, CAP / 6.0, band_c, can_every,
|
||||
U.cost_form(fixed=1.0))
|
||||
px = U._norm(us[k]).reindex(cal_us).ffill().values.astype(float)
|
||||
ret = np.zeros(len(px))
|
||||
ret[1:] = px[1:] / px[:-1] - 1.0
|
||||
p = pos.shift(d).fillna(0.0).values
|
||||
c = (pos.diff().abs() > 1e-12).astype(float).shift(d).fillna(0.0).values / (CAP / 6.0)
|
||||
cols[k] = __import__("pandas").Series(p * ret - c, index=cal_us)
|
||||
s = __import__("pandas").concat(cols, axis=1).mean(axis=1)
|
||||
m = U.met(s)
|
||||
if base_sh is None:
|
||||
base_sh, base_s = m["sharpe"], s.copy()
|
||||
peggio = sum(1 for y, g in s.groupby(s.index.year)
|
||||
if len(g) > 100 and U.met(g)["sharpe"] < U.met(base_s[base_s.index.year == y])["sharpe"])
|
||||
tot = sum(1 for y, g in s.groupby(s.index.year) if len(g) > 100)
|
||||
print(f" {str(d)+' giorni':>10s}{m['sharpe']:>9.2f}{m['cagr']:>8.2%}"
|
||||
f"{m['sharpe']-base_sh:>+10.2f} peggiora in {peggio}/{tot} anni")
|
||||
print("\n LETTURA: eseguire il giorno stesso o il giorno dopo costa ~nulla (-0.02, e peggiora")
|
||||
print(" in 6/11 anni = moneta). Il costo NON e' il ritardo tipico ma la CODA: dieci giorni")
|
||||
print(" valgono -0.27, cioe' quasi un terzo dello sleeve. Il rischio dell'operativita' manuale")
|
||||
print(" non e' la lentezza, e' la DIMENTICANZA — e quella si compra con un ALLARME, non con")
|
||||
print(" una API: `gtaa_rebalance_plan()` esiste gia' in produzione ed e' nato per un esecutore.")
|
||||
|
||||
# ---------- (5) cosa cercare sul proprio conto ----------
|
||||
print("\n" + "=" * 100)
|
||||
print(" (5) COSA CERCARE SUL PROPRIO BROKER — per ISIN, non per ticker")
|
||||
|
||||
Reference in New Issue
Block a user