-- estrazione dei dati di bilancio dalla tassonomia XBRL italianaSELECT f.codice_fiscale, f.anno,SUM(CASEWHEN f.concetto = 'itcc-ci:TotaleValoreProduzione'THEN f.valore END) AS valore_produzione,SUM(CASEWHEN f.concetto = 'itcc-ci:CostiProduzionePersonaleTotale'THEN f.valore END) AS costo_personale,SUM(CASEWHEN f.concetto = 'itcc-ci:AmmortamentiSvalutazioniTotale'THEN f.valore END) AS ammortamenti,SUM(CASEWHEN f.concetto = 'itcc-ci:DebitiTotaleDebiti'THEN f.valore END) AS debitiFROM xbrl_fatti AS fWHERE f.contesto = 'esercizio_corrente'AND f.anno BETWEEN2022AND2025GROUPBY f.codice_fiscale, f.annoORDERBY f.anno DESC;# leibniz/valutazione/modello.pyimport numpy as npfrom leibniz.dati import carica_bilanci_xbrl, carica_comparabilifrom leibniz.ia import ModelloSettorialefrom leibniz.core import enterprise_valuedef multiplo_ev_ebitda(settore: str, anno: int) -> float: campione = carica_comparabili(settore, anno) multipli = [c.ev / c.ebitda for c in campione if c.ebitda > 0]returnfloat(np.median(multipli))def simulazione_monte_carlo(fcf_base, wacc, g, n=10_000, seed=42): rng = np.random.default_rng(seed) crescita = rng.normal(g, 0.005, n) tassi = rng.normal(wacc, 0.01, n) ev = [enterprise_value(fcf_base, w, c) for w, c in zip(tassi, crescita)]return np.percentile(ev, [10, 50, 90])bilanci = carica_bilanci_xbrl(codice_fiscale, anni=range(2022, 2026))modello = ModelloSettoriale.carica("ateco-2025", versione="3.2")segnali = modello.analizza(bilanci, indicatori=["dscr", "pfn_ebitda", "rotazione_crediti"])p10, p50, p90 = simulazione_monte_carlo(segnali.fcf, wacc=0.0874, g=0.02)/* leibniz/core/cashflow.c */#include <math.h>#include"bilancio.h"#define ALIQUOTA_FISCALE 0.279typedefstruct {double ebit;double ammortamenti;double capex;double delta_ccn;} FlussiOperativi;double fcff(const FlussiOperativi *f){double nopat = f->ebit * (1.0 - ALIQUOTA_FISCALE);return nopat + f->ammortamenti - f->capex - f->delta_ccn;}double valore_terminale(double fcf_n, double wacc, double g){if (wacc <= g) return NAN;return fcf_n * (1.0 + g) / (wacc - g);}double enterprise_value(constdouble *fcf, int anni, double wacc, double g){double ev = 0.0;for (int t = 0; t < anni; t++) ev += fcf[t] / pow(1.0 + wacc, t + 1); ev += valore_terminale(fcf[anni - 1], wacc, g) / pow(1.0 + wacc, anni);return ev;}double delta_ccn(const StatoPatrimoniale *sp, const StatoPatrimoniale *prec){double ccn = sp->crediti_commerciali + sp->rimanenze - sp->debiti_fornitori;double ccn_prec = prec->crediti_commerciali + prec->rimanenze - prec->debiti_fornitori;return ccn - ccn_prec;}package it.progemafin.leibniz.analisi;import java.math.BigDecimal;import java.math.RoundingMode;publicfinalclass RiclassificazioneBilancio {privatestaticfinal BigDecimal ALIQUOTA = new BigDecimal("0.279");public ContoEconomicoRiclassificato aValoreAggiunto(Bilancio b) { BigDecimal valoreProduzione = b.ricavi() .add(b.variazioneRimanenze()) .add(b.altriRicavi()); BigDecimal valoreAggiunto = valoreProduzione .subtract(b.costiMateriePrime()) .subtract(b.costiServizi()) .subtract(b.godimentoBeniTerzi()); BigDecimal ebitda = valoreAggiunto.subtract(b.costoPersonale()); BigDecimal ebit = ebitda .subtract(b.ammortamenti()) .subtract(b.svalutazioni());returnnew ContoEconomicoRiclassificato(valoreProduzione, valoreAggiunto, ebitda, ebit); }public BigDecimal posizioneFinanziariaNetta(StatoPatrimoniale sp) {return sp.debitiVersoBanche() .add(sp.debitiVersoAltriFinanziatori()) .add(sp.obbligazioni()) .subtract(sp.disponibilitaLiquide()) .subtract(sp.attivitaFinanziarieCorrenti()); }public BigDecimal dscr(FlussiDiCassa f, ServizioDebito s) { BigDecimal servizio = s.quotaCapitale().add(s.interessi());if (servizio.signum() == 0) returnnull;return f.flussoOperativo().divide(servizio, 4, RoundingMode.HALF_UP); }public BigDecimal margineEbitda(ContoEconomicoRiclassificato ce) {return ce.ebitda().divide(ce.valoreProduzione(), 4, RoundingMode.HALF_UP); }}-- estrazione dei dati di bilancio dalla tassonomia XBRL italianaSELECT f.codice_fiscale, f.anno,SUM(CASEWHEN f.concetto = 'itcc-ci:TotaleValoreProduzione'THEN f.valore END) AS valore_produzione,SUM(CASEWHEN f.concetto = 'itcc-ci:CostiProduzionePersonaleTotale'THEN f.valore END) AS costo_personale,SUM(CASEWHEN f.concetto = 'itcc-ci:AmmortamentiSvalutazioniTotale'THEN f.valore END) AS ammortamenti,SUM(CASEWHEN f.concetto = 'itcc-ci:DebitiTotaleDebiti'THEN f.valore END) AS debitiFROM xbrl_fatti AS fWHERE f.contesto = 'esercizio_corrente'AND f.anno BETWEEN2022AND2025GROUPBY f.codice_fiscale, f.annoORDERBY f.anno DESC;package it.progemafin.leibniz.analisi;import java.math.BigDecimal;import java.math.RoundingMode;publicfinalclass RiclassificazioneBilancio {privatestaticfinal BigDecimal ALIQUOTA = new BigDecimal("0.279");public ContoEconomicoRiclassificato aValoreAggiunto(Bilancio b) { BigDecimal valoreProduzione = b.ricavi() .add(b.variazioneRimanenze()) .add(b.altriRicavi()); BigDecimal valoreAggiunto = valoreProduzione .subtract(b.costiMateriePrime()) .subtract(b.costiServizi()) .subtract(b.godimentoBeniTerzi()); BigDecimal ebitda = valoreAggiunto.subtract(b.costoPersonale()); BigDecimal ebit = ebitda .subtract(b.ammortamenti()) .subtract(b.svalutazioni());returnnew ContoEconomicoRiclassificato(valoreProduzione, valoreAggiunto, ebitda, ebit); }public BigDecimal posizioneFinanziariaNetta(StatoPatrimoniale sp) {return sp.debitiVersoBanche() .add(sp.debitiVersoAltriFinanziatori()) .add(sp.obbligazioni()) .subtract(sp.disponibilitaLiquide()) .subtract(sp.attivitaFinanziarieCorrenti()); }public BigDecimal dscr(FlussiDiCassa f, ServizioDebito s) { BigDecimal servizio = s.quotaCapitale().add(s.interessi());if (servizio.signum() == 0) returnnull;return f.flussoOperativo().divide(servizio, 4, RoundingMode.HALF_UP); }public BigDecimal margineEbitda(ContoEconomicoRiclassificato ce) {return ce.ebitda().divide(ce.valoreProduzione(), 4, RoundingMode.HALF_UP); }}/* leibniz/core/cashflow.c */#include <math.h>#include"bilancio.h"#define ALIQUOTA_FISCALE 0.279typedefstruct {double ebit;double ammortamenti;double capex;double delta_ccn;} FlussiOperativi;double fcff(const FlussiOperativi *f){double nopat = f->ebit * (1.0 - ALIQUOTA_FISCALE);return nopat + f->ammortamenti - f->capex - f->delta_ccn;}double valore_terminale(double fcf_n, double wacc, double g){if (wacc <= g) return NAN;return fcf_n * (1.0 + g) / (wacc - g);}double enterprise_value(constdouble *fcf, int anni, double wacc, double g){double ev = 0.0;for (int t = 0; t < anni; t++) ev += fcf[t] / pow(1.0 + wacc, t + 1); ev += valore_terminale(fcf[anni - 1], wacc, g) / pow(1.0 + wacc, anni);return ev;}double delta_ccn(const StatoPatrimoniale *sp, const StatoPatrimoniale *prec){double ccn = sp->crediti_commerciali + sp->rimanenze - sp->debiti_fornitori;double ccn_prec = prec->crediti_commerciali + prec->rimanenze - prec->debiti_fornitori;return ccn - ccn_prec;}# leibniz/valutazione/modello.pyimport numpy as npfrom leibniz.dati import carica_bilanci_xbrl, carica_comparabilifrom leibniz.ia import ModelloSettorialefrom leibniz.core import enterprise_valuedef multiplo_ev_ebitda(settore: str, anno: int) -> float: campione = carica_comparabili(settore, anno) multipli = [c.ev / c.ebitda for c in campione if c.ebitda > 0]returnfloat(np.median(multipli))def simulazione_monte_carlo(fcf_base, wacc, g, n=10_000, seed=42): rng = np.random.default_rng(seed) crescita = rng.normal(g, 0.005, n) tassi = rng.normal(wacc, 0.01, n) ev = [enterprise_value(fcf_base, w, c) for w, c in zip(tassi, crescita)]return np.percentile(ev, [10, 50, 90])bilanci = carica_bilanci_xbrl(codice_fiscale, anni=range(2022, 2026))modello = ModelloSettoriale.carica("ateco-2025", versione="3.2")segnali = modello.analizza(bilanci, indicatori=["dscr", "pfn_ebitda", "rotazione_crediti"])p10, p50, p90 = simulazione_monte_carlo(segnali.fcf, wacc=0.0874, g=0.02)leibniz> analisi avviata bilanci=1284 esercizi=2022..2025leibniz> riclassificazione a valore aggiunto ......... okleibniz> flussi di cassa FCFF / FCFE ................. ok ebitda_margin = 0.1418 pfn_su_ebitda = 2.31 dscr = 1.47 wacc = 0.0874 g_terminale = 0.0200 ev_p50 = 12640000leibniz> modello settoriale ateco-2025 v3.2 ........ in corsoleibniz> scenari Monte Carlo n=10000 ev_p10 = 10910000 ev_p90 = 14380000leibniz> report di sintesi in preparazione/* leibniz/core/cashflow.c */#include <math.h>#include"bilancio.h"#define ALIQUOTA_FISCALE 0.279typedefstruct {double ebit;double ammortamenti;double capex;double delta_ccn;} FlussiOperativi;double fcff(const FlussiOperativi *f){double nopat = f->ebit * (1.0 - ALIQUOTA_FISCALE);return nopat + f->ammortamenti - f->capex - f->delta_ccn;}double valore_terminale(double fcf_n, double wacc, double g){if (wacc <= g) return NAN;return fcf_n * (1.0 + g) / (wacc - g);}double enterprise_value(constdouble *fcf, int anni, double wacc, double g){double ev = 0.0;for (int t = 0; t < anni; t++) ev += fcf[t] / pow(1.0 + wacc, t + 1); ev += valore_terminale(fcf[anni - 1], wacc, g) / pow(1.0 + wacc, anni);return ev;}double delta_ccn(const StatoPatrimoniale *sp, const StatoPatrimoniale *prec){double ccn = sp->crediti_commerciali + sp->rimanenze - sp->debiti_fornitori;double ccn_prec = prec->crediti_commerciali + prec->rimanenze - prec->debiti_fornitori;return ccn - ccn_prec;}leibniz> analisi avviata bilanci=1284 esercizi=2022..2025leibniz> riclassificazione a valore aggiunto ......... okleibniz> flussi di cassa FCFF / FCFE ................. ok ebitda_margin = 0.1418 pfn_su_ebitda = 2.31 dscr = 1.47 wacc = 0.0874 g_terminale = 0.0200 ev_p50 = 12640000leibniz> modello settoriale ateco-2025 v3.2 ........ in corsoleibniz> scenari Monte Carlo n=10000 ev_p10 = 10910000 ev_p90 = 14380000leibniz> report di sintesi in preparazione# leibniz/valutazione/modello.pyimport numpy as npfrom leibniz.dati import carica_bilanci_xbrl, carica_comparabilifrom leibniz.ia import ModelloSettorialefrom leibniz.core import enterprise_valuedef multiplo_ev_ebitda(settore: str, anno: int) -> float: campione = carica_comparabili(settore, anno) multipli = [c.ev / c.ebitda for c in campione if c.ebitda > 0]returnfloat(np.median(multipli))def simulazione_monte_carlo(fcf_base, wacc, g, n=10_000, seed=42): rng = np.random.default_rng(seed) crescita = rng.normal(g, 0.005, n) tassi = rng.normal(wacc, 0.01, n) ev = [enterprise_value(fcf_base, w, c) for w, c in zip(tassi, crescita)]return np.percentile(ev, [10, 50, 90])bilanci = carica_bilanci_xbrl(codice_fiscale, anni=range(2022, 2026))modello = ModelloSettoriale.carica("ateco-2025", versione="3.2")segnali = modello.analizza(bilanci, indicatori=["dscr", "pfn_ebitda", "rotazione_crediti"])p10, p50, p90 = simulazione_monte_carlo(segnali.fcf, wacc=0.0874, g=0.02)Services / M&A
Strategic advisory for SME growth, acquisitions and succession
Turn an ownership or growth objective into a workable plan
Strategic advisory begins with a concrete question: how to grow, improve margins, finance an investment, acquire a competitor or prepare the company for succession. We work with SME owners to compare realistic options using the company’s commercial, operational and financial information.
Review the starting point
We examine the business model, customers, products, capacity and organisation alongside the accounts. A financial statement analysis helps identify profitability, working-capital and debt constraints. Interviews with management help distinguish a recurring problem from a temporary event.
Compare the alternatives
Organic growth, partnerships, an acquisition and a partial or full company sale have different resource needs and execution risks. We examine the assumptions behind each option, including management time, investment, funding and continuity of the team.
For an acquisition, strategic fit must be assessed alongside valuation, due diligence and integration. For succession, we examine ownership and management transition together rather than treating them as a single event.
Define actions and responsibilities
The work can lead to a prioritised plan with actions, owners, timing and measures of progress. A business plan translates the chosen direction into revenue, margin, investment and cash-flow scenarios. Management control supports the subsequent comparison between targets and actual results.
The scope is agreed around the decision you need to make. Describe your current position, the main objective and any timing constraints so that we can identify the information required for a first discussion.