What time does to your capital, and what it doesn’t guarantee
Adjust the assumptions. The tool plots the nominal projection and its real purchasing power: the terracotta band is what inflation removes.
€
€
%
yrs
%
Assumption −1.5%/yr (Dalbar QAIB methodology — contested: other studies find a smaller gap). Describes the observed gap between fund returns and the return actually captured by the average investor, not an individual fate.
Nominal projectionConstant return, on a spreadsheet
After behavior gapCaptured return < headline
Real purchasing power
Conditional projection, non-predictive · assumptions entered by the user · constant return, annual compounding, end-of-period contributions · Eco3min — educational tool, neither advice nor a recommendation.
HTML;
}
return
Simulateur · Intérêts composés
Ce que le temps fait à votre capital: et ce qu’il n’en garantit pas
Modifiez les hypothèses. L’outil trace la projection nominale et son pouvoir d’achat réel : la bande terracotta est ce que l’inflation retire.
€
€
%
ans
%
Hypothèse −1,5 %/an (méthodologie Dalbar QAIB — contestée : d’autres études situent l’écart plus bas). Décrit l’écart observé entre rendement des fonds et rendement réellement capté par l’investisseur moyen, pas une fatalité individuelle.
Projection nominaleRendement constant, sur tableur
Après écart comportementalRendement capté < affiché
Pouvoir d’achat réel
Projection conditionnelle, non prédictive · hypothèses saisies par l’utilisateur · rendement supposé constant, capitalisation annuelle, versements en fin de période · Eco3min — outil pédagogique, ni conseil ni recommandation.
HTML; case ‘capacite-endettement’:
if ( $lang === ‘en’ ) {
return
Simulator · Debt capacity
The ratio says “yes”: your remaining budget says whether you hold
The debt-to-income ratio (HCSF cap 35%) is necessary but not sufficient. At an equal ratio, it is the remaining budget that separates a robust situation from a fragile one.
€
€
€
%
yrs
ppl
Debt-to-income ratioHCSF cap 35%
Remaining budget / month
Budget-structure observation, non-predictive · assumptions entered by the user · the HCSF 35% cap is a regulatory reference, not an approval threshold · Eco3min — educational tool, neither advice nor a recommendation.
HTML;
}
return
Simulateur · Capacité d’endettement
Le ratio dit « oui »: le reste à vivre dit si vous tenez
Le taux d’endettement (plafond HCSF 35 %) est nécessaire mais pas suffisant. À ratio égal, c’est le reste à vivre qui sépare une situation robuste d’une situation fragile.
€
€
€
%
ans
pers.
Taux d’endettementPlafond HCSF 35 %
Reste à vivre / mois
Observation de structure budgétaire, non prédictive · hypothèses saisies par l’utilisateur · le plafond HCSF 35 % est un repère réglementaire, pas un seuil d’octroi · Eco3min — outil pédagogique, ni conseil ni recommandation.
HTML; case ‘resilience-financiere’:
if ( $lang === ‘en’ ) {
return
Simulator · Financial resilience
A positive balance doesn’t tell you how long you’d hold
Adjust your flows and the shock. This tool measures no return — it measures your resistance duration: how many months your safety savings absorb the shock before rupture.
€
€
€
€
%
%
Normal monthly balanceBefore the shock
Resistance duration
Budget-structure stress observation, non-predictive · assumptions entered by the user · the 3–6 month buffer is a commonly cited reference, not a norm · Eco3min — educational tool, neither advice nor a recommendation.
HTML;
}
return
Simulateur · Résilience financière
Un solde positif ne dit pas combien de temps vous tenez
Modifiez vos flux et le choc. L’outil ne mesure pas un rendement — il mesure votre durée de résistance : combien de mois votre épargne de sécurité absorbe le choc avant rupture.
€
€
€
€
%
%
Solde mensuel normalAvant le choc
Durée de résistance
Observation de structure budgétaire sous choc, non prédictive · hypothèses saisies par l’utilisateur · le matelas de 3–6 mois est une référence courante, pas une norme · Eco3min — outil pédagogique, ni conseil ni recommandation.
HTML; default:
return ‘
Type de simulateur inconnu : ' . esc_html( $type ) . '.
‘;
}
} /* =========================================================================
* 4. CSS
* ========================================================================= */
function eco3_simu_css() {
return =v) return steps[k]*mag; }
return 10*mag;
} //, i18n, var I18N = {
fr: {
loc:’fr-FR’, symAfter:true,
yr:function(n){ return n+’ an’+(n>1?’s’:”); },
leg:{nominal:’Nominal’, behav:’Après écart comportemental’, real:’Pouvoir du2019achat réel’, erode:’Érodé par lu2019inflation’},
delta:function(p){ return ‘u2212’+p+’ % vs nominal’; },
breakdown:function(o){
return ‘Total versé sur ‘+o.yrs+’ ans : ‘+o.versed+’‘
+’ · Intérêts générés (nominal) : ‘+o.interets+’‘
+’ · Pouvoir du2019achat érodé par lu2019inflation : u2212’+o.erode+’‘
+(o.dalbar?’ · Écart comportemental : u2212’+o.behav+’‘:”);
},
cap:{
leg:{enc:’Crédits en cours’, neu:’Nouvelle mensualité’, rav:’Reste à vivre’},
marker:’Plafond HCSF 35 %’,
perso:function(v){ return v+’ /personne’; },
breakdown:function(o){
return ‘Revenus : ‘+o.revenus+’/mois · Mensualités totales : ‘+o.charges+’ (taux du2019endettement ‘+o.ratio+’ %) · Reste à vivre : ‘+o.reste+’/mois (‘+o.perso+’)’;
}
},
res:{
leg:{normal:’Normal’, shock:’Sous choc’, ref:’Repère 3–6 mois’},
month:function(n){ return n+’ mois’; },
infinite:’∞’,
runwayUnit:function(v){ return v+’ mois’; },
delta:function(s){ return ‘sous choc : ‘+s+’/mois’; },
breakdown:function(o){
return ‘Régime normal : solde ‘+o.solde+’/mois · Sous choc (revenus −’+o.cr+’ %, charges +’+o.cc+’ %) : ‘+o.soldechoc+’/mois‘+(o.rupture?(‘ · votre épargne (‘+o.ep+’) couvre ‘+o.runway+’‘):(‘ · aucune rupture sous ce choc’));
}
}
},
en: {
loc:’en-IE’, symAfter:false,
yr:function(n){ return n+’ yr’+(n>1?’s’:”); },
leg:{nominal:’Nominal’, behav:’After behavior gap’, real:’Real purchasing power’, erode:’Eroded by inflation’},
delta:function(p){ return ‘u2212’+p+’% vs nominal’; },
breakdown:function(o){
return ‘Total contributed over ‘+o.yrs+’ yrs: ‘+o.versed+’‘
+’ · Interest generated (nominal): ‘+o.interets+’‘
+’ · Purchasing power eroded by inflation: u2212’+o.erode+’‘
+(o.dalbar?’ · Behavior gap: u2212’+o.behav+’‘:”);
},
cap:{
leg:{enc:’Existing loans’, neu:’New payment’, rav:’Remaining budget’},
marker:’HCSF cap 35%’,
perso:function(v){ return v+’ /person’; },
breakdown:function(o){
return ‘Income: ‘+o.revenus+’/mo · Total payments: ‘+o.charges+’ (debt-to-income ‘+o.ratio+’%) · Remaining budget: ‘+o.reste+’/mo (‘+o.perso+’)’;
}
},
res:{
leg:{normal:’Normal’, shock:’Under shock’, ref:’3–6-month reference’},
month:function(n){ return n+’ mo’; },
infinite:’∞’,
runwayUnit:function(v){ return v+’ months’; },
delta:function(s){ return ‘under shock: ‘+s+’/mo’; },
breakdown:function(o){
return ‘Normal regime: balance ‘+o.solde+’/mo · Under shock (income −’+o.cr+’%, costs +’+o.cc+’%): ‘+o.soldechoc+’/mo‘+(o.rupture?(‘ · your savings (‘+o.ep+’) cover ‘+o.runway+’‘):(‘ · no rupture under this shock’));
}
}
}
}; //, module : intérêts composés
function initInteretsComposes(root){
var lang = (root.getAttribute(‘data-lang’) === ‘en’) ? ‘en’ : ‘fr’;
var T = I18N[lang];
var EUR = new Intl.NumberFormat(T.loc,{style:’currency’,currency:’EUR’,maximumFractionDigits:0});
function fmt(v){ return EUR.format(Math.max(0, Math.round(v))); }
function shortEur(v){
v = Math.max(0, v);
if(lang === ‘en’){
if(v>=1e6) return ‘€’+(v/1e6).toFixed(v>=1e7?0:1)+’M’;
if(v>=1e3) return ‘€’+Math.round(v/1e3)+’k’;
return ‘€’+Math.round(v);
}
if(v>=1e6) return (v/1e6).toFixed(v>=1e7?0:1).replace(‘.’,’,’)+’ M€’;
if(v>=1e3) return Math.round(v/1e3)+’ k€’;
return Math.round(v)+’ €’;
} var binds = {};
root.querySelectorAll(‘[data-bind]’).forEach(function(el){
var k = el.getAttribute(‘data-bind’); (binds[k] = binds[k] || []).push(el);
});
var outs = {};
root.querySelectorAll(‘[data-out]’).forEach(function(el){ outs[el.getAttribute(‘data-out’)] = el; });
var behavCard = root.querySelector(‘[data-card=”behavioral”]’);
var resultsBox = root.querySelector(‘[data-results]’);
var svg = root.querySelector(‘[data-chart]’);
var legend = root.querySelector(‘[data-legend]’); function readVal(k, def){
var els = binds[k]; if(!els) return def;
var src = els.filter(function(e){return e.type===’number’;})[0] || els[0];
return num(src, def);
}
function syncFrom(el, k){
var els = binds[k]; if(!els) return;
var n = els.filter(function(e){return e.type===’number’;})[0];
var r = els.filter(function(e){return e.type===’range’;})[0];
if(!n || !r) return;
if(el.type === ‘range’){ n.value = r.value; }
else { r.value = Math.min(parseFloat(r.max), Math.max(parseFloat(r.min), num(n, parseFloat(r.value)))); }
} function compute(){
var P = Math.max(0, readVal(‘capital’, 0));
var m = Math.max(0, readVal(‘mensuel’, 0));
var r = Math.max(0, readVal(‘taux’, 0));
var yrs = Math.max(1, Math.min(60, Math.round(readVal(‘duree’, 1))));
var infl = Math.max(0, readVal(‘inflation’, 0));
var dalbar = !!(binds.dalbar && binds.dalbar[0].checked);
var rEff = dalbar ? Math.max(0, r – 1.5) : r; var nominal = fv(P, m, r, yrs);
var behavioral = fv(P, m, rEff, yrs);
var real = deflate(behavioral, infl, yrs);
var versed = P + m*Math.round(yrs*12); outs.nominal.textContent = fmt(nominal);
if (outs.behavioral) outs.behavioral.textContent = fmt(behavioral);
outs.real.textContent = fmt(real); var erodePct = nominal>0 ? Math.round((1 – real/nominal)*100) : 0;
if (outs.delta) outs.delta.textContent = erodePct>0 ? T.delta(erodePct) : ”;
if (behavCard) behavCard.hidden = !dalbar;
if (resultsBox) resultsBox.classList.toggle(‘is-three’, dalbar); outs.breakdown.innerHTML = T.breakdown({
yrs: yrs,
versed: fmt(versed),
interets: fmt(nominal – versed),
erode: fmt(nominal – deflate(nominal, infl, yrs)),
behav: fmt(nominal – behavioral),
dalbar: dalbar
}); drawChart({P:P,m:m,r:r,rEff:rEff,yrs:yrs,infl:infl,dalbar:dalbar});
} function drawChart(p){
var W=720,H=360, padL=62,padR=104,padT=20,padB=34;
var x0=padL, x1=W-padR, y0=H-padB, y1=padT;
var nom=[], rea=[], beh=[];
for(var y=0; ymaxV) maxV=d[1]; }); });
maxV = niceMax(maxV); function X(yr){ return x0 + (yr/p.yrs)*(x1-x0); }
function Y(v){ return y0 – (v/maxV)*(y0-y1); }
function pts(a){ return a.map(function(d){ return X(d[0]).toFixed(1)+’ ‘+Y(d[1]).toFixed(1); }); }
function path(a){ return a.map(function(d,i){ return (i?’L’:’M’)+X(d[0]).toFixed(1)+’ ‘+Y(d[1]).toFixed(1); }).join(‘ ‘); } var s=”, ticks=4;
for(var t=0;t‘;
s+=’‘+shortEur(val)+’‘;
}
[0, Math.round(p.yrs/2), p.yrs].forEach(function(yr){
s+=’‘+T.yr(yr)+’‘;
}); s+=’‘;
s+=’‘;
if(p.dalbar) s+=’‘;
s+=’‘; var nv=nom[nom.length-1][1], rv=rea[rea.length-1][1], ex=X(p.yrs), ny=Y(nv), ry=Y(rv);
s+=’‘;
s+=’‘;
var lift = (Math.abs(ny-ry)‘+shortEur(nv)+’‘;
s+=’‘+shortEur(rv)+’‘; svg.innerHTML=s; var L=T.leg;
var leg=’‘+L.nominal+’‘;
if(p.dalbar) leg+=’‘+L.behav+’‘;
leg+=’‘+L.real+’‘;
leg+=’‘+L.erode+’‘;
legend.innerHTML=leg;
} root.addEventListener(‘input’, function(e){
var el = e.target;
var b = el.getAttribute && el.getAttribute(‘data-bind’);
if(b && el.type !== ‘checkbox’) syncFrom(el, b);
compute();
});
root.addEventListener(‘change’, compute);
compute();
} //, module : capacité d’endettement (multi-sorties, composition)
function initCapaciteEndettement(root){
var lang = (root.getAttribute(‘data-lang’) === ‘en’) ? ‘en’ : ‘fr’;
var T = I18N[lang].cap, loc = I18N[lang].loc;
var EUR = new Intl.NumberFormat(loc,{style:’currency’,currency:’EUR’,maximumFractionDigits:0});
function fmt(v){ return EUR.format(Math.round(v)); }
function pct(v){ return (Math.round(v*10)/10).toLocaleString(loc); }
function ratioStr(v){ return lang===’en’ ? pct(v)+’%’ : pct(v)+’ %’; } var binds = {};
root.querySelectorAll(‘[data-bind]’).forEach(function(el){
var k = el.getAttribute(‘data-bind’); (binds[k] = binds[k] || []).push(el);
});
var outs = {};
root.querySelectorAll(‘[data-out]’).forEach(function(el){ outs[el.getAttribute(‘data-out’)] = el; });
var barWrap = root.querySelector(‘[data-bar]’);
var legend = root.querySelector(‘[data-legend]’);
var realCard = root.querySelector(‘.eco3-simu__stat–real’); function readVal(k, def){
var els = binds[k]; if(!els) return def;
var src = els.filter(function(e){return e.type===’number’;})[0] || els[0];
var v = parseFloat(src.value); return isFinite(v) ? v : def;
}
function syncFrom(el, k){
var els = binds[k]; if(!els) return;
var n = els.filter(function(e){return e.type===’number’;})[0];
var r = els.filter(function(e){return e.type===’range’;})[0];
if(!n || !r) return;
if(el.type === ‘range’){ n.value = r.value; }
else { var v=parseFloat(n.value); v=isFinite(v)?v:parseFloat(r.value);
r.value = Math.min(parseFloat(r.max), Math.max(parseFloat(r.min), v)); }
}
function mensualite(montant, tauxAnnuel, annees){
var i = tauxAnnuel/100/12, n = Math.round(annees*12);
if(n0 ? charges/revenus*100 : 0;
var reste = revenus – charges;
var perso = reste/pers; outs.ratio.textContent = ratioStr(ratio);
outs.reste.textContent = fmt(reste);
if(outs.resteperso) outs.resteperso.textContent = T.perso(fmt(perso));
if(realCard) realCard.classList.toggle(‘is-neg’, reste0 ? revenus : 1;
var wEnc = Math.max(0, encours)/base*100;
var wNew = Math.max(0, mNew)/base*100;
var wRav = Math.max(0, reste)/base*100;
var totalCredit = wEnc + wNew;
if(totalCredit > 100){ var sc=100/totalCredit; wEnc*=sc; wNew*=sc; wRav=0; }
var seg=”;
if(wEnc>0) seg+=’‘;
if(wNew>0) seg+=’‘;
if(wRav>0) seg+=’‘;
barWrap.innerHTML =
‘
‘+seg+’
‘
+ ‘‘
+ ‘
‘+T.marker+’
‘; var L=T.leg;
legend.innerHTML =
‘‘+L.enc+’‘
+ ‘‘+L.neu+’‘
+ ‘‘+L.rav+’‘;
} root.addEventListener(‘input’, function(e){
var el = e.target; var b = el.getAttribute && el.getAttribute(‘data-bind’);
if(b) syncFrom(el, b); compute();
});
compute();
} // ——– module : résilience financière (trajectoire, normal vs choc)
function initResilienceFinanciere(root){
var lang = (root.getAttribute(‘data-lang’) === ‘en’) ? ‘en’ : ‘fr’;
var T = I18N[lang].res, loc = I18N[lang].loc;
var EUR = new Intl.NumberFormat(loc,{style:’currency’,currency:’EUR’,maximumFractionDigits:0});
function fmt(v){ return EUR.format(Math.round(Math.abs(v))); }
function sfmt(v){ return (v>=0?’+’:’u2212′)+fmt(v); }
function shortEur(v){ v=Math.max(0,v); if(v>=1e6) return (lang===’en’?’u20ac’:”)+(v/1e6).toFixed(1)+(lang===’en’?’M’:’ Mu20ac’); if(v>=1e3) return (lang===’en’?’u20ac’:”)+Math.round(v/1e3)+(lang===’en’?’k’:’ ku20ac’); return (lang===’en’?’u20ac’:”)+Math.round(v)+(lang===’en’?”:’ u20ac’); } var binds={}; root.querySelectorAll(‘[data-bind]’).forEach(function(el){var k=el.getAttribute(‘data-bind’);(binds[k]=binds[k]||[]).push(el);});
var outs={}; root.querySelectorAll(‘[data-out]’).forEach(function(el){outs[el.getAttribute(‘data-out’)]=el;});
var svg=root.querySelector(‘[data-chart]’), legend=root.querySelector(‘[data-legend]’);
var realCard=root.querySelector(‘.eco3-simu__stat–real’); function readVal(k,def){ var els=binds[k]; if(!els) return def; var s=els.filter(function(e){return e.type===’number’;})[0]||els[0]; var v=parseFloat(s.value); return isFinite(v)?v:def; }
function syncFrom(el,k){ var els=binds[k]; if(!els) return; var n=els.filter(function(e){return e.type===’number’;})[0],r=els.filter(function(e){return e.type===’range’;})[0]; if(!n||!r) return; if(el.type===’range’){n.value=r.value;} else {var v=parseFloat(n.value); v=isFinite(v)?v:parseFloat(r.value); r.value=Math.min(parseFloat(r.max),Math.max(parseFloat(r.min),v));} }
function niceMax(v){ if(v=v) return st[k]*mag; } return 10*mag; } function compute(){
var revenus=Math.max(0,readVal(‘revenus’,0)), charges=Math.max(0,readVal(‘charges’,0)), dettes=Math.max(0,readVal(‘dettes’,0)), epargne=Math.max(0,readVal(‘epargne’,0));
var cr=Math.max(0,readVal(‘chocrev’,0)), cc=Math.max(0,readVal(‘choccharges’,0));
var soldeNormal = revenus – charges – dettes;
var revChoc = revenus*(1-cr/100), chChoc = charges*(1+cc/100);
var soldeChoc = revChoc – chChoc – dettes;
var deficit = -soldeChoc;
var rupture = deficit > 0;
var runway = rupture ? epargne/deficit : Infinity; outs.solde.textContent = sfmt(soldeNormal);
outs.runway.textContent = rupture ? T.runwayUnit(Math.round(runway*10)/10) : T.infinite;
if(outs.soldechoc) outs.soldechoc.textContent = T.delta(sfmt(soldeChoc));
if(realCard) realCard.classList.toggle(‘is-neg’, rupture && runway maxV)maxV=d[1];});}); maxV=niceMax(maxV||1000);
function X(m){ return x0+(m/horizon)*(x1-x0); }
function Y(v){ return y0-(v/maxV)*(y0-y1); }
function path(a){ return a.map(function(d,i){return (i?’L’:’M’)+X(d[0]).toFixed(1)+’ ‘+Y(d[1]).toFixed(1);}).join(‘ ‘); }
var s=”, ticks=4;
for(var t=0;t‘+shortEur(val)+’‘; }
[0, Math.round(horizon/2), horizon].forEach(function(m){ s+=’‘+T.month(m)+’‘; });
if(6‘; s+=’‘+T.leg.ref+’‘; }
s+=’‘;
s+=’‘;
if(p.rupture && p.runway‘; s+=’‘+T.runwayUnit(Math.round(p.runway*10)/10)+’‘; }
svg.innerHTML=s;
legend.innerHTML=’‘+T.leg.normal+’‘
+’‘+T.leg.shock+’‘
+’‘+T.leg.ref+’‘;
} root.addEventListener(‘input’, function(e){ var el=e.target; var b=el.getAttribute&&el.getAttribute(‘data-bind’); if(b) syncFrom(el,b); compute(); });
compute();
} function boot(){
document.querySelectorAll(‘.eco3-simu[data-eco3-simu]’).forEach(function(root){
if(root.dataset.e3sInit) return; root.dataset.e3sInit=’1′;
switch(root.getAttribute(‘data-eco3-simu’)){
case ‘interets-composes’: initInteretsComposes(root); break;
case ‘capacite-endettement’: initCapaciteEndettement(root); break;
case ‘resilience-financiere’: initResilienceFinanciere(root); break;
// futurs types : ajouter un case + un init dédié
}
});
}
if(document.readyState===’loading’) document.addEventListener(‘DOMContentLoaded’, boot);
else boot();
})();
ECO3JS;
} endif;
Last updated — 25 September 2026
Disclaimer – Financial and Legal Information: The analyses, commentary, and content published on eco3min.fr are provided for informational and educational purposes only. They do not constitute investment advice or a solicitation to buy or sell financial instruments. Past performance is not indicative of future results. All investment decisions involve risk and are the sole responsibility of the reader. Data, charts and calculated series are provided as is and may contain errors or lag behind their source: check any figure against the primary source cited before relying on it. Content describing laws, regulations or contracts reflects the law as of its publication date and does not constitute legal or tax advice; applying it to a specific situation requires a qualified legal or tax professional.
Manage Consent
We use cookies to keep the site running and, with your consent, to measure audience so we can improve our content. You can accept, decline or customise your choices at any time.
Fonctionnel Always active
Technical access or storage is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of transmitting a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistiques
The technical storage or access that is used exclusively for statistical purposes.Le stockage ou l’accès technique qui est utilisé exclusivement dans des finalités statistiques anonymes. En l’absence d’une assignation à comparaître, d’une conformité volontaire de la part de votre fournisseur d’accès à internet ou d’enregistrements supplémentaires provenant d’une tierce partie, les informations stockées ou extraites à cette seule fin ne peuvent généralement pas être utilisées pour vous identifier.
Marketing
L’accès ou le stockage technique est nécessaire pour créer des profils d’internautes afin d’envoyer des publicités, ou pour suivre l’utilisateur sur un site web ou sur plusieurs sites web ayant des finalités marketing similaires.
Eco3min measures its audience with Google Analytics (pages viewed, time on page, traffic source) and Microsoft Clarity (clicks, scrolling and session replay), with no advertising and no sale of data. You can opt out at any time. Privacy policy