venue_news: sorvegliare cosa il venue ANNUNCIA — e due correzioni dalla KB

Nasce dall'annuncio sulla fine della Proof of Reserves. La notizia in se' vale
poco: si perde un segnale ad alta frequenza e DEBOLE (una PoR auto-pubblicata
prova che gli attivi esistono in un istante, non che coprano le passivita') e si
guadagna un audit annuale indipendente sotto VARA piu' il 90% degli attivi presso
Coinbase come custode. E non l'abbiamo mai sorvegliata: zero occorrenze nel
codice. Rinunciato di proposito a catturare l'ultimo dato — uno snapshot singolo
auto-riportato non regge lo standard di prova e non permetterebbe di stimare `p`.

CONSEGUENZA VERA: la decisione "100% Deribit fino a $20k" ha fra i suoi riapritori
"`p` che diventa stimabile invece che assunto". Dal 1/9 il segnale pubblico passa
da quotidiano ad ANNUALE: da una serie si stima, da un punto all'anno no. Quel
riapritore diventa praticamente irraggiungibile => la decisione e' ora gated SOLO
dal capitale.

TROVATO CERCANDO: esiste un feed RSS degli exchange-update, e conteneva quattro
annunci materiali che nessuno leggeva. Il caso che decide: le specifiche dei perp
USDC sono cambiate il 18/08, ANNUNCIATE IL 14/08. check_specs() e' nato da quella
svista e gira ogni ora, ma rileva la deriva DOPO; il feed l'avrebbe detta quattro
giorni PRIMA. La prima volta e' andata bene solo perche' i cambi erano RIDUZIONI.

Costruito scripts/live/venue_news.py (in cron_daily accanto a fee_watch):
  - NON interpreta: dice "e' uscito questo, guardalo". Nessun automatismo su un
    testo di marketing (P13). Classifica solo l'urgenza.
  - parole-chiave DERIVATE da deribit._CONTRACT e config/live.json, non
    ridichiarate (P1): chi aggiunge un asset allarga la sorveglianza da solo, ed
    e' il test che lo blinda.
  - primo giro semina senza allertare (P9); feed illeggibile -> exit 2, mai
    silenzio implicito (P5).
Debito #8 si RESTRINGE, non si chiude: il Rulebook non ha un feed.

Confermato due volte lo zero USDC: l'espansione del 31/07 non contiene l'Italia
ne' alcun paese UE, mentre San Marino e Citta' del Vaticano SONO idonei. Non
asserisco una causa (ci sono anche Canada e Giappone).

DUE CORREZIONI dalla KB "Cross collateral specifications":
(a) Il saldo negativo costa una collateral fee dello 0,05% AL GIORNO = 18,25%/anno,
    al secondo — 4,3x la resa USDE. Il 30/08 avevo scritto "lo finanzia a
    interesse" SENZA il numero: giusto e vuoto. Col numero, il criterio del
    cuscino di regolamento diventa aritmetica (-14 punti). E il ribilanciamento
    automatico non salva: scatta a $1M assoluti o al 100% della cross equity,
    irraggiungibili a $2k. Non veniamo ribilanciati: sanguiniamo la fee.
(b) L'haircut USDe ufficiale e' 5%, noi abbiamo 0.10 registrato come "verificato
    sul venue" il 26/08 senza traccia di come. NON riparato (P12/M28): si tiene
    0.10 perche' e' il lato conservativo, non e' sul percorso soldi e non morde
    fino al 90% di quota. Divergenza dichiarata in config.
Di lato: BUIDL haircut 2% (sarebbe stato il miglior collaterale del listino, se
si potesse comprare), stETH 7,5% (terza ragione indipendente per lasciarlo stare).
Nessuna fonte documenta un tetto sulle QUANTITA': il ~31,2% resta misurato e non
spiegato — e ora si sa che non e' una svista di lettura.

Suite: 800 passati (5 nuovi su venue_news).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-08-31 07:47:15 +00:00
parent 41f83b5dd8
commit 30286ea033
8 changed files with 424 additions and 6 deletions
+64
View File
@@ -0,0 +1,64 @@
"""venue_news: il guardiano di cio' che il venue ANNUNCIA.
Si testano le funzioni PURE (parsing del feed, match, derivazione delle chiavi). La rete no:
`scarica()` ritorna None su qualunque errore ed e' quello il contratto — 'non vedo' non e'
'niente di nuovo' (P5).
"""
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
sys.path.insert(0, str(ROOT / "scripts" / "live"))
import importlib.util
_spec = importlib.util.spec_from_file_location(
"venue_news", ROOT / "scripts" / "live" / "venue_news.py")
vn = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(vn)
_FEED = """<rss><channel>
<item><title><![CDATA[Contract Specifications change for Linear USDC Perpetuals]]></title>
<link>https://x/a</link><guid>https://x/?p=1</guid><pubDate>Fri, 14 Aug 2026 09:18:57 +0000</pubDate></item>
<item><title>Deribit Welcomes Orbit Markets</title>
<link>https://x/b</link><guid>https://x/?p=2</guid><pubDate>Fri, 10 Jul 2026 00:00:00 +0000</pubDate></item>
</channel></rss>"""
def test_estrae_le_voci_con_guid_titolo_e_data():
v = vn.voci(_FEED)
assert [x["guid"] for x in v] == ["https://x/?p=1", "https://x/?p=2"]
assert v[0]["titolo"] == "Contract Specifications change for Linear USDC Perpetuals"
assert v[0]["data"].startswith("Fri, 14 Aug 2026")
def test_feed_illeggibile_non_solleva_e_non_inventa_voci():
assert vn.voci("") == []
assert vn.voci("<rss>rotto") == []
def test_le_chiavi_sono_DERIVATE_dagli_strumenti_del_book():
"""P1: il bersaglio si deriva dal codice sorvegliato, non si ridichiara. Se un domani il book
prende un altro asset, la sorveglianza lo segue da sola."""
from src.live.deribit import _CONTRACT
ks = vn.chiavi()
for nome in _CONTRACT:
base = nome.split("_")[0].split("-")[0].lower()
assert base in ks, f"{base} (da {nome}) non e' fra le parole sorvegliate"
assert "usdc" in ks and "margin" in ks and "collateral" in ks
def test_riconosce_l_annuncio_che_ci_tocca_e_lascia_stare_gli_altri():
ks = vn.chiavi()
assert vn.rilevante("Contract Specifications change for Linear USDC Perpetuals", ks)
assert vn.rilevante("New SM Margin Model On Deribit", ks)
assert vn.rilevante("Deribit to Discontinue Daily Proof of Reserves Publication", ks)
assert vn.rilevante("USDC Rewards Available In More Countries", ks)
assert not vn.rilevante("Deribit Welcomes Orbit Markets to Block RFQ Platform", ks)
def test_il_match_e_case_insensitive_e_riporta_QUALI_parole():
m = vn.rilevante("New SM MARGIN Model On Deribit", vn.chiavi())
assert "margin" in m