Files
PythagorasGoal/tests/test_telegram_daily.py
T

85 lines
3.4 KiB
Python

"""Lock del report giornaliero Telegram (in cron dal 2026-07-25).
Gira in produzione dentro cron_daily.sh: se rompe, non deve rompere nulla d'altro e non deve
MAI inviare ordini. I test bloccano proprio questo: e' sola lettura, tollera i pezzi mancanti,
e non invia niente in dry-run.
"""
from __future__ import annotations
import sys
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
sys.path.insert(0, str(ROOT / "scripts" / "live"))
telegram_daily = pytest.importorskip("telegram_daily")
def test_build_non_solleva_e_ha_le_sezioni():
txt = telegram_daily.build()
assert isinstance(txt, str) and len(txt) > 50
for sezione in ("Conto", "Perche' non opera", "Ordini", "Monitor in osservazione"):
assert sezione in txt, f"sezione mancante: {sezione}"
def test_nessuna_scrittura_ne_ordine():
"""Il modulo non deve importare l'esecutore ne' avere funzioni che inviano ordini."""
src = (ROOT / "scripts" / "live" / "telegram_daily.py").read_text()
for vietato in ("DeribitTrader", "book_execute", "--execute", "place_order", "buy(", "sell("):
assert vietato not in src, f"il report non deve poter operare: trovato {vietato!r}"
def test_tollera_i_log_mancanti(monkeypatch, tmp_path):
"""Se i log dei monitor non esistono, il report deve degradare, non esplodere."""
monkeypatch.setattr(telegram_daily, "ROOT", tmp_path)
righe = telegram_daily.monitors()
assert len(righe) == len(telegram_daily.GATES)
assert all(isinstance(r, str) and r.strip() for r in righe)
assert telegram_daily.last_trade().strip()
def test_gate_coerenti_con_i_pre_registrati():
"""Le date qui devono coincidere con i gate pre-registrati negli script di decisione."""
d = dict((n, x) for n, x, _, _ in telegram_daily.GATES)
assert str(d["STATARB-RESID"]) == "2026-09-27"
assert str(d["XSR01"]) == "2026-10-23"
def test_convenzione_trend_e_documentata():
"""La convenzione media-dei-segni (non frazione) e' la ragione per cui TP01 e' 0 con 1/3 su:
se sparisce dal codice, il report mentirebbe sul 'quanto manca'."""
assert "media dei SEGNI" in telegram_daily.trend_state.__doc__
def test_soglia_accensione_2_negativi_1_positivo():
"""2 negativi + 1 positivo: basta 1 flip -> soglia = il riferimento negativo PIU' BASSO."""
r = telegram_daily._soglia_accensione([-1, -1, 1], [100.0, 200.0])
assert r == 100.0
def test_soglia_accensione_3_negativi():
"""3 negativi: servono 2 flip -> soglia = il SECONDO riferimento negativo piu' basso, non il
minimo (il bug di #35 C3: superare solo il minimo lascia la media <= 0)."""
r = telegram_daily._soglia_accensione([-1, -1, -1], [100.0, 200.0, 300.0])
assert r == 200.0
def test_soglia_accensione_1_negativo_2_positivi_gia_acceso():
"""1 negativo + 2 positivi: la media e' gia' positiva (TP01 > 0) -> nessuna soglia da dare."""
assert telegram_daily._soglia_accensione([-1, 1, 1], [100.0]) is None
def test_soglia_accensione_nessun_negativo():
"""Tutti positivi: nessun riferimento negativo, nessuna soglia."""
assert telegram_daily._soglia_accensione([1, 1, 1], []) is None
def test_soglia_accensione_servono_tutti_i_flip():
"""2 negativi su 2 (nessun positivo): servono ENTRAMBI i flip -> k == len(neg_refs), soglia
= il piu' alto dei due (l'ultimo a bastare), non il minimo."""
r = telegram_daily._soglia_accensione([-1, -1], [200.0, 100.0])
assert r == 200.0