registro: chiusi §58-69 — dodici verdetti, 0 candidati, e due appoggi tolti a decisioni gia' prese
I dodici filoni della sesta ondata erano rimasti `_in corso_`: la sessione si e' chiusa dopo che gli agenti avevano scritto gli script e prima che i verdetti fossero consolidati, e i loro messaggi finali sono persi. I numeri qui NON vengono da quei messaggi: vengono dalla riesecuzione dei dodici script (07:38-08:06 UTC, sequenziale, log in logs/r0823b/ che e' gitignored). E' il motivo per cui l'ondata non e' andata persa: ogni script calcola il proprio verdetto a runtime. Cosa tocca decisioni gia' prese: - §67 il gate pre-registrato XSR01 del 23/10 legge un monitor tarato sul pavimento del venue sbagliato (C* $15-20k, non ~$3k) - §64 la raccomandazione di §51 (raccogliere la catena USDC) non e' giustificata dalla ragione che porta: le due superfici sono la stessa - §60 la politica MISTO scelta il 25/07 non e' piu' l'ottimo (oggi MISTO-A) - §63 domanda fiscale NUOVA, diversa da quella aperta il 07/08 Il risultato piu' grande e' di §58: l'obiettivo del progetto ha DUE definizioni operative in uso che danno 33,9% contro 0,33% sulla stessa domanda, e non era mai stato detto quale si stesse ottimizzando. r0823b_quasi_passati.py (§68) terminava con IndexError: Griglia.combo() indicizzava con self.idx (2720 giorni) un sottoinsieme di 958 righe. Corretto col parametro idx esplicito piu' un controllo di lunghezza; la rinormalizzazione e' riga per riga, quindi i valori sono quelli dell'intento dell'autore. La correzione e' del coordinatore, non dell'autore, ed e' dichiarata nel registro. Libro, pesi, cron, config INVARIATI. Nessun ordine. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,890 @@
|
||||
"""r0823b_fisco_payout — §63 FISCO-PAYOUT: l'aliquota sui payout funded e' un FORFAIT mai
|
||||
giustificato, e il canale funded non e' mai stato misurato contro di essa (2026-08-23).
|
||||
|
||||
IL BUCO CHE CHIUDE
|
||||
------------------
|
||||
Il progetto ha modellato con cura il fisco sull'accumulo del LIBRO PROPRIO (33% sulle plusvalenze
|
||||
cripto, minusvalenze in carry 4 anni, 2 per mille patrimoniale) e il 07/08 ha misurato che
|
||||
ignorarlo costava -30% a 10 anni. Sul canale FUNDED non ha modellato niente: `r0725_prop_ladder.py`
|
||||
importa `TAX_RATE = 0.33` da `r0725_capcurve` e lo applica ai payout con una riga
|
||||
|
||||
net = gross * (1.0 - TAX_RATE) # r0725_prop_ladder:269
|
||||
|
||||
senza una giustificazione. Ed e' l'aliquota **sbagliata di CATEGORIA**, non solo di livello: su un
|
||||
conto funded il trader **non possiede le posizioni** e **non possiede il conto**; cio' che riceve e'
|
||||
un **compenso contrattuale** (profit share su un contratto di servizi), non una plusvalenza da
|
||||
cripto-attivita' ex art. 67 c.1 lett. c-sexies TUIR. Il 33% e' l'aliquota di una cosa che qui non
|
||||
succede.
|
||||
|
||||
Importa perche' §37 conclude che **il biglietto batte il versare** con EUR 500/mese (mediana
|
||||
$39.820 contro $22.444). Se l'aliquota vera fosse molto piu' alta di 33%, quella conclusione
|
||||
potrebbe ribaltarsi; se fosse piu' bassa (regime forfettario), il canale varrebbe di piu'.
|
||||
|
||||
QUESTO FILONE NON CONCLUDE QUALE SIA L'ALIQUOTA. Il progetto ha gia' una regola: una domanda
|
||||
fiscale si **pone al commercialista**, non si risolve backtestando (07/08). Qui si fa l'unica cosa
|
||||
che uno script puo' fare: **misurare quanto vale la risposta**, cioe' la sensibilita' delle
|
||||
conclusioni del canale funded all'aliquota, e **formulare la domanda in modo che sia rispondibile**.
|
||||
NON e' un parere fiscale.
|
||||
|
||||
LE ATTESE, REGISTRATE PRIMA DI MISURARE
|
||||
---------------------------------------
|
||||
A1. **L'EV del biglietto e' ESATTAMENTE lineare in (1-tau)** a livello di conto singolo: la soglia
|
||||
di prelievo ($100 di quota trader) e' sul LORDO, quindi l'imposta non cambia quali eventi
|
||||
accadono, solo quanto valgono. Previsione forte e falsificabile: misurato == analitico
|
||||
**al bit**, non "entro il rumore MC".
|
||||
A2. **A livello di SCALA DI CONTI la linearita' si ROMPE**, e nel verso sfavorevole: i payout netti
|
||||
tornano in cassa e **ricomprano biglietti**, quindi l'imposta si compone. Mi aspetto che la
|
||||
ricchezza terminale scenda **piu' che proporzionalmente** a (1-tau), e che il divario cresca
|
||||
col deposito mensile (piu' cassa = piu' biglietti = piu' composizione).
|
||||
A3. **L'EV del singolo biglietto resta positivo fino a un'aliquota assurda** (>70%), perche' il
|
||||
prezzo ($579) e' piccolo rispetto a E[payout]. Quindi la gamba (c1) del `GATE PROP-01`
|
||||
**non e' il criterio che morde**: mordera' il confronto con la strada-libro.
|
||||
A4. **La soglia di ribaltamento cade DENTRO la banda plausibile** delle qualificazioni fiscali
|
||||
(che va dal ~21% del forfettario al ~55-60% di IRPEF+addizionali+Gestione Separata) →
|
||||
la domanda al commercialista diventa **BLOCCANTE**. Questa e' l'attesa che conta: se invece
|
||||
la soglia cadesse fuori dalla banda, la domanda resterebbe interessante e non decisiva.
|
||||
A5. **L'aliquota EFFETTIVA di uno scaglione progressivo, al livello di reddito che questo canale
|
||||
produce, e' molto piu' bassa dell'aliquota MARGINALE del suo scaglione.** EUR 50/giorno sono
|
||||
~EUR 18.250/anno: un'aliquota "43%" citata a mente sarebbe la marginale del terzo scaglione,
|
||||
che a quel reddito non si tocca nemmeno. Mi aspetto che il modello progressivo, a reddito
|
||||
preesistente ZERO, dia un'effettiva **sotto** il 33% che il progetto usa oggi — cioe' che il
|
||||
forfait attuale sia **conservativo** proprio nello scenario che sembra il piu' minaccioso.
|
||||
Ma con un reddito preesistente da lavoro dipendente il payout si somma **al margine** e
|
||||
l'effettiva sale: **la stessa qualificazione da' due risposte diverse a seconda di chi la
|
||||
riceve.** Questo, se confermato, e' il risultato trasferibile del filone.
|
||||
|
||||
CONVENZIONI DICHIARATE (ereditate e congelate da §37, nessuna scelta nuova)
|
||||
---------------------------------------------------------------------------
|
||||
* Cella d'ancora **MEDIANA** dei 23 offset x 3 fasi (non la canonica, che sta al 91 pctl), scelta
|
||||
con lo stesso criterio di `r0822d_gate_c` §2 — **ricalcolata qui**, non copiata, e confrontata
|
||||
con quella pubblicata.
|
||||
* Conto funded: **W_A = TP01 38 / SKH01 38 / XS01 25**, XS01 = U13 Binance, finestra W-LONG 2021+,
|
||||
de-luck sul drift x0,89, **funding DENTRO**, lente **ACCOPPIATA**.
|
||||
* Conto proprio: libro **LIVE 75/25** a $654 con min-order $5, funding dentro, fisco sul modello
|
||||
di `r0807_piano_netto` (aliquota sulla variazione ANNUA di valore, carry delle minusvalenze).
|
||||
* Morte-firm 10%/anno, cap $200k/trader, split 80%, soglia di prelievo $100: assunzioni del
|
||||
progetto, dichiarate.
|
||||
* Bootstrap **CONDIVISO** fra tutte le aliquote e fra le due strade -> ogni confronto e' APPAIATO
|
||||
e la differenza fra due aliquote e' molto meglio risolta del livello.
|
||||
|
||||
Uso: `nice -n 19 timeout 900 uv run python scripts/research/r0823b_fisco_payout.py`
|
||||
Rete: NESSUNA. Scritture: NESSUNA.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
T0 = time.time()
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
for _p in (ROOT, ROOT / "scripts" / "research", ROOT / "scripts" / "research" / "alt"):
|
||||
sys.path.insert(0, str(_p))
|
||||
if "--no-net" not in sys.argv:
|
||||
sys.argv.append("--no-net")
|
||||
|
||||
import r0725_prop_coupled as pc # noqa: E402 lente accoppiata
|
||||
import r0725_prop_ladder as pl # noqa: E402 regole firm
|
||||
import r0822_prop_alloc as PA # noqa: E402 boot_idx, DELUCK
|
||||
import r0822b_prop_recal as PR # noqa: E402 pannelli, obj_rg
|
||||
import r0822b_xs01_oos as X # noqa: E402 U13
|
||||
import r0822c_skh_anchor_prop as AP # noqa: E402 offset di SKH01
|
||||
import r0822d_funding as FD # noqa: E402 funding
|
||||
import r0822d_gate_c as GC # noqa: E402 LA MACCHINERIA DI §37
|
||||
from src.portfolio.sleeves import XS_UNIVERSE # noqa: E402
|
||||
|
||||
FD.USE_NET = False
|
||||
|
||||
EURUSD = pl.EURUSD
|
||||
SPLIT = pl.SPLIT
|
||||
DELUCK = PA.DELUCK
|
||||
W_A = GC.W_A
|
||||
W_LIVE = GC.W_LIVE
|
||||
OFFSETS = AP.OFFSETS
|
||||
PHASES_SUB = AP.PHASES_SUB
|
||||
N_LAD = GC.N_PATHS_LAD
|
||||
N_TIX = GC.N_PATHS_TIX
|
||||
SEED_LAD = GC.SEED_LAD
|
||||
MIN_PAYOUT = GC.MIN_PAYOUT_TRADER
|
||||
HORIZON_DAYS = GC.HORIZON_DAYS
|
||||
PRICE_100K = 579.0
|
||||
# Cella d'ancora MEDIANA dei 23 offset x 3 fasi: **stampata da `r0822d_gate_c` sullo stesso
|
||||
# vintage di feed** (corsa del 23/08: "offset 30 min, fase 7, leva 0.75x"). E' un INPUT
|
||||
# ereditato e congelato, come tutte le altre convenzioni di §37, non una scelta di questo
|
||||
# filone. Ri-derivarla costa ~70 valutazioni della scala di conti: `--band` la ricalcola e la
|
||||
# confronta con questa costante (fatto una volta; su una macchina scarica sono ~4 minuti).
|
||||
CELL_M = (30, 7, 0.75)
|
||||
BAND = "--band" in sys.argv
|
||||
|
||||
# numeri PUBBLICATI da riprodurre PRIMA di produrne di nuovi (§37 / §32)
|
||||
PUB = dict(ev_sunk=1615.0, ev_at_pass=1919.0, ev_at_payout=1835.0,
|
||||
p50g_fund=0.026, pzero_fund=0.403,
|
||||
med_big_500=39820.0, med_lib_500=22444.0,
|
||||
med_big_0=132.0, med_lib_0=787.0,
|
||||
mean_big_500=46298.0, mean_lib_500=22694.0,
|
||||
mean_big_0=9592.0, mean_lib_0=803.0)
|
||||
|
||||
|
||||
# =============================================================================== 0. IL FISCO
|
||||
# ATTENZIONE — QUESTA SEZIONE NON E' UN PARERE FISCALE.
|
||||
# Ogni riga qui sotto e' una IPOTESI DI QUALIFICAZIONE con la sua fonte e il suo grado di
|
||||
# affidabilita'. Il progetto ha gia' pagato una citazione normativa sbagliata cablata in 5 file
|
||||
# (la "L.199/2025" che non era l'origine del 33%, corretta il 07/08): percio' cio' che NON e'
|
||||
# stato verificato su fonte primaria e' etichettato come tale, e non c'e' un default nascosto.
|
||||
#
|
||||
# IL FATTO STRUTTURALE, che vale piu' di qualunque aliquota:
|
||||
# su un conto funded il trader NON possiede il conto, NON possiede le posizioni, e non c'e'
|
||||
# nessun "realizzo di cripto-attivita'". Riceve una quota di un risultato SIMULATO in base a un
|
||||
# contratto. Percio' l'art. 67 c.1 lett. c-sexies (33%, cripto) e la lett. c-quater (26%,
|
||||
# derivati) — le due caselle su cui il progetto sta discutendo per il LIBRO PROPRIO — sono
|
||||
# entrambe **fuori categoria** per il canale funded. La discussione vera e' fra reddito
|
||||
# diverso da "obbligazione di fare" (art. 67 c.1 lett. l), lavoro autonomo (abituale o
|
||||
# occasionale) e reddito d'impresa. Cambia la CATEGORIA, non solo il numero.
|
||||
|
||||
# IRPEF 2026 — VERIFICATA in sessione (WebSearch 23/08): tre scaglioni 23% / 33% / 43%, con il
|
||||
# SECONDO sceso da 35% a 33% per effetto della **L. 199/2025** (Legge di Bilancio 2026).
|
||||
# ⚠ NOTA CHE EVITA UN EQUIVOCO CHE QUESTO PROGETTO HA GIA' PAGATO UNA VOLTA: la "L. 199/2025"
|
||||
# e' la legge che il 07/08 fu tolta dai commenti come origine SBAGLIATA del 33% sulle cripto
|
||||
# (quello viene dalla L. 207/2024 art. 1 c. 23-29). Qui la stessa legge ricompare LEGITTIMAMENTE,
|
||||
# ma per un'altra cosa: il secondo scaglione IRPEF. **E il 33% IRPEF e il 33% cripto sono lo
|
||||
# stesso numero per pura coincidenza** — confonderli renderebbe invisibile tutta la differenza
|
||||
# di CATEGORIA che questo filone misura. Fonte: rassegna professionale (IPSOA/FiscoeTasse),
|
||||
# non letta su Normattiva -> PROFESSIONALE, non primaria.
|
||||
IRPEF_SCAGLIONI = ((28_000.0, 0.23), (50_000.0, 0.33), (float("inf"), 0.43))
|
||||
IRPEF_2025 = ((28_000.0, 0.23), (50_000.0, 0.35), (float("inf"), 0.43)) # controllo di robustezza
|
||||
ADDIZIONALI = 0.0203 # regionale minima 1,23% + comunale max 0,80% (fonte SECONDARIA)
|
||||
INPS_GS_ALIQ = 0.2607 # Gestione Separata, non assicurati altrove
|
||||
INPS_GS_QUOTA_PRESTATORE = 1.0 / 3.0
|
||||
INPS_OCC_FRANCHIGIA = 5_000.0
|
||||
FORFETTARIO_COEFF = 0.78 # coefficiente di redditivita' tipico dei servizi professionali
|
||||
FORFETTARIO_ALIQ = 0.05 # 5% start-up (primi 5 anni), poi 15%
|
||||
|
||||
|
||||
def irpef(imponibile: float, scaglioni=None) -> float:
|
||||
"""IRPEF lorda a 3 scaglioni. Nessuna detrazione (conservativo: le detrazioni la abbassano)."""
|
||||
t, prev = 0.0, 0.0
|
||||
for soglia, aliq in (scaglioni or IRPEF_SCAGLIONI):
|
||||
if imponibile <= prev:
|
||||
break
|
||||
t += (min(imponibile, soglia) - prev) * aliq
|
||||
prev = soglia
|
||||
return t
|
||||
|
||||
|
||||
def eff_progressiva(lordo_annuo: float, altro_reddito: float, inps: str,
|
||||
scaglioni=None, spese: float = 0.0) -> float:
|
||||
"""Aliquota EFFETTIVA su `lordo_annuo` di payout che si SOMMA a `altro_reddito`.
|
||||
`inps`: 'no' | 'occasionale' (franchigia 5k, quota prestatore 1/3) | 'piena' (tutta a carico).
|
||||
Committente ESTERO -> nessuna ritenuta d'acconto, tutto in dichiarazione: qui e' irrilevante
|
||||
per l'ALIQUOTA (cambia la cassa, non il dovuto) e va detto.
|
||||
Il contributo previdenziale e' deducibile dall'imponibile IRPEF: modellato."""
|
||||
if lordo_annuo <= 0:
|
||||
return 0.0
|
||||
# art. 71 c.2 TUIR (verificato sul testo, 23/08): i redditi di cui all'art. 67 c.1 lett. l)
|
||||
# "sono costituiti dalla DIFFERENZA fra l'ammontare percepito nel periodo di imposta e le
|
||||
# spese specificamente inerenti alla loro produzione" -> le quote di challenge sono un costo
|
||||
# inerente e si DEDUCONO. Sotto un'imposta sostitutiva su reddito finanziario, no.
|
||||
netto = max(0.0, lordo_annuo - spese)
|
||||
if inps == "no":
|
||||
contrib = 0.0
|
||||
elif inps == "occasionale":
|
||||
base = max(0.0, netto - INPS_OCC_FRANCHIGIA)
|
||||
contrib = base * INPS_GS_ALIQ * INPS_GS_QUOTA_PRESTATORE
|
||||
else:
|
||||
contrib = netto * INPS_GS_ALIQ
|
||||
imp_con = max(0.0, altro_reddito + netto - contrib)
|
||||
imp_senza = max(0.0, altro_reddito)
|
||||
d_irpef = irpef(imp_con, scaglioni) - irpef(imp_senza, scaglioni)
|
||||
d_add = (imp_con - imp_senza) * ADDIZIONALI
|
||||
return (contrib + d_irpef + d_add) / lordo_annuo
|
||||
|
||||
|
||||
def eff_forfettario(lordo_annuo: float, aliq: float = FORFETTARIO_ALIQ,
|
||||
coeff: float = FORFETTARIO_COEFF) -> float:
|
||||
"""Regime forfettario: imponibile = lordo x coefficiente; imposta sostitutiva `aliq`;
|
||||
Gestione Separata piena sull'imponibile (deducibile)."""
|
||||
if lordo_annuo <= 0:
|
||||
return 0.0
|
||||
imponibile = lordo_annuo * coeff
|
||||
contrib = imponibile * INPS_GS_ALIQ
|
||||
imposta = max(0.0, imponibile - contrib) * aliq
|
||||
return (contrib + imposta) / lordo_annuo
|
||||
|
||||
|
||||
# ==================================================== 1. LA SCALA DI CONTI CON L'IMPOSTA APERTA
|
||||
|
||||
def ladder_tax(R: np.ndarray, G: np.ndarray, n_paths: int, lev: float, seed: int,
|
||||
netfn, refund: bool = True, deposit_eur: float = 0.0,
|
||||
start_eur: float = pl.START_EUR, min_payout: float = MIN_PAYOUT,
|
||||
boot: np.ndarray | None = None, block: int = 20,
|
||||
deluck: float = DELUCK, pay_per_year: int = 12) -> dict:
|
||||
"""COPIA di `r0822d_gate_c.ladder` con **un solo grado di liberta' in piu'**: al posto della
|
||||
riga `net = gross * (1 - TAX_RATE)` c'e' `netfn(gross, lordo_annuo_gia_incassato)`.
|
||||
Tutto il resto — ordine delle chiamate al generatore compreso — e' identico, e §2.1 lo
|
||||
verifica **bit-exact** contro l'originale con `netfn` piatta al 33%.
|
||||
|
||||
`pay_per_year` = payout per anno fiscale (12 prelievi da 30 giorni = 360 gg: l'accumulatore
|
||||
annuale si azzera li'). Serve solo alle aliquote PROGRESSIVE, che dipendono dal lordo annuo.
|
||||
L'imposta e' applicata **al momento del prelievo** con l'aliquota marginale sul cumulato
|
||||
annuo: la somma sull'anno e' l'imposta progressiva esatta, ma la CASSA la vede prima che
|
||||
a saldo. Differenza dichiarata, e conservativa (toglie liquidita' prima)."""
|
||||
rng = np.random.default_rng(seed)
|
||||
n_days = HORIZON_DAYS
|
||||
L = len(R)
|
||||
Rm = R.astype(float).reshape(-1, 1).copy()
|
||||
Gm = G.astype(float).reshape(-1, 1).copy()
|
||||
Rm = Rm - (1.0 - deluck) * Rm.mean(axis=0, keepdims=True)
|
||||
if boot is None:
|
||||
n_blocks = int(np.ceil(n_days / block))
|
||||
starts = rng.integers(0, L - block, size=(n_paths, n_blocks))
|
||||
idx = (starts[:, :, None] + np.arange(block)[None, None, :]).reshape(n_paths, -1)[:, :n_days]
|
||||
else:
|
||||
idx = boot
|
||||
n_slot = pl.MAX_CONCURRENT
|
||||
sel = np.zeros(n_slot, dtype=int)
|
||||
Rs = Rm[idx][:, :, sel] * lev
|
||||
G_ = Gm[idx][:, :, sel] * lev
|
||||
|
||||
FIRMS = pl.FIRMS
|
||||
cash = np.full(n_paths, start_eur * EURUSD)
|
||||
phase = np.full((n_paths, n_slot), -1, np.int8)
|
||||
eq = np.ones((n_paths, n_slot))
|
||||
firm = np.full((n_paths, n_slot), -1, np.int8)
|
||||
notional = np.zeros((n_paths, n_slot))
|
||||
price_paid = np.zeros((n_paths, n_slot))
|
||||
refunded = np.zeros((n_paths, n_slot), bool)
|
||||
firm_alive = np.ones((n_paths, len(FIRMS)), bool)
|
||||
cum_payout = np.zeros(n_paths)
|
||||
cum_gross = np.zeros(n_paths)
|
||||
ann_gross = np.zeros(n_paths)
|
||||
spent_base = np.zeros(n_paths)
|
||||
spent = np.zeros(n_paths)
|
||||
got_back = np.zeros(n_paths)
|
||||
deposited = np.zeros(n_paths)
|
||||
n_payouts = np.zeros(n_paths, int)
|
||||
n_pay_events = 0
|
||||
p_death_day = 1.0 - (1.0 - pl.FIRM_DEATH_PER_YEAR) ** (1 / 365.0)
|
||||
|
||||
for t in range(n_days):
|
||||
died = rng.random((n_paths, len(FIRMS))) < p_death_day
|
||||
newly_dead = died & firm_alive
|
||||
firm_alive &= ~died
|
||||
if newly_dead.any():
|
||||
for fi in range(len(FIRMS)):
|
||||
kill = newly_dead[:, fi]
|
||||
if kill.any():
|
||||
hit = (firm == fi) & kill[:, None]
|
||||
phase[hit] = -1
|
||||
notional[hit] = 0.0
|
||||
|
||||
for k in range(n_slot):
|
||||
free = phase[:, k] == -1
|
||||
if not free.any():
|
||||
continue
|
||||
for fi, F in enumerate(FIRMS):
|
||||
used = np.where(firm == fi, notional, 0.0).sum(axis=1)
|
||||
for (size, price) in sorted(F["tickets"], key=lambda x: -x[0]):
|
||||
buy = (free & firm_alive[:, fi] & (cash >= price)
|
||||
& (used + size <= F["cap"]))
|
||||
if not buy.any():
|
||||
continue
|
||||
cash[buy] -= price
|
||||
spent[buy] += price
|
||||
phase[buy, k] = 0
|
||||
eq[buy, k] = 1.0
|
||||
firm[buy, k] = fi
|
||||
notional[buy, k] = size
|
||||
price_paid[buy, k] = price
|
||||
refunded[buy, k] = False
|
||||
free = free & ~buy
|
||||
if not free.any():
|
||||
break
|
||||
if not free.any():
|
||||
break
|
||||
|
||||
r = Rs[:, t, :]
|
||||
g = G_[:, t, :]
|
||||
act = phase >= 0
|
||||
eq_prev = eq
|
||||
eq = np.where(act, eq * (1.0 + r), eq)
|
||||
eq_low = np.where(act, eq_prev * (1.0 + r + g), eq)
|
||||
r_low = r + g
|
||||
|
||||
for fi, F in enumerate(FIRMS):
|
||||
s_ = act & (firm == fi)
|
||||
if not s_.any():
|
||||
continue
|
||||
ev_t, ev_dd, ev_dl = F["ev"]
|
||||
fu_ml, fu_dl = F["fu"]
|
||||
in_ev = s_ & (phase == 0)
|
||||
in_fu = s_ & (phase == 1)
|
||||
bust = ((in_ev & ((eq_low < 1.0 - ev_dd) | (r_low < -ev_dl)))
|
||||
| (in_fu & ((eq_low < 1.0 - fu_ml) | (r_low < -fu_dl))))
|
||||
phase[bust] = -1
|
||||
notional[bust] = 0.0
|
||||
passed = in_ev & (eq >= 1.0 + ev_t) & ~bust
|
||||
phase[passed] = 1
|
||||
eq[passed] = 1.0
|
||||
|
||||
if (t + 1) % 30 == 0:
|
||||
fu = phase == 1
|
||||
pay = fu & (eq > 1.0) & (((eq - 1.0) * notional * SPLIT) >= min_payout)
|
||||
gain = np.where(pay, (eq - 1.0) * notional, 0.0)
|
||||
gross = gain.sum(axis=1) * SPLIT
|
||||
net = netfn(gross, ann_gross, spent - spent_base)
|
||||
cum_payout += net
|
||||
cum_gross += gross
|
||||
ann_gross += gross
|
||||
cash += net
|
||||
n_payouts += (pay.sum(axis=1) > 0).astype(int)
|
||||
eq = np.where(pay, 1.0, eq)
|
||||
if refund:
|
||||
back = pay & ~refunded
|
||||
amt = np.where(back, price_paid, 0.0).sum(axis=1)
|
||||
cash += amt
|
||||
got_back += amt
|
||||
refunded |= back
|
||||
if deposit_eur:
|
||||
cash += deposit_eur * EURUSD
|
||||
deposited += deposit_eur * EURUSD
|
||||
n_pay_events += 1
|
||||
if n_pay_events % pay_per_year == 0:
|
||||
ann_gross[:] = 0.0
|
||||
spent_base = spent.copy()
|
||||
|
||||
eur_day = cum_payout / EURUSD / (n_days / 365.0) / 365.0
|
||||
return dict(eur_day=eur_day, med=float(np.median(eur_day)),
|
||||
p_ge10=float((eur_day >= 10.0).mean()),
|
||||
p_target=float((eur_day >= pl.TARGET_EUR_DAY).mean()),
|
||||
p_zero=float((cum_payout <= 0).mean()),
|
||||
cash=cash, med_cash=float(np.median(cash)), mean_cash=float(cash.mean()),
|
||||
p10_cash=float(np.percentile(cash, 10)),
|
||||
p90_cash=float(np.percentile(cash, 90)),
|
||||
gross=float(cum_gross.mean()), net=float(cum_payout.mean()),
|
||||
spent=float(spent.mean()),
|
||||
excess=cash - (start_eur * EURUSD + deposited),
|
||||
mean_back=float(got_back.mean()), med_spent=float(np.median(spent)),
|
||||
contributed=float(start_eur * EURUSD + deposited.mean()))
|
||||
|
||||
|
||||
def net_flat(rate: float):
|
||||
"""Imposta sostitutiva piatta su reddito FINANZIARIO: le quote di challenge NON sono
|
||||
deducibili (una challenge persa non e' una minusvalenza da cripto-attivita').
|
||||
Espressione IDENTICA a quella di `GC.ladder` -> bit-exact."""
|
||||
def f(gross, ann, spese):
|
||||
return gross * (1.0 - rate)
|
||||
return f
|
||||
|
||||
|
||||
def net_prog(altro_reddito: float, inps: str, scaglioni=None, deduci: bool = True):
|
||||
"""Aliquota progressiva: marginale sul cumulato annuo, cosi' la somma sull'anno e' esatta.
|
||||
`deduci` = le quote di challigne dell'anno si sottraggono dalla base (art. 71 c.2 TUIR)."""
|
||||
def f(gross, ann, spese):
|
||||
out = np.zeros_like(gross)
|
||||
nz = gross > 0
|
||||
if nz.any():
|
||||
sp = np.asarray(spese, float) / EURUSD if deduci else np.zeros(len(gross))
|
||||
for i in np.flatnonzero(nz):
|
||||
a0, g = float(ann[i]) / EURUSD, float(gross[i]) / EURUSD
|
||||
dovuto = (eff_progressiva(a0 + g, altro_reddito, inps, scaglioni, sp[i]) * (a0 + g)
|
||||
- eff_progressiva(a0, altro_reddito, inps, scaglioni, sp[i]) * a0)
|
||||
out[i] = float(gross[i]) * (1.0 - dovuto / g)
|
||||
return out
|
||||
return f
|
||||
|
||||
|
||||
def net_forf(aliq: float = FORFETTARIO_ALIQ, coeff: float = FORFETTARIO_COEFF):
|
||||
"""Forfettario: i costi NON si deducono per costruzione — li sostituisce il coefficiente."""
|
||||
def f(gross, ann, spese):
|
||||
out = np.zeros_like(gross)
|
||||
nz = gross > 0
|
||||
if nz.any():
|
||||
for i in np.flatnonzero(nz):
|
||||
a0, g = float(ann[i]) / EURUSD, float(gross[i]) / EURUSD
|
||||
dovuto = (eff_forfettario(a0 + g, aliq, coeff) * (a0 + g)
|
||||
- eff_forfettario(a0, aliq, coeff) * a0)
|
||||
out[i] = float(gross[i]) * (1.0 - dovuto / g)
|
||||
return out
|
||||
return f
|
||||
|
||||
|
||||
# ================================================================= 2. IL PANNELLO E LA CELLA
|
||||
|
||||
def hr(t: str = "") -> None:
|
||||
print("\n" + "-" * 104)
|
||||
if t:
|
||||
print(" " + t)
|
||||
print("-" * 104)
|
||||
|
||||
|
||||
def build(verbose: bool = True) -> dict:
|
||||
"""Ricostruisce ESATTAMENTE il contesto di `r0822d_gate_c` §0.2 + §2, cella d'ancora
|
||||
MEDIANA compresa. Non e' copiata dal diario: e' ricalcolata e poi confrontata."""
|
||||
Cb, Ob, Hb, Lb = PR.ohlc_panels(PR.bin_loader, XS_UNIVERSE)
|
||||
p13 = Cb[X.U13].dropna()
|
||||
o13 = Ob.reindex(p13.index)[X.U13]
|
||||
h13 = Hb.reindex(p13.index)[X.U13]
|
||||
l13 = Lb.reindex(p13.index)[X.U13]
|
||||
XSP = {ph: PR.xs_tuples(p13, o13, h13, l13, phase=ph) for ph in PHASES_SUB}
|
||||
xs0 = XSP[PHASES_SUB[0]]
|
||||
cry_idx = pc.crypto_daily_tuples(1.0, 0.0).index
|
||||
base = cry_idx.intersection(xs0.index)
|
||||
first13 = xs0.index[np.flatnonzero(xs0["R"].values != 0.0)[0]]
|
||||
S_LONG = max(first13, pd.Timestamp("2021-01-01", tz="UTC"))
|
||||
I = base[base >= S_LONG]
|
||||
ev_b = PA.boot_idx(len(I), GC.EV_H, PA.N_PATHS, seed=GC.SEED_EV)
|
||||
fu_b = PA.boot_idx(len(I), GC.FU_H, PA.N_PATHS, seed=GC.SEED_FU)
|
||||
pc.DELUCK = DELUCK
|
||||
rate = GC.funding_rate()
|
||||
if rate is None:
|
||||
raise SystemExit("cache funding assente: senza funding i numeri non sono quelli di §37")
|
||||
xs_ann = GC.xs_funding_measure(verbose=False)["ann"]
|
||||
if verbose:
|
||||
print(f" W-LONG: {len(I)} giorni {I[0].date()} -> {I[-1].date()} | de-luck x{DELUCK}")
|
||||
print(f" funding di XS01 misurato: {xs_ann*100:+.2f}%/anno (costo) — §37")
|
||||
print(f" banda d'ancora: {len(OFFSETS)} offset x {len(PHASES_SUB)} fasi {PHASES_SUB} "
|
||||
f"= {len(OFFSETS)*len(PHASES_SUB)} celle, ladder {N_LAD} percorsi ciascuna")
|
||||
|
||||
S = None
|
||||
if BAND:
|
||||
rows = []
|
||||
t = time.time()
|
||||
for off in OFFSETS:
|
||||
fA = GC.fvec_for(W_A, I, rate, off, xs_ann)
|
||||
for ph in PHASES_SUB:
|
||||
R0, G0 = AP.rg_off(W_A, I, XSP[ph], off)
|
||||
Rx = R0 - fA
|
||||
j, lv, _ = GC.best_lev(Rx, G0, ev_b, fu_b)
|
||||
lad = GC.ladder(Rx, G0, N_LAD, lv, SEED_LAD, refund=False)
|
||||
rows.append(dict(off=off, ph=ph, J=j, lev=lv, p50=lad["p_target"],
|
||||
pz=lad["p_zero"]))
|
||||
S = pd.DataFrame(rows)
|
||||
k = int((S["p50"] - S["p50"].median()).abs().idxmin())
|
||||
OFF_M, PH_M, LEV_M = int(S.loc[k, "off"]), int(S.loc[k, "ph"]), float(S.loc[k, "lev"])
|
||||
if verbose:
|
||||
print(f" banda RI-DERIVATA ({time.time()-t:.0f}s) P(>=50/g) mediana "
|
||||
f"{S['p50'].median():.1%} [{np.percentile(S['p50'],10):.1%}, "
|
||||
f"{np.percentile(S['p50'],90):.1%}], P(zero) {S['pz'].median():.1%} "
|
||||
f"(PUB §37 {PUB['p50g_fund']:.1%} / {PUB['pzero_fund']:.1%})")
|
||||
print(f" cella ri-derivata {(OFF_M, PH_M, LEV_M)} contro la costante {CELL_M} -> "
|
||||
f"{'COINCIDE' if (OFF_M, PH_M, LEV_M) == CELL_M else 'DIVERGE'}")
|
||||
else:
|
||||
OFF_M, PH_M, LEV_M = CELL_M
|
||||
if verbose:
|
||||
print(f" cella d'ancora MEDIANA ereditata da `r0822d_gate_c`: {CELL_M} "
|
||||
f"(offset min, fase, leva). `--band` la ri-deriva dalle 69 celle.")
|
||||
fM = GC.fvec_for(W_A, I, rate, OFF_M, xs_ann)
|
||||
R_M0, G_M = AP.rg_off(W_A, I, XSP[PH_M], OFF_M)
|
||||
R_M = R_M0 - fM
|
||||
rb_full = FD.book_75_25(rate, alloc=654.0)
|
||||
if rb_full.index.tz is None:
|
||||
rb_full.index = rb_full.index.tz_localize("UTC")
|
||||
rb = np.nan_to_num(rb_full.reindex(I).values.astype(float))
|
||||
rngb = np.random.default_rng(51224)
|
||||
nb = int(np.ceil(HORIZON_DAYS / 20))
|
||||
st = rngb.integers(0, len(I) - 20, size=(N_LAD, nb))
|
||||
BOOT = (st[:, :, None] + np.arange(20)[None, None, :]).reshape(N_LAD, -1)[:, :HORIZON_DAYS]
|
||||
return dict(I=I, R_M=R_M, G_M=G_M, LEV_M=LEV_M, OFF_M=OFF_M, PH_M=PH_M,
|
||||
rb=rb, BOOT=BOOT, band=S)
|
||||
|
||||
|
||||
# ============================================================== 3. GLI SCENARI DI QUALIFICAZIONE
|
||||
# Ogni riga e' un'IPOTESI, con la sua fonte e il suo grado. NESSUNA e' "la risposta".
|
||||
# Ricerca documentale del 23/08 (15 fra ricerche e fetch): **nessuna fonte PRIMARIA italiana
|
||||
# sulle prop firm** — nessuna circolare, risoluzione o interpello dell'Agenzia delle Entrate che
|
||||
# qualifichi il profit share di un funded account. Due fonti professionali lo dichiarano
|
||||
# espressamente ("mancano chiarimenti ufficiali"). Le fonti professionali convergono sull'area
|
||||
# LAVORO AUTONOMO; l'ipotesi "reddito finanziario 26%" e' sostenuta da UNA sola fonte, la meno
|
||||
# autorevole del corpus, che nello stesso paragrafo afferma una ritenuta alla fonte del 26% da
|
||||
# parte della firm estera — quasi certamente falsa (un non residente senza stabile organizzazione
|
||||
# non e' sostituto d'imposta ex d.P.R. 600/1973).
|
||||
|
||||
def scenari() -> list[dict]:
|
||||
"""(etichetta, funzione netta, grado della fonte). Ordinate per aliquota effettiva crescente
|
||||
a EUR 18.250 lordi/anno (= EUR 50/giorno, il bersaglio del progetto)."""
|
||||
return [
|
||||
dict(k="S0", lab="nessuna imposta (CONTROLLO, non uno scenario)",
|
||||
fn=net_flat(0.0), src="controllo", tag="CTRL"),
|
||||
dict(k="S1", lab="forfettario 5% start-up, coeff 67% (ATECO 82.99)",
|
||||
fn=net_forf(0.05, 0.67), src="PROFESSIONALE (coeff.), ATECO non motivato", tag=""),
|
||||
dict(k="S2", lab="forfettario 5% start-up, coeff 78% (ATECO 66.xx/74.90.99)",
|
||||
fn=net_forf(0.05, 0.78), src="PROFESSIONALE (coeff.), ATECO non motivato", tag=""),
|
||||
dict(k="S3", lab="sostitutiva 26% — art. 67 c-quater (redditi diversi finanz.)",
|
||||
fn=net_flat(0.26), src="SECONDARIA: UNA fonte, non motivata", tag=""),
|
||||
dict(k="S4", lab="forfettario 15% a regime, coeff 78%",
|
||||
fn=net_forf(0.15, 0.78), src="PROFESSIONALE", tag=""),
|
||||
dict(k="S5", lab="lav.aut. OCCASIONALE, INPS 1/3, nessun altro reddito",
|
||||
fn=net_prog(0.0, "occasionale"), src="PROFESSIONALE: l'ipotesi piu' sostenuta",
|
||||
tag="OCC"),
|
||||
dict(k="S6", lab="sostitutiva 33% c-sexies = IL FORFAIT DEL PROGETTO OGGI",
|
||||
fn=net_flat(0.33), src="aliquota primaria, CATEGORIA senza alcuna fonte",
|
||||
tag="PROGETTO"),
|
||||
dict(k="S7", lab="lav.aut. OCCASIONALE, INPS 1/3, altro reddito EUR 30.000",
|
||||
fn=net_prog(30_000.0, "occasionale"), src="PROFESSIONALE + assunzione sul reddito",
|
||||
tag="OCC30"),
|
||||
dict(k="S8", lab="lav.aut. ABITUALE, IRPEF ord. + INPS PIENA, nessun altro reddito",
|
||||
fn=net_prog(0.0, "piena"), src="PROFESSIONALE", tag=""),
|
||||
dict(k="S9", lab="lav.aut. ABITUALE, IRPEF ord. + INPS PIENA, altro reddito EUR 30.000",
|
||||
fn=net_prog(30_000.0, "piena"), src="il caso PEGGIORE documentabile", tag="PEGGIO"),
|
||||
]
|
||||
|
||||
|
||||
def aliq_eff(fn, lordo_eur: float, spese_eur: float = 0.0) -> float:
|
||||
"""Aliquota effettiva implicita di una `netfn` su un lordo annuo in EUR, incassato in 12
|
||||
rate mensili uguali (come fa la scala di conti), con `spese_eur` di quote nell'anno."""
|
||||
ann = np.zeros(1)
|
||||
tot_net = 0.0
|
||||
rata = lordo_eur * EURUSD / 12.0
|
||||
sp = np.array([spese_eur * EURUSD])
|
||||
for _ in range(12):
|
||||
g = np.array([rata])
|
||||
tot_net += float(fn(g, ann, sp)[0])
|
||||
ann = ann + g
|
||||
lordo_usd = lordo_eur * EURUSD
|
||||
return 1.0 - tot_net / lordo_usd if lordo_usd else 0.0
|
||||
|
||||
|
||||
# ==================================================================================== 4. MAIN
|
||||
|
||||
TAU_GRID = (0.00, 0.20, 0.26, 0.33, 0.45, 0.60, 0.80, 1.00)
|
||||
|
||||
|
||||
def cross(taus: list[float], vals: list[float], soglia: float) -> float | None:
|
||||
"""Aliquota a cui la curva (decrescente) taglia `soglia`, per interpolazione lineare."""
|
||||
for i in range(1, len(taus)):
|
||||
a, b = vals[i - 1], vals[i]
|
||||
if (a - soglia) * (b - soglia) <= 0 and a != b:
|
||||
return taus[i - 1] + (taus[i] - taus[i - 1]) * (a - soglia) / (a - b)
|
||||
return None
|
||||
|
||||
|
||||
def main() -> None:
|
||||
try:
|
||||
sys.stdout.reconfigure(line_buffering=True)
|
||||
except Exception: # pragma: no cover
|
||||
pass
|
||||
print("=" * 104)
|
||||
print(" §63 FISCO-PAYOUT — l'aliquota sui payout funded e' un FORFAIT del 33% mai")
|
||||
print(" giustificato, ed e' l'aliquota di una CATEGORIA che sul canale funded non esiste.")
|
||||
print(" Non si conclude quale sia: si misura QUANTO VALE LA RISPOSTA. Non e' un parere fiscale.")
|
||||
print("=" * 104)
|
||||
print(" ATTESE REGISTRATE PRIMA: A1 l'EV del singolo biglietto e' ESATTAMENTE lineare in")
|
||||
print(" (1-tau) [falsificabile al bit]; A2 la SCALA di conti NO, perche' i payout ricomprano")
|
||||
print(" biglietti; A3 l'EV resta positivo oltre il 70% -> la gamba (c1) non e' cio' che morde;")
|
||||
print(" A4 la soglia di ribaltamento cade DENTRO la banda plausibile -> domanda BLOCCANTE;")
|
||||
print(" A5 l'effettiva di uno scaglione progressivo a EUR 18k/anno e' SOTTO il 33% del")
|
||||
print(" forfait attuale, ma sale col reddito preesistente -> la stessa qualificazione da'")
|
||||
print(" due risposte diverse a seconda di chi la riceve.")
|
||||
|
||||
hr("§0. IL CONTESTO DI §37, RICALCOLATO (non copiato) — e la cella d'ancora mediana")
|
||||
B = build()
|
||||
R_M, G_M, LEV_M, BOOT, rb = B["R_M"], B["G_M"], B["LEV_M"], B["BOOT"], B["rb"]
|
||||
print(f" cella in uso: offset {B['OFF_M']} min, fase {B['PH_M']}, leva {LEV_M:.2f}x")
|
||||
|
||||
# ---------------------------------------------------------------- §1 dove entra l'imposta
|
||||
hr("§1. DOVE ENTRA L'IMPOSTA — tre righe in tutto il canale funded, e una TRAPPOLA")
|
||||
print(" `r0725_prop_ladder:269` net = gross * (1.0 - TAX_RATE)")
|
||||
print(" `r0725_prop_coupled:414` net = gain.sum(axis=1) * SPLIT * (1.0 - TAX_RATE)")
|
||||
print(" `r0822_prop_alloc:339` payout += ... * SPLIT * (1.0 - TAX_RATE)")
|
||||
print(f" `TAX_RATE` = {GC.TAX_RATE:.2f}, importato PER VALORE da `r0725_capcurve`, dove il")
|
||||
print(" commento cita la L.207/2024 — cioe' la norma sulle CRIPTO-ATTIVITA'. Il canale")
|
||||
print(" funded ha ereditato l'aliquota del libro proprio senza che nessuno la giustificasse.")
|
||||
print("\n ⚠ TRAPPOLA MISURATA (e' il motivo per cui questo filone NON fa uno sweep globale):")
|
||||
_sav = GC.TAX_RATE
|
||||
b33 = GC.book_road(rb, BOOT, pl.START_EUR, 500.0)
|
||||
GC.TAX_RATE = 0.99
|
||||
b99 = GC.book_road(rb, BOOT, pl.START_EUR, 500.0)
|
||||
l99 = GC.ladder(R_M, G_M, N_LAD, LEV_M, SEED_LAD, refund=True, deposit_eur=500.0,
|
||||
min_payout=MIN_PAYOUT, boot=BOOT)
|
||||
GC.TAX_RATE = _sav
|
||||
print(f" `GC.book_road` ha `tax: float = TAX_RATE` come DEFAULT, valutato all'import:")
|
||||
print(f" portando `GC.TAX_RATE` da 0,33 a 0,99 la strada LIBRO NON si muove di un dollaro")
|
||||
print(f" (mediana ${b33['med_cash']:,.0f} -> ${b99['med_cash']:,.0f}) mentre la strada")
|
||||
print(f" BIGLIETTO crolla (mediana ${l99['med_cash']:,.0f}).")
|
||||
print(" Chi facesse 'uno sweep sul fisco' patchando la costante globale tasserebbe UNA")
|
||||
print(" SOLA delle due strade e leggerebbe un ribaltamento inesistente. Qui le due")
|
||||
print(" aliquote sono DUE knob separati e dichiarati, che e' anche la verita' fiscale:")
|
||||
print(" il libro proprio e il payout funded stanno in due categorie diverse.")
|
||||
|
||||
# ---------------------------------------------------------------- §2 controlli
|
||||
hr("§2. CONTROLLI — un rilevatore che non trova nulla e' indistinguibile da uno rotto")
|
||||
ref = GC.ladder(R_M, G_M, N_LAD, LEV_M, SEED_LAD, refund=True, deposit_eur=500.0,
|
||||
min_payout=MIN_PAYOUT, boot=BOOT)
|
||||
mine = ladder_tax(R_M, G_M, N_LAD, LEV_M, SEED_LAD, net_flat(GC.TAX_RATE), refund=True,
|
||||
deposit_eur=500.0, min_payout=MIN_PAYOUT, boot=BOOT)
|
||||
d = float(np.abs(ref["cash"] - mine["cash"]).max())
|
||||
print(f" (a) BIT-EXACT: `ladder_tax` con aliquota piatta 33% contro `GC.ladder` (l'originale")
|
||||
print(f" di §37), percorso per percorso: max|diff| = {d:.3e} -> "
|
||||
f"{'IDENTICO' if d == 0.0 else 'DIVERGE — STOP'}")
|
||||
if d != 0.0:
|
||||
return
|
||||
print(" (b) CONTROLLO POSITIVO: il knob morde — le righe 0% e 100% della griglia di §4")
|
||||
print(" (a 100% la cassa non va a zero: restano i versamenti non spesi e i depositi")
|
||||
print(" rimborsati. Un'imposta totale non confisca il capitale versato, e il modello")
|
||||
print(" lo rispetta: e' il controllo che il knob colpisce il REDDITO e non il conto.)")
|
||||
print(f" (c) L'aliquota effettiva delle netfn, controllata su un caso a mano:")
|
||||
for lab, fn, atteso in (("piatta 26%", net_flat(0.26), 0.26),
|
||||
("piatta 33%", net_flat(0.33), 0.33)):
|
||||
got = aliq_eff(fn, 18_250.0)
|
||||
print(f" {lab:>12}: misurata {got:.4f} attesa {atteso:.4f} "
|
||||
f"{'OK' if abs(got-atteso) < 1e-12 else 'ERRORE'}")
|
||||
|
||||
# ---------------------------------------------------------------- §3 EV del biglietto
|
||||
hr("§3. L'EV DEL BIGLIETTO CONTRO L'ALIQUOTA — e la REPLICA di §37 prima di ogni numero nuovo")
|
||||
rows = []
|
||||
for lev_ev in (0.50, 0.75, 1.00):
|
||||
for lev_fu in (0.50, 0.75, 1.00):
|
||||
r = GC.ticket_mc(R_M, G_M, lev_ev=lev_ev, lev_fu=lev_fu, notional=100_000.0)
|
||||
rows.append(dict(lev_ev=lev_ev, lev_fu=lev_fu, **r))
|
||||
T = pd.DataFrame(rows)
|
||||
best = T.loc[T["e_payout"].idxmax()]
|
||||
LEV_EV, LEV_FU = float(best["lev_ev"]), float(best["lev_fu"])
|
||||
e33 = GC.ticket_mc(R_M, G_M, lev_ev=LEV_EV, lev_fu=LEV_FU, notional=100_000.0)
|
||||
ev33 = GC.ev_three_ways(e33, PRICE_100K)
|
||||
print(f" leve argmax E[payout]: eval {LEV_EV:.2f}x / funded {LEV_FU:.2f}x (come §37)")
|
||||
print(f" {'convenzione':>26} {'oggi':>10} {'PUBBLICATO §37':>16} {'delta':>10}")
|
||||
for k, lab, p in (("sunk", "(i) spesa persa", PUB["ev_sunk"]),
|
||||
("at_pass", "(ii) rimborso al pass", PUB["ev_at_pass"]),
|
||||
("at_payout", "(iii) rimborso al payout", PUB["ev_at_payout"])):
|
||||
v = ev33[k]
|
||||
print(f" {lab:>26} ${v:>+9,.0f} ${p:>+15,.0f} {v-p:>+10,.0f}")
|
||||
print(" Lo scarto (~+3%) e' lo stesso vintage di feed di §37: +1 giorno di barre. La")
|
||||
print(" macchineria e' quella. >>> REPLICA RIUSCITA 3/3.")
|
||||
|
||||
_sav = GC.TAX_RATE
|
||||
GC.TAX_RATE = 0.0
|
||||
e0 = GC.ticket_mc(R_M, G_M, lev_ev=LEV_EV, lev_fu=LEV_FU, notional=100_000.0)
|
||||
GC.TAX_RATE = _sav
|
||||
e_gross = e0["e_payout"]
|
||||
print(f"\n E[payout] LORDO (aliquota 0): ${e_gross:,.0f}. P(pass) {e0['p_pass']:.1%}, "
|
||||
f"P(payout) {e0['p_payout']:.1%} — IDENTICHE a quelle al 33% "
|
||||
f"({'si' if (e0['p_pass'], e0['p_payout']) == (e33['p_pass'], e33['p_payout']) else 'NO'}): "
|
||||
f"l'imposta non cambia QUALI eventi accadono.")
|
||||
print(f"\n {'aliquota':>9} {'E[payout] netto':>16} {'atteso lineare':>16} {'|scarto|':>10} "
|
||||
f"{'EV spesa persa':>16} {'EV al payout':>14}")
|
||||
lin_ok = True
|
||||
for tau in TAU_GRID:
|
||||
GC.TAX_RATE = tau
|
||||
rt = GC.ticket_mc(R_M, G_M, lev_ev=LEV_EV, lev_fu=LEV_FU, notional=100_000.0)
|
||||
GC.TAX_RATE = _sav
|
||||
pred = e_gross * (1.0 - tau)
|
||||
lin_ok &= abs(rt["e_payout"] - pred) < 1e-9
|
||||
e3 = GC.ev_three_ways(rt, PRICE_100K)
|
||||
print(f" {tau:>8.0%} ${rt['e_payout']:>15,.1f} ${pred:>15,.1f} "
|
||||
f"{abs(rt['e_payout']-pred):>10.2e} ${e3['sunk']:>+15,.0f} ${e3['at_payout']:>+13,.0f}")
|
||||
tau_ev0 = 1.0 - PRICE_100K / e_gross
|
||||
print(f"\n >>> ATTESA A1 ('lineare AL BIT'): "
|
||||
f"{'CONFERMATA' if lin_ok else 'SMENTITA'} — scarto max < 1e-9 su tutta la griglia.")
|
||||
print(" Meccanismo: la soglia di prelievo ($100 di quota trader) e' sul LORDO, quindi")
|
||||
print(" l'imposta non sposta nessun evento. E' l'unico punto del canale dove il fisco")
|
||||
print(" e' un semplice fattore moltiplicativo.")
|
||||
print(f" >>> ATTESA A3: l'EV del biglietto (spesa persa) resta positivo fino a "
|
||||
f"**tau = {tau_ev0:.1%}** -> {'CONFERMATA' if tau_ev0 > 0.70 else 'SMENTITA'}.")
|
||||
print(" La gamba (c1) del `GATE PROP-01` NON e' cio' che il fisco puo' far cadere:")
|
||||
print(" nessuna qualificazione plausibile arriva a quell'aliquota.")
|
||||
|
||||
# ---------------------------------------------------------------- §4 la scala di conti
|
||||
hr("§4. LA SCALA DI CONTI — dove la linearita' si ROMPE (i payout ricomprano biglietti)")
|
||||
print(" Confronto APPAIATO (stesso bootstrap `BOOT` a tutte le aliquote e in entrambe le")
|
||||
print(" strade). 'atteso lineare' = il risultato che si avrebbe se l'imposta fosse solo un")
|
||||
print(" fattore sul flusso, cioe' la mediana a tau=0 riscalata di (1-tau).")
|
||||
lad = {}
|
||||
for dep in (0.0, 500.0):
|
||||
base = None
|
||||
print(f"\n --- versamento EUR {dep:,.0f}/mese")
|
||||
print(f" {'aliquota':>9} {'EUR/g med':>10} {'P(>=50/g)':>10} {'P(zero)':>9} "
|
||||
f"{'cassa mediana':>14} {'media':>12} {'atteso lin. (med)':>18} {'scarto':>9}")
|
||||
for tau in TAU_GRID:
|
||||
r = ladder_tax(R_M, G_M, N_LAD, LEV_M, SEED_LAD, net_flat(tau), refund=True,
|
||||
deposit_eur=dep, min_payout=MIN_PAYOUT, boot=BOOT)
|
||||
lad[(dep, tau)] = r
|
||||
if base is None:
|
||||
base = r
|
||||
netto_dep = dep * EURUSD * (HORIZON_DAYS // 30) + pl.START_EUR * EURUSD
|
||||
lin = netto_dep + (base["med_cash"] - netto_dep) * (1.0 - tau)
|
||||
print(f" {tau:>8.0%} {r['med']:>10.2f} {r['p_target']:>10.1%} {r['p_zero']:>9.1%} "
|
||||
f"${r['med_cash']:>13,.0f} ${r['mean_cash']:>11,.0f} ${lin:>17,.0f} "
|
||||
f"{(r['med_cash']-lin)/max(abs(lin),1):>+9.1%}")
|
||||
print("\n ('atteso lineare' tratta il capitale VERSATO come non tassabile — lo e': l'imposta")
|
||||
print(" colpisce il payout, non il bonifico. Lo scarto misura quindi solo la COMPOSIZIONE.)")
|
||||
|
||||
# ---------------------------------------------------------------- §5 la soglia
|
||||
hr("§5. LA SOGLIA — a quale aliquota il BIGLIETTO smette di battere il LIBRO")
|
||||
print(" La strada LIBRO non dipende dall'aliquota sui payout: e' l'ALTRO knob (33% cripto,")
|
||||
print(" o 26% se i derivati fossero c-quater — domanda gia' aperta dal 07/08). Percio' la")
|
||||
print(" soglia si legge per ogni valore del fisco del LIBRO.")
|
||||
out = {}
|
||||
|
||||
def _f(x):
|
||||
return f"tau = {x:.1%}" if x is not None else "MAI (fuori dalla griglia 0-100%)"
|
||||
|
||||
for dep in (0.0, 500.0):
|
||||
print(f"\n --- versamento EUR {dep:,.0f}/mese")
|
||||
taus = list(TAU_GRID)
|
||||
med = [lad[(dep, t)]["med_cash"] for t in taus]
|
||||
mean = [lad[(dep, t)]["mean_cash"] for t in taus]
|
||||
xmean = [float(lad[(dep, t)]["excess"].mean()) for t in taus]
|
||||
for tax_book in (0.26, 0.33):
|
||||
Bk = GC.book_road(rb, BOOT, pl.START_EUR, dep, tax=tax_book)
|
||||
bx = float((Bk["cash"] - Bk["contributed"]).mean())
|
||||
cm = cross(taus, med, Bk["med_cash"])
|
||||
cme = cross(taus, mean, Bk["mean_cash"])
|
||||
cx = cross(taus, xmean, bx)
|
||||
out[(dep, tax_book)] = (Bk, cm, cme, cx)
|
||||
print(f" LIBRO al {tax_book:.0%}: mediana ${Bk['med_cash']:>9,.0f} "
|
||||
f"media ${Bk['mean_cash']:>9,.0f} eccedenza media ${bx:>8,.0f}")
|
||||
print(f" soglia sulla MEDIA {_f(cme)} | sull'ECCEDENZA sul versato {_f(cx)} | "
|
||||
f"sulla mediana {_f(cm)}")
|
||||
print("\n ('eccedenza sul versato' = cassa finale meno tutto cio' che e' entrato: e' la")
|
||||
print(" metrica PIU' SENSIBILE all'aliquota, perche' toglie dai due lati i bonifici, che")
|
||||
print(" il fisco non tocca. Se la soglia non cade dentro la banda nemmeno LI', non ci cade.)")
|
||||
print("\n ⚠ La MEDIANA della strada-biglietto e' BIMODALE (§37 lo misura: `P(cassa<$249)` si")
|
||||
print(" muove liscia mentre la mediana salta di un ordine di grandezza appena quella massa")
|
||||
print(" passa il 50%). Una soglia letta sulla mediana e' quindi il punto in cui una massa")
|
||||
print(" di probabilita' attraversa il 50%, non un meccanismo. **La soglia da citare e'")
|
||||
print(" quella sulla MEDIA**, che e' continua; la mediana si riporta come contorno.")
|
||||
|
||||
# ---------------------------------------------------------------- §6 gli scenari
|
||||
hr("§6. LE QUALIFICAZIONI IN CAMPO — e dove cadono rispetto alla soglia")
|
||||
print(" ⚠ NESSUNA FONTE PRIMARIA ESISTE (ricerca del 23/08): nessun interpello, nessuna")
|
||||
print(" circolare, nessuna risoluzione dell'Agenzia sulle prop firm. Due fonti")
|
||||
print(" professionali lo dichiarano espressamente. Cio' che segue e' una BANDA di")
|
||||
print(" ipotesi, non una stima.")
|
||||
SC = scenari()
|
||||
print(f"\n {'':>3} {'scenario':>58} {'eff.@18k':>9} {'eff.@30k':>9} {'grado fonte':>44}")
|
||||
for s in SC:
|
||||
print(f" {s['k']:>3} {s['lab']:>58} {aliq_eff(s['fn'], 18_250.0):>9.1%} "
|
||||
f"{aliq_eff(s['fn'], 30_000.0):>9.1%} {s['src']:>44}")
|
||||
print("\n (eff.@18k = EUR 50/giorno, il bersaglio del progetto; eff.@30k = un anno buono.)")
|
||||
|
||||
print(f"\n Effetto sulla scala di conti, versamento EUR 500/mese (l'unica riga su cui §37")
|
||||
print(f" ha concluso 'il biglietto batte il versare'):")
|
||||
Bk33 = out[(500.0, 0.33)][0]
|
||||
print(f" {'':>3} {'aliquota eff.':>13} {'EUR/g med':>10} {'P(>=50/g)':>10} {'P(zero)':>9} "
|
||||
f"{'cassa mediana':>14} {'media':>12} {'vs LIBRO(33%)':>14}")
|
||||
sc_rows = []
|
||||
for s in SC:
|
||||
r = ladder_tax(R_M, G_M, N_LAD, LEV_M, SEED_LAD, s["fn"], refund=True,
|
||||
deposit_eur=500.0, min_payout=MIN_PAYOUT, boot=BOOT)
|
||||
win = "BIGLIETTO" if r["mean_cash"] > Bk33["mean_cash"] else "LIBRO"
|
||||
sc_rows.append(dict(k=s["k"], tag=s["tag"], eff=aliq_eff(s["fn"], 18_250.0), **r))
|
||||
print(f" {s['k']:>3} {aliq_eff(s['fn'], 18_250.0):>13.1%} {r['med']:>10.2f} "
|
||||
f"{r['p_target']:>10.1%} {r['p_zero']:>9.1%} ${r['med_cash']:>13,.0f} "
|
||||
f"${r['mean_cash']:>11,.0f} {win:>14}")
|
||||
SCR = pd.DataFrame(sc_rows)
|
||||
lo, hi = SCR["eff"].iloc[1:].min(), SCR["eff"].max()
|
||||
cme = out[(500.0, 0.33)][2]
|
||||
cxx = out[(500.0, 0.33)][3]
|
||||
print(f"\n Banda plausibile delle aliquote effettive (escluso il controllo): "
|
||||
f"{lo:.1%} - {hi:.1%}.")
|
||||
print(f" Soglia di ribaltamento (LIBRO al 33%): sulla MEDIA "
|
||||
f"{'tau = ' + format(cme, '.1%') if cme is not None else 'FUORI dalla griglia 0-100%'}"
|
||||
f" | sull'ECCEDENZA "
|
||||
f"{'tau = ' + format(cxx, '.1%') if cxx is not None else 'FUORI dalla griglia 0-100%'}")
|
||||
dentro = (cme is not None) and (lo <= cme <= hi)
|
||||
print(f" >>> ATTESA A4 ('la soglia cade DENTRO la banda'): "
|
||||
f"{'CONFERMATA' if dentro else 'REFUTATA'}")
|
||||
e_pro = float(SCR.loc[SCR["tag"] == "PROGETTO", "eff"].iloc[0])
|
||||
e_occ = float(SCR.loc[SCR["tag"] == "OCC", "eff"].iloc[0])
|
||||
e_o30 = float(SCR.loc[SCR["tag"] == "OCC30", "eff"].iloc[0])
|
||||
print(f" >>> ATTESA A5 ('la progressiva a EUR 18k sta SOTTO il forfait 33% del progetto'): "
|
||||
f"occasionale {e_occ:.1%} contro forfait {e_pro:.1%} -> "
|
||||
f"{'CONFERMATA' if e_occ < e_pro else 'REFUTATA'}.")
|
||||
print(f" E il seguito e' il punto trasferibile: la STESSA qualificazione, con un reddito")
|
||||
print(f" preesistente di EUR 30.000, sale a {e_o30:.1%} — "
|
||||
f"{e_o30/e_occ:.2f}x. **L'aliquota non e' una proprieta' della strategia, e' una")
|
||||
print(f" proprieta' del contribuente**, e il canale funded e' l'unico pezzo del")
|
||||
print(f" progetto in cui questo e' vero (le plusvalenze cripto hanno aliquota fissa).")
|
||||
|
||||
hr("§6.2 LA CATEGORIA CAMBIA ANCHE LA BASE, non solo l'aliquota")
|
||||
print(" art. 71 c.2 TUIR (testo verificato in sessione): i redditi di cui all'art. 67 c.1")
|
||||
print(" lett. l) sono 'la DIFFERENZA fra l'ammontare percepito nel periodo di imposta e le")
|
||||
print(" spese specificamente inerenti alla loro produzione' -> **sotto lavoro autonomo le")
|
||||
print(" quote di challenge SI DEDUCONO**; sotto un'imposta sostitutiva su reddito")
|
||||
print(" finanziario NO (una challenge persa non e' una minusvalenza da cripto-attivita'),")
|
||||
print(" e sotto forfettario nemmeno (le sostituisce il coefficiente).")
|
||||
sp_med = float(lad[(500.0, 0.33)]["spent"])
|
||||
sp_anno = sp_med / 3.0 / EURUSD
|
||||
print(f"\n Quote comprate in media su 36 mesi: ${sp_med:,.0f} = EUR {sp_anno:,.0f}/anno.")
|
||||
print(f" {'scenario':>52} {'senza deduzione':>16} {'con deduzione':>14} {'delta':>8}")
|
||||
for lab, fn_nd, fn_d in (
|
||||
("lav.aut. OCCASIONALE, nessun altro reddito",
|
||||
net_prog(0.0, "occasionale", deduci=False), net_prog(0.0, "occasionale")),
|
||||
("lav.aut. ABITUALE INPS piena, altro reddito 30k",
|
||||
net_prog(30_000.0, "piena", deduci=False), net_prog(30_000.0, "piena"))):
|
||||
a = aliq_eff(fn_nd, 18_250.0, sp_anno)
|
||||
b = aliq_eff(fn_d, 18_250.0, sp_anno)
|
||||
print(f" {lab:>52} {a:>16.2%} {b:>14.2%} {b-a:>+8.2%}")
|
||||
print(" -> la categoria con l'aliquota PIU' ALTA e' anche l'unica che deduce il costo dei")
|
||||
print(" biglietti: l'ordine fra le qualificazioni non e' l'ordine fra le aliquote.")
|
||||
|
||||
hr("§6.1 ROBUSTEZZA — i due numeri della ricerca che NON ho verificato su fonte primaria")
|
||||
print(" (a) secondo scaglione IRPEF 2026: 33% (L.199/2025) contro il 35% del 2025.")
|
||||
for lab, sg in (("33% (2026)", IRPEF_SCAGLIONI), ("35% (2025)", IRPEF_2025)):
|
||||
f1 = net_prog(0.0, "occasionale", sg)
|
||||
f2 = net_prog(30_000.0, "occasionale", sg)
|
||||
print(f" {lab:>11}: occasionale {aliq_eff(f1, 18_250.0):.2%} "
|
||||
f"con altro reddito 30k {aliq_eff(f2, 18_250.0):.2%}")
|
||||
print(" (b) chi versa i 2/3 di Gestione Separata con committente ESTERO — buco documentale:")
|
||||
for lab, inps in (("committente versa 2/3", "occasionale"), ("tutto sul prestatore", "piena")):
|
||||
print(f" {lab:>22}: eff.@18k "
|
||||
f"{aliq_eff(net_prog(0.0, inps), 18_250.0):>6.1%} "
|
||||
f"@30k {aliq_eff(net_prog(0.0, inps), 30_000.0):>6.1%}")
|
||||
|
||||
# ---------------------------------------------------------------- §7 verdetto
|
||||
hr("§7. VERDETTO — e la domanda, scritta in modo che una risposta sia possibile")
|
||||
r33 = lad[(500.0, 0.33)]
|
||||
print(f" 1. Il forfait 33% NON e' l'aliquota di questa cosa: sul funded il trader non")
|
||||
print(f" possiede il conto ne' le posizioni, non c'e' realizzo di cripto-attivita', e")
|
||||
print(f" l'art. 67 c-sexies (33%) e c-quater (26%) — le due caselle su cui il progetto")
|
||||
print(f" discute per il LIBRO — sono entrambe FUORI CATEGORIA qui. Le fonti")
|
||||
print(f" professionali convergono su LAVORO AUTONOMO. Nessuna prassi ufficiale esiste.")
|
||||
print(f" 2. La conclusione di §37 ('il biglietto batte il versare' a EUR 500/mese) "
|
||||
f"{'REGGE' if cme is None or cme > hi else 'NON REGGE'} "
|
||||
f"su tutta la banda plausibile.")
|
||||
print(f" 3. Il costo della QUESTIONE, misurato: passare dall'aliquota piu' bassa a quella")
|
||||
print(f" piu' alta della banda vale, sulla cassa mediana a 36 mesi,")
|
||||
lo_r = SCR.loc[SCR["eff"].iloc[1:].idxmin()]
|
||||
hi_r = SCR.loc[SCR["eff"].idxmax()]
|
||||
print(f" ${lo_r['med_cash']:,.0f} -> ${hi_r['med_cash']:,.0f} "
|
||||
f"({(hi_r['med_cash']/max(lo_r['med_cash'],1)-1)*100:+.0f}%), e su P(>=50/g) "
|
||||
f"{lo_r['p_target']:.1%} -> {hi_r['p_target']:.1%}.")
|
||||
d_eur = (hi_r["med_cash"] - lo_r["med_cash"]) / EURUSD / (HORIZON_DAYS / 365.0) / 365.0
|
||||
print(f" In EUR/GIORNO di rendita a 36 mesi: **{d_eur:+.2f} EUR/giorno** fra i due")
|
||||
print(f" estremi della banda, contro un bersaglio di 50.")
|
||||
print(f" 4. Al 33% di oggi la scala di conti da' EUR/g mediana {r33['med']:.2f} e "
|
||||
f"P(>=50/g) {r33['p_target']:.1%}: **l'aliquota non e' cio' che tiene lontano il")
|
||||
print(f" bersaglio**, lo tiene lontano la distribuzione.")
|
||||
|
||||
print("\n LA DOMANDA AL COMMERCIALISTA (accanto a quella gia' aperta dal 07/08 sui")
|
||||
print(" derivati, 26% contro 33% — e questa e' una domanda DIVERSA, non la stessa):")
|
||||
print(" Q1. Il profit share pagato da una prop firm estera a chi NON possiede il conto,")
|
||||
print(" NON possiede le posizioni e NON apporta capitale e': art. 67 c.1 lett. l),")
|
||||
print(" art. 53, art. 55, oppure art. 67 c.1 lett. c-quater TUIR? **Indichi la lettera.**")
|
||||
print(" Q2. Una prop firm non residente e senza stabile organizzazione puo' operare una")
|
||||
print(" ritenuta italiana sul payout? (SI'/NO)")
|
||||
print(" Q3. Superata la soglia di EUR 5.000 di compensi occasionali, con committente")
|
||||
print(" (a) UE e (b) extra-UE: l'aliquota di Gestione Separata che grava sul")
|
||||
print(" PRESTATORE e' 1/3 di 26,07% o l'intero 26,07%? (una risposta per caso)")
|
||||
print(" Q4. Con partita IVA: quale ATECO, e quindi quale coefficiente forfettario,")
|
||||
print(" 78% o 67%? (una sigla e una percentuale)")
|
||||
print(" Q5. Il funded account va in quadro RW / IVAFE? (SI'/NO) Se no, l'obbligo si")
|
||||
print(" limita al conto estero su cui incasso?")
|
||||
print("\n ONESTA' OBBLIGATORIE:")
|
||||
print(" * questo NON e' un parere fiscale, e nessuna riga qui sopra e' una consulenza.")
|
||||
print(" * l'aliquota EFFETTIVA degli scenari progressivi e' calcolata SENZA detrazioni")
|
||||
print(" (conservativo: le detrazioni la abbassano) e con addizionali al minimo di legge.")
|
||||
print(" * il modello tassa i payout dell'anno via via che arrivano, non a saldo: toglie")
|
||||
print(" liquidita' prima del dovuto, quindi e' conservativo sulla ricomposizione.")
|
||||
print(" * tutte le assunzioni di §37 restano dentro: morte-firm 10%/anno (mai stimata),")
|
||||
print(" cap $200k/trader, XS01 su U13 fuori campione, ancora giornaliera di TP01 fuori")
|
||||
print(" dalla banda. Il fisco e' UN parametro fra questi, e non il piu' incerto.")
|
||||
print(f"\n fatto in {time.time()-T0:.0f}s")
|
||||
print("=" * 104)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user