ktongue/docker_container / ENISE /Finances /analyse_bricorama.py
download
raw
14.1 kB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Analyse financière de Bricorama France - Valorisation DCF et structuration LBO
Devoir Maison - Financement et valorisation
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, Border, Side, PatternFill
from openpyxl.utils import get_column_letter
plt.rcParams['font.family'] = 'DejaVu Sans'
plt.rcParams['axes.unicode_minus'] = False
# =============================================================================
# 1. DONNÉES HISTORIQUES BRICORAMA (k EUR) - Source: Pappers
# =============================================================================
data_hist = {
'annee': [2022, 2023, 2024],
'ca': [165420, 175280, 185640],
'ebe': [5200, 5600, 6100],
'dotations': [1800, 1900, 2100],
'stocks': [28500, 30100, 32400],
'creances_clients': [8200, 9100, 9800],
'dettes_fournisseurs': [18500, 20300, 21500],
'dettes_financieres': [12400, 11800, 10900],
'disponibilites': [2500, 2800, 3200],
'capitaux_propres': [29300, 31200, 33100],
'capital_social': 7500,
'actif_immobilise': 26100,
}
df = pd.DataFrame(data_hist).set_index('annee')
# Calculs derivados
df['actif_circulant'] = df['stocks'] + df['creances_clients'] + df['disponibilites'] # simplificado
df['passif_circulant'] = df['dettes_fournisseurs'] + (df['dettes_financieres'] * 0.2) # parte corrente
df['total_bilan'] = df['actif_immobilise'] + df['actif_circulant']
print("=" * 60)
print("BRICORAMA FRANCE - ANALYSE FINANCIERE")
print("=" * 60)
# =============================================================================
# 2. RATIOS HISTORIQUES
# =============================================================================
df['liquidite_generale'] = df['actif_circulant'] / df['passif_circulant']
df['liquidite_reduite'] = (df['actif_circulant'] - df['stocks']) / df['passif_circulant']
df['taux_endettement'] = df['dettes_financieres'] / df['capitaux_propres']
df['capacite_remboursement'] = df['dettes_financieres'] / df['ebe']
df['autonomie_financiere'] = df['capitaux_propres'] / df['total_bilan']
df['ratio_legal'] = df['capitaux_propres'] / df['capital_social']
df['marge_ebe_pct'] = df['ebe'] / df['ca'] * 100 # colonne nommee differemment pour eviter conflit
print("\n=== RATIOS DE LIQUIDITE ===")
print(f"2022: LG={df.loc[2022, 'liquidite_generale']:.2f}, LR={df.loc[2022, 'liquidite_reduite']:.2f}")
print(f"2023: LG={df.loc[2023, 'liquidite_generale']:.2f}, LR={df.loc[2023, 'liquidite_reduite']:.2f}")
print(f"2024: LG={df.loc[2024, 'liquidite_generale']:.2f}, LR={df.loc[2024, 'liquidite_reduite']:.2f}")
print("\n=== RATIOS DE VULNERABILITE ===")
print(f"2022: Taux endett={df.loc[2022, 'taux_endettement']:.2f}, Cap remb={df.loc[2022, 'capacite_remboursement']:.2f}ans")
print(f"2023: Taux endett={df.loc[2023, 'taux_endettement']:.2f}, Cap remb={df.loc[2023, 'capacite_remboursement']:.2f}ans")
print(f"2024: Taux endett={df.loc[2024, 'taux_endettement']:.2f}, Cap remb={df.loc[2024, 'capacite_remboursement']:.2f}ans")
# =============================================================================
# 3. HYPOTHESES DCF
# =============================================================================
print("\n" + "=" * 60)
print("HYPOTHESES DCF")
print("=" * 60)
# Paramètres
croissance_volume = 0.05
inflation = 0.05
croissance_nominale = (1 + croissance_volume) * (1 + inflation) - 1 # 10.25%
print(f"Croissance nominale: {croissance_nominale:.2%}")
marge_ebe = float(df.loc[2024, 'ebe']) / float(df.loc[2024, 'ca']) # ~3.29%
print(f"Marge EBE 2024: {marge_ebe*100:.2%}")
taux_dotation = df['dotations'].iloc[-1] / df['ca'].iloc[-1]
print(f"Taux dotations/CA: {taux_dotation*100:.2%}")
taux_invest = 0.02
taux_is = 0.25
wacc = 0.08
g = 0.02
multiple_ebe = 3.5
taux_dette = 0.05
horizon = 5
# BFR normatif (jours de CA)
ca_moyen = df.loc[2023:2024, 'ca'].mean()
stocks_moyen = df.loc[2023:2024, 'stocks'].mean()
clients_moyen = df.loc[2023:2024, 'creances_clients'].mean()
fourn_moyen = df.loc[2023:2024, 'dettes_fournisseurs'].mean()
achats_moyen = (104500 + 110800) / 2
jours_stocks = (stocks_moyen / ca_moyen) * 360
jours_clients = (clients_moyen / ca_moyen) * 360
jours_fourn = (fourn_moyen / achats_moyen) * 360
bfr_jours = jours_stocks + jours_clients - jours_fourn
coef_bfr = bfr_jours / 360
print(f"\nBFR normatif: {bfr_jours:.1f} jours ({coef_bfr*100:.2f}% CA)")
# =============================================================================
# 4. PROJECTION DCF 2025-2029
# =============================================================================
print("\n" + "=" * 60)
print("TABLEAU DCF (k EUR)")
print("=" * 60)
ca_base = df.loc[2024, 'ca']
annees = [2025, 2026, 2027, 2028, 2029]
# Projections
ca_list = [ca_base * (1 + croissance_nominale)**i for i in range(1, horizon+1)]
ebe_list = [ca * marge_ebe for ca in ca_list]
dot_list = [ca * taux_dotation for ca in ca_list]
ebit_list = [ebe - dot_ for ebe, dot_ in zip(ebe_list, dot_list)]
impot_list = [ebit_ * taux_is for ebit_ in ebit_list]
invest_list = [ca * taux_invest for ca in ca_list]
# BFR
bfr_initial = ca_base * coef_bfr
bfr_list = [ca * coef_bfr for ca in ca_list]
var_bfr = [bfr_list[0] - bfr_initial] + [bfr_list[i] - bfr_list[i-1] for i in range(1, horizon)]
# FCF CORRIGE: FCF = EBE - Impot(EBIT) - Investissements - Variation BFR
fcf_list = [ebe - imp - inv - var_ for ebe, imp, inv, var_ in zip(ebe_list, impot_list, invest_list, var_bfr)]
# Actualisation
coeffs = [1 / (1 + wacc)**(i+1) for i in range(horizon)]
fcf_act = [fcf * coeff for fcf, coeff in zip(fcf_list, coeffs)]
# Affichage
print(f"{'2024':>6} | {'CA':>10} | {'EBE':>8} | {'EBIT':>8} | {'Impôt':>8} | {'FCF':>10}")
print("-" * 65)
print(f"{'Base':>6} | {ca_base:>10,.0f} | {df.loc[2024,'ebe']:>8,.0f} | {df.loc[2024,'ebe']-df.loc[2024,'dotations']:>8,.0f} | {(df.loc[2024,'ebe']-df.loc[2024,'dotations'])*0.25:>8,.0f} |")
for i, (ca, ebe, ebit, imp, fcf) in enumerate(zip(ca_list, ebe_list, ebit_list, impot_list, fcf_list)):
print(f"{annees[i]:>6} | {ca:>10,.0f} | {ebe:>8,.0f} | {ebit:>8,.0f} | {imp:>8,.0f} | {fcf:>10,.0f}")
print(f"\nSomme FCF actualisés: {sum(fcf_act):,.0f} k EUR")
# =============================================================================
# 5. VALORISATION
# =============================================================================
print("\n" + "=" * 60)
print("VALORISATION")
print("=" * 60)
# Valeur terminale (Gordon-Shapiro)
vt = fcf_list[-1] * (1 + g) / (wacc - g)
vt_act = vt * coeffs[-1]
ve = sum(fcf_act) + vt_act
dette_nette = df.loc[2024, 'dettes_financieres'] - df.loc[2024, 'disponibilites']
valeur_titres = ve - dette_nette
print(f"FCF actualisés (5 ans): {sum(fcf_act):,.0f} k EUR")
print(f"Valeur terminale: {vt:,.0f} k EUR")
print(f"VT actualisée: {vt_act:,.0f} k EUR")
print(f"\n>>> VALEUR D'ENTREPRISE (VE): {ve:,.0f} k EUR ({ve/1000:.1f} M EUR)")
print(f"Dette nette 2024: {dette_nette:,.0f} k EUR")
print(f">>> VALEUR DES TITRES: {valeur_titres:,.0f} k EUR ({valeur_titres/1000:.1f} M EUR)")
# =============================================================================
# 6. STRUCTURATION FINANCIERE
# =============================================================================
print("\n" + "=" * 60)
print("STRUCTURATION DU FINANCEMENT")
print("=" * 60)
ebe_moyen = np.mean(ebe_list)
dette_max = multiple_ebe * ebe_moyen
print(f"EBE moyen: {ebe_moyen:,.0f} k EUR")
print(f"Dette max ({multiple_ebe}x EBE): {dette_max:,.0f} k EUR")
# Cas 1: dette non consolidée
print("\n--- CAS 1: DETTE NON CONSOLIDEE ---")
dette1 = min(dette_max, valeur_titres)
apport1 = valeur_titres - dette1
print(f"Dette senior holding: {dette1:,.0f} k EUR")
print(f"APPORT EN CAPITAL: {apport1:,.0f} k EUR ({apport1/1000:.1f} M EUR)")
# Cas 2: dette consolidée
print("\n--- CAS 2: DETTE CONSOLIDEE ---")
dette_existante = df.loc[2024, 'dettes_financieres']
dette2 = max(0, dette_max - dette_existante)
apport2 = valeur_titres - dette2
print(f"Dette existante cible: {dette_existante:,.0f} k EUR")
print(f"Dette holding max: {dette2:,.0f} k EUR")
print(f"APPORT EN CAPITAL: {apport2:,.0f} k EUR ({apport2/1000:.1f} M EUR)")
# =============================================================================
# 7. BUDGET DE TRESORERIE HOLDING (Cas 1)
# =============================================================================
print("\n" + "=" * 60)
print("BUDGET TRESORERIE HOLDING (k EUR)")
print("=" * 60)
remboursement = dette1 / horizon
tresor = apport1
dette_rest = dette1
print(f"{'Annee':>6} | {'TresDebut':>10} | {'FCF':>8} | {'Interets':>8} | {'Rembours':>8} | {'TresFin':>10} | {'Dette':>10}")
print("-" * 75)
budget = []
for i, annee in enumerate(annees):
interets = dette_rest * taux_dette
tresor_fin = tresor + fcf_list[i] - interets - remboursement
budget.append({'annee': annee, 'tres_debut': tresor, 'fcf': fcf_list[i],
'interets': interets, 'remboursement': remboursement,
'tres_fin': tresor_fin, 'dette': dette_rest - remboursement})
print(f"{annee:>6} | {tresor:>10,.0f} | {fcf_list[i]:>8,.0f} | {interets:>8,.0f} | {remboursement:>8,.0f} | {tresor_fin:>10,.0f} | {dette_rest-remboursement:>10,.0f}")
tresor = tresor_fin
dette_rest -= remboursement
# =============================================================================
# 8. GRAPHIQUES
# =============================================================================
print("\n" + "=" * 60)
print("GENERATION GRAPHIQUES")
print("=" * 60)
colors = {'blue': '#4472C4', 'orange': '#ED7D31', 'green': '#70AD47'}
# Graphique 1: CA et EBE historique
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
axes[0,0].bar([2022,2023,2024], df['ca']/1000, color=colors['blue'], alpha=0.8)
axes[0,0].set_title('Chiffre Affaire (M EUR)')
axes[0,0].set_ylabel('M EUR')
axes[0,1].bar([2022,2023,2024], df['ebe']/1000, color=colors['orange'], alpha=0.8)
axes[0,1].set_title('EBE (M EUR)')
axes[0,2].plot([2022,2023,2024], df['liquidite_generale'], 'o-', color=colors['blue'], linewidth=2)
axes[0,2].plot([2022,2023,2024], df['liquidite_reduite'], 's-', color=colors['orange'], linewidth=2)
axes[0,2].axhline(y=1, color='green', linestyle='--', label='Seuil LG>1')
axes[0,2].set_title('Ratios Liquidité')
axes[0,2].legend()
axes[1,0].bar([2022,2023,2024], df['capacite_remboursement'], color=colors['green'], alpha=0.8)
axes[1,0].axhline(y=4, color='red', linestyle='--', label='Alerte >4 ans')
axes[1,0].set_title('Capacité Remboursement (ans)')
axes[1,0].legend()
axes[1,1].bar(annees, [f/1000 for f in fcf_list], color=colors['blue'], alpha=0.8, label='FCF')
axes[1,1].plot(annees, [f/1000 for f in fcf_act], 'o-', color=colors['orange'], linewidth=2, label='FCF actu.')
axes[1,1].set_title('Projection FCF (M EUR)')
axes[1,1].legend()
# Graphique décomposition valeur
labels = ['FCF actu.', 'VT actu.', 'VE', 'Dette', 'Titres']
values = [sum(fcf_act)/1000, vt_act/1000, ve/1000, -dette_nette/1000, valeur_titres/1000]
pos = [0, 1, 2.5, 3.5, 4.5]
axes[1,2].bar(pos[:2], values[:2], color=[colors['blue'], colors['orange']])
axes[1,2].bar(2, values[2], color=colors['green'])
axes[1,2].bar(3, values[3], color='red')
axes[1,2].bar(4, values[4], color=colors['green'])
axes[1,2].set_xticks(pos)
axes[1,2].set_xticklabels(labels, fontsize=8)
axes[1,2].set_title('Décomposition Valeur (M EUR)')
axes[1,2].axhline(y=0, color='black')
plt.tight_layout()
plt.savefig('bricorama_graphiques.png', dpi=150, bbox_inches='tight')
print("- bricorama_graphiques.png")
plt.close()
# =============================================================================
# 9. GENERATION EXCEL
# =============================================================================
print("\n" + "=" * 60)
print("GENERATION EXCEL")
print("=" * 60)
wb = Workbook()
ws = wb.active
ws.title = "Resume"
ws['A1'] = "BRICORAMA FRANCE - ANALYSE FINANCIERE"
ws['A1'].font = Font(bold=True, size=14)
# Hypotheses
ws['A3'] = "HYPOTHESES"
ws['A3'].font = Font(bold=True)
data_hyp = [
("Croissance nominale", f"{croissance_nominale*100:.2f}%"),
("Marge EBE", f"{marge_ebe*100:.2f}%"),
("Taux dotations", f"{taux_dotation*100:.2f}%"),
("Taux investissement", f"{taux_invest*100:.0f}%"),
("Coefficient BFR", f"{coef_bfr*100:.2f}%"),
("WACC", f"{wacc*100:.0f}%"),
("g (croissance perpétuelle)", f"{g*100:.0f}%"),
("Taux IS", f"{taux_is*100:.0f}%"),
("Multiple EBE dette", multiple_ebe),
]
for i, (k, v) in enumerate(data_hyp, start=4):
ws[f'A{i}'] = k
ws[f'B{i}'] = v
# Resultats valorisation
ws['A14'] = "VALORISATION"
ws['A14'].font = Font(bold=True)
ws['A15'] = "Somme FCF actualisés (5 ans)"
ws['B15'] = sum(fcf_act)
ws['A16'] = "Valeur Terminale actualisée"
ws['B16'] = vt_act
ws['A17'] = "VALEUR D'ENTREPRISE"
ws['B17'] = ve
ws['A18'] = "Dette nette"
ws['B18'] = dette_nette
ws['A19'] = "VALEUR DES TITRES"
ws['B19'] = valeur_titres
ws['B17'].font = Font(bold=True)
ws['B19'].font = Font(bold=True)
# Financement
ws['A22'] = "FINANCEMENT"
ws['A22'].font = Font(bold=True)
ws['A23'] = "Cas 1 - Dette non consolidée"
ws['B23'] = apport1
ws['A24'] = "Cas 2 - Dette consolidée"
ws['B24'] = apport2
wb.save('bricorama_analyse.xlsx')
print("- bricorama_analyse.xlsx")
# =============================================================================
# 10. RESUME FINAL
# =============================================================================
print("\n" + "=" * 60)
print("RESUME FINAL")
print("=" * 60)
print(f"""
VALORISATION DCF - BRICORAMA FRANCE
===================================
Valeur d'Entreprise (VE): {ve:,.0f} k EUR ({ve/1000:.1f} M EUR)
Dette nette 2024: {dette_nette:,.0f} k EUR
VALEUR DES TITRES: {valeur_titres:,.0f} k EUR ({valeur_titres/1000:.1f} M EUR)
STRUCTURATION LBO:
- Cas 1 (non consolidé): Apport = {apport1:,.0f} k EUR ({apport1/1000:.1f} M EUR)
- Cas 2 (consolidé): Apport = {apport2:,.0f} k EUR ({apport2/1000:.1f} M EUR)
FICHIERS GENERES:
- bricorama_graphiques.png
- bricorama_analyse.xlsx
""")
print("=== FIN DU SCRIPT ===")

Xet Storage Details

Size:
14.1 kB
·
Xet hash:
254d930fc847c770158f87dc6d4e912b73acdd93324238f3bafd21ddf18b0bf1

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.