292 lines
12 KiB
HTML
292 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Monetary Policy Interactive Diagram</title>
|
|
|
|
<!-- Tailwind CSS -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
|
<!-- React and ReactDOM -->
|
|
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
|
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
|
|
|
<!-- Babel for JSX -->
|
|
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
|
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
|
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
|
sans-serif;
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
}
|
|
|
|
/* Custom styles for better slider appearance */
|
|
input[type="range"] {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
height: 6px;
|
|
border-radius: 5px;
|
|
background: #d3d3d3;
|
|
outline: none;
|
|
opacity: 0.7;
|
|
transition: opacity .2s;
|
|
}
|
|
|
|
input[type="range"]:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
input[type="range"]::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
width: 20px;
|
|
height: 20px;
|
|
border-radius: 50%;
|
|
background: #4CAF50;
|
|
cursor: pointer;
|
|
}
|
|
|
|
input[type="range"]::-moz-range-thumb {
|
|
width: 20px;
|
|
height: 20px;
|
|
border-radius: 50%;
|
|
background: #4CAF50;
|
|
cursor: pointer;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
|
|
<script type="text/babel">
|
|
const { useState } = React;
|
|
|
|
// Simple icon components (replacing lucide-react)
|
|
const ArrowRight = ({ size = 24, className = "" }) => (
|
|
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className={className}>
|
|
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
<polyline points="12 5 19 12 12 19"></polyline>
|
|
</svg>
|
|
);
|
|
|
|
const LineChart = ({ size = 24 }) => (
|
|
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
<polyline points="3 17 9 11 13 15 21 7"></polyline>
|
|
</svg>
|
|
);
|
|
|
|
const MonetaryPolicyDiagram = () => {
|
|
const [activeScenario, setActiveScenario] = useState('expansion');
|
|
const [showGraphs, setShowGraphs] = useState(false);
|
|
|
|
// Graph parameters
|
|
const [moneySupply, setMoneySupply] = useState(100);
|
|
const [income, setIncome] = useState(100);
|
|
const [foreignRate, setForeignRate] = useState(2);
|
|
const [inflation, setInflation] = useState(2);
|
|
const [outputGap, setOutputGap] = useState(0);
|
|
|
|
// Calculate equilibrium interest rate from money market
|
|
const calcInterestRate = (ms, y) => {
|
|
const k1 = 0.5;
|
|
const k2 = 20;
|
|
const rate = Math.max(0, (k1 * y - ms) / k2);
|
|
return rate;
|
|
};
|
|
|
|
// Calculate exchange rate from UIP
|
|
const calcExchangeRate = (domesticRate, foreignRate) => {
|
|
const base = 1.0;
|
|
const rateDiff = domesticRate - foreignRate;
|
|
return base * Math.exp(-rateDiff * 0.1);
|
|
};
|
|
|
|
// Calculate Taylor Rule rate
|
|
const calcTaylorRate = (inflationRate, inflationTarget, outputGap) => {
|
|
const rStar = 2;
|
|
const fPi = 1.5;
|
|
const fY = 0.5;
|
|
return rStar + fPi * (inflationRate - inflationTarget) + fY * outputGap;
|
|
};
|
|
|
|
const domesticRate = calcInterestRate(moneySupply, income);
|
|
const exchangeRate = calcExchangeRate(domesticRate, foreignRate);
|
|
const taylorRate = calcTaylorRate(inflation, 2, outputGap);
|
|
|
|
// Generate points for money demand curve
|
|
const generateMoneyDemandCurve = (y) => {
|
|
const points = [];
|
|
for (let r = 0; r <= 8; r += 0.2) {
|
|
const md = 0.5 * y - 20 * r;
|
|
if (md > 0) {
|
|
points.push({ r, md });
|
|
}
|
|
}
|
|
return points;
|
|
};
|
|
|
|
// Generate points for UIP curve
|
|
const generateUIPCurve = (rFor) => {
|
|
const points = [];
|
|
for (let rDom = 0; rDom <= 8; rDom += 0.2) {
|
|
const e = calcExchangeRate(rDom, rFor);
|
|
points.push({ rDom, e });
|
|
}
|
|
return points;
|
|
};
|
|
|
|
const moneyDemandPoints = generateMoneyDemandCurve(income);
|
|
const uipPoints = generateUIPCurve(foreignRate);
|
|
|
|
const scenarios = {
|
|
expansion: {
|
|
title: 'Monetary Expansion (Ms ↑)',
|
|
color: 'blue',
|
|
steps: [
|
|
{ label: 'Central Bank', action: 'Increases Money Supply (Ms ↑)', color: 'bg-blue-100' },
|
|
{ label: 'Money Market', action: 'Interest Rate Falls (R ↓)', color: 'bg-blue-200' },
|
|
{ label: 'FX Market', action: 'Currency Depreciates (E ↑)', color: 'bg-blue-300' },
|
|
{ label: 'Real Economy', action: 'Investment ↑, Exports ↑, AD ↑', color: 'bg-blue-400' }
|
|
]
|
|
},
|
|
contraction: {
|
|
title: 'Monetary Contraction (Ms ↓)',
|
|
color: 'red',
|
|
steps: [
|
|
{ label: 'Central Bank', action: 'Decreases Money Supply (Ms ↓)', color: 'bg-red-100' },
|
|
{ label: 'Money Market', action: 'Interest Rate Rises (R ↑)', color: 'bg-red-200' },
|
|
{ label: 'FX Market', action: 'Currency Appreciates (E ↓)', color: 'bg-red-300' },
|
|
{ label: 'Real Economy', action: 'Investment ↓, Exports ↓, AD ↓', color: 'bg-red-400' }
|
|
]
|
|
},
|
|
taylor: {
|
|
title: 'Taylor Rule Response to High Inflation',
|
|
color: 'orange',
|
|
steps: [
|
|
{ label: 'Shock', action: 'Inflation Above Target (π > π*)', color: 'bg-orange-100' },
|
|
{ label: 'Taylor Rule', action: 'R = R* + 1.5(π - π*) + 0.5(y - y*)', color: 'bg-orange-200' },
|
|
{ label: 'Policy Action', action: 'Raise R aggressively (by > 1% per 1% inflation)', color: 'bg-orange-300' },
|
|
{ label: 'Effect', action: 'Real Rate ↑ → Borrowing ↓ → AD ↓ → π ↓', color: 'bg-orange-400' }
|
|
]
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="w-full max-w-6xl mx-auto p-6 bg-gray-50">
|
|
<h1 className="text-3xl font-bold text-center mb-8 text-gray-800">
|
|
Monetary Policy Transmission Mechanism
|
|
</h1>
|
|
|
|
{/* Scenario Selector */}
|
|
<div className="flex gap-4 mb-8 justify-center flex-wrap">
|
|
<button
|
|
onClick={() => setActiveScenario('expansion')}
|
|
className={`px-6 py-3 rounded-lg font-semibold transition-all ${
|
|
activeScenario === 'expansion'
|
|
? 'bg-blue-500 text-white shadow-lg'
|
|
: 'bg-white text-gray-700 hover:bg-gray-100'
|
|
}`}
|
|
>
|
|
Monetary Expansion
|
|
</button>
|
|
<button
|
|
onClick={() => setActiveScenario('contraction')}
|
|
className={`px-6 py-3 rounded-lg font-semibold transition-all ${
|
|
activeScenario === 'contraction'
|
|
? 'bg-red-500 text-white shadow-lg'
|
|
: 'bg-white text-gray-700 hover:bg-gray-100'
|
|
}`}
|
|
>
|
|
Monetary Contraction
|
|
</button>
|
|
<button
|
|
onClick={() => setActiveScenario('taylor')}
|
|
className={`px-6 py-3 rounded-lg font-semibold transition-all ${
|
|
activeScenario === 'taylor'
|
|
? 'bg-orange-500 text-white shadow-lg'
|
|
: 'bg-white text-gray-700 hover:bg-gray-100'
|
|
}`}
|
|
>
|
|
Taylor Rule
|
|
</button>
|
|
<button
|
|
onClick={() => setShowGraphs(!showGraphs)}
|
|
className={`px-6 py-3 rounded-lg font-semibold transition-all flex items-center gap-2 ${
|
|
showGraphs
|
|
? 'bg-green-500 text-white shadow-lg'
|
|
: 'bg-white text-gray-700 hover:bg-gray-100'
|
|
}`}
|
|
>
|
|
<LineChart size={20} />
|
|
{showGraphs ? 'Hide Graphs' : 'Show Interactive Graphs'}
|
|
</button>
|
|
</div>
|
|
|
|
{/* Active Scenario Flow */}
|
|
<div className="bg-white rounded-xl shadow-lg p-8 mb-8">
|
|
<h2 className="text-2xl font-bold mb-6 text-center text-gray-800">
|
|
{scenarios[activeScenario].title}
|
|
</h2>
|
|
<div className="flex items-center justify-between">
|
|
{scenarios[activeScenario].steps.map((step, idx) => (
|
|
<React.Fragment key={idx}>
|
|
<div className="flex-1">
|
|
<div className={`${step.color} rounded-lg p-6 h-32 flex flex-col justify-center items-center text-center shadow-md`}>
|
|
<div className="font-bold text-lg mb-2">{step.label}</div>
|
|
<div className="text-sm">{step.action}</div>
|
|
</div>
|
|
</div>
|
|
{idx < scenarios[activeScenario].steps.length - 1 && (
|
|
<ArrowRight className="mx-4 text-gray-400" size={32} />
|
|
)}
|
|
</React.Fragment>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Add the rest of your component JSX here - truncated for brevity */}
|
|
{/* This would include the interactive graphs section, core relationships, etc. */}
|
|
|
|
{/* Key Takeaways */}
|
|
<div className="mt-8 bg-gradient-to-r from-purple-100 to-blue-100 rounded-xl p-6">
|
|
<h3 className="text-xl font-bold mb-4 text-gray-800">Key Takeaways</h3>
|
|
<ul className="space-y-2 text-sm">
|
|
<li className="flex items-start">
|
|
<span className="text-purple-600 mr-2">•</span>
|
|
<span><strong>Money Market:</strong> Central bank controls Ms, which determines R through equilibrium condition</span>
|
|
</li>
|
|
<li className="flex items-start">
|
|
<span className="text-purple-600 mr-2">•</span>
|
|
<span><strong>Exchange Rates:</strong> Interest rate differentials drive currency movements (UIP)</span>
|
|
</li>
|
|
<li className="flex items-start">
|
|
<span className="text-purple-600 mr-2">•</span>
|
|
<span><strong>Taylor Rule:</strong> Systematic policy response to inflation and output gaps (f<sub>π</sub> {'>'} 1 is crucial)</span>
|
|
</li>
|
|
<li className="flex items-start">
|
|
<span className="text-purple-600 mr-2">•</span>
|
|
<span><strong>Transmission:</strong> Monetary policy affects economy through multiple channels simultaneously</span>
|
|
</li>
|
|
<li className="flex items-start">
|
|
<span className="text-purple-600 mr-2">•</span>
|
|
<span><strong>Real Effects:</strong> Changes in R and E both impact aggregate demand (C, I, CA components)</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// Render the app
|
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
|
root.render(<MonetaryPolicyDiagram />);
|
|
</script>
|
|
</body>
|
|
</html>
|