Skip to content
Learni
View all tutorials
Data Science

Comment créer une prévision de trésorerie en Python en 2026

Introduction

La prévision de trésorerie est un outil essentiel pour toute entreprise, permettant d'anticiper les soldes futurs à partir des flux entrants (encaissements) et sortants (décaissements). En 2026, avec la volatilité économique, automatiser ces calculs via Python devient indispensable pour gagner du temps et minimiser les erreurs humaines.

Ce tutoriel intermédiaire vous guide pas à pas pour créer une application web complète avec Streamlit, Pandas et Matplotlib. Vous partirez de données historiques (CSV simple) pour projeter 12 mois en avant, en utilisant une méthode hybride : moyenne mobile pour la stabilité et régression linéaire pour la tendance. Imaginez comme un GPS financier : il analyse votre parcours passé pour tracer la route future.

Résultat : une interface interactive où vous uploadez vos données, ajustez les paramètres, et visualisez soldes, alertes de découvert et graphiques. Parfait pour CFOs tech-savvy ou devs en finance. Temps estimé : 30 minutes pour un prototype fonctionnel.

Prérequis

  • Python 3.10+ installé
  • Connaissances de base en Pandas et DataFrames
  • pip pour les dépendances
  • Fichier CSV exemple avec colonnes : date (YYYY-MM-DD), entrees (float), sorties (float), solde_initial (optionnel)
  • Éditeur comme VS Code

Installation des dépendances

terminal
pip install streamlit pandas numpy matplotlib plotly scikit-learn

Ces paquets forment la base : Streamlit pour l'interface web, Pandas/Numpy pour les calculs, Matplotlib/Plotly pour les visualisations interactives, et scikit-learn pour la régression linéaire. Exécutez en terminal pour un environnement virtuel recommandé (via venv).

Préparation des données d'exemple

Créez un fichier CSV de test pour simuler des flux réels. Colonnes obligatoires : date, entrees, sorties. Le solde se calcule cumulativement : solde_mensuel = solde_precedent + entrees - sorties. Utilisez des dates mensuelles pour simplifier les agrégations.

Génération du fichier CSV d'exemple

generate_sample_data.py
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# Paramètres
start_date = datetime(2025, 1, 1)
dates = pd.date_range(start=start_date, periods=24, freq='MS')

# Flux aléatoires réalistes (entrees > sorties en moyenne)
np.random.seed(42)
entrees = np.random.normal(50000, 10000, 24).clip(20000)
sorties = np.random.normal(40000, 8000, 24).clip(15000)

# Solde initial
df = pd.DataFrame({
    'date': dates,
    'entrees': entrees,
    'sorties': sorties
})
df['solde'] = df['entrees'].cumsum() - df['sorties'].cumsum() + 100000  # Solde initial 100k€

df.to_csv('tresorerie_historique.csv', index=False)
print('Fichier créé : tresorerie_historique.csv')
print(df.head())

Ce script génère 24 mois de données fictives mais réalistes (moyenne entrees 50k€, sorties 40k€, solde initial 100k€). La seed assure la reproductibilité. Exécutez-le pour obtenir tresorerie_historique.csv, prêt pour les tests. Piège : toujours clipper les valeurs négatives pour éviter les flux absurdes.

Chargement et nettoyage des données

Dans l'app Streamlit, chargez le CSV, convertissez date en datetime, agrégez mensuellement si besoin, et calculez les soldes cumulés. Gérez les NaN et validez les colonnes pour robustesse.

Fonctions de chargement et nettoyage

data_loader.py
import pandas as pd
import streamlit as st

@st.cache_data
def load_data(uploaded_file):
    df = pd.read_csv(uploaded_file)
    df['date'] = pd.to_datetime(df['date'])
    df = df.sort_values('date').reset_index(drop=True)
    
    # Vérifications
    required_cols = ['date', 'entrees', 'sorties']
    if not all(col in df.columns for col in required_cols):
        st.error('Colonnes manquantes : date, entrees, sorties')
        st.stop()
    
    # Nettoyage
    df = df.dropna(subset=required_cols)
    df['entrees'] = pd.to_numeric(df['entrees'], errors='coerce').fillna(0)
    df['sorties'] = pd.to_numeric(df['sorties'], errors='coerce').fillna(0)
    
    # Calcul solde cumulé
    solde_initial = st.number_input('Solde initial (€)', value=100000.0)
    df['solde'] = solde_initial + df['entrees'].cumsum() - df['sorties'].cumsum()
    
    return df

# Utilisation : df = load_data(st.file_uploader('Upload CSV'))

Cette fonction charge, valide et nettoie les données via Streamlit. Le @st.cache_data optimise les rechargements. Solde cumulé dynamique avec input utilisateur. Piège : ignorer les erreurs de conversion peut corrompre les calculs ; utilisez toujours errors='coerce'. Copiez dans votre app principale.

Algorithme de prévision

Moyenne mobile (période 3 mois) pour lisser les fluctuations + régression linéaire sur les tendances entrees/sorties. Projetez 12 mois : pour chaque mois futur, appliquez les prédictions aux soldes cumulés. Alertes si solde < 10k€.

Fonctions de prévision

forecaster.py
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from datetime import timedelta

def forecast_tresorerie(df, periods=12):
    df_forecast = df.copy()
    
    # Moyenne mobile pour lissage
    df['entrees_smooth'] = df['entrees'].rolling(window=3, min_periods=1).mean()
    df['sorties_smooth'] = df['sorties'].rolling(window=3, min_periods=1).mean()
    
    # Régression linéaire sur tendances
    X = np.arange(len(df)).reshape(-1, 1)
    reg_entrees = LinearRegression().fit(X, df['entrees_smooth'])
    reg_sorties = LinearRegression().fit(X, df['sorties_smooth'])
    
    # Projection
    last_date = df['date'].max()
    future_dates = pd.date_range(start=last_date + timedelta(days=1), periods=periods, freq='MS')
    future_X = np.arange(len(df), len(df) + periods).reshape(-1, 1)
    
    future_entrees = reg_entrees.predict(future_X)
    future_sorties = reg_sorties.predict(future_X)
    
    future_df = pd.DataFrame({
        'date': future_dates,
        'entrees_pred': future_entrees,
        'sorties_pred': future_sorties
    })
    
    # Solde projeté
    last_solde = df['solde'].iloc[-1]
    future_df['solde_pred'] = np.cumsum(future_entrees - future_sorties) + last_solde
    
    df_forecast = pd.concat([df_forecast, future_df], ignore_index=True)
    df_forecast['type'] = ['historique'] * len(df) + ['prevision'] * periods
    
    return df_forecast

# Utilisation : df_full = forecast_tresorerie(df)

Hybride robuste : rolling mean lisse le bruit, LinearRegression capture la croissance. freq='MS' pour mensuel. Soldes cumulés préservent la réalité comptable. Piège : sans min_periods=1, les débuts manquent ; testez avec <3 mois de data.

Visualisation interactive

Affichez graphiques : évolution soldes (ligne), histo flux (barres), avec zoom Plotly. Ajoutez métriques : solde min projeté, % croissance moyenne.

Visualisations et métriques

visualizer.py
import streamlit as st
import plotly.express as px
import plotly.graph_objects as go

def plot_forecast(df_full):
    fig = go.Figure()
    
    # Soldes
    fig.add_trace(go.Scatter(x=df_full['date'], y=df_full['solde'],
                             mode='lines+markers', name='Solde historique',
                             line=dict(color='blue')))
    fig.add_trace(go.Scatter(x=df_full[df_full['type']=='prevision']['date'],
                             y=df_full[df_full['type']=='prevision']['solde_pred'],
                             mode='lines+markers', name='Solde prévisionnel',
                             line=dict(color='orange', dash='dash')))
    
    fig.update_layout(title='Évolution de la trésorerie', xaxis_title='Date', yaxis_title='Solde (€)')
    st.plotly_chart(fig, use_container_width=True)
    
    # Métriques
    solde_min = df_full[df_full['type']=='prevision']['solde_pred'].min()
    if solde_min < 10000:
        st.error(f'🚨 Alerte : Solde minimum projeté = {solde_min:,.0f}€')
    else:
        st.success(f'Solde minimum projeté = {solde_min:,.0f}€')
    
    croissance = (df_full['entrees'].tail(12).mean() / df_full['entrees'].head(12).mean() - 1) * 100
    st.metric('Croissance moyenne entrees (%)', f'{croissance:.1f}%')

# Utilisation : plot_forecast(df_full)

Plotly pour interactivité (zoom, hover). Traces séparées historique/prévision. Alertes conditionnelles boostent l'utilité. Piège : sans use_container_width=True, le chart déborde ; toujours filtrer par type pour clarté.

Application Streamlit complète

app.py
import streamlit as st
from data_loader import load_data
from forecaster import forecast_tresorerie
from visualizer import plot_forecast

st.set_page_config(page_title='Prévision Trésorerie', layout='wide')

st.title('🚀 Prévision de Trésorerie Automatisée')

uploaded_file = st.file_uploader('Choisissez votre fichier CSV', type='csv')
if uploaded_file is not None:
    df = load_data(uploaded_file)
    st.subheader('Données chargées')
    st.dataframe(df.tail())
    
    periods = st.slider('Mois à prévoir', 3, 24, 12)
    df_full = forecast_tresorerie(df, periods)
    
    col1, col2 = st.columns(2)
    with col1:
        plot_forecast(df_full)
    with col2:
        st.subheader('Tableau prévisionnel')
        st.dataframe(df_full[df_full['type']=='prevision'])
        
        st.download_button('Télécharger CSV complet', df_full.to_csv(index=False),
                          'tresorerie_forecast.csv')

if __name__ == '__main__':
    st.info('Exécutez : streamlit run app.py')

App intégrant tout : upload, params, viz, export. Layout wide optimise l'espace. Modularité via imports. Lancez avec streamlit run app.py. Piège : sans st.cache_data, rechargements lents ; testez avec gros CSV.

Bonnes pratiques

  • Validez toujours les données : colonnes, types, NaN pour éviter crashes en prod.
  • Utilisez des environnements virtuels : venv + requirements.txt pour déploiement.
  • Modularisez le code : fonctions séparées pour tests unitaires (pytest).
  • Sécurisez les inputs : limitez tailles fichiers, sanitizez valeurs.
  • Déployez sur cloud : Streamlit Cloud gratuit pour sharing avec équipe finance.

Erreurs courantes à éviter

  • Oublier le cumulé des soldes : prévision non-réaliste si on reset à zéro chaque mois.
  • Pas de lissage : moyenne mobile absente amplifie le bruit aléatoire.
  • Dates mal formatées : pd.to_datetime échoue sans gestion errors → crash app.
  • Prévisions trop optimistes : ajoutez scénarios pessimistes (facteur 1.2 sur sorties).

Pour aller plus loin

Intégrez ML avancé (Prophet pour saisonnalité) ou API compta (QuickBooks). Découvrez nos formations Python Data Science et Streamlit Pro. Ressources : Doc Pandas, Streamlit Gallery.