Modelo de intercambio¶
Yago Derek Martell Morayra
Material de Base hecho por Pablo Rojas
¹ Undergraduate Economist, Universidad Nacional Mayor de San Marcos
📧 yago.martell@unmsm.edu.pe
🌐 https://mundosocial-peru.blogspot.com
Resumen:¶
Se resolvieron computacionalmente un modelo económico. En el modelo de intercambio, se determinó el precio relativo de equilibrio que iguala la oferta y demanda agregada de dos bienes, dados ingresos determinados por dotaciones iniciales y preferencias Cobb-Douglas. En el modelo Ricardiano, se encontró la asignación óptima de trabajo entre dos sectores productivos y el precio relativo de equilibrio, utilizando funciones de producción lineales y preferencias del consumidor. Ambos modelos fueron resueltos numéricamente con el método fsolve, evidenciando cómo herramientas computacionales permiten resolver sistemas de ecuaciones simultáneas que definen el equilibrio económico. Los resultados obtenidos confirman la consistencia teórica de los modelos y su aplicabilidad en simulaciones económicas.
Introducción:¶
En este trabajo se implementan un modelo fundamental de la teoría microeconómica utilizando Python: un modelo de intercambio puro con preferencias Cobb-Douglas . El objetivo es resolver computacionalmente los equilibrios de ambos sistemas a partir de los parámetros definidos, aplicando herramientas de optimización numérica. En el modelo de intercambio se determina el precio relativo que equilibra los mercados dados los ingresos y preferencias de dos agentes. Este ejercicio permite ilustrar cómo, mediante el uso de fsolve de la librería scipy.optimize, es posible encontrar soluciones de equilibrio general incluso en sistemas no lineales.
Modelo de Intercambio¶
Algo que debemos entender antes de hacer el modelo en Python es enteneder el modelo, tanto en su forma lógica como en su forma matemática. Para esto recomiendo el libro de Tello(2017).
La conclusión clave en este modelo es que la diferencia de precios es la que genera el intercambio, y esta es determinada por las preferencias y las dotaciones , en este modelo no hay producción.
Modelamos en Python¶
Lo que haremos primero es importar las bibliotecas que nos permitirán resolver ecuaciones no lineales y lineales. Para una explicación de como funcionan estas bibliotecas te recomiendo ver nuestra publicación anterior sobre como resolver ecuaciones lineales y no lineales en Python.
import numpy as np
from scipy.optimize import fsolve
Ahora que ya hemos importado las bibliotecas que nos permitirán resolver las ecuaciones. Primero definiremos los parámetros. En este ejercicio supondremos que el consumir no tiene mayor propensión media al gasto , para ninguno de los dos bienes, es decir que los parámetros $\alpha$ de la función de utilidad del consumidor - en este caso supondremos que la función o índice de utilidad es una Coob Doouglas - son iguales a 0.5 (para ambos consumidores). Por lo que la suma de los dos será 1, entonces esta función es homogénea de grado 1. $$ U_A(X_1, X_2) = X_1^{0.5} X_2^{0.5}$$ $$ U_B(X_1, X_2) = X_1^{0.5} X_2^{0.5}$$
beta = np.array([0.5, 0.5]) # preferencias de A y B (Cobb-Douglas)
Ya definida la función de utilidad, ahora es turno de definir de cuáles serán las condiciones iniciales para cada uno de los dos consumidores. Como vimos en la parte teórica esto junto a la función de preferencias, serán los que definiran los precios subjetivos (TMS
) de cada uno de los consumidores. De forma matemática:
$$ TMS_i = \frac{\alpha_1 X_2}{\alpha_2 X_1}$$
En donde vemos que el precio subjetivo de los individuos depende de los alphas y de las dotaciones iniciales. Entonces definimos que el individuo tiene las siguientes dotaciones. Y luego de ellos sumamos sus dotaciones de ambos individuos para hallar el número total de dotaciones, para hacerse una idea gráfica,recomiendo que recuerdes o veas el gráfico de la caja de Edgeworth.
dotacion = np.array([[5, 5], # dotación de A: [bien1, bien2]
[5, 5]]) # dotación de B: [bien1, bien2]
total_dotacion = np.sum(dotacion, axis=0) # [ω1_total, ω2_total]
Ahora que ya tenemos nuestros datos iniciales debemos pensar en que queremos hacer. Lo que hace este modelo es básicamente explicarnos la razón por la que hay comercio, y como se mencionó anteriormente esta es la diferencia entre los precios subjetivos o las TMS
. Entonces nos encontraremos ante dos situaciones, una es cuando los individuos no intercambian, ya que los precios de ambos son iguales, y otra en la que son diferentes. Entonces como vemos lo que se busca en este modelo es buscar ese precio- que puede ser igual al inicial (si ambos tienen la misma TMS
) - que vacíe el mercado, es decir que los excesos de demanda sean iguales a 0, una forma más elegante de decir que la oferta sea igual a la demanda. Y esto se cumple cuando los precios subjetivos son iguales, este es el precio de equlibrio, cuando los individuos ya no tienen incentivos a intercambiar, este punto es pareto eficiente (si no hay distorsiones).
Entendido esto, ahora estamos en la búsqueda del precio de equilibrio que nos permite vaciar los mercados, antes de ello definiremos una función que nos permitirá obtener el resultado de una forma más eficiente, a través de la siguiente línea de código, hallaremos la cantidad demandada del bien $X_1$ y $X_2$, que maximice nuestra utilidad dada nuestras preferencias, nuestros ingresos -que en este modelo dependen de las dotaciones (W)- , y los precios. Por lo que nos encontramos ante el siguiente problema: $$ \max U_i (X_1, X_2)$$ $$ s.a. \quad P.X \leq P.W = I$$
Para poder terminar de entender, las demandas que vemos en las líneas de códigos son las demandas Marshalianas: $$c_1 = \frac{I \alpha_1}{(\alpha_1 + \alpha_2) P_1}$$ $$c_2 = \frac{I \alpha_2}{(\alpha_1 + \alpha_2) P_2}$$
Pero como supusimos incialmente que los alfas suman 1 entonces: $$c_1 = \frac{I \alpha_1}{P_1}$$ $$c_2 = \frac{I (1- \alpha_1)}{ P_2}$$
Por último, debemos saber que según el corolario de la Ley de Walras, si n-1 mercados están en equilibrio el n-ésimo mercado también está en equilibrio, por lo que no hace falta encontrar el precio de uno de estos (ya no es necesario resolver n ecuaciones para hallar los n precios, solo tendremos que resolver n-1 ecuaciones), ya que uno de los precios , asumiremos igual a 1 , este es el precio llamado como numerario. Para nuestro código asumimos que el precio numerario será el del bien 1.
def optimal_demand(beta_i, income, p):
x = beta_i * income / 1 # precio del bien 1 = 1
y = (1 - beta_i) * income / p
return np.array([x, y])
Entonces vemos que solo tenemos que hallar un solo precio para el modelo de intercambio de 2 individuos. Ahora a través del siguiente código, hallaremos el precio que nos permitirá vaciar los mercados
# Encontrar p* tal que el mercado de cada bien está en equilibrio
def find_equilibrium_price():
def excess_demand(p):
# Precios: p1 = 1, p2 = p (relativo)
p = p[0]
if p <= 0:
return 1e3 # penalizar precios negativos
demands = []
for i in range(2):
income = dotacion[i,0]*1 + dotacion[i,1]*p
d = optimal_demand(beta[i], income, p)
demands.append(d)
demands = np.array(demands)
total_demand = np.sum(demands, axis=0)
excess = total_demand - total_dotacion
return excess[1] # exceso de demanda del bien 2
p_star = fsolve(excess_demand, x0=1.0)[0]
return p_star
Vamos a explicar paso a paso lo que se hizo en el código anterior.
Con esta función buscamos hallar el precio de equilibrio que vacía el mercado, la función principal, es la de exceso_de_demnanda
, la función de Buscando_precio_de_equilibrio()
, solo nos permite resolver el problema , sin volver a escribir cada vez fsolve(exceso_de_demnanda, x0=1.0)[0]
, x0
es el número por el que se empezará a iterar los posibles resultados de p
, y se pone el [0]
, ya que la función fsolve, siempre arroja un array como resultado, por lo que si queremos seleccionar el resultado debemos elegir el primer elemento de dicho array.Finalmente esto nos devolverá el resultado del p_star
, que es el precio de equilibrio. Ahora volvamos al problema central, que es la función exceso de demanda
Con estas líneas de códigos creamos nuestras ecuaciones que el comando fsolve tendrá que resolver, lo que hace el primer comando, es seleccionar el primer elemento del array p[0]
, como mencionamos anteriormente, el programa siempre da un array,a pesar de ser un escalar, la línea siguiente es el if
, lo que hace es penalizar los precios negativos, pero ¿cómo lo hace?, lo que hace este comando es si el programa fsolve nos da un precio negativo (lo cuál no puede ser el resultado , ya que no tiene sentido económico), nos regresa como resultado de nuestro problema 1e3-mil-( debes tener cuidado al momento de colocar esta penalización si esta es muy grande el programa no convergerá a un resultado, y te dará un precio que no siempre se acercará al que genera el equilibrio, atento a mensajes de warning
), lo que se aleja mucho del 0 (el resultado esperado, en este caso que los excesos de demanda sean ceros), lo que le da a entender al programa que se está alejando mucho del resultado,y ya no usará números negativos. Luego de eso creamos una lista, para almacenar los valores de la demanda que se crearán en el siguiente for
. Lo que hace este loop, es hallar las demandas de ambos consumidores por ello el range(2)
, para hallar las demandas dado los precios, el ingreso y las preferencias, usaremos la función de optimal_demand
, pero esta necesita un ingreso, para poder hallar las demandas, y esta se halla a través de hallar el valor nominal de tus dotaciones iniciales (por ello se multiplica por el vector precios), por lo que es fácil entender porque definimos así income
, pero cabe aclarar que la dotación del bien 1, al ser el numerario este es el $ precio = 1 $, por ello se pone así en el problema. Entendido esto lo que se hace es hallar el vector de cantidades para cada uno de los individuos, agregarlo a la lista, para luego convertirlo en un array
, lo que nos facilitará que sumemos los elementos dentro de cada vector (axis=0) indica que sumará las columnas, es decir lo que demandan los dos consumidores del bien x
y y
, y esto debe ser igual a las dotaciones de los bienes x
y y
, es decir los excesos de demanda deben ser iguales a 0. Entonces este es el problema que debe resolver el programa, debe buscar los precios que igualen el exceso de demanda a cero.
Entendido esto ahora, solo debemos ejecutar la función y el resultado se almacenará en p_equilibrio
, y con fines didácticos mostraremos el resultado.
p_equilibrio = find_equilibrium_price()
print(p_equilibrio)
1.0
Ahora lo que haremos es mostrar valores que toman las variables, ya con el precio de equilibrio. Lo que hacemos a continuación es guardar en la variable resultados, el ingreso, la demanda y la utilidad, de cada uno de los dos individuos, y luego de eso, lo que haremos será imprimir los resultados con un poco de formato.
resultados = []
for i in range(2):
ingreso = dotacion[i, 0] * 1 + dotacion[i, 1] * p_equilibrio # Ingreso de cada individuo
demanda = optimal_demand(beta[i], ingreso, p_equilibrio) # Demanda óptima por individuo
utilidad = demanda[0]**(beta[i]) * demanda[1]**(1-(beta[i]))
resultados.append((ingreso, demanda, utilidad))
print(f"Precio relativo de equilibrio p2/p1: {p_equilibrio:.2f}\n")
for i, label in enumerate(['A', 'B']):
ingreso, demanda, utilidad = resultados[i]
print(f"Individuo {label}:")
print(f" Ingreso nominal: {ingreso:.2f}")
print(f" Demanda óptima: Bien 1 = {demanda[0]:.2f}, Bien 2 = {demanda[1]:.2f}\n")
print(f" Utilidad: {utilidad:.2f}")
Precio relativo de equilibrio p2/p1: 1.00 Individuo A: Ingreso nominal: 10.00 Demanda óptima: Bien 1 = 5.00, Bien 2 = 5.00 Utilidad: 5.00 Individuo B: Ingreso nominal: 10.00 Demanda óptima: Bien 1 = 5.00, Bien 2 = 5.00 Utilidad: 5.00
Conclusión¶
Con esto espero que ahora ya sea capaz de hacer el modelo de intercambio en Python, y te haya quedado en claro algunos fundamentos de este modelo, si bien no fue el fin espero que haya sido suficiente para tener una noción de como funciona este modelo, y que es lo que busca explicar. Cada semana subiremos un nuevo modelo, y terminaremos haciendo un modelo de equilibrio general computable. Esta idea nace, cuando me di cuenta de que no existe mucha material en la web sobre como hacer estos programas. Cualquier consulta sobre el código puedes escribirme a mi LinkedIn que está anexado en el encabezado, o a mi correo. Hasta la próxima.
muchas gracias
ReplyDelete