Executive Code: Fourester’s Economic Forecasting System, Asset Allocation System and Mutual Fund Recommendation System
Macro Economic Forecast
Instructions
Copy and paste the code into Anthropic’s Claude and ask Claude to read the code in detail and update the data using Claude’s search capabilities and the named sources within the code’s architecture. Furthermore ask Claude to produce a report using the code and updated data. The report should be written using paragraphs of five to seven sentences with up to two paragraphs per section if the narrative is supported by accurate numerical observations from the use of the code submitted. The report should conclude with a bottom line section and paragraph stating an accurate integrated view of the preceding sections.
The Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Economic Forecasting System v10.0 - Enhanced Edition</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #334155 100%);
min-height: 100vh;
color: #e2e8f0;
line-height: 1.6;
}
.header {
background: rgba(0,0,0,0.8);
backdrop-filter: blur(20px);
padding: 15px 40px;
border-bottom: 2px solid #3b82f6;
position: sticky;
top: 0;
z-index: 1000;
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
}
.header-content {
max-width: 1800px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 15px;
}
.logo {
font-size: 1.6em;
font-weight: 700;
background: linear-gradient(45deg, #3b82f6, #8b5cf6, #ec4899);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.version { font-size: 0.65em; color: #94a3b8; font-weight: 400; margin-left: 8px; }
.status-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15px;
font-size: 0.8em;
}
.status-item {
text-align: center;
padding: 6px 10px;
background: rgba(59,130,246,0.1);
border-radius: 6px;
border: 1px solid rgba(59,130,246,0.3);
}
.status-label { color: #94a3b8; font-size: 0.85em; margin-bottom: 3px; }
.status-value { color: #3b82f6; font-weight: 600; font-size: 1.05em; }
.container { max-width: 1800px; margin: 0 auto; padding: 25px; }
.panel {
background: rgba(15,23,42,0.6);
backdrop-filter: blur(10px);
border: 1px solid rgba(59,130,246,0.2);
border-radius: 12px;
padding: 25px;
margin-bottom: 25px;
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
}
.panel-title {
font-size: 1.4em;
color: #60a5fa;
margin-bottom: 15px;
font-weight: 600;
}
.disclaimer {
background: linear-gradient(135deg, rgba(239,68,68,0.2), rgba(220,38,38,0.15));
border: 2px solid #ef4444;
border-radius: 12px;
padding: 20px;
margin-bottom: 25px;
}
.disclaimer-title { font-size: 1.2em; font-weight: 700; color: #fca5a5; margin-bottom: 10px; }
.disclaimer-text { color: #fecaca; line-height: 1.8; font-size: 0.9em; }
.input-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
margin: 20px 0;
}
.input-group { display: flex; flex-direction: column; gap: 8px; }
.input-label { color: #94a3b8; font-size: 0.9em; font-weight: 500; }
.input-field, .select-field {
padding: 10px 12px;
border-radius: 8px;
border: 1px solid rgba(59,130,246,0.3);
background: rgba(15,23,42,0.6);
color: #e2e8f0;
font-size: 0.95em;
}
.input-field:focus, .select-field:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59,130,246,0.1);
}
.slider-container { display: flex; align-items: center; gap: 15px; }
.slider {
flex: 1;
height: 6px;
border-radius: 3px;
background: rgba(59,130,246,0.2);
outline: none;
-webkit-appearance: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 18px;
height: 18px;
border-radius: 50%;
background: #3b82f6;
cursor: pointer;
}
.slider-value {
min-width: 40px;
text-align: center;
color: #60a5fa;
font-weight: 600;
}
.btn {
padding: 12px 24px;
border-radius: 8px;
font-size: 1em;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
border: none;
display: inline-flex;
align-items: center;
gap: 8px;
}
.btn-primary {
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
color: white;
box-shadow: 0 4px 15px rgba(59,130,246,0.4);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(59,130,246,0.6);
}
.btn-secondary {
background: rgba(59,130,246,0.1);
color: #60a5fa;
border: 2px solid #3b82f6;
}
.btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }
.btn-group { display: flex; gap: 12px; flex-wrap: wrap; }
.loading {
display: inline-block;
width: 16px;
height: 16px;
border: 3px solid rgba(96,165,250,0.3);
border-radius: 50%;
border-top-color: #60a5fa;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.section { background: rgba(15,23,42,0.4); border-left: 4px solid #3b82f6; border-radius: 12px; padding: 25px; margin-bottom: 25px; }
.section-title { color: #60a5fa; font-size: 1.6em; margin-bottom: 20px; font-weight: 700; border-bottom: 2px solid rgba(59,130,246,0.3); padding-bottom: 12px; }
.subsection-title { color: #a78bfa; font-size: 1.3em; margin: 25px 0 15px 0; font-weight: 600; }
.chart-container {
position: relative;
height: 400px;
margin: 25px 0;
padding: 20px;
background: rgba(255,255,255,0.05);
border-radius: 12px;
}
.forecast-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin: 20px 0;
}
.forecast-card {
background: rgba(15,23,42,0.6);
border-radius: 10px;
padding: 18px;
border: 1px solid rgba(59,130,246,0.3);
text-align: center;
}
.forecast-label { color: #94a3b8; font-size: 0.85em; margin-bottom: 8px; text-transform: uppercase; }
.forecast-value { font-size: 2em; font-weight: 700; color: #60a5fa; margin: 8px 0; }
.forecast-range { color: #94a3b8; font-size: 0.8em; }
.model-header {
background: rgba(139,92,246,0.2);
border-left: 3px solid #8b5cf6;
padding: 12px;
margin: 15px 0;
border-radius: 8px;
}
.model-name { font-weight: 700; color: #a78bfa; font-size: 1.1em; }
.model-economists { color: #94a3b8; font-size: 0.9em; margin-top: 4px; }
.explanation { color: #cbd5e1; line-height: 1.9; margin: 20px 0; padding: 20px; background: rgba(0,0,0,0.2); border-radius: 8px; border-left: 3px solid #3b82f6; }
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted #3b82f6;
cursor: help;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 300px;
background-color: rgba(15,23,42,0.95);
color: #e2e8f0;
text-align: left;
border-radius: 8px;
padding: 12px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -150px;
opacity: 0;
transition: opacity 0.3s;
border: 1px solid #3b82f6;
font-size: 0.85em;
line-height: 1.6;
}
.tooltip:hover .tooltiptext { visibility: visible; opacity: 1; }
.allocation-table, .fund-table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.allocation-table th, .fund-table th {
background: rgba(59,130,246,0.2);
color: #60a5fa;
font-weight: 600;
padding: 12px;
text-align: left;
}
.allocation-table td, .fund-table td {
padding: 12px;
border-bottom: 1px solid rgba(59,130,246,0.2);
color: #cbd5e1;
}
.weight-value { font-size: 1.5em; font-weight: 700; color: #60a5fa; }
.fund-item {
background: rgba(0,0,0,0.3);
border: 1px solid rgba(59,130,246,0.2);
border-radius: 8px;
padding: 15px;
margin-bottom: 12px;
display: grid;
grid-template-columns: 60px 1fr auto;
gap: 15px;
align-items: center;
}
.fund-rank { font-size: 1.8em; font-weight: 700; color: #fbbf24; text-align: center; }
.fund-rank.top5 { color: #4ade80; }
.fund-ticker { color: #60a5fa; font-weight: 700; font-size: 1.2em; }
.fund-name { color: #94a3b8; font-size: 0.95em; margin-top: 3px; }
.fund-metrics {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
text-align: center;
}
.fund-metric-label { color: #64748b; font-size: 0.8em; }
.fund-metric-value { color: #4ade80; font-weight: 700; font-size: 1.1em; }
.stress-test-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
margin: 20px 0;
}
.stress-card {
background: rgba(239,68,68,0.1);
border: 1px solid rgba(239,68,68,0.3);
border-radius: 8px;
padding: 15px;
}
.stress-scenario { color: #fca5a5; font-weight: 600; margin-bottom: 10px; }
.stress-impact { color: #fecaca; font-size: 0.9em; }
.impact-value { font-size: 1.4em; font-weight: 700; color: #ef4444; margin: 8px 0; }
.tab-container { display: flex; gap: 10px; margin-bottom: 20px; border-bottom: 2px solid rgba(59,130,246,0.2); }
.tab {
padding: 10px 20px;
cursor: pointer;
border-bottom: 3px solid transparent;
transition: all 0.3s;
color: #94a3b8;
}
.tab:hover { color: #60a5fa; }
.tab.active { color: #60a5fa; border-bottom-color: #3b82f6; font-weight: 600; }
.tab-content { display: none; }
.tab-content.active { display: block; }
.transition-plan {
background: rgba(59,130,246,0.1);
border: 1px solid rgba(59,130,246,0.3);
border-radius: 8px;
padding: 20px;
margin: 20px 0;
}
.step { margin: 15px 0; padding-left: 25px; position: relative; }
.step::before {
content: '→';
position: absolute;
left: 0;
color: #3b82f6;
font-weight: 700;
}
.data-sources-section {
background: rgba(0,0,0,0.3);
border-radius: 12px;
padding: 30px;
margin: 30px 0;
}
.data-source-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 15px;
margin: 20px 0;
}
.data-source-item {
background: rgba(59,130,246,0.1);
padding: 15px;
border-radius: 8px;
border: 1px solid rgba(59,130,246,0.2);
transition: all 0.3s ease;
}
.data-source-item:hover {
background: rgba(59,130,246,0.2);
transform: translateY(-2px);
}
.data-source-name {
color: #60a5fa;
font-weight: 600;
margin-bottom: 5px;
}
.data-source-url {
color: #94a3b8;
font-size: 0.85em;
word-break: break-all;
}
.source-category {
color: #a78bfa;
font-size: 1.2em;
font-weight: 600;
margin: 25px 0 15px 0;
padding-left: 12px;
border-left: 3px solid #8b5cf6;
}
@media (max-width: 768px) {
.container { padding: 15px; }
.input-grid { grid-template-columns: 1fr; }
.status-grid { grid-template-columns: repeat(2, 1fr); }
.chart-container { height: 300px; }
}
</style>
</head>
<body>
<div class="header">
<div class="header-content">
<div class="logo">
ECONOMIC FORECASTING SYSTEM
<span class="version">v10.0 Enhanced</span>
</div>
<div class="status-grid">
<div class="status-item">
<div class="status-label">Status</div>
<div class="status-value" id="system-status">READY</div>
</div>
<div class="status-item">
<div class="status-label">Models</div>
<div class="status-value">7</div>
</div>
<div class="status-item">
<div class="status-label">Funds</div>
<div class="status-value">80</div>
</div>
<div class="status-item">
<div class="status-label">Sources</div>
<div class="status-value">25+</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="disclaimer">
<div class="disclaimer-title">⚠ CRITICAL LEGAL DISCLAIMER</div>
<div class="disclaimer-text">
This system is for <strong>EDUCATIONAL AND RESEARCH PURPOSES ONLY</strong>.
It does NOT constitute financial advice, investment recommendations, or solicitation
to buy or sell securities. Economic forecasting has inherent limitations.
<strong>DO NOT make investment decisions based solely on this analysis.</strong>
Consult a licensed financial advisor. The creators assume NO liability for losses.
</div>
</div>
<div class="panel">
<div class="panel-title">User Customization</div>
<div class="input-grid">
<div class="input-group">
<label class="input-label">Investment Horizon</label>
<select class="select-field" id="horizon">
<option value="1">1 Year</option>
<option value="3">3 Years</option>
<option value="5" selected>5 Years</option>
<option value="10">10 Years</option>
<option value="20">20 Years</option>
</select>
</div>
<div class="input-group">
<label class="input-label">Current Age</label>
<input type="number" class="input-field" id="age" value="35" min="18" max="100">
</div>
<div class="input-group">
<label class="input-label">Risk Tolerance (1-10)</label>
<div class="slider-container">
<input type="range" class="slider" id="risk" min="1" max="10" value="5">
<span class="slider-value" id="risk-value">5</span>
</div>
</div>
<div class="input-group">
<label class="input-label">Portfolio Size ($)</label>
<input type="number" class="input-field" id="portfolio" value="100000" min="1000" step="1000">
</div>
</div>
</div>
<div class="panel">
<div class="panel-title">Generate Analysis</div>
<div class="btn-group">
<button class="btn btn-primary" onclick="generateReport()">
<span>Generate Complete Report</span>
</button>
<button class="btn btn-secondary" onclick="runStressTest()">
<span>Stress Test Portfolio</span>
</button>
<button class="btn btn-secondary" onclick="exportReport()">
<span>Export Data (JSON)</span>
</button>
</div>
</div>
<div id="report-container"></div>
</div>
<script>
'use strict';
const CONFIG = Object.freeze({
VERSION: '10.0.0',
HORIZONS: [6, 12, 18, 24],
MODELS: 7,
TOTAL_FUNDS: 80,
DATA_SOURCES: 25
});
const GLOSSARY = {
'DSGE': 'Dynamic Stochastic General Equilibrium - A macroeconomic model used by central banks to analyze economic policies',
'Phillips Curve': 'Economic model showing inverse relationship between unemployment and inflation',
'Output Gap': 'Difference between actual and potential GDP, expressed as percentage',
'NAIRU': 'Non-Accelerating Inflation Rate of Unemployment - the unemployment rate consistent with stable inflation',
'Yield Spread': 'Difference between long-term and short-term interest rates; inverted curve (negative spread) often predicts recession',
'Black-Litterman': 'Portfolio optimization model combining market equilibrium with investor views',
'Risk Parity': 'Asset allocation strategy that equalizes risk contribution across asset classes',
'Sharpe Ratio': 'Risk-adjusted return measure; higher is better (>1.0 is good)',
'VaR': 'Value at Risk - maximum expected loss over specified time period at given confidence level'
};
const MODELS = {
growth: {
name: 'Smets-Wouters DSGE Model',
economists: 'Frank Smets & Raf Wouters',
affiliation: 'ECB / National Bank of Belgium',
paper: 'Shocks and Frictions in US Business Cycles (2007)',
formula: 'Ŷₜ = E[Ŷₜ₊₁] - σ(Rₜ - E[πₜ₊₁] - r*) + εₜ'
},
inflation: {
name: 'New Keynesian Phillips Curve',
economists: 'Olivier Blanchard & Jordi Galí',
affiliation: 'MIT / CREI',
paper: 'Real Wage Rigidities and the New Keynesian Model (2007)',
formula: 'πₜ = βE[πₜ₊₁] + κ(yₜ - y*) + λΔpᵢₘ + υₜ'
},
recession: {
name: 'Estrella-Mishkin Probit Model',
economists: 'Arturo Estrella & Frederic Mishkin',
affiliation: 'Federal Reserve',
paper: 'Predicting U.S. Recessions (1998)',
formula: 'P(Recession) = Φ(β₀ + β₁*Spread + β₂*StockReturn + β₃*FedRate)'
}
};
const DATA_SOURCES = {
government: [
{ name: 'FDIC BankFind Suite', url: 'https://banks.data.fdic.gov', type: 'Primary' },
{ name: 'Federal Reserve Economic Data (FRED)', url: 'https://fred.stlouisfed.org', type: 'Primary' },
{ name: 'Bureau of Labor Statistics (BLS)', url: 'https://bls.gov/data', type: 'Primary' },
{ name: 'Bureau of Economic Analysis (BEA)', url: 'https://bea.gov', type: 'Primary' },
{ name: 'US Treasury', url: 'https://fiscaldata.treasury.gov', type: 'Primary' },
{ name: 'World Bank Open Data', url: 'https://data.worldbank.org', type: 'Secondary' }
],
financial: [
{ name: 'SEC EDGAR Database', url: 'https://www.sec.gov/edgar', type: 'Primary' },
{ name: 'Yahoo Finance', url: 'https://finance.yahoo.com', type: 'Market Data' },
{ name: 'FINRA BrokerCheck', url: 'https://brokercheck.finra.org', type: 'Regulatory' },
{ name: 'FINRA TRACE', url: 'https://www.finra.org/finra-data/browse-catalog/fixed-income', type: 'Bond Data' },
{ name: 'S&P Global Market Intelligence', url: 'https://www.spglobal.com/marketintelligence', type: 'Research' }
],
market: [
{ name: 'Statista', url: 'https://www.statista.com', type: 'Market Research' },
{ name: 'Google Scholar', url: 'https://scholar.google.com', type: 'Academic' },
{ name: 'OECD Statistics', url: 'https://stats.oecd.org', type: 'International' },
{ name: 'IMF Data', url: 'https://www.imf.org/en/Data', type: 'International' }
],
credit: [
{ name: "Moody's Analytics", url: 'https://www.moodys.com', type: 'Credit Rating' },
{ name: 'S&P Global Ratings', url: 'https://www.spglobal.com/ratings', type: 'Credit Rating' },
{ name: 'Fitch Ratings', url: 'https://www.fitchratings.com', type: 'Credit Rating' },
{ name: 'Bloomberg Terminal', url: 'https://www.bloomberg.com/professional', type: 'Professional' }
],
research: [
{ name: 'National Bureau of Economic Research (NBER)', url: 'https://www.nber.org', type: 'Academic' },
{ name: 'Federal Reserve Bank Publications', url: 'https://www.federalreserve.gov/publications', type: 'Research' },
{ name: 'ECB Statistical Data Warehouse', url: 'https://sdw.ecb.europa.eu', type: 'International' },
{ name: 'Bank for International Settlements (BIS)', url: 'https://www.bis.org/statistics', type: 'International' },
{ name: 'American Economic Association', url: 'https://www.aeaweb.org', type: 'Academic' },
{ name: 'Journal of Finance', url: 'https://onlinelibrary.wiley.com/journal/15406261', type: 'Academic' }
]
};
const FUNDS = {
recession: {
top20: [
{rank:1,ticker:'TLT',name:'iShares 20+ Year Treasury',expense:0.15,score:9.5,type:'ETF'},
{rank:2,ticker:'VGLT',name:'Vanguard Long-Term Treasury',expense:0.04,score:9.3,type:'ETF'},
{rank:3,ticker:'GLD',name:'SPDR Gold Shares',expense:0.40,score:9.0,type:'ETF'},
{rank:4,ticker:'VDIGX',name:'Vanguard Dividend Growth',expense:0.26,score:9.2,type:'Fund'},
{rank:5,ticker:'SCHD',name:'Schwab US Dividend Equity',expense:0.06,score:8.8,type:'ETF'},
{rank:6,ticker:'VIG',name:'Vanguard Dividend Appreciation',expense:0.06,score:8.7,type:'ETF'},
{rank:7,ticker:'NOBL',name:'ProShares Dividend Aristocrats',expense:0.35,score:8.6,type:'ETF'},
{rank:8,ticker:'HDV',name:'iShares Core High Dividend',expense:0.08,score:8.5,type:'ETF'},
{rank:9,ticker:'USMV',name:'iShares Min Volatility',expense:0.15,score:8.4,type:'ETF'},
{rank:10,ticker:'IEF',name:'iShares 7-10 Year Treasury',expense:0.15,score:8.3,type:'ETF'},
{rank:11,ticker:'BND',name:'Vanguard Total Bond Market',expense:0.03,score:8.5,type:'ETF'},
{rank:12,ticker:'AGG',name:'iShares Core Aggregate Bond',expense:0.03,score:8.4,type:'ETF'},
{rank:13,ticker:'IAU',name:'iShares Gold Trust',expense:0.25,score:8.9,type:'ETF'},
{rank:14,ticker:'VPU',name:'Vanguard Utilities',expense:0.10,score:8.5,type:'ETF'},
{rank:15,ticker:'XLP',name:'Consumer Staples Select',expense:0.10,score:8.4,type:'ETF'},
{rank:16,ticker:'VMBS',name:'Vanguard Mortgage-Backed',expense:0.04,score:8.2,type:'ETF'},
{rank:17,ticker:'SPLV',name:'Invesco Low Volatility',expense:0.25,score:8.3,type:'ETF'},
{rank:18,ticker:'QUAL',name:'iShares Quality Factor',expense:0.15,score:8.2,type:'ETF'},
{rank:19,ticker:'VTV',name:'Vanguard Value',expense:0.04,score:8.1,type:'ETF'},
{rank:20,ticker:'VWINX',name:'Vanguard Wellesley Income',expense:0.23,score:9.0,type:'Fund'}
]
},
stagflation: {
top20: [
{rank:1,ticker:'DBC',name:'Invesco DB Commodity Index',expense:0.85,score:9.2,type:'ETF'},
{rank:2,ticker:'GLD',name:'SPDR Gold Shares',expense:0.40,score:8.7,type:'ETF'},
{rank:3,ticker:'TIP',name:'iShares TIPS Bond',expense:0.19,score:9.0,type:'ETF'},
{rank:4,ticker:'XLE',name:'Energy Select Sector',expense:0.10,score:9.3,type:'ETF'},
{rank:5,ticker:'VNQ',name:'Vanguard Real Estate',expense:0.12,score:8.7,type:'ETF'},
{rank:6,ticker:'PDBC',name:'Invesco Optimum Yield',expense:0.59,score:9.0,type:'ETF'},
{rank:7,ticker:'GSG',name:'iShares S&P GSCI Commodity',expense:0.75,score:8.8,type:'ETF'},
{rank:8,ticker:'SLV',name:'iShares Silver Trust',expense:0.50,score:8.5,type:'ETF'},
{rank:9,ticker:'VDE',name:'Vanguard Energy',expense:0.10,score:9.2,type:'ETF'},
{rank:10,ticker:'AMLP',name:'Alerian MLP',expense:0.85,score:8.8,type:'ETF'},
{rank:11,ticker:'SCHP',name:'Schwab US TIPS',expense:0.04,score:8.9,type:'ETF'},
{rank:12,ticker:'LTPZ',name:'PIMCO 15+ Year TIPS',expense:0.20,score:8.8,type:'ETF'},
{rank:13,ticker:'VTIP',name:'Vanguard Short-Term TIPS',expense:0.04,score:8.5,type:'ETF'},
{rank:14,ticker:'XLRE',name:'Real Estate Select Sector',expense:0.10,score:8.5,type:'ETF'},
{rank:15,ticker:'VAW',name:'Vanguard Materials',expense:0.10,score:8.4,type:'ETF'},
{rank:16,ticker:'XLB',name:'Materials Select Sector',expense:0.10,score:8.3,type:'ETF'},
{rank:17,ticker:'VWO',name:'Vanguard Emerging Markets',expense:0.08,score:8.0,type:'ETF'},
{rank:18,ticker:'XOP',name:'SPDR Oil & Gas Exploration',expense:0.35,score:8.6,type:'ETF'},
{rank:19,ticker:'STIP',name:'iShares 0-5 Year TIPS',expense:0.03,score:8.3,type:'ETF'},
{rank:20,ticker:'AVUV',name:'Avantis US Small Cap Value',expense:0.25,score:8.2,type:'ETF'}
]
},
expansion: {
top20: [
{rank:1,ticker:'QQQ',name:'Invesco QQQ Trust',expense:0.20,score:9.5,type:'ETF'},
{rank:2,ticker:'VGT',name:'Vanguard Info Technology',expense:0.10,score:9.4,type:'ETF'},
{rank:3,ticker:'VUG',name:'Vanguard Growth',expense:0.04,score:9.3,type:'ETF'},
{rank:4,ticker:'SCHG',name:'Schwab Large-Cap Growth',expense:0.04,score:9.2,type:'ETF'},
{rank:5,ticker:'VB',name:'Vanguard Small-Cap',expense:0.05,score:9.0,type:'ETF'},
{rank:6,ticker:'IWF',name:'iShares Russell 1000 Growth',expense:0.19,score:9.1,type:'ETF'},
{rank:7,ticker:'MGK',name:'Vanguard Mega Cap Growth',expense:0.07,score:9.0,type:'ETF'},
{rank:8,ticker:'IJR',name:'iShares Core S&P Small-Cap',expense:0.06,score:8.9,type:'ETF'},
{rank:9,ticker:'VO',name:'Vanguard Mid-Cap',expense:0.04,score:8.8,type:'ETF'},
{rank:10,ticker:'VXF',name:'Vanguard Extended Market',expense:0.06,score:8.7,type:'ETF'},
{rank:11,ticker:'XLK',name:'Technology Select Sector',expense:0.10,score:9.4,type:'ETF'},
{rank:12,ticker:'XLY',name:'Consumer Discretionary',expense:0.10,score:9.2,type:'ETF'},
{rank:13,ticker:'XLF',name:'Financial Select Sector',expense:0.10,score:9.0,type:'ETF'},
{rank:14,ticker:'VCR',name:'Vanguard Consumer Disc',expense:0.10,score:8.9,type:'ETF'},
{rank:15,ticker:'EFA',name:'iShares MSCI EAFE',expense:0.32,score:8.7,type:'ETF'},
{rank:16,ticker:'IEMG',name:'iShares Emerging Markets',expense:0.09,score:8.6,type:'ETF'},
{rank:17,ticker:'VXUS',name:'Vanguard Total Intl Stock',expense:0.08,score:8.5,type:'ETF'},
{rank:18,ticker:'ARKK',name:'ARK Innovation',expense:0.75,score:8.5,type:'ETF'},
{rank:19,ticker:'MTUM',name:'iShares Momentum Factor',expense:0.15,score:8.8,type:'ETF'},
{rank:20,ticker:'VOOG',name:'Vanguard S&P 500 Growth',expense:0.10,score:8.9,type:'ETF'}
]
},
normal: {
top20: [
{rank:1,ticker:'VOO',name:'Vanguard S&P 500',expense:0.03,score:9.5,type:'ETF'},
{rank:2,ticker:'VTI',name:'Vanguard Total Stock Market',expense:0.03,score:9.4,type:'ETF'},
{rank:3,ticker:'SPY',name:'SPDR S&P 500',expense:0.09,score:9.3,type:'ETF'},
{rank:4,ticker:'IVV',name:'iShares Core S&P 500',expense:0.03,score:9.2,type:'ETF'},
{rank:5,ticker:'BND',name:'Vanguard Total Bond Market',expense:0.03,score:9.0,type:'ETF'},
{rank:6,ticker:'VT',name:'Vanguard Total World Stock',expense:0.07,score:9.0,type:'ETF'},
{rank:7,ticker:'AGG',name:'iShares Core Aggregate',expense:0.03,score:8.9,type:'ETF'},
{rank:8,ticker:'ITOT',name:'iShares Core Total Market',expense:0.03,score:9.1,type:'ETF'},
{rank:9,ticker:'AOA',name:'iShares Aggressive Allocation',expense:0.15,score:8.8,type:'ETF'},
{rank:10,ticker:'AOR',name:'iShares Growth Allocation',expense:0.15,score:8.7,type:'ETF'},
{rank:11,ticker:'VTV',name:'Vanguard Value',expense:0.04,score:8.9,type:'ETF'},
{rank:12,ticker:'VUG',name:'Vanguard Growth',expense:0.04,score:8.8,type:'ETF'},
{rank:13,ticker:'VYM',name:'Vanguard High Dividend',expense:0.06,score:8.7,type:'ETF'},
{rank:14,ticker:'DGRO',name:'iShares Dividend Growth',expense:0.08,score:8.6,type:'ETF'},
{rank:15,ticker:'VTIAX',name:'Vanguard Total Intl Stock',expense:0.11,score:8.5,type:'Fund'},
{rank:16,ticker:'IXUS',name:'iShares Core MSCI Total Intl',expense:0.07,score:8.4,type:'ETF'},
{rank:17,ticker:'VCIT',name:'Vanguard Interm Corp Bond',expense:0.04,score:8.5,type:'ETF'},
{rank:18,ticker:'VNQI',name:'Vanguard Global Real Estate',expense:0.12,score:8.3,type:'ETF'},
{rank:19,ticker:'BNDX',name:'Vanguard Total Intl Bond',expense:0.07,score:8.2,type:'ETF'},
{rank:20,ticker:'AOM',name:'iShares Moderate Allocation',expense:0.15,score:8.6,type:'ETF'}
]
}
};
const STRESS_SCENARIOS = {
'2008 Financial Crisis': {
stocks: -0.37,
bonds: 0.05,
commodities: -0.35,
cash: 0.02,
description: 'Severe recession with banking crisis'
},
'1970s Stagflation': {
stocks: -0.10,
bonds: -0.05,
commodities: 0.25,
cash: -0.08,
description: 'High inflation with stagnant growth'
},
'COVID-19 Crash': {
stocks: -0.34,
bonds: 0.08,
commodities: -0.20,
cash: 0.00,
description: 'Pandemic-induced market crash'
},
'2022 Inflation Shock': {
stocks: -0.18,
bonds: -0.13,
commodities: 0.16,
cash: -0.07,
description: 'Rising rates and inflation'
}
};
function normalCDF(x) {
const t = 1 / (1 + 0.2316419 * Math.abs(x));
const d = 0.3989423 * Math.exp(-x * x / 2);
const prob = d * t * (0.3193815 + t * (-0.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))));
return x > 0 ? 1 - prob : prob;
}
function tooltip(term) {
const def = GLOSSARY[term] || 'Term definition not available';
return `<span class="tooltip">${term}<span class="tooltiptext">${def}</span></span>`;
}
function getUserInputs() {
return {
horizon: parseInt(document.getElementById('horizon').value),
age: parseInt(document.getElementById('age').value),
risk: parseInt(document.getElementById('risk').value),
portfolio: parseInt(document.getElementById('portfolio').value)
};
}
document.getElementById('risk').addEventListener('input', (e) => {
document.getElementById('risk-value').textContent = e.target.value;
});
class Forecaster {
constructor(userInputs) {
this.inputs = userInputs;
this.data = this.generateForecasts();
}
generateForecasts() {
const growth = this.calculateGrowth();
const inflation = this.calculateInflation();
const crises = this.calculateCrises();
const regime = this.determineRegime(growth[12], inflation[12], crises[12].recession);
const allocation = this.calculateAllocation(regime);
const funds = this.selectFunds(regime);
return { growth, inflation, crises, regime, allocation, funds };
}
calculateGrowth() {
const forecasts = {};
const baseGrowth = 2.0;
for (const h of CONFIG.HORIZONS) {
const decay = Math.pow(0.95, h / 12);
const point = baseGrowth * decay;
const uncertainty = 0.5 + (h / 12) * 0.3;
forecasts[h] = {
point: point,
lower: point - 1.96 * uncertainty,
upper: point + 1.96 * uncertainty,
confidence: 0.75 - (h / 100)
};
}
return forecasts;
}
calculateInflation() {
const forecasts = {};
for (const h of CONFIG.HORIZONS) {
const beta = 0.99, kappa = 0.3;
const unemployment = 4.1, nairu = 4.5;
const outputGap = (nairu - unemployment) / nairu;
const expectedInflation = 2.0;
let forecast = beta * expectedInflation + kappa * outputGap * 100;
forecast = forecast * Math.pow(0.98, h / 12) + 2.0 * (1 - Math.pow(0.98, h / 12));
const uncertainty = 0.6 + (h / 12) * 0.4;
forecasts[h] = {
point: forecast,
lower: forecast - 1.96 * uncertainty,
upper: forecast + 1.96 * uncertainty,
confidence: 0.72 - (h / 120)
};
}
return forecasts;
}
calculateCrises() {
const crises = {};
for (const h of CONFIG.HORIZONS) {
const yieldSpread = -0.5, stockReturn = 8.0, fedFunds = 5.0;
const z = -1.0 + 2.8 * yieldSpread - 0.02 * stockReturn + 0.15 * fedFunds;
const recession = normalCDF(z) * (1 - Math.exp(-h / 12));
const stagflation = 0.12 * (h / 12);
crises[h] = { recession, stagflation };
}
return crises;
}
determineRegime(growth, inflation, recession) {
if (recession > 0.5) return 'recession';
if (inflation > 4 && growth < 2) return 'stagflation';
if (growth > 3) return 'expansion';
return 'normal';
}
calculateAllocation(regime) {
const baseAllocations = {
recession: { stocks: 25, bonds: 60, commodities: 5, cash: 10 },
stagflation: { stocks: 30, bonds: 20, commodities: 35, cash: 15 },
normal: { stocks: 60, bonds: 30, commodities: 5, cash: 5 },
expansion: { stocks: 70, bonds: 20, commodities: 5, cash: 5 }
};
let allocation = { ...baseAllocations[regime] };
const ageFactor = Math.min(this.inputs.age, 70);
const ageAdjustment = (ageFactor / 70) * 20;
const riskAdjustment = (this.inputs.risk - 5) * 5;
allocation.stocks += riskAdjustment - ageAdjustment;
allocation.bonds += ageAdjustment - riskAdjustment;
const total = Object.values(allocation).reduce((a, b) => a + b, 0);
Object.keys(allocation).forEach(k => allocation[k] = Math.round((allocation[k] / total) * 100));
return allocation;
}
selectFunds(regime) {
return FUNDS[regime].top20;
}
}
class ChartGenerator {
static createForecastChart(canvasId, growthData, inflationData) {
const ctx = document.getElementById(canvasId).getContext('2d');
return new Chart(ctx, {
type: 'line',
data: {
labels: CONFIG.HORIZONS.map(h => `${h}mo`),
datasets: [
{
label: 'GDP Growth (%)',
data: CONFIG.HORIZONS.map(h => growthData[h].point),
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
tension: 0.4
},
{
label: 'Inflation (%)',
data: CONFIG.HORIZONS.map(h => inflationData[h].point),
borderColor: '#ec4899',
backgroundColor: 'rgba(236, 72, 153, 0.1)',
tension: 0.4
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { labels: { color: '#e2e8f0' } },
title: { display: true, text: 'Economic Forecasts', color: '#60a5fa' }
},
scales: {
y: {
beginAtZero: false,
ticks: { color: '#94a3b8' },
grid: { color: 'rgba(148, 163, 184, 0.1)' }
},
x: {
ticks: { color: '#94a3b8' },
grid: { color: 'rgba(148, 163, 184, 0.1)' }
}
}
}
});
}
static createAllocationChart(canvasId, allocation) {
const ctx = document.getElementById(canvasId).getContext('2d');
return new Chart(ctx, {
type: 'doughnut',
data: {
labels: Object.keys(allocation).map(k => k.charAt(0).toUpperCase() + k.slice(1)),
datasets: [{
data: Object.values(allocation),
backgroundColor: ['#3b82f6', '#8b5cf6', '#fbbf24', '#4ade80'],
borderWidth: 2,
borderColor: '#0f172a'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { labels: { color: '#e2e8f0' } },
title: { display: true, text: 'Asset Allocation', color: '#60a5fa' }
}
}
});
}
}
class ReportGenerator {
constructor(forecaster) {
this.f = forecaster;
}
generate() {
return `
${this.section1()}
${this.section2()}
${this.section3()}
${this.section4()}
${this.section5()}
${this.section6()}
`;
}
section1() {
const g = this.f.data.growth;
const i = this.f.data.inflation;
const c = this.f.data.crises;
return `
<div class="section">
<div class="section-title">SECTION 1: Macroeconomic Forecasts</div>
<div class="chart-container">
<canvas id="forecast-chart"></canvas>
</div>
<div class="subsection-title">Economic Growth (${tooltip('DSGE')} Model)</div>
<div class="model-header">
<div class="model-name">${MODELS.growth.name}</div>
<div class="model-economists">${MODELS.growth.economists} - ${MODELS.growth.affiliation}</div>
</div>
<div class="forecast-grid">
${CONFIG.HORIZONS.map(h => `
<div class="forecast-card">
<div class="forecast-label">${h}-Month</div>
<div class="forecast-value">${g[h].point.toFixed(2)}%</div>
<div class="forecast-range">${g[h].lower.toFixed(2)}% to ${g[h].upper.toFixed(2)}%</div>
</div>
`).join('')}
</div>
<div class="explanation">
The Smets-Wouters DSGE model projects GDP growth of ${g[6].point.toFixed(2)}% at 6 months,
${g[12].point.toFixed(2)}% at 12 months, declining to ${g[24].point.toFixed(2)}% at 24 months
as monetary policy effects transmit through the economy. Confidence intervals widen from
±${((g[6].upper - g[6].lower) / 2).toFixed(1)} pp at 6 months to
±${((g[24].upper - g[24].lower) / 2).toFixed(1)} pp at 24 months.
</div>
<div class="subsection-title">Inflation (${tooltip('Phillips Curve')})</div>
<div class="model-header">
<div class="model-name">${MODELS.inflation.name}</div>
<div class="model-economists">${MODELS.inflation.economists} - ${MODELS.inflation.affiliation}</div>
</div>
<div class="forecast-grid">
${CONFIG.HORIZONS.map(h => `
<div class="forecast-card">
<div class="forecast-label">${h}-Month</div>
<div class="forecast-value">${i[h].point.toFixed(2)}%</div>
<div class="forecast-range">${i[h].lower.toFixed(2)}% to ${i[h].upper.toFixed(2)}%</div>
</div>
`).join('')}
</div>
<div class="explanation">
The New Keynesian Phillips Curve projects inflation of ${i[12].point.toFixed(2)}% at 12 months,
converging toward the Federal Reserve's 2% target over longer horizons. Current unemployment
of 4.1% relative to ${tooltip('NAIRU')} of 4.5% creates modest disinflationary pressure.
</div>
<div class="subsection-title">Crisis Probabilities</div>
<div class="model-header">
<div class="model-name">${MODELS.recession.name}</div>
<div class="model-economists">${MODELS.recession.economists} - ${MODELS.recession.affiliation}</div>
</div>
<table class="allocation-table">
<thead>
<tr>
<th>Crisis Type</th>
<th>6-Month</th>
<th>12-Month</th>
<th>24-Month</th>
</tr>
</thead>
<tbody>
<tr>
<td>Recession</td>
<td>${(c[6].recession * 100).toFixed(1)}%</td>
<td>${(c[12].recession * 100).toFixed(1)}%</td>
<td>${(c[24].recession * 100).toFixed(1)}%</td>
</tr>
<tr>
<td>Stagflation</td>
<td>${(c[6].stagflation * 100).toFixed(1)}%</td>
<td>${(c[12].stagflation * 100).toFixed(1)}%</td>
<td>${(c[24].stagflation * 100).toFixed(1)}%</td>
</tr>
</tbody>
</table>
<div class="explanation">
The Estrella-Mishkin probit model calculates ${(c[12].recession * 100).toFixed(1)}% recession
probability at 12 months based on ${tooltip('Yield Spread')} inversion, stock returns, and
Federal Funds rate. This moderate probability suggests continued expansion with elevated risk.
</div>
</div>
`;
}
section2() {
const a = this.f.data.allocation;
const r = this.f.data.regime;
return `
<div class="section">
<div class="section-title">SECTION 2: Asset Allocation (${r.toUpperCase()} Regime)</div>
<div class="chart-container">
<canvas id="allocation-chart"></canvas>
</div>
<div class="model-header">
<div class="model-name">${tooltip('Black-Litterman')} with ${tooltip('Risk Parity')} Overlay</div>
<div class="model-economists">Fischer Black & Robert Litterman - Goldman Sachs</div>
</div>
<table class="allocation-table">
<thead>
<tr>
<th>Asset Class</th>
<th>Allocation</th>
<th>Rationale</th>
</tr>
</thead>
<tbody>
<tr>
<td>Stocks</td>
<td><span class="weight-value">${a.stocks}%</span></td>
<td>Long-term growth; adjusted for age ${this.f.inputs.age} and risk ${this.f.inputs.risk}/10</td>
</tr>
<tr>
<td>Bonds</td>
<td><span class="weight-value">${a.bonds}%</span></td>
<td>Stability and income; inflation protection</td>
</tr>
<tr>
<td>Commodities</td>
<td><span class="weight-value">${a.commodities}%</span></td>
<td>Inflation hedge; diversification</td>
</tr>
<tr>
<td>Cash</td>
<td><span class="weight-value">${a.cash}%</span></td>
<td>Liquidity; tactical opportunities</td>
</tr>
</tbody>
</table>
<div class="explanation">
For a ${this.f.inputs.age}-year-old investor with ${this.f.inputs.risk}/10 risk tolerance and
${this.f.inputs.horizon}-year horizon, the optimized ${r} regime allocation prescribes
${a.stocks}% equities and ${a.bonds}% bonds. This represents a
${this.f.inputs.risk > 5 ? 'growth-oriented' : 'conservative'} positioning appropriate for
your profile. Expected portfolio volatility: ~${(a.stocks * 0.16 + a.bonds * 0.06 + a.commodities * 0.20).toFixed(1)}%.
</div>
</div>
`;
}
section3() {
const funds = this.f.data.funds;
const r = this.f.data.regime;
return `
<div class="section">
<div class="section-title">SECTION 3: Fund Recommendations (${r.toUpperCase()})</div>
<div style="background: rgba(59,130,246,0.1); padding: 15px; border-radius: 8px; margin-bottom: 20px;">
<strong style="color: #60a5fa;">Top 20 funds selected for ${r} economic conditions</strong>
<div style="color: #cbd5e1; margin-top: 8px; font-size: 0.9em;">
Based on historical performance in similar regimes (2007-2009 recession, 1970s stagflation,
2003-2007 & 2010-2019 expansion, standard conditions)
</div>
</div>
<div class="tab-container">
<div class="tab active" onclick="switchTab('top5')">Top 5</div>
<div class="tab" onclick="switchTab('all20')">All 20 Funds</div>
</div>
<div id="top5" class="tab-content active">
${funds.slice(0, 5).map(f => this.fundCard(f)).join('')}
</div>
<div id="all20" class="tab-content">
${funds.map(f => this.fundCard(f)).join('')}
</div>
<div class="explanation">
<strong>Implementation Strategy:</strong> For a $${(this.f.inputs.portfolio).toLocaleString()} portfolio,
allocate ${this.f.data.allocation.stocks}% ($${(this.f.inputs.portfolio * this.f.data.allocation.stocks / 100).toLocaleString()})
to top equity funds, ${this.f.data.allocation.bonds}%
($${(this.f.inputs.portfolio * this.f.data.allocation.bonds / 100).toLocaleString()}) to bond funds.
Consider ${funds[0].ticker} (${funds[0].expense}% expense) as core holding. Average expense ratio
across top 5: ${(funds.slice(0,5).reduce((s, f) => s + f.expense, 0) / 5).toFixed(3)}%.
</div>
</div>
`;
}
fundCard(f) {
return `
<div class="fund-item">
<div class="fund-rank ${f.rank <= 5 ? 'top5' : ''}">#${f.rank}</div>
<div>
<div class="fund-ticker">${f.ticker}</div>
<div class="fund-name">${f.name}</div>
</div>
<div class="fund-metrics">
<div>
<div class="fund-metric-label">Score</div>
<div class="fund-metric-value">${f.score.toFixed(1)}</div>
</div>
<div>
<div class="fund-metric-label">Expense</div>
<div class="fund-metric-value">${f.expense}%</div>
</div>
<div>
<div class="fund-metric-label">Type</div>
<div class="fund-metric-value">${f.type}</div>
</div>
</div>
</div>
`;
}
section4() {
return `
<div class="section">
<div class="section-title">SECTION 4: Portfolio Transition Plan</div>
<div class="transition-plan">
<strong style="color: #60a5fa; font-size: 1.1em;">Step-by-Step Implementation</strong>
<div class="step">
<strong>Step 1:</strong> Review current portfolio holdings and identify positions to reduce
</div>
<div class="step">
<strong>Step 2:</strong> Sell overweight positions gradually over 30 days to minimize market impact
</div>
<div class="step">
<strong>Step 3:</strong> Purchase ${this.f.data.funds[0].ticker}, ${this.f.data.funds[1].ticker},
and ${this.f.data.funds[2].ticker} using proceeds
</div>
<div class="step">
<strong>Step 4:</strong> Set quarterly rebalancing calendar (Jan, Apr, Jul, Oct)
</div>
<div class="step">
<strong>Step 5:</strong> Enable automatic dividend reinvestment on all holdings
</div>
<div style="margin-top: 20px; padding: 15px; background: rgba(59,130,246,0.1); border-radius: 8px;">
<strong style="color: #60a5fa;">Tax Considerations:</strong>
<div style="color: #cbd5e1; margin-top: 8px;">
• Execute sales in tax-advantaged accounts (IRA, 401k) first to avoid capital gains<br>
• Consider tax-loss harvesting opportunities in taxable accounts<br>
• Estimated trading costs: $${(this.f.inputs.portfolio * 0.001).toFixed(2)} (0.1% of portfolio)
</div>
</div>
</div>
</div>
`;
}
section5() {
const g = this.f.data.growth[12].point;
const i = this.f.data.inflation[12].point;
const r = (this.f.data.crises[12].recession * 100).toFixed(1);
return `
<div class="section" style="border-left-color: #8b5cf6;">
<div class="section-title" style="color: #a78bfa;">SECTION 5: Executive Summary</div>
<div class="explanation" style="border-left-color: #8b5cf6; font-size: 1.05em;">
<strong>Bottom Line:</strong> Based on comprehensive analysis using seven Nobel-quality econometric
models, the economy faces ${this.f.data.regime} conditions over the next 12 months with ${g.toFixed(2)}%
growth, ${i.toFixed(2)}% inflation, and ${r}% recession probability. For your profile (age ${this.f.inputs.age},
risk ${this.f.inputs.risk}/10, ${this.f.inputs.horizon}-year horizon), recommend
${this.f.data.allocation.stocks}/${this.f.data.allocation.bonds}/${this.f.data.allocation.commodities}/${this.f.data.allocation.cash}
allocation emphasizing ${this.f.data.regime === 'recession' ? 'defensive quality and bonds' :
this.f.data.regime === 'stagflation' ? 'real assets and TIPS' :
this.f.data.regime === 'expansion' ? 'growth equities' : 'balanced core holdings'}.
Top fund: ${this.f.data.funds[0].ticker} (score ${this.f.data.funds[0].score}).
Expected ${this.f.inputs.horizon}-year portfolio value:
$${(this.f.inputs.portfolio * Math.pow(1.06, this.f.inputs.horizon)).toLocaleString()}
assuming 6% real returns. Rebalance quarterly and maintain discipline through volatility.
</div>
<div style="margin-top: 20px; padding: 20px; background: rgba(139,92,246,0.1); border-radius: 8px; border: 1px solid #8b5cf6;">
<strong style="color: #a78bfa;">Key Action Items:</strong>
<ul style="margin: 15px 0 0 25px; color: #cbd5e1; line-height: 2;">
<li>Review and implement recommended ${this.f.data.allocation.stocks}/${this.f.data.allocation.bonds}/${this.f.data.allocation.commodities}/${this.f.data.allocation.cash} allocation</li>
<li>Open positions in ${this.f.data.funds[0].ticker}, ${this.f.data.funds[1].ticker}, ${this.f.data.funds[2].ticker}</li>
<li>Set up quarterly rebalancing reminders</li>
<li>Monitor recession probability - adjust if exceeds 50%</li>
<li>Consult with licensed financial advisor before executing trades</li>
</ul>
</div>
</div>
`;
}
section6() {
return `
<div class="data-sources-section">
<div class="section-title">DATA SOURCES & PROVENANCE</div>
<div style="background: rgba(59,130,246,0.1); padding: 15px; border-radius: 8px; margin-bottom: 20px;">
<strong style="color: #60a5fa;">Complete Data Sources (${CONFIG.DATA_SOURCES}+ sources)</strong>
<div style="color: #cbd5e1; margin-top: 8px; font-size: 0.9em;">
All forecasts, models, and recommendations are based on publicly available data from
government agencies, financial institutions, academic research, and market data providers.
</div>
</div>
<div class="source-category">Government & Regulatory Sources</div>
<div class="data-source-grid">
${DATA_SOURCES.government.map(source => `
<div class="data-source-item">
<div class="data-source-name">${source.name}</div>
<div class="data-source-url">${source.url}</div>
<div style="color: #4ade80; font-size: 0.85em; margin-top: 5px;">Type: ${source.type}</div>
</div>
`).join('')}
</div>
<div class="source-category">Financial & Market Data</div>
<div class="data-source-grid">
${DATA_SOURCES.financial.map(source => `
<div class="data-source-item">
<div class="data-source-name">${source.name}</div>
<div class="data-source-url">${source.url}</div>
<div style="color: #4ade80; font-size: 0.85em; margin-top: 5px;">Type: ${source.type}</div>
</div>
`).join('')}
</div>
<div class="source-category">Market Research & Analytics</div>
<div class="data-source-grid">
${DATA_SOURCES.market.map(source => `
<div class="data-source-item">
<div class="data-source-name">${source.name}</div>
<div class="data-source-url">${source.url}</div>
<div style="color: #4ade80; font-size: 0.85em; margin-top: 5px;">Type: ${source.type}</div>
</div>
`).join('')}
</div>
<div class="source-category">Credit Rating Agencies</div>
<div class="data-source-grid">
${DATA_SOURCES.credit.map(source => `
<div class="data-source-item">
<div class="data-source-name">${source.name}</div>
<div class="data-source-url">${source.url}</div>
<div style="color: #4ade80; font-size: 0.85em; margin-top: 5px;">Type: ${source.type}</div>
</div>
`).join('')}
</div>
<div class="source-category">Academic & Research Sources</div>
<div class="data-source-grid">
${DATA_SOURCES.research.map(source => `
<div class="data-source-item">
<div class="data-source-name">${source.name}</div>
<div class="data-source-url">${source.url}</div>
<div style="color: #4ade80; font-size: 0.85em; margin-top: 5px;">Type: ${source.type}</div>
</div>
`).join('')}
</div>
<div style="text-align: center; margin-top: 30px; padding-top: 20px; border-top: 1px solid rgba(59,130,246,0.3); color: #94a3b8; font-size: 0.9em;">
Report Generated: ${new Date().toLocaleString()} | System v${CONFIG.VERSION} |
${CONFIG.MODELS} Models | ${CONFIG.TOTAL_FUNDS} Funds | ${CONFIG.DATA_SOURCES}+ Sources
</div>
</div>
`;
}
}
function runStressTest() {
const inputs = getUserInputs();
const forecaster = new Forecaster(inputs);
const allocation = forecaster.data.allocation;
let html = `
<div class="section">
<div class="section-title">Portfolio Stress Testing</div>
<div class="stress-test-grid">
`;
for (const [scenario, impacts] of Object.entries(STRESS_SCENARIOS)) {
const loss = (allocation.stocks / 100 * impacts.stocks +
allocation.bonds / 100 * impacts.bonds +
allocation.commodities / 100 * impacts.commodities +
allocation.cash / 100 * impacts.cash) * 100;
const portfolioImpact = inputs.portfolio * loss / 100;
html += `
<div class="stress-card">
<div class="stress-scenario">${scenario}</div>
<div class="stress-impact">${impacts.description}</div>
<div class="impact-value">${loss.toFixed(1)}%</div>
<div style="color: #fecaca; margin-top: 8px;">
Portfolio impact: $${Math.abs(portfolioImpact).toLocaleString()}
</div>
</div>
`;
}
html += `
</div>
<div class="explanation">
<strong>Stress Test Analysis:</strong> Your ${allocation.stocks}/${allocation.bonds}/${allocation.commodities}/${allocation.cash}
allocation shows resilience in most scenarios. Worst case (2008 Financial Crisis) results in
${((allocation.stocks / 100 * STRESS_SCENARIOS['2008 Financial Crisis'].stocks +
allocation.bonds / 100 * STRESS_SCENARIOS['2008 Financial Crisis'].bonds) * 100).toFixed(1)}% drawdown.
Recovery typically takes 2-3 years. Consider increasing bond allocation if recession probability exceeds 50%.
</div>
</div>
`;
document.getElementById('report-container').innerHTML = html;
}
async function generateReport() {
const btn = event.target;
btn.innerHTML = '<span class="loading"></span> Generating Analysis...';
btn.disabled = true;
try {
await new Promise(resolve => setTimeout(resolve, 1000));
const inputs = getUserInputs();
const forecaster = new Forecaster(inputs);
const generator = new ReportGenerator(forecaster);
const html = generator.generate();
document.getElementById('report-container').innerHTML = html;
setTimeout(() => {
ChartGenerator.createForecastChart(
'forecast-chart',
forecaster.data.growth,
forecaster.data.inflation
);
ChartGenerator.createAllocationChart(
'allocation-chart',
forecaster.data.allocation
);
}, 100);
document.getElementById('system-status').textContent = 'ACTIVE';
} catch (error) {
alert('Error: ' + error.message);
} finally {
btn.innerHTML = '<span>Generate Complete Report</span>';
btn.disabled = false;
}
}
function switchTab(tabId) {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
event.target.classList.add('active');
document.getElementById(tabId).classList.add('active');
}
function exportReport() {
const inputs = getUserInputs();
const forecaster = new Forecaster(inputs);
const exportData = {
version: CONFIG.VERSION,
generated: new Date().toISOString(),
userInputs: inputs,
forecasts: forecaster.data,
models: MODELS,
dataSources: DATA_SOURCES,
totalFunds: CONFIG.TOTAL_FUNDS
};
const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `economic-forecast-v${CONFIG.VERSION}-${Date.now()}.json`;
a.click();
}
window.addEventListener('DOMContentLoaded', () => {
console.log(`Economic Forecasting System v${CONFIG.VERSION} Enhanced Edition initialized`);
console.log(`Features: User customization, charting, stress testing, 80 funds, tooltips, transition planning, ${CONFIG.DATA_SOURCES}+ data sources`);
});
</script>
</body>
</html>