<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Clase 12
Step1:  1. Gráficos del Pay Off de opciones Call y Put europeas
En primer lugar, para poder bajar precios y información sobre opciones de Yahoo, es necesario cargar algunos paquetes de Python. En este caso, el paquete principal será Pandas. También, se usarán el Scipy y el Numpy para las matemáticas necesarias y, el Matplotlib y el Seaborn para hacer gráficos de las series de datos.
Step2:  2. Gráficos de estrategias
Ejemplo (Hull) Un inversionista adquiere en $\$3$ una opción de compra a tres meses con un precio de ejercicio de $\$30$, y vende en $\$1$ una opción de compra a tres meses con un precio de $\$35$. El beneficio derivado de esta estrategia de diferencial alcista es de $\$5$ si el precio de la acción esta por encima de $\$35$ y de cero si está por debajo de $\$30$. Si el precio de la acción está entre $\$30$ y $\$35$, el beneficio es la cantidad en la cual el precio de ejercicio excede a $\$30$. El costo de la estategia es de $\$2$, por tanto la utilidad es de 
Un inversionista adquiere en $\$3$ una opción de compra a tres meses con un precio de ejercicio de $\$30$
Step3:  Vende en $\$1$ una opción de compra a tres meses con un precio de $\$35$
Step4:  El beneficio derivado de esta estrategia de diferencial alcista es de $\$5$ si el precio de la acción esta por encima de $\$35$ y de cero si está por debajo de $\$30$. Si el precio de la acción está entre $\$30$ y $\$35$, el beneficio es la cantidad en la cual el precio de ejercicio excede a $\$30$. El costo de la estategia es de $\$2$, por tanto la utilidad es de
<ASSISTANT_TASK:>
Python Code:
#importar los paquetes que se van a usar
import pandas as pd
import pandas_datareader.data as web
import numpy as np
import datetime
from datetime import datetime
import scipy.stats as stats
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
#algunas opciones para Python
pd.set_option('display.notebook_repr_html', True)
pd.set_option('display.max_columns', 6)
pd.set_option('display.max_rows', 10)
pd.set_option('display.width', 78)
pd.set_option('precision', 3)
Explanation: Clase 12: Estrategias relacionadas con opciones
Juan Diego Sánchez Torres, 
Profesor, MAF ITESO
Departamento de Matemáticas y Física
dsanchez@iteso.mx
Tel. 3669-34-34 Ext. 3069
Oficina: Cubículo 4, Edificio J, 2do piso
End of explanation
def call_payoff(ST, K):
    return max(0, ST-K)
call_payoff(25, 30)
def call_payoffs(STmin, STmax, K, step=1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs = np.vectorize(call_payoff)(maturities, K)
    df = pd.DataFrame({'Strike': K, 'Payoff': payoffs}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
call_payoffs(10,25,15)
def plot_call_payoffs(STmin, STmax, K, step=1):
    payoffs = call_payoffs(STmin, STmax, K, step)
    plt.ylim(payoffs.Payoff.min() - 10, payoffs.Payoff.max() + 10)
    plt.ylabel("Payoff")
    plt.xlabel("Precio de maduración")
    plt.title('Payoff call, Precio strike={0}'.format(K))
    plt.xlim(STmin, STmax)
    plt.plot(payoffs.index, payoffs.Payoff.values);
plot_call_payoffs(10, 25, 15)
def put_payoff(ST, K):
    return max(0, K-ST)
put_payoff(25, 30)
def put_payoffs(STmin, STmax, K, step=1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs = np.vectorize(put_payoff)(maturities, K)
    df = pd.DataFrame({'Strike': K, 'Payoff': payoffs}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
put_payoffs(10,25,15)
def plot_put_payoffs(STmin, STmax, K, step=1):
    payoffs = put_payoffs(STmin, STmax, K, step)
    plt.ylim(payoffs.Payoff.min() - 10, payoffs.Payoff.max() + 10)
    plt.ylabel("Payoff")
    plt.xlabel("Precio de maduración")
    plt.title('Payoff put, Precio strike={0}'.format(K))
    plt.xlim(STmin, STmax)
    plt.plot(payoffs.index, payoffs.Payoff.values);
plot_put_payoffs(10, 25, 15)
def call_pnl_buyer(ct, K, STmin, STmax, step = 1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs = np.vectorize(call_payoff)(maturities, K)
    df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnL': payoffs-ct}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
call_pnl_buyer(12, 15, 10, 35)
def call_pnl_seller(ct, K, STmin, STmax, step = 1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs = np.vectorize(call_payoff)(maturities, K)
    df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnL': ct-payoffs}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
call_pnl_seller(12, 15, 10, 35)
def call_pnl_combined(ct, K, STmin, STmax, step = 1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs = np.vectorize(call_payoff)(maturities, K)
    df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnLcomprador': payoffs-ct, 'PnLvendedor': ct-payoffs}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
call_pnl_combined(12, 15, 10, 35)
def put_pnl_buyer(ct, K, STmin, STmax, step = 1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs = np.vectorize(put_payoff)(maturities, K)
    df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnL': payoffs-ct}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
put_pnl_buyer(2, 15, 10, 30)
def put_pnl_seller(ct, K, STmin, STmax, step = 1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs = np.vectorize(put_payoff)(maturities, K)
    df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnL': ct-payoffs}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
put_pnl_seller(2, 15, 10, 30)
def put_pnl_combined(ct, K, STmin, STmax, step = 1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs = np.vectorize(put_payoff)(maturities, K)
    df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnLcomprador': payoffs-ct, 'PnLvendedor': ct-payoffs}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
put_pnl_combined(2, 15, 10, 30)
def plot_pnl(pnl_df, okind, who):
    plt.ylim(pnl_df.Payoff.min() - 10, pnl_df.Payoff.max() + 10)
    plt.ylabel("Ganancia/pérdida")
    plt.xlabel("Precio de maduración")
    plt.title('Ganancia y pérdida de una opción {0} para el {1}, Prima={2}, Strike={3}'.format(okind, who, pnl_df.Prima.iloc[0],
    pnl_df.Strike.iloc[0]))
    plt.ylim(pnl_df.PnL.min()-3, pnl_df.PnL.max() + 3)
    plt.xlim(pnl_df.index[0], pnl_df.index[len(pnl_df.index)-1])
    plt.plot(pnl_df.index, pnl_df.PnL)
    plt.axhline(0, color='g');
plot_pnl(call_pnl_buyer(12, 15, 10, 35), "call", "comprador")
plot_pnl(call_pnl_seller(12, 15, 10, 35), "call", "vendedor")
plot_pnl(put_pnl_buyer(2, 15, 10, 30), "put", "comprador")
Explanation: 1. Gráficos del Pay Off de opciones Call y Put europeas
En primer lugar, para poder bajar precios y información sobre opciones de Yahoo, es necesario cargar algunos paquetes de Python. En este caso, el paquete principal será Pandas. También, se usarán el Scipy y el Numpy para las matemáticas necesarias y, el Matplotlib y el Seaborn para hacer gráficos de las series de datos.
End of explanation
plot_pnl(call_pnl_buyer(3, 30, 25, 40), "call", "comprador")
Explanation: 2. Gráficos de estrategias
Ejemplo (Hull) Un inversionista adquiere en $\$3$ una opción de compra a tres meses con un precio de ejercicio de $\$30$, y vende en $\$1$ una opción de compra a tres meses con un precio de $\$35$. El beneficio derivado de esta estrategia de diferencial alcista es de $\$5$ si el precio de la acción esta por encima de $\$35$ y de cero si está por debajo de $\$30$. Si el precio de la acción está entre $\$30$ y $\$35$, el beneficio es la cantidad en la cual el precio de ejercicio excede a $\$30$. El costo de la estategia es de $\$2$, por tanto la utilidad es de 
Un inversionista adquiere en $\$3$ una opción de compra a tres meses con un precio de ejercicio de $\$30$
End of explanation
plot_pnl(call_pnl_seller(1, 35, 25, 40), "call", "comprador")
def bull_call(ct_short, K_short, ct_long, K_long, STmin, STmax, step = 1):
    maturities = np.arange(STmin, STmax+step, step)
    payoffs_cl = np.vectorize(call_payoff)(maturities, K_long)
    payoffs_cs = np.vectorize(call_payoff)(maturities, K_short)
    df = pd.DataFrame({'Strike': K_long, 'Payoff': payoffs_cs, 'Prima': ct_long-ct_short, 'PnL': payoffs_cl-ct_long+(ct_short-payoffs_cs)}, index=maturities)
    df.index.name = 'Precio de maduración'
    return df
Explanation: Vende en $\$1$ una opción de compra a tres meses con un precio de $\$35$
End of explanation
plot_pnl(bull_call(1, 35, 3, 30, 25, 40), "call", "comprador")
Explanation: El beneficio derivado de esta estrategia de diferencial alcista es de $\$5$ si el precio de la acción esta por encima de $\$35$ y de cero si está por debajo de $\$30$. Si el precio de la acción está entre $\$30$ y $\$35$, el beneficio es la cantidad en la cual el precio de ejercicio excede a $\$30$. El costo de la estategia es de $\$2$, por tanto la utilidad es de
End of explanation
<END_TASK>