El modelo de apreciación de activos de capital (CAPM, por sus siglas en inglés) describe la relación entre el retorno esperado y el riesgo sistemático del mercado.

La fórmula del CAPM

Definimos el retorno esperado de un activo con $R_i(t)$:

$$ R_i(t) = \texttt{r} + \beta_i(R_m - \texttt{r}) $$

donde $\texttt{r}$ es la tasa libre de riesgo, $\beta_i$ es la beta de una acción con relación al mercado y $R_m - \texttt{r}$ es el premio del riesgo. Para calcular el Beta de una acción usamos

$$ \beta = \frac{\text{Cov}(r_s,r_b)}{\text{Var}(r_b)} $$

El modelo CAPM es una extensión de la teoría de portafolio de Markowitz. Este modelo se desarrolló de manera indepentiende por William Sharpe, Jack Treynor, Jan Mossin y John Lintner que se basó en la idea de diversificación de Markowitz.

El CAPM intenta poner precio a los activos examinando la relación entre rendimientos esperados y riesgo. El modelo implica que los inversionistas siempre combinan dos tipos de activos: un activo libre de riesgo y un activo riesgoso.

Como hemos visto antes, el inversionista espera ser recompensado por tener estos activos riesgosos. Para entender CAPM de una manera más intuitiva te recomiendo el siguiente video:

https://www.youtube.com/embed/LWsEJYPSw0k

Un ejemplo en Python

Ya que comprendimos el modelo y cómo funciona, vamos a ponerlo a la práctica con el siguiente código en Python:

import pandas as pd
import statsmodels.api as sm
import pandas_datareader.data as web

'''
En primer lugar usaremos datos con precios de cierre de Facebook y del índice S&P 500 de Yahooo
Formato del periodo: DD/MM/YEAR
'''
# Facebook
fb = web.get_data_yahoo("FB", "02/05/2016", interval = 'm')
# SP 500
sp_500 = web.get_data_yahoo("^GSPC", "02/05/2016", "30/11/2014", interval = 'm')

df = pd.concat([fb["Close"], sp_500["Close"]], axis = 1)
df.columns = ['FB', '^GSPC']

# verificar la base de datos viendo la cabecera
print(df.head())

# Calculo de retornos mensuales
monthly_returns = df.pct_change(1)
clean_monthly_returns = monthly_returns.dropna(axis = 0) # Para dejar la primera fila con NA
print(clean_monthly_returns.head())

El siguiente paso es realizar una regresión de Mínimos Cuadrados Ordinarios (OLS) usando Statsmodels.

# Dividimos la variable dependiente e independiente
X = clean_monthly_returns['^GSPC']
y = clean_monthly_returns['FB']

# Agreguemos la constante de la variable independiente
X1 = sm.add_constant(X)

# Realizamos el modelo de mínimos cuadrados
model = sm.OLS(y, X1)

# Realizar el ajuste del modelo y mostrar los resultados
results = model.fit()
print(results.summary())

Bonus: Regresión Lineal con lingress (scipy)

from scipy import stats

# Captura los elementos de la regresión en diferentes variables
slope, intercept, r_value, pvalue, std_err = stats.linregress(X,y)

print(slope)

Bonus: Grafica la regresión