simulador de mercado
Simulador de Economía Agrícola – Oferta y Demanda
https://cdn.tailwindcss.com
https://cdn.jsdelivr.net/npm/chart.js
Simulador de Mercado Agrícola
Modifica las variables del entorno para ver cómo se ajustan la Oferta, la Demanda y el Precio de Equilibrio en tiempo real.
🌱 Variables del Entorno
Clima y Costos de Producción (Oferta)
Clima Normal (Equilibrio base)
Sequía Severa (- Oferta)
Cosecha Récord / Excelente clima (+ Oferta)
Aumento en el precio de Fertilizantes (- Oferta)
Tendencias del Consumidor (Demanda)
Demanda Estándar
Tendencia Saludable / Boom de consumo (+ Demanda)
Recesión Económica (- Demanda)
Aparición de un Sustituto más barato (- Demanda)
Resultado del Mercado
Precio de Equilibrio
$25.00 / kg
Cantidad Transada
100 tns
Análisis del Docente:
El mercado se encuentra en un punto de equilibrio ideal. La cantidad que los agricultores desean producir coincide exactamente con lo que los consumidores están dispuestos a comprar.
const ctx = document.getElementById(‘marketChart’).getContext(‘2d’);
let marketChart;
// Ecuaciones base lineales simplificadas: Q = mP + b
// Demanda base: Q = -4P + 200 => P = (200 – Q)/4
// Oferta base: Q = 4P => P = Q/4
function calculateEquilibrium(supplyShift, demandShift) {
// Modificamos el intercepto (b) según los desplazamientos
let demandIntercept = 200 + parseFloat(demandShift);
let supplyIntercept = 0 – parseFloat(supplyShift);
// En equilibrio: Oferta = Demanda => 4P – supplyIntercept = -4P + demandIntercept
// 8P = demandIntercept + supplyIntercept
let P_eq = (demandIntercept + supplyIntercept) / 8;
let Q_eq = 4 * P_eq – supplyIntercept;
return {
price: P_eq.toFixed(2),
quantity: Q_eq.toFixed(0),
demandIntercept,
supplyIntercept
};
}
function generateData(supplyShift, demandShift) {
const eq = calculateEquilibrium(supplyShift, demandShift);
const prices = [10, 15, 20, 25, 30, 35, 40];
// Calcular puntos de las curvas para la gráfica
const demandPoints = prices.map(p => ({ x: -4 * p + eq.demandIntercept, y: p }));
const supplyPoints = prices.map(p => ({ x: 4 * p – eq.supplyIntercept, y: p }));
return { demandPoints, supplyPoints, eq };
}
function updateMarket() {
const supplyShift = document.getElementById(‘supplyShock’).value;
const demandShift = document.getElementById(‘demandShock’).value;
const data = generateData(supplyShift, demandShift);
// Actualizar textos en la interfaz
document.getElementById(‘priceDisplay’).innerText = `$${data.eq.price} / kg`;
document.getElementById(‘quantityDisplay’).innerText = `${data.eq.quantity} tns`;
// Generar explicación dinámica pedagógica
let análisis = «»;
if (supplyShift 0) análisis += «Un choque positivo de oferta (buen clima) desplaza la curva a la derecha, provocando abundancia del cultivo y bajando los precios del mercado. «;
if (demandShift > 0) análisis += «El aumento en el interés del consumidor desplaza la curva de demanda a la derecha; al haber más compradores compitiendo por el producto, el precio sube. «;
if (demandShift < 0) análisis += "La caída de la demanda desplaza su curva a la izquierda; la falta de compradores obliga a los productores a bajar precios para no perder su cosecha. ";
if (supplyShift == 0 && demandShift == 0) análisis += "El mercado está balanceado en su punto histórico óptimo.";
document.getElementById('analysisText').innerText = análisis;
// Actualizar la gráfica
marketChart.data.datasets[0].data = data.demandPoints;
marketChart.data.datasets[1].data = data.supplyPoints;
marketChart.data.datasets[2].data = [{ x: parseFloat(data.eq.quantity), y: parseFloat(data.eq.price) }];
marketChart.update();
}
// Inicialización de la gráfica Chart.js
const initialData = generateData(0, 0);
marketChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [
{
label: 'Demanda (Consumidores)',
data: initialData.demandPoints,
borderColor: 'rgb(59, 130, 246)',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
borderWidth: 3,
tension: 0.1
},
{
label: 'Oferta (Agricultores)',
data: initialData.supplyPoints,
borderColor: 'rgb(16, 185, 129)',
backgroundColor: 'rgba(16, 185, 129, 0.1)',
borderWidth: 3,
tension: 0.1
},
{
label: 'Punto de Equilibrio',
data: [{ x: parseFloat(initialData.eq.quantity), y: parseFloat(initialData.eq.price) }],
borderColor: 'rgb(220, 38, 38)',
backgroundColor: 'rgb(220, 38, 38)',
pointRadius: 8,
pointHoverRadius: 10,
showLine: false
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
type: 'linear',
title: { display: true, text: 'Cantidad (Toneladas Métricas)' },
min: 20,
max: 220
},
y: {
title: { display: true, text: 'Precio ($ por Kilogramo)' },
min: 5,
max: 45
}
}
}
});