# Sensibilidad OIS

**Definición:** una curva cupón cero es una colección ordenada de plazos y tasas de interés donde cada una de las tasas es una  tasa adecuada para traer a valor presente un flujo de caja al plazo que corresponde a la tasa.

Consideremos un instrumento financiero cuyo valor depende de una curva cupón cero. Por ejemplo, un swap de tasa de interés. Matemáticamente, esta dependencia se expresa como:

$$
V = V\left(z_1,\ldots,z_n;\alpha\right)
$$

donde $z_1,\ldots,z_N$ son los valores de las tasas de la curva y $\alpha$ representa un vector de parámetros adicionales (como la tasa de cupón en un bono o un tipo de cambio en un swap de monedas).

**Definición:** la cantidad $\Delta_i$ de $V$ respecto a $z_i$ se define como:

$$
\Delta_i=\frac{\partial V}{\partial z_i}
$$

**Definición:** la sensibilidad de $V$ respecto a un cambio $\delta_i$ (positivo o negativo) en la tasa $z_i$ se define como:

$$
S\left(V,z_i,\delta_i\right)=V\left(z_1,...,z_i+\delta_i,\ldots,z_n\right)-V\left(z_1,\ldots,z_i,\ldots,z_n\right)
$$

Cuando se busca conocer la sensibilidad a un cambio $\delta_i$  en la tasa $z_i$, donde $\delta_i$ representa una magnitud sin signo, se utiliza la siguiente definición:

**Definición:** la sensibilidad de $V$ respecto a un cambio de magnitud $\delta_i$ en la tasa $z_i$ se define como:

$$
\overline{S}\left(V,z_i,\delta_i\right)=\frac{V\left(z_1,\ldots ,z_i+\delta_i,\ldots,z_n\right)-V\left(z_1,\ldots,z_i-\delta_i,...,z_n\right)}{2}
$$

En ocasiones, cuando se busca conocer la sensibilidad a un movimiento de magnitud pequeña, resulta conveniente realizar la siguiente aproximación:

$$
\overline{S}\left(V,z_i,\delta_i\right)\approx\Delta_i \cdot\delta_i
$$

este es el caso, cuando se busca conocer esta sensibilidad para un elevado número de operaciones. Es importante considerar que se puede asegurar que esta aproximación es válida cuando la función $V$ satisface los requerimientos de regularidad necesarios para aplicar el [Teorema de Taylor](https://en.wikipedia.org/wiki/Taylor%27s_theorem).


f(x0 + h) - f(x0) = f'(x0) x h + error, error --> 0, para h --> 0 

## Configuración

### Librerías


```python
from finrisk import QC_Financial_3 as Qcf
import modules.auxiliary as aux
from functools import partial
from enum import Enum
import pandas as pd
```

### Variables Globales


```python
class BusCal(Enum):
    NY = 1
    SCL = 2
    TARGET = 3
```


```python
def get_cal(code: BusCal) -> Qcf.BusinessCalendar:
    """
    """
    if code == BusCal.NY:
        cal = Qcf.BusinessCalendar(Qcf.QCDate(1, 1, 2020), 20)
        for agno in range(2020, 2071):
            f = Qcf.QCDate(12, 10, agno)
            if f.week_day() == Qcf.WeekDay.SAT:
                cal.add_holiday(Qcf.QCDate(14, 10, agno))
            elif f.week_day() == Qcf.WeekDay.SUN:
                cal.add_holiday(Qcf.QCDate(13, 10, agno))
            elif f.week_day() == Qcf.WeekDay.MON:
                cal.add_holiday(Qcf.QCDate(12, 10, agno))
            elif f.week_day() == Qcf.WeekDay.TUE:
                cal.add_holiday(Qcf.QCDate(11, 10, agno))
            elif f.week_day() == Qcf.WeekDay.WED:
                cal.add_holiday(Qcf.QCDate(10, 10, agno))
            elif f.week_day() == Qcf.WeekDay.THU:
                cal.add_holiday(Qcf.QCDate(9, 10, agno))
            else:
                cal.add_holiday(Qcf.QCDate(8, 10, agno))
        
        cal.add_holiday(Qcf.QCDate(15, 2, 2021))
        
    return cal
```


```python
get_cal(BusCal.NY)
```




    <finrisk.QC_Financial_3.BusinessCalendar at 0x7f3e87e9e538>




```python
frmt = {
    'tasa': '{:.6%}',
    'df': '{:.6%}',
    'valor_tasa': '{:.4%}',
    'spread': '{:.4%}',
    'nominal': '{:,.0f}',
    'interes': '{:,.0f}',
    'amortizacion': '{:,.0f}',
    'flujo': '{:,.4f}',
}
```


```python
class TypeOis(Enum):
    SOFR = 1
    ICP = 2
```


```python
type_ois_template = {
    TypeOis.SOFR: {
        'currency': Qcf.QCUSD(),
        'periodicity': Qcf.Tenor('1Y'),
        'stub_period': Qcf.StubPeriod.SHORTFRONT,
        'settlement_lag': 0,
        'calendar': BusCal.NY,
        'bus_adj_rule': Qcf.BusyAdjRules.MODFOLLOW,
        'amort_is_cashflow': True,
        'fixed_rate': Qcf.QCInterestRate(0.0, Qcf.QCAct360(), Qcf.QCLinearWf()),
    },
    
    TypeOis.ICP: {
        'currency': Qcf.QCCLP(),
        'periodicity': Qcf.Tenor('6M'),
        'stub_period': Qcf.StubPeriod.SHORTFRONT,
        'settlement_lag': 0,
        'calendar': BusCal.SCL,
        'bus_adj_rule': Qcf.BusyAdjRules.MODFOLLOW,
        'amort_is_cashflow': True,
        'fixed_rate': Qcf.QCInterestRate(0.0, Qcf.QCAct360(), Qcf.QCLinearWf()),
    }
}
```

## Importa Curva Cero Cupón

Se importa la data de la curva cupón cero que fue construida en el notebook 6.


```python
df_curva = pd.read_excel('data/20201012_built_sofr_zero.xlsx')
```


```python
df_curva.head(20).style.format(frmt)
```




<style  type="text/css" >
</style><table id="T_4fc27bee_419a_11ec_a147_02cba411ec9d" ><thead>    <tr>        <th class="blank level0" ></th>        <th class="col_heading level0 col0" >plazo</th>        <th class="col_heading level0 col1" >tasa</th>        <th class="col_heading level0 col2" >df</th>    </tr></thead><tbody>
                <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row0" class="row_heading level0 row0" >0</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow0_col0" class="data row0 col0" >1</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow0_col1" class="data row0 col1" >0.081111%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow0_col2" class="data row0 col2" >99.999778%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row1" class="row_heading level0 row1" >1</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow1_col0" class="data row1 col0" >7</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow1_col1" class="data row1 col1" >0.084051%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow1_col2" class="data row1 col2" >99.998388%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row2" class="row_heading level0 row2" >2</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow2_col0" class="data row2 col0" >14</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow2_col1" class="data row2 col1" >0.077967%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow2_col2" class="data row2 col2" >99.997010%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row3" class="row_heading level0 row3" >3</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow3_col0" class="data row3 col0" >21</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow3_col1" class="data row3 col1" >0.077358%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow3_col2" class="data row3 col2" >99.995549%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row4" class="row_heading level0 row4" >4</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow4_col0" class="data row4 col0" >33</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow4_col1" class="data row4 col1" >0.078067%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow4_col2" class="data row4 col2" >99.992942%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row5" class="row_heading level0 row5" >5</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow5_col0" class="data row5 col0" >61</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow5_col1" class="data row5 col1" >0.078064%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow5_col2" class="data row5 col2" >99.986954%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row6" class="row_heading level0 row6" >6</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow6_col0" class="data row6 col0" >92</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow6_col1" class="data row6 col1" >0.081103%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow6_col2" class="data row6 col2" >99.979560%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row7" class="row_heading level0 row7" >7</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow7_col0" class="data row7 col0" >125</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow7_col1" class="data row7 col1" >0.078059%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow7_col2" class="data row7 col2" >99.973271%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row8" class="row_heading level0 row8" >8</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow8_col0" class="data row8 col0" >152</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow8_col1" class="data row8 col1" >0.076030%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow8_col2" class="data row8 col2" >99.968343%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row9" class="row_heading level0 row9" >9</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow9_col0" class="data row9 col0" >182</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow9_col1" class="data row9 col1" >0.075014%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow9_col2" class="data row9 col2" >99.962603%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row10" class="row_heading level0 row10" >10</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow10_col0" class="data row10 col0" >212</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow10_col1" class="data row10 col1" >0.073593%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow10_col2" class="data row10 col2" >99.957265%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row11" class="row_heading level0 row11" >11</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow11_col0" class="data row11 col0" >243</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow11_col1" class="data row11 col1" >0.072476%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow11_col2" class="data row11 col2" >99.951761%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row12" class="row_heading level0 row12" >12</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow12_col0" class="data row12 col0" >273</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow12_col1" class="data row12 col1" >0.071967%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow12_col2" class="data row12 col2" >99.946187%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row13" class="row_heading level0 row13" >13</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow13_col0" class="data row13 col0" >306</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow13_col1" class="data row13 col1" >0.071356%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow13_col2" class="data row13 col2" >99.940196%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row14" class="row_heading level0 row14" >14</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow14_col0" class="data row14 col0" >335</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow14_col1" class="data row14 col1" >0.070848%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow14_col2" class="data row14 col2" >99.934996%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row15" class="row_heading level0 row15" >15</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow15_col0" class="data row15 col0" >365</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow15_col1" class="data row15 col1" >0.070238%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow15_col2" class="data row15 col2" >99.929787%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row16" class="row_heading level0 row16" >16</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow16_col0" class="data row16 col0" >547</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow16_col1" class="data row16 col1" >0.064161%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow16_col2" class="data row16 col2" >99.903893%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row17" class="row_heading level0 row17" >17</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow17_col0" class="data row17 col0" >730</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow17_col1" class="data row17 col1" >0.056758%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow17_col2" class="data row17 col2" >99.886549%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row18" class="row_heading level0 row18" >18</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow18_col0" class="data row18 col0" >1097</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow18_col1" class="data row18 col1" >0.075010%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow18_col2" class="data row18 col2" >99.774813%</td>
            </tr>
            <tr>
                        <th id="T_4fc27bee_419a_11ec_a147_02cba411ec9dlevel0_row19" class="row_heading level0 row19" >19</th>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow19_col0" class="data row19 col0" >1462</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow19_col1" class="data row19 col1" >0.125752%</td>
                        <td id="T_4fc27bee_419a_11ec_a147_02cba411ec9drow19_col2" class="data row19 col2" >99.497569%</td>
            </tr>
    </tbody></table>




```python
def get_curve_from_dataframe(
        yf: Qcf.QCYearFraction,
        wf: Qcf.QCWealthFactor,
        df_curva: pd.DataFrame) -> Qcf.ZeroCouponCurve:
    """
    Retorna un objeto Qcf.ZeroCouponCurve. Esta función requiere que `df_curva` tenga una columna
    de nombre 'plazo' y una columna de nombre 'tasa'. Se usa interpolación lineal en la curva que
    se retorna.
    """
    plazos = Qcf.long_vec()
    tasas = Qcf.double_vec()
    for row in df_curva.itertuples():
        plazos.append(row.plazo)
        tasas.append(row.tasa)
    curva = Qcf.QCCurve(plazos, tasas)
    curva = Qcf.QCLinearInterpolator(curva)
    tipo_tasa = Qcf.QCInterestRate(0.0, yf, wf)
    curva = Qcf.ZeroCouponCurve(curva, tipo_tasa)
    return curva
```


```python
zcc = get_curve_from_dataframe(
    Qcf.QCAct365(),
    Qcf.QCCompoundWf(), 
    df_curva
)
```

Algunos métodos del objeto`zcc`.


```python
plazo = 900
print(f"Tasa a {plazo} días es igual a {zcc.get_rate_at(plazo):.4%}")
print(f"Factor de descuento a {plazo} días es igual a {zcc.get_discount_factor_at(plazo):.6%}")
```

    Tasa a 900 días es igual a 0.0652%
    Factor de descuento a 900 días es igual a 99.839384%


## Valorización


```python
def get_ois_using_template(
    template,
    type_ois: TypeOis,
    rp: Qcf.RecPay,
    notional: float,
    start_date: Qcf.QCDate,
    tenor: Qcf.Tenor,
    fixed_rate_value: float,
    spread: float,
    gearing: float
):
    """
    """
    template_dict = template[type_ois]
    meses = tenor.get_years() * 12 + tenor.get_months()
    end_date = start_date.add_months(meses)
    template_dict['fixed_rate'].set_value(fixed_rate_value)
    es_bono = False

    # Construye la pata fija
    fixed_rate_leg = Qcf.LegFactory.build_bullet_fixed_rate_leg(
        rp,
        start_date,
        end_date,
        template_dict['bus_adj_rule'],
        template_dict['periodicity'],
        template_dict['stub_period'],
        get_cal(template_dict['calendar']),
        template_dict['settlement_lag'],
        notional,
        template_dict['amort_is_cashflow'],
        template_dict['fixed_rate'],
        template_dict['currency'],
        es_bono)

    # Construye la pata ois
    rp = Qcf.RecPay.PAY if rp == Qcf.RecPay.RECEIVE else Qcf.RecPay.RECEIVE
    icp_clp_leg = Qcf.LegFactory.build_bullet_icp_clp2_leg(
        rp,
        start_date,
        end_date,
        template_dict['bus_adj_rule'],
        template_dict['periodicity'],
        template_dict['stub_period'],
        get_cal(template_dict['calendar']),
        template_dict['settlement_lag'],
        notional,
        template_dict['amort_is_cashflow'],
        spread,
        gearing,
        True
    )

    for i in range(icp_clp_leg.size()):
        cshflw = icp_clp_leg.get_cashflow_at(i)
        cshflw.set_start_date_icp(1.0)
        cshflw.set_end_date_icp(1.0)

    return fixed_rate_leg, icp_clp_leg
```

### Operación Ejemplo


```python
op = get_ois_using_template(
    type_ois_template,
    TypeOis.SOFR,
    Qcf.RecPay.RECEIVE,
    10000000,
    Qcf.QCDate(14, 10, 2020),
    Qcf.Tenor('2Y'),
    .01,
    0.0,
    1.0
)
op
```




    (<finrisk.QC_Financial_3.Leg at 0x7f3e85682100>,
     <finrisk.QC_Financial_3.Leg at 0x7f3e85682e68>)



#### Digresión: `functools.partial`

Supongamos que estoy en una situación en la que sólo quiero construir OIS de *SOFR*. Me gustaría no tener que repetir los argumentos `type_ois_template` y `TypeOis.SOFR` cada vez que llamo la función `get_ois_using_template`. Puedo definir una nueva función de la siguiente forma:


```python
get_ois_sofr = partial(get_ois_using_template, type_ois_template, TypeOis.SOFR)
```


```python
y = f(x, y, z)
y12 = f(1, 2, z)
```

Con esta nueva función, `get_ois_sofr`, ahora puedo construir la operación `op` de la siguiente forma:


```python
op = get_ois_sofr(
    Qcf.RecPay.RECEIVE,
    10000000,
    Qcf.QCDate(14, 10, 2020),
    Qcf.Tenor('2Y'),
    .01,
    0.0,
    1.0
)
```


```python
op
```




    (<finrisk.QC_Financial_3.Leg at 0x7f3e847e53d8>,
     <finrisk.QC_Financial_3.Leg at 0x7f3e847e51d0>)



#### Continuamos (fin digresión ...)


```python
aux.show_leg(op[0], 'FixedRateCashflow', '').style.format(frmt)
```




<style  type="text/css" >
</style><table id="T_861266ac_41a7_11ec_a147_02cba411ec9d" ><thead>    <tr>        <th class="blank level0" ></th>        <th class="col_heading level0 col0" >fecha_inicial</th>        <th class="col_heading level0 col1" >fecha_final</th>        <th class="col_heading level0 col2" >fecha_pago</th>        <th class="col_heading level0 col3" >nominal</th>        <th class="col_heading level0 col4" >amortizacion</th>        <th class="col_heading level0 col5" >interes</th>        <th class="col_heading level0 col6" >amort_es_flujo</th>        <th class="col_heading level0 col7" >flujo</th>        <th class="col_heading level0 col8" >moneda</th>        <th class="col_heading level0 col9" >valor_tasa</th>        <th class="col_heading level0 col10" >tipo_tasa</th>    </tr></thead><tbody>
                <tr>
                        <th id="T_861266ac_41a7_11ec_a147_02cba411ec9dlevel0_row0" class="row_heading level0 row0" >0</th>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col0" class="data row0 col0" >2020-10-14</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col1" class="data row0 col1" >2021-10-14</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col2" class="data row0 col2" >2021-10-14</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col3" class="data row0 col3" >10,000,000</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col4" class="data row0 col4" >0</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col5" class="data row0 col5" >101,389</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col6" class="data row0 col6" >True</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col7" class="data row0 col7" >101,388.8889</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col8" class="data row0 col8" >USD</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col9" class="data row0 col9" >1.0000%</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow0_col10" class="data row0 col10" >LinAct360</td>
            </tr>
            <tr>
                        <th id="T_861266ac_41a7_11ec_a147_02cba411ec9dlevel0_row1" class="row_heading level0 row1" >1</th>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col0" class="data row1 col0" >2021-10-14</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col1" class="data row1 col1" >2022-10-14</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col2" class="data row1 col2" >2022-10-14</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col3" class="data row1 col3" >10,000,000</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col4" class="data row1 col4" >10,000,000</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col5" class="data row1 col5" >101,389</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col6" class="data row1 col6" >True</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col7" class="data row1 col7" >10,101,388.8889</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col8" class="data row1 col8" >USD</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col9" class="data row1 col9" >1.0000%</td>
                        <td id="T_861266ac_41a7_11ec_a147_02cba411ec9drow1_col10" class="data row1 col10" >LinAct360</td>
            </tr>
    </tbody></table>




```python
aux.show_leg(op[1], 'IcpClpCashflow', '').style.format(frmt)
```




<style  type="text/css" >
</style><table id="T_660e832b_419a_11ec_a147_02cba411ec9d" ><thead>    <tr>        <th class="blank level0" ></th>        <th class="col_heading level0 col0" >fecha_inicial</th>        <th class="col_heading level0 col1" >fecha_final</th>        <th class="col_heading level0 col2" >fecha_pago</th>        <th class="col_heading level0 col3" >nominal</th>        <th class="col_heading level0 col4" >amortizacion</th>        <th class="col_heading level0 col5" >amort_es_flujo</th>        <th class="col_heading level0 col6" >flujo</th>        <th class="col_heading level0 col7" >moneda</th>        <th class="col_heading level0 col8" >icp_inicial</th>        <th class="col_heading level0 col9" >icp_final</th>        <th class="col_heading level0 col10" >valor_tasa</th>        <th class="col_heading level0 col11" >interes</th>        <th class="col_heading level0 col12" >spread</th>        <th class="col_heading level0 col13" >gearing</th>        <th class="col_heading level0 col14" >tipo_tasa</th>    </tr></thead><tbody>
                <tr>
                        <th id="T_660e832b_419a_11ec_a147_02cba411ec9dlevel0_row0" class="row_heading level0 row0" >0</th>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col0" class="data row0 col0" >2020-10-14</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col1" class="data row0 col1" >2021-10-14</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col2" class="data row0 col2" >2021-10-14</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col3" class="data row0 col3" >-10,000,000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col4" class="data row0 col4" >0</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col5" class="data row0 col5" >True</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col6" class="data row0 col6" >0.0000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col7" class="data row0 col7" >CLP</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col8" class="data row0 col8" >1.000000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col9" class="data row0 col9" >1.000000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col10" class="data row0 col10" >0.0000%</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col11" class="data row0 col11" >-0</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col12" class="data row0 col12" >0.0000%</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col13" class="data row0 col13" >1.000000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow0_col14" class="data row0 col14" >LinAct360</td>
            </tr>
            <tr>
                        <th id="T_660e832b_419a_11ec_a147_02cba411ec9dlevel0_row1" class="row_heading level0 row1" >1</th>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col0" class="data row1 col0" >2021-10-14</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col1" class="data row1 col1" >2022-10-14</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col2" class="data row1 col2" >2022-10-14</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col3" class="data row1 col3" >-10,000,000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col4" class="data row1 col4" >-10,000,000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col5" class="data row1 col5" >True</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col6" class="data row1 col6" >-10,000,000.0000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col7" class="data row1 col7" >CLP</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col8" class="data row1 col8" >1.000000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col9" class="data row1 col9" >1.000000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col10" class="data row1 col10" >0.0000%</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col11" class="data row1 col11" >-0</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col12" class="data row1 col12" >0.0000%</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col13" class="data row1 col13" >1.000000</td>
                        <td id="T_660e832b_419a_11ec_a147_02cba411ec9drow1_col14" class="data row1 col14" >LinAct360</td>
            </tr>
    </tbody></table>



#### Valor Presente Pata Fija


```python
vp = Qcf.PresentValue()
```


```python
fecha_val = Qcf.QCDate(14, 10, 2020)
```


```python
vp_fija = vp.pv(fecha_val, op[0], zcc)
print(f'El valor presente de la pata fija es: USD {vp_fija:,.2f}')
```

    El valor presente de la pata fija es: USD 10,008,917.25


**Ejercicio:** Replique el valor de la pata fija en Excel utilizando los flujos y los factores de descuento que obtiene de la curva `zcc`.


```python
# Se dan de alta las fechas finales de ambos cupones
fecha1 = Qcf.QCDate(14, 10, 2021)
fecha2 = Qcf.QCDate(14, 10, 2022)

# O de forma más automática:
fecha1 = op[0].get_cashflow_at(0).get_settlement_date()
fecha2 = op[0].get_cashflow_at(1).get_settlement_date()

# Se calcula el número de días entre la fecha de valorización (fecha_val) y las fechas
# finales de ambos cupones.
plazo1 = fecha_val.day_diff(fecha1)
plazo2 = fecha_val.day_diff(fecha2)

# Utilizando la curva zcc se calculan los df a esos plazos 
df1 = zcc.get_discount_factor_at(plazo1)
df2 = zcc.get_discount_factor_at(plazo2)

# Se obtienen los flujos totales (interés y amortización) de ambos cupones
flujo1 = op[0].get_cashflow_at(0).amount()
flujo2 = op[0].get_cashflow_at(1).amount()

# Finalmente, se calcula el valor presente como el producto (escalar) entre los df y los flujos.
check_vp = df1 * flujo1 + df2 * flujo2

# Se muestra el resultado.
print(f'El valor presente a mano es: {check_vp:,.2f}')
```

    El valor presente a mano es: 10,008,917.25


#### Valor Presente Pata Flotante


```python
fwd = Qcf.ForwardRates()
```

Este valor presente sólo considera el flujo del nocional al vencimiento. Esto porque aún no hemos calculado el valor esperado de los índices (o las tasas equivalentes).


```python
print(f'VP: {vp.pv(fecha_val, op[1], zcc):,.2f}')
```

    VP: -9,988,658.09


Comprobamos.


```python
print(f'{-df2 * 10000000:,.2f}')
```

    -9,988,658.09


Ahora se calculan los valores esperados.


```python
fwd.set_rates_icp_clp_leg(fecha_val, 1.0, op[1], zcc)
```


```python
aux.show_leg(op[1], 'IcpClpCashflow', '').style.format(frmt)
```




<style  type="text/css" >
</style><table id="T_886d0d94_419d_11ec_a147_02cba411ec9d" ><thead>    <tr>        <th class="blank level0" ></th>        <th class="col_heading level0 col0" >fecha_inicial</th>        <th class="col_heading level0 col1" >fecha_final</th>        <th class="col_heading level0 col2" >fecha_pago</th>        <th class="col_heading level0 col3" >nominal</th>        <th class="col_heading level0 col4" >amortizacion</th>        <th class="col_heading level0 col5" >amort_es_flujo</th>        <th class="col_heading level0 col6" >flujo</th>        <th class="col_heading level0 col7" >moneda</th>        <th class="col_heading level0 col8" >icp_inicial</th>        <th class="col_heading level0 col9" >icp_final</th>        <th class="col_heading level0 col10" >valor_tasa</th>        <th class="col_heading level0 col11" >interes</th>        <th class="col_heading level0 col12" >spread</th>        <th class="col_heading level0 col13" >gearing</th>        <th class="col_heading level0 col14" >tipo_tasa</th>    </tr></thead><tbody>
                <tr>
                        <th id="T_886d0d94_419d_11ec_a147_02cba411ec9dlevel0_row0" class="row_heading level0 row0" >0</th>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col0" class="data row0 col0" >2020-10-14</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col1" class="data row0 col1" >2021-10-14</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col2" class="data row0 col2" >2021-10-14</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col3" class="data row0 col3" >-10,000,000</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col4" class="data row0 col4" >0</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col5" class="data row0 col5" >True</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col6" class="data row0 col6" >-7,023.7778</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col7" class="data row0 col7" >CLP</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col8" class="data row0 col8" >1.000000</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col9" class="data row0 col9" >1.000702</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col10" class="data row0 col10" >0.0700%</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col11" class="data row0 col11" >-7,097</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col12" class="data row0 col12" >0.0000%</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col13" class="data row0 col13" >1.000000</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow0_col14" class="data row0 col14" >LinAct360</td>
            </tr>
            <tr>
                        <th id="T_886d0d94_419d_11ec_a147_02cba411ec9dlevel0_row1" class="row_heading level0 row1" >1</th>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col0" class="data row1 col0" >2021-10-14</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col1" class="data row1 col1" >2022-10-14</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col2" class="data row1 col2" >2022-10-14</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col3" class="data row1 col3" >-10,000,000</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col4" class="data row1 col4" >-10,000,000</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col5" class="data row1 col5" >True</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col6" class="data row1 col6" >-10,004,327.9717</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col7" class="data row1 col7" >CLP</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col8" class="data row1 col8" >1.000702</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col9" class="data row1 col9" >1.001135</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col10" class="data row1 col10" >0.0400%</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col11" class="data row1 col11" >-4,056</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col12" class="data row1 col12" >0.0000%</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col13" class="data row1 col13" >1.000000</td>
                        <td id="T_886d0d94_419d_11ec_a147_02cba411ec9drow1_col14" class="data row1 col14" >LinAct360</td>
            </tr>
    </tbody></table>




```python
vp_flot = vp.pv(fecha_val, op[1], zcc)
print(f'El valor presente de la pata flotante es: USD {vp_flot:,.2f}')
```

    El valor presente de la pata flotante es: USD -10,000,000.00


¿Porqué sabíamos que tenía que dar 10,000,000.00? Hint: la respuesta está en la construcción de la curva cero OIS.

## Sensibilidad

En `QC_Financial_3` al calcular el valor presente, también se calculan las derivadas del valor presente respecto a cada uno de los vértices de la curva.

### Pata Fija

f(g(x)) = y --> dy/dx = f'(g(x)) . g'(x)


```python
vp.pv(fecha_val, op[0], zcc)
der = vp.get_derivatives()
```

Tengo que ejecutar el método `get_derivatives` justo después de valorizar. 


```python
for d in der:
    print(d)
```

    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    -10124.661219898855
    0.0
    -19986227.206320565
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0


Con esas derivadas, se puede calcular la sensibilidad a cada vértice de la curva cupón cero para un movimiento de 1 punto básico.


```python
print(type(der))
```

    <class 'finrisk.QC_Financial_3.double_vec'>



```python
delta = .0001
total = 0
for i, d in enumerate(der):
    total += d * delta
    print(f"Sensibilidad en {i}: {d * delta: 0,.2f}")
print(f"Sensibilidad total: {total:,.2f}")
```

    Sensibilidad en 0:  0.00
    Sensibilidad en 1:  0.00
    Sensibilidad en 2:  0.00
    Sensibilidad en 3:  0.00
    Sensibilidad en 4:  0.00
    Sensibilidad en 5:  0.00
    Sensibilidad en 6:  0.00
    Sensibilidad en 7:  0.00
    Sensibilidad en 8:  0.00
    Sensibilidad en 9:  0.00
    Sensibilidad en 10:  0.00
    Sensibilidad en 11:  0.00
    Sensibilidad en 12:  0.00
    Sensibilidad en 13:  0.00
    Sensibilidad en 14:  0.00
    Sensibilidad en 15: -1.01
    Sensibilidad en 16:  0.00
    Sensibilidad en 17: -1,998.62
    Sensibilidad en 18:  0.00
    Sensibilidad en 19:  0.00
    Sensibilidad en 20:  0.00
    Sensibilidad en 21:  0.00
    Sensibilidad en 22:  0.00
    Sensibilidad en 23:  0.00
    Sensibilidad en 24:  0.00
    Sensibilidad en 25:  0.00
    Sensibilidad en 26:  0.00
    Sensibilidad en 27:  0.00
    Sensibilidad en 28:  0.00
    Sensibilidad en 29:  0.00
    Sensibilidad en 30:  0.00
    Sensibilidad en 31:  0.00
    Sensibilidad en 32:  0.00
    Sensibilidad total: -1,999.64


**Ejercicio:** Verifique por diferencias finitas centrales la derivada y la sensibilidad en el vértice 17. La aproximación de la derivada por diferencias finitas centrales es:

$$
\begin{equation}
f^{\prime}\left(x\right)\approx\frac{f\left(x+h\right)-f\left(x-h\right)}{2h}
\end{equation}
$$

### Pata Flotante

En este caso, al rescatar estas derivadas, obtengo sólo lo relacionado con la curva de descuento.


```python
vp.pv(fecha_val, op[1], zcc)
der = vp.get_derivatives()
```

La sensibilidad es muy parecida a la de la pata fija.


```python
total = 0
for i, d in enumerate(der):
    total += d * delta
    print(f"Sensibilidad en {i}: {d * delta: 0,.2f}")
print(f"Sensibilidad total: {total:,.2f}")
```

    Sensibilidad en 0:  0.00
    Sensibilidad en 1:  0.00
    Sensibilidad en 2:  0.00
    Sensibilidad en 3:  0.00
    Sensibilidad en 4:  0.00
    Sensibilidad en 5:  0.00
    Sensibilidad en 6:  0.00
    Sensibilidad en 7:  0.00
    Sensibilidad en 8:  0.00
    Sensibilidad en 9:  0.00
    Sensibilidad en 10:  0.00
    Sensibilidad en 11:  0.00
    Sensibilidad en 12:  0.00
    Sensibilidad en 13:  0.00
    Sensibilidad en 14:  0.00
    Sensibilidad en 15:  0.70
    Sensibilidad en 16:  0.00
    Sensibilidad en 17:  1,997.46
    Sensibilidad en 18:  0.00
    Sensibilidad en 19:  0.00
    Sensibilidad en 20:  0.00
    Sensibilidad en 21:  0.00
    Sensibilidad en 22:  0.00
    Sensibilidad en 23:  0.00
    Sensibilidad en 24:  0.00
    Sensibilidad en 25:  0.00
    Sensibilidad en 26:  0.00
    Sensibilidad en 27:  0.00
    Sensibilidad en 28:  0.00
    Sensibilidad en 29:  0.00
    Sensibilidad en 30:  0.00
    Sensibilidad en 31:  0.00
    Sensibilidad en 32:  0.00
    Sensibilidad total: 1,998.16


La estructura es la misma que para una pata fija, lo que indica que se debe también incluir la sensibilidad a la curva de proyección.


```python
import numpy as np
result = []
for i in range(op[1].size()):
    cshflw = op[1].get_cashflow_at(i)
    
    # Se calcularon las derivadas al calcular los valores
    # esperados de las tasas
    amt_der = cshflw.get_amount_derivatives() 
    
    # Se calcula el factor de descuento al plazo del flujo.
    df = zcc.get_discount_factor_at(fecha_val.day_diff(cshflw.get_settlement_date()))
    
    # 
    amt_der = [a * df * delta for a in amt_der]
    if len(amt_der) > 0:
        result.append(np.array(amt_der))
total = result[0] * 0

for r in result:
    total += r

for i in range(len(total)):
    print(f"Sensibilidad en {i}: {total[i]:0,.2f}")

print(f"Sensibilidad de proyección: {sum(total):,.2f} USD")
```

    Sensibilidad en 0: -0.00
    Sensibilidad en 1: -0.00
    Sensibilidad en 2: -0.00
    Sensibilidad en 3: -0.00
    Sensibilidad en 4: -0.00
    Sensibilidad en 5: -0.00
    Sensibilidad en 6: -0.00
    Sensibilidad en 7: -0.00
    Sensibilidad en 8: -0.00
    Sensibilidad en 9: -0.00
    Sensibilidad en 10: -0.00
    Sensibilidad en 11: -0.00
    Sensibilidad en 12: -0.00
    Sensibilidad en 13: -0.00
    Sensibilidad en 14: -0.00
    Sensibilidad en 15: -0.70
    Sensibilidad en 16: -0.00
    Sensibilidad en 17: -1,997.46
    Sensibilidad en 18: -0.00
    Sensibilidad en 19: -0.00
    Sensibilidad en 20: -0.00
    Sensibilidad en 21: -0.00
    Sensibilidad en 22: -0.00
    Sensibilidad en 23: -0.00
    Sensibilidad en 24: -0.00
    Sensibilidad en 25: -0.00
    Sensibilidad en 26: -0.00
    Sensibilidad en 27: -0.00
    Sensibilidad en 28: -0.00
    Sensibilidad en 29: -0.00
    Sensibilidad en 30: -0.00
    Sensibilidad en 31: -0.00
    Sensibilidad en 32: -0.00
    Sensibilidad de proyección: -1,998.16 USD


**Ejercicio:** Ambas sensibilidades se cancelan. ¿Porqué?

En fórmula:

Cashflow = F(z1, z2, z3) / Df(z1, z2, z3)

Al calcular las derivadas del valor presente, sólo derivamos respecto a z1, z2, z3 en el denominador.

Al calcular las derivadas del flujo, derivamos respecto a z1, z2 y z3 en el numerador, lo que coincide con derivar la función F respecto a z1, z2 y z3.
