@jjlmoya/utils-finance 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +64 -0
- package/src/category/i18n/en.ts +159 -0
- package/src/category/i18n/es.ts +159 -0
- package/src/category/i18n/fr.ts +159 -0
- package/src/category/index.ts +24 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +11 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +32 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/locale_completeness.test.ts +39 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/schemas_fulfillment.test.ts +23 -0
- package/src/tests/seo_length.test.ts +23 -0
- package/src/tests/title_quality.test.ts +55 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/compoundInterest/bibliography.astro +14 -0
- package/src/tool/compoundInterest/component.astro +697 -0
- package/src/tool/compoundInterest/i18n/en.ts +212 -0
- package/src/tool/compoundInterest/i18n/es.ts +212 -0
- package/src/tool/compoundInterest/i18n/fr.ts +212 -0
- package/src/tool/compoundInterest/index.ts +34 -0
- package/src/tool/compoundInterest/logic.ts +40 -0
- package/src/tool/compoundInterest/seo.astro +14 -0
- package/src/tool/compoundInterest/ui.ts +19 -0
- package/src/tool/courtFeeCalculator/bibliography.astro +14 -0
- package/src/tool/courtFeeCalculator/component.astro +427 -0
- package/src/tool/courtFeeCalculator/i18n/en.ts +268 -0
- package/src/tool/courtFeeCalculator/i18n/es.ts +268 -0
- package/src/tool/courtFeeCalculator/i18n/fr.ts +268 -0
- package/src/tool/courtFeeCalculator/index.ts +33 -0
- package/src/tool/courtFeeCalculator/logic.ts +86 -0
- package/src/tool/courtFeeCalculator/seo.astro +14 -0
- package/src/tool/courtFeeCalculator/ui.ts +31 -0
- package/src/tool/debtSnowball/bibliography.astro +14 -0
- package/src/tool/debtSnowball/component.astro +1052 -0
- package/src/tool/debtSnowball/i18n/en.ts +288 -0
- package/src/tool/debtSnowball/i18n/es.ts +288 -0
- package/src/tool/debtSnowball/i18n/fr.ts +288 -0
- package/src/tool/debtSnowball/index.ts +37 -0
- package/src/tool/debtSnowball/logic.ts +156 -0
- package/src/tool/debtSnowball/seo.astro +14 -0
- package/src/tool/debtSnowball/ui.ts +49 -0
- package/src/tool/fireCalculator/bibliography.astro +14 -0
- package/src/tool/fireCalculator/component.astro +689 -0
- package/src/tool/fireCalculator/i18n/en.ts +261 -0
- package/src/tool/fireCalculator/i18n/es.ts +261 -0
- package/src/tool/fireCalculator/i18n/fr.ts +261 -0
- package/src/tool/fireCalculator/index.ts +33 -0
- package/src/tool/fireCalculator/logic.ts +108 -0
- package/src/tool/fireCalculator/seo.astro +14 -0
- package/src/tool/fireCalculator/ui.ts +33 -0
- package/src/tool/ibanBicSwiftConverter/bibliography.astro +14 -0
- package/src/tool/ibanBicSwiftConverter/component.astro +581 -0
- package/src/tool/ibanBicSwiftConverter/i18n/en.ts +167 -0
- package/src/tool/ibanBicSwiftConverter/i18n/es.ts +216 -0
- package/src/tool/ibanBicSwiftConverter/i18n/fr.ts +167 -0
- package/src/tool/ibanBicSwiftConverter/index.ts +33 -0
- package/src/tool/ibanBicSwiftConverter/logic.ts +101 -0
- package/src/tool/ibanBicSwiftConverter/seo.astro +14 -0
- package/src/tool/ibanBicSwiftConverter/ui.ts +17 -0
- package/src/tool/inflation/bibliography.astro +14 -0
- package/src/tool/inflation/component.astro +400 -0
- package/src/tool/inflation/i18n/en.ts +301 -0
- package/src/tool/inflation/i18n/es.ts +301 -0
- package/src/tool/inflation/i18n/fr.ts +301 -0
- package/src/tool/inflation/index.ts +34 -0
- package/src/tool/inflation/logic.ts +92 -0
- package/src/tool/inflation/seo.astro +14 -0
- package/src/tool/inflation/ui.ts +17 -0
- package/src/tool/lateInterest/bibliography.astro +14 -0
- package/src/tool/lateInterest/component.astro +655 -0
- package/src/tool/lateInterest/i18n/en.ts +255 -0
- package/src/tool/lateInterest/i18n/es.ts +224 -0
- package/src/tool/lateInterest/i18n/fr.ts +224 -0
- package/src/tool/lateInterest/index.ts +34 -0
- package/src/tool/lateInterest/logic.ts +89 -0
- package/src/tool/lateInterest/seo.astro +14 -0
- package/src/tool/lateInterest/ui.ts +33 -0
- package/src/tool/legalInterestRate/bibliography.astro +14 -0
- package/src/tool/legalInterestRate/component.astro +650 -0
- package/src/tool/legalInterestRate/i18n/en.ts +159 -0
- package/src/tool/legalInterestRate/i18n/es.ts +159 -0
- package/src/tool/legalInterestRate/i18n/fr.ts +159 -0
- package/src/tool/legalInterestRate/index.ts +33 -0
- package/src/tool/legalInterestRate/logic.ts +29 -0
- package/src/tool/legalInterestRate/seo.astro +14 -0
- package/src/tool/legalInterestRate/ui.ts +23 -0
- package/src/tool/lotteryOptimizer/bibliography.astro +14 -0
- package/src/tool/lotteryOptimizer/component.astro +863 -0
- package/src/tool/lotteryOptimizer/i18n/en.ts +188 -0
- package/src/tool/lotteryOptimizer/i18n/es.ts +281 -0
- package/src/tool/lotteryOptimizer/i18n/fr.ts +188 -0
- package/src/tool/lotteryOptimizer/index.ts +33 -0
- package/src/tool/lotteryOptimizer/logic.ts +133 -0
- package/src/tool/lotteryOptimizer/seo.astro +14 -0
- package/src/tool/lotteryOptimizer/ui.ts +33 -0
- package/src/tool/mortgage/bibliography.astro +14 -0
- package/src/tool/mortgage/component.astro +1030 -0
- package/src/tool/mortgage/i18n/en.ts +227 -0
- package/src/tool/mortgage/i18n/es.ts +227 -0
- package/src/tool/mortgage/i18n/fr.ts +227 -0
- package/src/tool/mortgage/index.ts +34 -0
- package/src/tool/mortgage/logic.ts +118 -0
- package/src/tool/mortgage/seo.astro +14 -0
- package/src/tool/mortgage/ui.ts +35 -0
- package/src/tool/percentageCalculator/bibliography.astro +14 -0
- package/src/tool/percentageCalculator/component.astro +640 -0
- package/src/tool/percentageCalculator/i18n/en.ts +233 -0
- package/src/tool/percentageCalculator/i18n/es.ts +233 -0
- package/src/tool/percentageCalculator/i18n/fr.ts +233 -0
- package/src/tool/percentageCalculator/index.ts +34 -0
- package/src/tool/percentageCalculator/logic.ts +48 -0
- package/src/tool/percentageCalculator/seo.astro +14 -0
- package/src/tool/percentageCalculator/ui.ts +30 -0
- package/src/tool/rentIncreaseCalculator/bibliography.astro +14 -0
- package/src/tool/rentIncreaseCalculator/component.astro +587 -0
- package/src/tool/rentIncreaseCalculator/i18n/en.ts +159 -0
- package/src/tool/rentIncreaseCalculator/i18n/es.ts +220 -0
- package/src/tool/rentIncreaseCalculator/i18n/fr.ts +159 -0
- package/src/tool/rentIncreaseCalculator/index.ts +33 -0
- package/src/tool/rentIncreaseCalculator/logic.ts +43 -0
- package/src/tool/rentIncreaseCalculator/seo.astro +14 -0
- package/src/tool/rentIncreaseCalculator/ui.ts +19 -0
- package/src/tools.ts +16 -0
- package/src/types.ts +74 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { FIRECalculatorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const slug = 'calculatrice-regle-4-pour-cent-fire';
|
|
6
|
+
const title = 'Calculatrice FIRE Espagne: Règle des 4%';
|
|
7
|
+
const description = 'Calculez votre chiffre magique pour l\'indépendance financière en Espagne. Planifiez votre retraite anticipée et visualisez votre chemin vers la liberté économique.';
|
|
8
|
+
|
|
9
|
+
const faqData = [
|
|
10
|
+
{
|
|
11
|
+
question: 'Qu\'est-ce que la Règle des 4%?',
|
|
12
|
+
answer: 'La Règle des 4% est une stratégie de retraite basée sur l\'Étude Trinity indiquant que vous pouvez retirer 4% de votre patrimoine la première année, ajusté pour l\'inflation par la suite, sans épuiser vos fonds sur 30 ans.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: 'Qu\'est-ce que FIRE?',
|
|
16
|
+
answer: 'FIRE signifie Financial Independence, Retire Early (Indépendance Financière, Retraite Anticipée). C\'est un mouvement cherchant la liberté économique par une épargne agressive et des investissements intelligents.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: 'Quel est mon chiffre magique?',
|
|
20
|
+
answer: 'Votre chiffre magique est le patrimoine total nécessaire pour vivre des rendements sans travailler. Il est calculé en divisant vos dépenses annuelles par le taux de retrait sûr (généralement 4%).',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
question: 'Quelle est la différence entre Lean, Barista et Fat FIRE?',
|
|
24
|
+
answer: 'Lean FIRE signifie vivre avec des dépenses minimales (70% actuelles), Barista FIRE est un travail à temps partiel avec investissements couvrant le reste (50%), et Fat FIRE est un style de vie confortable (150% des dépenses).',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
question: 'La Règle des 4% est-elle réaliste?',
|
|
28
|
+
answer: 'La Règle des 4% a un taux de réussite historique de 95% dans un portefeuille 50/50 actions-obligations sur 30 ans. Cependant, elle ne tient pas compte du risque de séquence de rendements et repose principalement sur les données du marché américain.',
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const howToData = [
|
|
33
|
+
{
|
|
34
|
+
name: 'Calculez vos dépenses mensuelles',
|
|
35
|
+
text: 'Analysez ce que vous dépensez réellement chaque mois en incluant logement, nourriture, services et loisirs.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Choisissez votre taux de retrait sûr',
|
|
39
|
+
text: 'La Règle des 4% est standard, mais ajustez entre 2,5% (conservateur) et 6% (agressif) selon votre tolérance au risque.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'Entrez votre patrimoine actuel',
|
|
43
|
+
text: 'Additionnez vos investissements, épargnes et actifs générateurs de revenus.',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'Visualisez votre progression',
|
|
47
|
+
text: 'Voyez le graphique de croissance et les jalons de liberté (Lean, Barista, Fat FIRE) pour comprendre quand vous atteindrez votre objectif.',
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const bibliographyData = [
|
|
52
|
+
{
|
|
53
|
+
name: 'L\'Étude Trinity: Survivabilité du Portefeuille',
|
|
54
|
+
url: 'https://en.wikipedia.org/wiki/Trinity_study',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'Forum de Retraite Anticipée',
|
|
58
|
+
url: 'https://www.bogleheads.org/forum/',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'Indice CAPE de Shiller',
|
|
62
|
+
url: 'https://www.multpl.com/shiller-pe',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'Banque de France - Orientations Financières',
|
|
66
|
+
url: 'https://www.banque-france.fr/',
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
71
|
+
'@context': 'https://schema.org',
|
|
72
|
+
'@type': 'FAQPage',
|
|
73
|
+
mainEntity: faqData.map((item) => ({
|
|
74
|
+
'@type': 'Question',
|
|
75
|
+
name: item.question,
|
|
76
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
77
|
+
})),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const howToSchema: WithContext<HowTo> = {
|
|
81
|
+
'@context': 'https://schema.org',
|
|
82
|
+
'@type': 'HowTo',
|
|
83
|
+
name: title,
|
|
84
|
+
description,
|
|
85
|
+
step: howToData.map((step, i) => ({
|
|
86
|
+
'@type': 'HowToStep',
|
|
87
|
+
position: i + 1,
|
|
88
|
+
name: step.name,
|
|
89
|
+
text: step.text,
|
|
90
|
+
})),
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
94
|
+
'@context': 'https://schema.org',
|
|
95
|
+
'@type': 'SoftwareApplication',
|
|
96
|
+
name: title,
|
|
97
|
+
description,
|
|
98
|
+
applicationCategory: 'FinanceApplication',
|
|
99
|
+
operatingSystem: 'All',
|
|
100
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
101
|
+
inLanguage: 'fr',
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const content: ToolLocaleContent<FIRECalculatorUI> = {
|
|
105
|
+
slug,
|
|
106
|
+
title,
|
|
107
|
+
description,
|
|
108
|
+
faqTitle: 'Questions Fréquemment Posées',
|
|
109
|
+
faq: faqData,
|
|
110
|
+
bibliographyTitle: 'Sources et Références',
|
|
111
|
+
bibliography: bibliographyData,
|
|
112
|
+
howTo: howToData,
|
|
113
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
114
|
+
seo: [
|
|
115
|
+
{
|
|
116
|
+
type: 'title',
|
|
117
|
+
text: 'Règle des 4%: Le Saint Graal de la Retraite Anticipée',
|
|
118
|
+
level: 2,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
type: 'paragraph',
|
|
122
|
+
html: 'Découvrez comment calculer le patrimoine nécessaire pour vivre des rendements à jamais. La <strong>Règle des 4%</strong> provient de l\'Étude Trinity, menée en 1998 par trois professeurs de finance. Ils ont analysé les données de marché historiques depuis 1926 pour déterminer quel pourcentage pouvait être retiré annuellement sans épuiser le portefeuille en 30 ans.',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: 'stats',
|
|
126
|
+
columns: 4,
|
|
127
|
+
items: [
|
|
128
|
+
{ value: '95%', label: 'Taux de Réussite' },
|
|
129
|
+
{ value: '50/50', label: 'Mix Actions/Obligations' },
|
|
130
|
+
{ value: '30', label: 'Horizon Temporel' },
|
|
131
|
+
{ value: '4%', label: 'Retrait Sûr' },
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
type: 'title',
|
|
136
|
+
text: 'Qu\'est-ce que le Mouvement FIRE?',
|
|
137
|
+
level: 3,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: 'list',
|
|
141
|
+
items: [
|
|
142
|
+
'FIRE signifie Financial Independence, Retire Early (Indépendance Financière, Retraite Anticipée).',
|
|
143
|
+
'Cherche la liberté de choisir comment passer votre temps sans contraintes financières.',
|
|
144
|
+
'Basé sur l\'optimisation de l\'épargne et des stratégies d\'investissement intelligentes.',
|
|
145
|
+
'Vise ce que vos actifs génèrent suffisamment de flux de trésorerie pour couvrir vos dépenses.',
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: 'title',
|
|
150
|
+
text: 'Types de Liberté Financière',
|
|
151
|
+
level: 3,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: 'comparative',
|
|
155
|
+
columns: 3,
|
|
156
|
+
items: [
|
|
157
|
+
{
|
|
158
|
+
title: 'Lean FIRE',
|
|
159
|
+
description: 'Mode de vie minimaliste couvrant uniquement les dépenses de survie.',
|
|
160
|
+
points: ['Épargne extrême', 'Dépenses très faibles', 'Liberté frugale'],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
title: 'Barista FIRE',
|
|
164
|
+
description: 'Situation hybride où les investissements couvrent la moitié de vos dépenses.',
|
|
165
|
+
points: ['Travail par choix', 'Couverture sociale assurée', 'Moins de stress'],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
title: 'Fat FIRE',
|
|
169
|
+
description: 'Retraite confortable avec budget pour luxes et voyages.',
|
|
170
|
+
points: ['Patrimoine élevé', 'Aucune restriction', 'Héritage familial'],
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: 'title',
|
|
176
|
+
text: 'Comment Utiliser Notre Calculatrice FIRE?',
|
|
177
|
+
level: 3,
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
type: 'list',
|
|
181
|
+
items: [
|
|
182
|
+
'<strong>Suivi des Dépenses:</strong> Analysez vos dépenses réelles sur 12 mois.',
|
|
183
|
+
'<strong>Définition du Taux:</strong> Choisissez votre taux de retrait sûr selon votre risque.',
|
|
184
|
+
'<strong>Patrimoine Actuel:</strong> Entrez la valeur totale de vos investissements.',
|
|
185
|
+
'<strong>Capacité d\'Épargne:</strong> Projetez combien de temps jusqu\'à votre objectif.',
|
|
186
|
+
'<strong>Aperçus Visuels:</strong> Analysez votre graphique de croissance et jalons.',
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
type: 'title',
|
|
191
|
+
text: 'Analyse de la Règle des 4%',
|
|
192
|
+
level: 3,
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
type: 'comparative',
|
|
196
|
+
columns: 2,
|
|
197
|
+
items: [
|
|
198
|
+
{
|
|
199
|
+
title: 'Avantages',
|
|
200
|
+
description: 'Pourquoi la règle des 4% fonctionne',
|
|
201
|
+
points: [
|
|
202
|
+
'Mathématiques simples pour une planification rapide.',
|
|
203
|
+
'Basée sur près d\'un siècle de données historiques.',
|
|
204
|
+
'Adaptable à n\'importe quel niveau de dépenses.',
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
title: 'Limitations',
|
|
209
|
+
description: 'Ce que la règle des 4% ne couvre pas',
|
|
210
|
+
points: [
|
|
211
|
+
'Ne tient pas compte du risque de séquence de rendements.',
|
|
212
|
+
'Basée principalement sur les données du marché américain.',
|
|
213
|
+
'Ignore les changements majeurs de lois fiscales.',
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
type: 'title',
|
|
220
|
+
text: 'Facteur Critique: L\'Inflation',
|
|
221
|
+
level: 3,
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
type: 'paragraph',
|
|
225
|
+
html: 'Rappelez-vous que 1 000€ aujourd\'hui ne achèteront pas la même chose à l\'avenir. Il est vital d\'utiliser des rendements réels (ajustés pour l\'inflation) pour que vos projections conservent le pouvoir d\'achat actuel. La Règle des 4% suppose que vous ajustez les retraits annuellement pour l\'inflation.',
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
ui: {
|
|
229
|
+
labelTitle: 'Calculatrice FIRE: Règle des 4%',
|
|
230
|
+
labelDescription: 'Calculez votre chiffre magique pour l\'indépendance financière et visualisez vos jalons vers la liberté économique.',
|
|
231
|
+
labelMonthlyExpenses: 'Dépenses Mensuelles',
|
|
232
|
+
labelSWR: 'Taux de Retrait Sûr',
|
|
233
|
+
labelCurrentWorth: 'Patrimoine Actuel',
|
|
234
|
+
labelMonthlySavings: 'Capacité d\'Épargne Mensuelle',
|
|
235
|
+
labelAnnualReturn: 'Rendement Estimé (Net)',
|
|
236
|
+
labelFreedomMilestones: 'Jalons de Liberté',
|
|
237
|
+
labelLeanFIRE: 'Lean FIRE (70% survie)',
|
|
238
|
+
labelBaristaFIRE: 'Barista FIRE (50% revenus)',
|
|
239
|
+
labelFatFIRE: 'Fat FIRE (150% luxe)',
|
|
240
|
+
labelMagicNumber: 'Votre Chiffre Magique pour la Liberté',
|
|
241
|
+
labelMagicNumberDesc: 'Capital nécessaire pour vivre des rendements',
|
|
242
|
+
labelTimeRemaining: 'Temps jusqu\'à la liberté financière',
|
|
243
|
+
labelTimeRemainingFormat: 'Il vous reste {years} ans et {months} mois',
|
|
244
|
+
labelAlreadyFI: 'Vous avez déjà atteint la liberté financière!',
|
|
245
|
+
labelUnachievable: 'Objectif inatteignable avec cette épargne',
|
|
246
|
+
labelHiddenCostsChecklist: 'Liste de Contrôle des Dépenses Cachées',
|
|
247
|
+
labelHealth: 'Assurance Santé (+200€)',
|
|
248
|
+
labelTaxes: 'Impôts (+150€)',
|
|
249
|
+
labelHome: 'Entretien Domicile (+100€)',
|
|
250
|
+
labelTravel: 'Voyage et Loisirs (+300€)',
|
|
251
|
+
labelEmergency: 'Fonds d\'Urgence (+100€)',
|
|
252
|
+
labelSubscriptions: 'Abonnements (+50€)',
|
|
253
|
+
labelAdded: 'Ajouté:',
|
|
254
|
+
labelSavePlan: 'Enregistrer le Plan',
|
|
255
|
+
labelSWRTooltip: 'Taux de Retrait Sûr: Le pourcentage de vos épargnes que vous pouvez retirer chaque année sans manquer d\'argent.',
|
|
256
|
+
labelReturnTooltip: 'Rendement annuel du marché (ajusté pour l\'inflation). La norme historique est de 7%.',
|
|
257
|
+
currencySymbol: '€',
|
|
258
|
+
currencyCode: 'EUR',
|
|
259
|
+
currencyLocale: 'fr-FR',
|
|
260
|
+
},
|
|
261
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FinanceToolEntry, ToolLocaleContent, ToolDefinition } from '../../types';
|
|
2
|
+
import FIRECalculatorComponent from './component.astro';
|
|
3
|
+
import FIRECalculatorSEO from './seo.astro';
|
|
4
|
+
import FIRECalculatorBibliography from './bibliography.astro';
|
|
5
|
+
import type { FIRECalculatorUI } from './ui';
|
|
6
|
+
|
|
7
|
+
export type FIRECalculatorLocaleContent = ToolLocaleContent<FIRECalculatorUI>;
|
|
8
|
+
|
|
9
|
+
import { content as es } from './i18n/es';
|
|
10
|
+
import { content as en } from './i18n/en';
|
|
11
|
+
import { content as fr } from './i18n/fr';
|
|
12
|
+
|
|
13
|
+
export const fireCalculator: FinanceToolEntry<FIRECalculatorUI> = {
|
|
14
|
+
id: 'calculadora-regla-4-por-ciento-fire',
|
|
15
|
+
icons: {
|
|
16
|
+
bg: 'mdi:chart-line',
|
|
17
|
+
fg: 'mdi:trending-up',
|
|
18
|
+
},
|
|
19
|
+
i18n: {
|
|
20
|
+
es: async () => es,
|
|
21
|
+
en: async () => en,
|
|
22
|
+
fr: async () => fr,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { FIRECalculatorComponent, FIRECalculatorSEO, FIRECalculatorBibliography };
|
|
27
|
+
|
|
28
|
+
export const FIRE_CALCULATOR_TOOL: ToolDefinition = {
|
|
29
|
+
entry: fireCalculator,
|
|
30
|
+
Component: FIRECalculatorComponent,
|
|
31
|
+
SEOComponent: FIRECalculatorSEO,
|
|
32
|
+
BibliographyComponent: FIRECalculatorBibliography,
|
|
33
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export interface FIRECalculationResult {
|
|
2
|
+
magicNumber: number;
|
|
3
|
+
monthlyExpenses: number;
|
|
4
|
+
annualExpenses: number;
|
|
5
|
+
annualReturn: number;
|
|
6
|
+
currentWorth: number;
|
|
7
|
+
monthlySavings: number;
|
|
8
|
+
swr: number;
|
|
9
|
+
yearsToFI: number;
|
|
10
|
+
monthsToFI: number;
|
|
11
|
+
leanTarget: number;
|
|
12
|
+
baristaTarget: number;
|
|
13
|
+
fatTarget: number;
|
|
14
|
+
wealthHistory: number[];
|
|
15
|
+
isAlreadyFI: boolean;
|
|
16
|
+
isAchievable: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface CalcParams {
|
|
20
|
+
monthlyExpenses: number;
|
|
21
|
+
swr: number;
|
|
22
|
+
currentWorth: number;
|
|
23
|
+
monthlySavings: number;
|
|
24
|
+
annualReturn: number;
|
|
25
|
+
extraCosts?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface HistoryParams {
|
|
29
|
+
pv: number;
|
|
30
|
+
pmt: number;
|
|
31
|
+
r: number;
|
|
32
|
+
totalMonths: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class FIRELogic {
|
|
36
|
+
static calculateFIRE(params: CalcParams): FIRECalculationResult {
|
|
37
|
+
const totalExpenses = params.monthlyExpenses + (params.extraCosts || 0);
|
|
38
|
+
const annualExpenses = totalExpenses * 12;
|
|
39
|
+
const magicNumber = annualExpenses / (params.swr / 100);
|
|
40
|
+
const monthlyReturn = Math.pow(1 + params.annualReturn / 100, 1 / 12) - 1;
|
|
41
|
+
const timeAndTargets = this.calculateTimeToFI(monthlyReturn, params.currentWorth, params.monthlySavings, magicNumber);
|
|
42
|
+
const wealthHistory = this.generateWealthHistory({ pv: params.currentWorth, pmt: params.monthlySavings, r: monthlyReturn, totalMonths: timeAndTargets.months });
|
|
43
|
+
const { leanTarget, baristaTarget, fatTarget } = this.calculateTargets(magicNumber);
|
|
44
|
+
return {
|
|
45
|
+
magicNumber, monthlyExpenses: totalExpenses, annualExpenses, annualReturn: params.annualReturn, currentWorth: params.currentWorth,
|
|
46
|
+
monthlySavings: params.monthlySavings, swr: params.swr, yearsToFI: timeAndTargets.yearsToFI, monthsToFI: timeAndTargets.monthsToFI,
|
|
47
|
+
leanTarget, baristaTarget, fatTarget, wealthHistory, isAlreadyFI: timeAndTargets.isAlreadyFI, isAchievable: timeAndTargets.isAchievable,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private static calculateTimeToFI(
|
|
52
|
+
r: number,
|
|
53
|
+
PV: number,
|
|
54
|
+
PMT: number,
|
|
55
|
+
FV: number
|
|
56
|
+
): { months: number; yearsToFI: number; monthsToFI: number; isAlreadyFI: boolean; isAchievable: boolean } {
|
|
57
|
+
let months = 0;
|
|
58
|
+
let isAlreadyFI = false;
|
|
59
|
+
let isAchievable = true;
|
|
60
|
+
|
|
61
|
+
if (PV >= FV) {
|
|
62
|
+
isAlreadyFI = true;
|
|
63
|
+
} else if (r === 0) {
|
|
64
|
+
isAchievable = PMT > 0;
|
|
65
|
+
months = isAchievable ? (FV - PV) / PMT : Infinity;
|
|
66
|
+
} else {
|
|
67
|
+
const numerator = FV * r + PMT;
|
|
68
|
+
const denominator = PV * r + PMT;
|
|
69
|
+
isAchievable = numerator > 0 && denominator > 0;
|
|
70
|
+
months = isAchievable ? Math.log(numerator / denominator) / Math.log(1 + r) : Infinity;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
months,
|
|
75
|
+
yearsToFI: Math.floor(months / 12),
|
|
76
|
+
monthsToFI: Math.ceil(months) % 12,
|
|
77
|
+
isAlreadyFI,
|
|
78
|
+
isAchievable,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private static generateWealthHistory(params: HistoryParams): number[] {
|
|
83
|
+
const { pv, pmt, r, totalMonths } = params;
|
|
84
|
+
const history: number[] = [pv];
|
|
85
|
+
const steps = 50;
|
|
86
|
+
const duration = isFinite(totalMonths) ? Math.max(totalMonths, 12) : 12 * 50;
|
|
87
|
+
|
|
88
|
+
for (let i = 1; i <= steps; i++) {
|
|
89
|
+
const t = (i / steps) * duration;
|
|
90
|
+
const w = r === 0 ? pv + pmt * t : pv * Math.pow(1 + r, t) + (pmt * (Math.pow(1 + r, t) - 1)) / r;
|
|
91
|
+
history.push(w);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return history;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private static calculateTargets(magicNumber: number) {
|
|
98
|
+
return {
|
|
99
|
+
leanTarget: magicNumber * 0.7,
|
|
100
|
+
baristaTarget: magicNumber * 0.5,
|
|
101
|
+
fatTarget: magicNumber * 1.5,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static getMilestoneProgress(current: number, target: number): number {
|
|
106
|
+
return Math.min(100, (current / target) * 100);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { SEORenderer } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { fireCalculator } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await fireCalculator.i18n[locale]?.();
|
|
12
|
+
if (!content) return null;
|
|
13
|
+
---
|
|
14
|
+
<SEORenderer content={{ locale: locale as string, sections: content.seo }} />
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface FIRECalculatorUI {
|
|
2
|
+
labelTitle: string;
|
|
3
|
+
labelDescription: string;
|
|
4
|
+
labelMonthlyExpenses: string;
|
|
5
|
+
labelSWR: string;
|
|
6
|
+
labelCurrentWorth: string;
|
|
7
|
+
labelMonthlySavings: string;
|
|
8
|
+
labelAnnualReturn: string;
|
|
9
|
+
labelFreedomMilestones: string;
|
|
10
|
+
labelLeanFIRE: string;
|
|
11
|
+
labelBaristaFIRE: string;
|
|
12
|
+
labelFatFIRE: string;
|
|
13
|
+
labelMagicNumber: string;
|
|
14
|
+
labelMagicNumberDesc: string;
|
|
15
|
+
labelTimeRemaining: string;
|
|
16
|
+
labelTimeRemainingFormat: string;
|
|
17
|
+
labelAlreadyFI: string;
|
|
18
|
+
labelUnachievable: string;
|
|
19
|
+
labelHiddenCostsChecklist: string;
|
|
20
|
+
labelHealth: string;
|
|
21
|
+
labelTaxes: string;
|
|
22
|
+
labelHome: string;
|
|
23
|
+
labelTravel: string;
|
|
24
|
+
labelEmergency: string;
|
|
25
|
+
labelSubscriptions: string;
|
|
26
|
+
labelAdded: string;
|
|
27
|
+
labelSavePlan: string;
|
|
28
|
+
labelSWRTooltip: string;
|
|
29
|
+
labelReturnTooltip: string;
|
|
30
|
+
currencySymbol: string;
|
|
31
|
+
currencyCode: string;
|
|
32
|
+
currencyLocale: string;
|
|
33
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { ibanBicSwift } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await ibanBicSwift.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <SharedBibliography links={content.bibliography} />}
|