Construcción de Operaciones¶
Para ejecutar todos los ejemplos se debe importar la librería. Se sugiere utilizar siempre el alias qcf.
import qcfinancial as qcf
from qcfinancial import FxFixingLagAppliesTo
import aux_functions as aux
import pandas as pd
qcf.id()
'version: 1.6.1, build: 2025-06-06 09:09'
Legs¶
Los objetos de tipo Leg son una lista (o vector) de objetos Cashflow y representan una pata de un instrumento financiero. Un objeto de tipo Leg puede construirse a mano es decir, dando de alta cashflows y agregándolos uno a uno o con algunos métodos de conveniencia cuyo funcionamiento se mostrará.
Construcción Manual¶
Se verá como construir un Leg con 2 SimpleCashflow de forma manual. En particular, este objeto Leg podría representar una operación FX por entrega física.
Primero se construye dos objetos de tipo SimpleCashflow:
fecha_vencimiento = qcf.QCDate(23, 9, 2024)
simple_cashflow_1 = qcf.SimpleCashflow(
fecha_vencimiento, # fecha del flujo
1_000, # monto
qcf.QCUSD() # moneda
)
simple_cashflow_2 = qcf.SimpleCashflow(
fecha_vencimiento, # fecha del flujo
-900_000, # monto
qcf.QCCLP()) # moneda
Con esto, se construye un objeto de tipo Leg. En este momento el objeto está vacío.
leg = qcf.Leg()
leg.size()
0
Agregamos los dos cashflows.
leg.append_cashflow(simple_cashflow_1)
leg.append_cashflow(simple_cashflow_2)
Se observa el resultado (usamos la función del módulo aux_functions que a su vez depende del método show).
df = aux.leg_as_dataframe(leg)
df.style.format(aux.format_dict)
| fecha_pago | monto | moneda | |
|---|---|---|---|
| 0 | 2024-09-23 | 1,000.00 | USD |
| 1 | 2024-09-23 | -900,000.00 | CLP |
Agregar todo tipo de cashflows a un mismo objeto Leg entrega mucha flexibilidad para construir operaciones con estructuras complicadas. Partiremos, sin embargo, explicando como construir objetos Leg a partir de cashflows del mismo tipo.
Construcción Asistida de un FixedRateLeg¶
Se verá como construir objetos Leg donde cada Cashflow es un objeto de tipo FixedRateCashflow, todos con la misma tasa fija. En el primer ejemplo se construye un Leg de tipo bullet: una única amortización igual al capital vigente de todos los FixedRateCasflow en el último flujo.
Se requieren los siguientes parámetros, los cuales permitirán construir las variedades más comunes de FixedRateLeg, entre las cuales están las utilizadas en las operaciones estándar de mercado.
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados (FOLLOW, MOD_FOLLOW)Tenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para los ajustes de fechas y fechas de pagounsigned int: lag de pago expresado en díasfloat: nominal inicialbool: si esTruesignifica que la amortización es un flujo de caja efectivoQCInterestRate: la tasa a aplicar en cada flujoQCCurrency: moneda del nominal y de los flujosbool: si esTruefuerza a que las fechas de pago coincidan con las fechas finales. Esto para lograr una valorización acorde a las convenciones de los mercados de renta fija, en caso que laLegrepresente un bono a tasa fija.SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo y no se ha definido un ajuste en las fechas finales. Las alternativas son dos, se calcula sumando elsettlement_lagdesdeend_dateo se calcula sumandosettlement_laga partir de la primera fecha hábil posterior aend_date.
El parámetro SettLagBehaviour se agregó en la versión 0.11.0 .
Vamos a un ejemplo.
Se da de alta los parámetros requeridos
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(29, 7, 2024)
fecha_final = qcf.QCDate(29, 7, 2026)
bus_adj_rule = qcf.BusyAdjRules.FOLLOW
periodicidad = qcf.Tenor('6M')
periodo_irregular = qcf.StubPeriod.NO
calendario = aux.get_business_calendar('CL', range(2024, 2027)) # Se apoya en holidays
lag_pago = 0
nominal = 100_000_000.0
amort_es_flujo = True
valor_tasa = .05
tasa_cupon = qcf.QCInterestRate(valor_tasa, qcf.QCAct360(), qcf.QCLinearWf())
moneda = qcf.QCCLP()
es_bono = False
Este argumento tiene como valor por default qcf.SettLagBehaviour.DONT_MOVE. Aquí, por claridad, se define explícitamente.
sett_lag_behaviour = qcf.SettLagBehaviour.DONT_MOVE
Se da de alta el objeto.
fixed_rate_leg = qcf.LegFactory.build_bullet_fixed_rate_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=moneda,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
)
Como en el capítulo anterior, se puede lograr una muy buena visualización del resultado utilizando un pandas.Dataframe de pandas y el método show.
df = aux.leg_as_dataframe(fixed_rate_leg)
df.style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-07-29 | 2025-01-29 | 2025-01-29 | 100,000,000.00 | 0.00 | 2,555,555.56 | True | 2,555,555.56 | CLP | 5.0000% | LinAct360 |
| 1 | 2025-01-29 | 2025-07-29 | 2025-07-29 | 100,000,000.00 | 0.00 | 2,513,888.89 | True | 2,513,888.89 | CLP | 5.0000% | LinAct360 |
| 2 | 2025-07-29 | 2026-01-29 | 2026-01-29 | 100,000,000.00 | 0.00 | 2,555,555.56 | True | 2,555,555.56 | CLP | 5.0000% | LinAct360 |
| 3 | 2026-01-29 | 2026-07-29 | 2026-07-29 | 100,000,000.00 | 100,000,000.00 | 2,513,888.89 | True | 102,513,888.89 | CLP | 5.0000% | LinAct360 |
Otros StubPeriod¶
Período irregular corto al inicio (qcf.StubPeriod.SHORTFRONT)
fecha_final = fecha_inicio.add_months(27)
periodo_irregular = qcf.StubPeriod.SHORTFRONT
fixed_rate_leg = qcf.LegFactory.build_bullet_fixed_rate_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=moneda,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
)
df = aux.leg_as_dataframe(fixed_rate_leg)
df.style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-07-29 | 2024-10-29 | 2024-10-29 | 100,000,000.00 | 0.00 | 1,277,777.78 | True | 1,277,777.78 | CLP | 5.0000% | LinAct360 |
| 1 | 2024-10-29 | 2025-04-29 | 2025-04-29 | 100,000,000.00 | 0.00 | 2,527,777.78 | True | 2,527,777.78 | CLP | 5.0000% | LinAct360 |
| 2 | 2025-04-29 | 2025-10-29 | 2025-10-29 | 100,000,000.00 | 0.00 | 2,541,666.67 | True | 2,541,666.67 | CLP | 5.0000% | LinAct360 |
| 3 | 2025-10-29 | 2026-04-29 | 2026-04-29 | 100,000,000.00 | 0.00 | 2,527,777.78 | True | 2,527,777.78 | CLP | 5.0000% | LinAct360 |
| 4 | 2026-04-29 | 2026-10-29 | 2026-10-29 | 100,000,000.00 | 100,000,000.00 | 2,541,666.67 | True | 102,541,666.67 | CLP | 5.0000% | LinAct360 |
Período irregular corto al final (qcf.StubPeriod.SHORTBACK)
periodo_irregular = qcf.StubPeriod.SHORTBACK
fixed_rate_leg = qcf.LegFactory.build_bullet_fixed_rate_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=moneda,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
)
df = aux.leg_as_dataframe(fixed_rate_leg)
df.style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-07-29 | 2025-01-29 | 2025-01-29 | 100,000,000.00 | 0.00 | 2,555,555.56 | True | 2,555,555.56 | CLP | 5.0000% | LinAct360 |
| 1 | 2025-01-29 | 2025-07-29 | 2025-07-29 | 100,000,000.00 | 0.00 | 2,513,888.89 | True | 2,513,888.89 | CLP | 5.0000% | LinAct360 |
| 2 | 2025-07-29 | 2026-01-29 | 2026-01-29 | 100,000,000.00 | 0.00 | 2,555,555.56 | True | 2,555,555.56 | CLP | 5.0000% | LinAct360 |
| 3 | 2026-01-29 | 2026-07-29 | 2026-07-29 | 100,000,000.00 | 0.00 | 2,513,888.89 | True | 2,513,888.89 | CLP | 5.0000% | LinAct360 |
| 4 | 2026-07-29 | 2026-10-29 | 2026-10-29 | 100,000,000.00 | 100,000,000.00 | 1,277,777.78 | True | 101,277,777.78 | CLP | 5.0000% | LinAct360 |
Período irregular largo al principio (qcf.StubPeriod.LONGFRONT)
periodo_irregular = qcf.StubPeriod.LONGFRONT
fixed_rate_leg = qcf.LegFactory.build_bullet_fixed_rate_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=moneda,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
)
df = aux.leg_as_dataframe(fixed_rate_leg)
df.style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-07-29 | 2025-04-29 | 2025-04-29 | 100,000,000.00 | 0.00 | 3,805,555.56 | True | 3,805,555.56 | CLP | 5.0000% | LinAct360 |
| 1 | 2025-04-29 | 2025-10-29 | 2025-10-29 | 100,000,000.00 | 0.00 | 2,541,666.67 | True | 2,541,666.67 | CLP | 5.0000% | LinAct360 |
| 2 | 2025-10-29 | 2026-04-29 | 2026-04-29 | 100,000,000.00 | 0.00 | 2,527,777.78 | True | 2,527,777.78 | CLP | 5.0000% | LinAct360 |
| 3 | 2026-04-29 | 2026-10-29 | 2026-10-29 | 100,000,000.00 | 100,000,000.00 | 2,541,666.67 | True | 102,541,666.67 | CLP | 5.0000% | LinAct360 |
Período irregular largo al final (qcf.StubPeriod.LONGBACK)
periodo_irregular = qcf.StubPeriod.LONGBACK
fixed_rate_leg = qcf.LegFactory.build_bullet_fixed_rate_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=moneda,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
)
df = aux.leg_as_dataframe(fixed_rate_leg)
df.style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-07-29 | 2025-01-29 | 2025-01-29 | 100,000,000.00 | 0.00 | 2,555,555.56 | True | 2,555,555.56 | CLP | 5.0000% | LinAct360 |
| 1 | 2025-01-29 | 2025-07-29 | 2025-07-29 | 100,000,000.00 | 0.00 | 2,513,888.89 | True | 2,513,888.89 | CLP | 5.0000% | LinAct360 |
| 2 | 2025-07-29 | 2026-01-29 | 2026-01-29 | 100,000,000.00 | 0.00 | 2,555,555.56 | True | 2,555,555.56 | CLP | 5.0000% | LinAct360 |
| 3 | 2026-01-29 | 2026-10-29 | 2026-10-29 | 100,000,000.00 | 100,000,000.00 | 3,791,666.67 | True | 103,791,666.67 | CLP | 5.0000% | LinAct360 |
Período de gracia, usual en la cobertura de créditos (qcf.StubPeriod.LONGFRONT3)
fecha_final = fecha_inicio.add_months(12 * 5) # Swap de 5Y
periodo_irregular = qcf.StubPeriod.LONGFRONT3 # Una de varias opciones parecidas para alargar el primer período de intereses
fixed_rate_leg = qcf.LegFactory.build_bullet_fixed_rate_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=moneda,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
)
df = aux.leg_as_dataframe(fixed_rate_leg)
df.style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-07-29 | 2026-01-29 | 2026-01-29 | 100,000,000.00 | 0.00 | 7,625,000.00 | True | 7,625,000.00 | CLP | 5.0000% | LinAct360 |
| 1 | 2026-01-29 | 2026-07-29 | 2026-07-29 | 100,000,000.00 | 0.00 | 2,513,888.89 | True | 2,513,888.89 | CLP | 5.0000% | LinAct360 |
| 2 | 2026-07-29 | 2027-01-29 | 2027-01-29 | 100,000,000.00 | 0.00 | 2,555,555.56 | True | 2,555,555.56 | CLP | 5.0000% | LinAct360 |
| 3 | 2027-01-29 | 2027-07-29 | 2027-07-29 | 100,000,000.00 | 0.00 | 2,513,888.89 | True | 2,513,888.89 | CLP | 5.0000% | LinAct360 |
| 4 | 2027-07-29 | 2028-01-31 | 2028-01-31 | 100,000,000.00 | 0.00 | 2,583,333.33 | True | 2,583,333.33 | CLP | 5.0000% | LinAct360 |
| 5 | 2028-01-31 | 2028-07-31 | 2028-07-31 | 100,000,000.00 | 0.00 | 2,527,777.78 | True | 2,527,777.78 | CLP | 5.0000% | LinAct360 |
| 6 | 2028-07-31 | 2029-01-29 | 2029-01-29 | 100,000,000.00 | 0.00 | 2,527,777.78 | True | 2,527,777.78 | CLP | 5.0000% | LinAct360 |
| 7 | 2029-01-29 | 2029-07-30 | 2029-07-30 | 100,000,000.00 | 100,000,000.00 | 2,527,777.78 | True | 102,527,777.78 | CLP | 5.0000% | LinAct360 |
Construcción Asistida de un CustomAmortFixedRateLeg¶
En este ejemplo se construye un Leg con cashflows a tasa fija donde la estructura de amortizaciones es customizada.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagounsigned int: lag de pago expresado en díasCustomNotionalAndAmort: vector de capital vigente y amortizaciones customizadobool: si esTruesignifica que la amortización es un flujo de caja efectivoQCInterestRate: la tasa a aplicar en cada flujoQCCurrency: moneda del nominal y de los flujosSettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.
Notar que este tipo de Leg no admite el parámetro is_bond. Se puede lograr el mismo efecto construyendo una pata bullet y luego customizando su amortización.
Vamos a un ejemplo.
Primero se da de alta los parámetros requeridos
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(31, 1, 2024)
fecha_final = qcf.QCDate(31, 1, 2028)
calendario = aux.get_business_calendar('US', range(2024, 2027))
bus_adj_rule = qcf.BusyAdjRules.NO
periodicidad = qcf.Tenor('6M')
periodo_irregular = qcf.StubPeriod.NO
lag_pago = 1
amort_es_flujo = True
valor_tasa = .05
tasa_cupon = qcf.QCInterestRate(
valor_tasa,
qcf.QC30360(),
qcf.QCLinearWf()
)
moneda = qcf.QCCLP()
sett_lag_behaviour = qcf.SettLagBehaviour.DONT_MOVE
Aquí se da de alta el vector de capitales vigentes y amortizaciones. Cada elemento del vector es una tupla que continen el capital vigente y amortización del correspondiente cupón.
custom_notional_amort = qcf.CustomNotionalAmort()
custom_notional_amort.set_size(8) # De la fecha inicio, fecha final y periodicidad se deduce que serán 8 cupones
for i in range(0, 8):
custom_notional_amort.set_notional_amort_at(i, 800.0 - i * 100.0, 100.0)
Se da de alta el objeto.
fixed_rate_custom_leg = qcf.LegFactory.build_custom_amort_fixed_rate_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
notional_and_amort=custom_notional_amort,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=moneda,
sett_lag_behaviour=sett_lag_behaviour,
)
df = aux.leg_as_dataframe(fixed_rate_custom_leg)
df.style.format(aux.format_dict).set_properties(
**{'background-color': '#FFCFC9', 'color':'black'},
subset=['nocional','amortizacion', 'flujo']
).set_properties(
**{'background-color': '#FFCFA9', 'color':'black'},
subset=['flujo']
)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-01-31 | 2024-07-31 | 2024-08-01 | 800.00 | 100.00 | 20.00 | True | 120.00 | CLP | 5.0000% | Lin30360 |
| 1 | 2024-07-31 | 2025-01-31 | 2025-02-03 | 700.00 | 100.00 | 17.50 | True | 117.50 | CLP | 5.0000% | Lin30360 |
| 2 | 2025-01-31 | 2025-07-31 | 2025-08-01 | 600.00 | 100.00 | 15.00 | True | 115.00 | CLP | 5.0000% | Lin30360 |
| 3 | 2025-07-31 | 2026-01-31 | 2026-02-02 | 500.00 | 100.00 | 12.50 | True | 112.50 | CLP | 5.0000% | Lin30360 |
| 4 | 2026-01-31 | 2026-07-31 | 2026-08-03 | 400.00 | 100.00 | 10.00 | True | 110.00 | CLP | 5.0000% | Lin30360 |
| 5 | 2026-07-31 | 2027-01-31 | 2027-02-01 | 300.00 | 100.00 | 7.50 | True | 107.50 | CLP | 5.0000% | Lin30360 |
| 6 | 2027-01-31 | 2027-07-31 | 2027-08-02 | 200.00 | 100.00 | 5.00 | True | 105.00 | CLP | 5.0000% | Lin30360 |
| 7 | 2027-07-31 | 2028-01-31 | 2028-02-01 | 100.00 | 100.00 | 2.50 | True | 102.50 | CLP | 5.0000% | Lin30360 |
Construcción Asistida de un FixedRateMultiCurrencyLeg¶
Se verá como construir objetos Leg donde cada Cashflow es un objeto de tipo FixedRateMultiCurrencyCashflow, todos con la misma tasa fija. En el primer ejemplo se construye un Leg de tipo bullet: una única amortización igual al capital vigente de todos los FixedRateMultiCurrencyCasflow en el último flujo.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagounsigned int: lag de pago expresado en díasfloat: nominal inicialbool: si esTruesignifica que la amortización es un flujo de caja efectivoQCInterestRate: la tasa a aplicar en cada flujoQCCurrency: moneda del nominalbool: si esTruefuerza a que las fechas de pago coincidan con las fechas finales. Esto para lograr una valorización acorde a las convenciones de los mercados de renta fija, en caso que laLegrepresente un bono a tasa fija.SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.
MultiCurrency
- QCCurrency: moneda de los flujos
- FXRateIndex: índice con el cual se transforma cada flujo a la moneda de pago.
- unsigned int: lag de fijación del valor del índice de tipo de cambio.
- FxFixingLagPivot: este parámetro indica si el lag de fijación del índice FX se aplica sobre end_date o sobre settlement_date.
- FxFixingLagAppliesTo: indica si el lag se refiere a FIXING_DATE o PUBISHING_DATE del índice.
Vamos a un ejemplo.
Primero se debe dar de alta un FXRateIndex
scl = aux.get_business_calendar('CL', range(2024, 2031))
ny = aux.get_business_calendar('US', range(2024, 2031))
scl_ny = scl + ny
usd = qcf.QCUSD()
clp = qcf.QCCLP()
usdclp = qcf.FXRate(usd, clp)
one_d = qcf.Tenor('1D')
usdclp_obs = qcf.FXRateIndex(
usdclp,
'USDOBS', # Vamos a suponer que es el Dólar Observado
one_d,
one_d,
scl, # Es Santiago
)
Luego se dan de alta los otros parámetros requeridos para la construcción
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(17, 7, 2024)
Vamos a aplicar un truco para el cálculo de la fecha final. Se define el plazo de la pata con un objeto de tipo qcf.Tenor.
plazo = qcf.Tenor("6Y")
fecha_final = fecha_inicio.add_months(plazo.get_years() * 12 + plazo.get_months())
print(f"Fecha final: {fecha_final}")
Fecha final: 2030-07-17
Vamos con el resto de parámetros.
bus_adj_rule = qcf.BusyAdjRules.MODFOLLOW
periodicidad = qcf.Tenor('6M')
periodo_irregular = qcf.StubPeriod.NO
lag_pago = 1
valor_tasa = .03
tasa_cupon = qcf.QCInterestRate(
valor_tasa,
qcf.QC30360(),
qcf.QCLinearWf()
)
es_bono = False
lag_pago = 0
sett_lag_behaviour = qcf.SettLagBehaviour.DONT_MOVE
fx_rate_index_fixing_lag = 2 # lag de fijación del índice FX
fx_fixing_lag_pivot = qcf.FxFixingLagPivot.END_DATE
fx_fixing_lag_applies_to = qcf.FxFixingLagAppliesTo.FIXING_DATE
Finalmente, se da de alta el objeto.
fixed_rate_mccy_leg = qcf.LegFactory.build_bullet_fixed_rate_mccy_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=scl_ny,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=usd,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
# Parámetros MultiCurrency
settlement_currency=clp,
fx_rate_index=usdclp_obs,
fx_rate_index_fixing_lag=fx_rate_index_fixing_lag,
fx_fixing_lag_pivot=fx_fixing_lag_pivot,
fx_fixing_lag_applies_to=fx_fixing_lag_applies_to
)
scl_ny.shift(qcf.QCDate("2025-07-17"), -fx_rate_index_fixing_lag)
2025-07-14
Visualización.
df = aux.leg_as_dataframe(fixed_rate_mccy_leg)
df.style.format(aux.format_dict).set_properties(
**{'background-color': '#FFCFC9', 'color':'black'},
subset=['fecha_pago',]
).set_properties(
**{'background-color': '#FFCFA9', 'color':'black'},
subset=['fecha_fixing_fx']
)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | fecha_fixing_fx | moneda_pago | indice_fx | valor_indice_fx | amortizacion_moneda_pago | interes_moneda_pago | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-07-17 | 2025-01-17 | 2025-01-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2025-01-16 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 1 | 2025-01-17 | 2025-07-17 | 2025-07-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2025-07-15 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 2 | 2025-07-17 | 2026-01-20 | 2026-01-20 | 100,000,000.00 | 0.00 | 1,525,000.00 | True | 1,525,000.00 | USD | 3.0000% | Lin30360 | 2026-01-16 | CLP | USDOBS | 1.00 | 0.00 | 1,525,000.00 |
| 3 | 2026-01-20 | 2026-07-17 | 2026-07-17 | 100,000,000.00 | 0.00 | 1,475,000.00 | True | 1,475,000.00 | USD | 3.0000% | Lin30360 | 2026-07-15 | CLP | USDOBS | 1.00 | 0.00 | 1,475,000.00 |
| 4 | 2026-07-17 | 2027-01-19 | 2027-01-19 | 100,000,000.00 | 0.00 | 1,516,666.67 | True | 1,516,666.67 | USD | 3.0000% | Lin30360 | 2027-01-15 | CLP | USDOBS | 1.00 | 0.00 | 1,516,666.67 |
| 5 | 2027-01-19 | 2027-07-19 | 2027-07-19 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2027-07-15 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 6 | 2027-07-19 | 2028-01-18 | 2028-01-18 | 100,000,000.00 | 0.00 | 1,491,666.67 | True | 1,491,666.67 | USD | 3.0000% | Lin30360 | 2028-01-14 | CLP | USDOBS | 1.00 | 0.00 | 1,491,666.67 |
| 7 | 2028-01-18 | 2028-07-17 | 2028-07-17 | 100,000,000.00 | 0.00 | 1,491,666.67 | True | 1,491,666.67 | USD | 3.0000% | Lin30360 | 2028-07-14 | CLP | USDOBS | 1.00 | 0.00 | 1,491,666.67 |
| 8 | 2028-07-17 | 2029-01-17 | 2029-01-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2029-01-15 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 9 | 2029-01-17 | 2029-07-17 | 2029-07-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2029-07-13 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 10 | 2029-07-17 | 2030-01-17 | 2030-01-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2030-01-16 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 11 | 2030-01-17 | 2030-07-17 | 2030-07-17 | 100,000,000.00 | 100,000,000.00 | 1,500,000.00 | True | 101,500,000.00 | USD | 3.0000% | Lin30360 | 2030-07-15 | CLP | USDOBS | 1.00 | 100,000,000.00 | 1,500,000.00 |
Veamos el efecto de cambiar la opción fix_fixing_lag_pivot.
fx_fixing_lag_pivot = qcf.FxFixingLagPivot.END_DATE
fixed_rate_mccy_leg = qcf.LegFactory.build_bullet_fixed_rate_mccy_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=usd,
settlement_currency=clp,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
# Parámetros MultiCurrency
fx_rate_index=usdclp_obs,
fx_rate_index_fixing_lag=fx_rate_index_fixing_lag,
fx_fixing_lag_pivot=fx_fixing_lag_pivot,
)
df = aux.leg_as_dataframe(fixed_rate_mccy_leg)
df.style.format(aux.format_dict).set_properties(
**{'background-color': '#FFCFC9', 'color':'black'},
subset=['fecha_final',]
).set_properties(
**{'background-color': '#FFCFA9', 'color':'black'},
subset=['fecha_fixing_fx']
)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | valor_tasa | tipo_tasa | fecha_fixing_fx | moneda_pago | indice_fx | valor_indice_fx | amortizacion_moneda_pago | interes_moneda_pago | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-07-17 | 2025-01-17 | 2025-01-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2025-01-15 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 1 | 2025-01-17 | 2025-07-17 | 2025-07-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2025-07-15 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 2 | 2025-07-17 | 2026-01-20 | 2026-01-20 | 100,000,000.00 | 0.00 | 1,525,000.00 | True | 1,525,000.00 | USD | 3.0000% | Lin30360 | 2026-01-15 | CLP | USDOBS | 1.00 | 0.00 | 1,525,000.00 |
| 3 | 2026-01-20 | 2026-07-17 | 2026-07-17 | 100,000,000.00 | 0.00 | 1,475,000.00 | True | 1,475,000.00 | USD | 3.0000% | Lin30360 | 2026-07-15 | CLP | USDOBS | 1.00 | 0.00 | 1,475,000.00 |
| 4 | 2026-07-17 | 2027-01-18 | 2027-01-18 | 100,000,000.00 | 0.00 | 1,508,333.33 | True | 1,508,333.33 | USD | 3.0000% | Lin30360 | 2027-01-14 | CLP | USDOBS | 1.00 | 0.00 | 1,508,333.33 |
| 5 | 2027-01-18 | 2027-07-19 | 2027-07-19 | 100,000,000.00 | 0.00 | 1,508,333.33 | True | 1,508,333.33 | USD | 3.0000% | Lin30360 | 2027-07-15 | CLP | USDOBS | 1.00 | 0.00 | 1,508,333.33 |
| 6 | 2027-07-19 | 2028-01-17 | 2028-01-17 | 100,000,000.00 | 0.00 | 1,483,333.33 | True | 1,483,333.33 | USD | 3.0000% | Lin30360 | 2028-01-13 | CLP | USDOBS | 1.00 | 0.00 | 1,483,333.33 |
| 7 | 2028-01-17 | 2028-07-17 | 2028-07-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2028-07-13 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 8 | 2028-07-17 | 2029-01-17 | 2029-01-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2029-01-15 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 9 | 2029-01-17 | 2029-07-17 | 2029-07-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2029-07-13 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 10 | 2029-07-17 | 2030-01-17 | 2030-01-17 | 100,000,000.00 | 0.00 | 1,500,000.00 | True | 1,500,000.00 | USD | 3.0000% | Lin30360 | 2030-01-15 | CLP | USDOBS | 1.00 | 0.00 | 1,500,000.00 |
| 11 | 2030-01-17 | 2030-07-17 | 2030-07-17 | 100,000,000.00 | 100,000,000.00 | 1,500,000.00 | True | 101,500,000.00 | USD | 3.0000% | Lin30360 | 2030-07-15 | CLP | USDOBS | 1.00 | 100,000,000.00 | 1,500,000.00 |
Construcción Asistida de un CustomAmortFixedRateMultiCurrencyLeg¶
Se verá como construir objetos Leg donde cada Cashflow es un objeto de tipo FixedRateMultiCurrencyCashflow, todos con la misma tasa fija. En este ejemplo se construye un Leg de tipo custom_amort: amortizaciones irregulares en cada FixedRateMultiCurrencyCasflow.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagounsigned int: lag de pago expresado en díasfloat: nominal inicialbool: si esTruesignifica que la amortización es un flujo de caja efectivoQCInterestRate: la tasa a aplicar en cada flujoQCCurrency: moneda del nominalQCCurrency: moneda de los flujosFXRateIndex: índice con el cual se transforma cada flujo a la moneda de pago.bool: si esTruefuerza a que las fechas de pago coincidan con las fechas finales. Esto para lograr una valorización acorde a las convenciones de los mercados de renta fija, en caso que laLegrepresente un bono a tasa fija.SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.FxFixingLagPivot: este parámetro indica si el lag de fijación del índice FX se aplica sobreend_dateo sobresettlement_date.
Vamos a un ejemplo
Primero se debe dar de alta un FXRateIndex
usd = qcf.QCUSD()
clp = qcf.QCCLP()
usdclp = qcf.FXRate(usd, clp)
one_d = qcf.Tenor('1D')
usdclp_obs = qcf.FXRateIndex(
usdclp,
'USDOBS',
one_d,
one_d,
calendario
)
Luego se dan de alta los otros parámetros requeridos para la construcción
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(12, 7, 1968)
fecha_final = qcf.QCDate(12, 7, 1974)
bus_adj_rule = qcf.BusyAdjRules.NO
periodicidad = qcf.Tenor('6M')
periodo_irregular = qcf.StubPeriod.NO
lag_pago = 1
es_bono = False
fx_rate_index_fixing_lag = 1
fx_fixing_lag_pivot = qcf.FxFixingLagPivot.SETTLEMENT_DATE
sett_lag_behaviour = qcf.SettLagBehaviour.DONT_MOVE
Se da de alta el vector de capitales vigentes y amortizaciones. Cada elemento del vector es el capital vigente y amortización del correspondiente cupón.
custom_notional_amort = qcf.CustomNotionalAmort()
custom_notional_amort.set_size(12) # De la fecha inicio y fecha final se deduce que serán 8 cupones
for i in range(0, 12):
custom_notional_amort.set_notional_amort_at(i, 1200.0 - i * 100.0, 100.0)
Finalmente, se da de alta el objeto.
fixed_rate_mccy_leg = qcf.LegFactory.build_custom_amort_fixed_rate_mccy_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad,
settlement_stub_period=periodo_irregular,
settlement_calendar=calendario,
settlement_lag=lag_pago,
notional_and_amort=custom_notional_amort,
amort_is_cashflow=amort_es_flujo,
interest_rate=tasa_cupon,
notional_currency=usd,
is_bond=es_bono,
sett_lag_behaviour=sett_lag_behaviour,
# Parámetros MultiCurrency
settlement_currency=clp,
fx_rate_index=usdclp_obs,
fx_rate_index_fixing_lag=fx_rate_index_fixing_lag,
fx_fixing_lag_pivot=fx_fixing_lag_pivot,
)
Visualización.
aux.leg_as_dataframe(fixed_rate_mccy_leg).style.format(aux.format_dict).set_properties(
**{'background-color': '#FFCFC9', 'color':'black'},
subset=['nominal','amortizacion', 'flujo']
).set_properties(
**{'background-color': '#FFCFA9', 'color':'black'},
subset=['flujo']
)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/IPython/core/formatters.py:406, in BaseFormatter.__call__(self, obj)
404 method = get_real_method(obj, self.print_method)
405 if method is not None:
--> 406 return method()
407 return None
408 else:
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/io/formats/style.py:405, in Styler._repr_html_(self)
400 """
401 Hooks into Jupyter notebook rich display system, which calls _repr_html_ by
402 default if an object is returned at the end of a cell.
403 """
404 if get_option("styler.render.repr") == "html":
--> 405 return self.to_html()
406 return None
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/io/formats/style.py:1345, in Styler.to_html(self, buf, table_uuid, table_attributes, sparse_index, sparse_columns, bold_headers, caption, max_rows, max_columns, encoding, doctype_html, exclude_styles, **kwargs)
1342 obj.set_caption(caption)
1344 # Build HTML string..
-> 1345 html = obj._render_html(
1346 sparse_index=sparse_index,
1347 sparse_columns=sparse_columns,
1348 max_rows=max_rows,
1349 max_cols=max_columns,
1350 exclude_styles=exclude_styles,
1351 encoding=encoding or get_option("styler.render.encoding"),
1352 doctype_html=doctype_html,
1353 **kwargs,
1354 )
1356 return save_to_buffer(
1357 html, buf=buf, encoding=(encoding if buf is not None else None)
1358 )
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/io/formats/style_render.py:204, in StylerRenderer._render_html(self, sparse_index, sparse_columns, max_rows, max_cols, **kwargs)
192 def _render_html(
193 self,
194 sparse_index: bool,
(...) 198 **kwargs,
199 ) -> str:
200 """
201 Renders the ``Styler`` including all applied styles to HTML.
202 Generates a dict with necessary kwargs passed to jinja2 template.
203 """
--> 204 d = self._render(sparse_index, sparse_columns, max_rows, max_cols, " ")
205 d.update(kwargs)
206 return self.template_html.render(
207 **d,
208 html_table_tpl=self.template_html_table,
209 html_style_tpl=self.template_html_style,
210 )
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/io/formats/style_render.py:161, in StylerRenderer._render(self, sparse_index, sparse_columns, max_rows, max_cols, blank)
147 def _render(
148 self,
149 sparse_index: bool,
(...) 153 blank: str = "",
154 ):
155 """
156 Computes and applies styles and then generates the general render dicts.
157
158 Also extends the `ctx` and `ctx_index` attributes with those of concatenated
159 stylers for use within `_translate_latex`
160 """
--> 161 self._compute()
162 dxs = []
163 ctx_len = len(self.index)
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/io/formats/style_render.py:256, in StylerRenderer._compute(self)
254 r = self
255 for func, args, kwargs in self._todo:
--> 256 r = func(self)(*args, **kwargs)
257 return r
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/io/formats/style.py:2027, in Styler._map(self, func, subset, **kwargs)
2025 subset = IndexSlice[:]
2026 subset = non_reducing_slice(subset)
-> 2027 result = self.data.loc[subset].map(func)
2028 self._update_ctx(result)
2029 return self
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:1184, in _LocationIndexer.__getitem__(self, key)
1182 if self._is_scalar_access(key):
1183 return self.obj._get_value(*key, takeable=self._takeable)
-> 1184 return self._getitem_tuple(key)
1185 else:
1186 # we by definition only have the 0th axis
1187 axis = self.axis or 0
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:1377, in _LocIndexer._getitem_tuple(self, tup)
1374 if self._multi_take_opportunity(tup):
1375 return self._multi_take(tup)
-> 1377 return self._getitem_tuple_same_dim(tup)
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:1020, in _LocationIndexer._getitem_tuple_same_dim(self, tup)
1017 if com.is_null_slice(key):
1018 continue
-> 1020 retval = getattr(retval, self.name)._getitem_axis(key, axis=i)
1021 # We should never have retval.ndim < self.ndim, as that should
1022 # be handled by the _getitem_lowerdim call above.
1023 assert retval.ndim == self.ndim
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:1420, in _LocIndexer._getitem_axis(self, key, axis)
1417 if hasattr(key, "ndim") and key.ndim > 1:
1418 raise ValueError("Cannot index with multidimensional key")
-> 1420 return self._getitem_iterable(key, axis=axis)
1422 # nested tuple slicing
1423 if is_nested_tuple(key, labels):
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:1360, in _LocIndexer._getitem_iterable(self, key, axis)
1357 self._validate_key(key, axis)
1359 # A collection of keys
-> 1360 keyarr, indexer = self._get_listlike_indexer(key, axis)
1361 return self.obj._reindex_with_indexers(
1362 {axis: [keyarr, indexer]}, copy=True, allow_dups=True
1363 )
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:1558, in _LocIndexer._get_listlike_indexer(self, key, axis)
1555 ax = self.obj._get_axis(axis)
1556 axis_name = self.obj._get_axis_name(axis)
-> 1558 keyarr, indexer = ax._get_indexer_strict(key, axis_name)
1560 return keyarr, indexer
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/core/indexes/base.py:6212, in Index._get_indexer_strict(self, key, axis_name)
6209 else:
6210 keyarr, indexer, new_indexer = self._reindex_non_unique(keyarr)
-> 6212 self._raise_if_missing(keyarr, indexer, axis_name)
6214 keyarr = self.take(indexer)
6215 if isinstance(key, Index):
6216 # GH 42790 - Preserve name from an Index
File ~/qcf_repos/qcfinancial-docs/.venv/lib/python3.12/site-packages/pandas/core/indexes/base.py:6264, in Index._raise_if_missing(self, key, indexer, axis_name)
6261 raise KeyError(f"None of [{key}] are in the [{axis_name}]")
6263 not_found = list(ensure_index(key)[missing_mask.nonzero()[0]].unique())
-> 6264 raise KeyError(f"{not_found} not in index")
KeyError: "['nominal'] not in index"
<pandas.io.formats.style.Styler at 0x112f76480>
Construcción Asistida de un BulletIborLeg¶
En este ejemplo se construye un Leg con IborCashflow y amortización bullet.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagounsigned int: lag de pago expresado en díasTenor: periodicidad de fijaciónQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular para el calendario de fijacionesQCBusinessCalendar: calendario que aplica para las fechas de fijaciónunsigned int: lag de fijación expresado en díasInterestRateIndex: índice de tasa de interés utilizado en cadaIborCashflowfloat: nominalbool: si esTruesignifica que la amortización final es un flujo de caja efectivoQCCurrency: moneda del nominal y de los flujosfloat: spread aditivogearing: spread multiplicativo (tasa * gearing + spread)SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.
NOTA: para construir un Leg con IborCashflow y amortización customizada, sólo se debe cambiar el parámetro nominal por CustomNotionalAndAmort e invocar el método qcf.LegFactory.build_custom_amort_ibor_leg(...).
Vamos a un ejemplo. Primero, se da de alta los parámetros requeridos.
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(15, 2, 2024)
fecha_final = qcf.QCDate(15, 2, 2026)
bus_adj_rule = qcf.BusyAdjRules.NO
periodicidad_pago = qcf.Tenor('3M')
periodo_irregular_pago = qcf.StubPeriod.NO
calendario = aux.get_business_calendar('US', range(2024, 2035))
lag_pago = 1
periodicidad_fijacion = qcf.Tenor('3M')
periodo_irregular_fijacion = qcf.StubPeriod.NO
sett_lag_behaviour = qcf.SettLagBehaviour.MOVE_TO_WORKING_DAY
# Se utilizará el mismo calendario para pago y fijaciones
lag_de_fijacion = 2
nominal = 1_000_000.0
amort_es_flujo = True
moneda = usd
spread = .01
gearing = 1.0
Se define el índice de tasa de interés.
codigo = 'TERMSOFR3M'
lin_act360 = qcf.QCInterestRate(.0, qcf.QCAct360(), qcf.QCLinearWf())
fixing_lag = qcf.Tenor('2d')
tenor = qcf.Tenor('3m')
fixing_calendar = calendario
settlement_calendar = calendario
usd = qcf.QCUSD()
termsofr_3m = qcf.InterestRateIndex(
codigo,
lin_act360,
fixing_lag,
tenor,
calendario,
calendario,
usd
)
Se da de alta el objeto, pero antes almacenaremos los parámetros en un dict. Esto permitirá una sintaxis un poco más liviana.
params = dict(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad_pago,
settlement_stub_period=periodo_irregular_pago,
settlement_calendar=calendario,
settlement_lag=lag_pago,
fixing_periodicity=periodicidad_fijacion,
fixing_stub_period=periodo_irregular_fijacion,
fixing_calendar=calendario,
fixing_lag=lag_de_fijacion,
interest_rate_index=termsofr_3m,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
notional_currency=moneda,
spread=spread,
gearing=gearing,
sett_lag_behaviour=sett_lag_behaviour,
)
ibor_leg = qcf.LegFactory.build_bullet_ibor_leg(**params)
Visualización. Notar que los flujos de intereses corresponden al spread de 1%. No están fijados los valores del índice en cada cupón.
aux.leg_as_dataframe(ibor_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_fixing | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | codigo_indice_tasa | valor_tasa | spread | gearing | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-02-15 | 2024-05-15 | 2024-02-13 | 2024-05-16 | 1,000,000.00 | 0.00 | 2,500.00 | True | 2,500.00 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 1 | 2024-05-15 | 2024-08-15 | 2024-05-13 | 2024-08-16 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 2 | 2024-08-15 | 2024-11-15 | 2024-08-13 | 2024-11-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 3 | 2024-11-15 | 2025-02-15 | 2024-11-13 | 2025-02-19 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 4 | 2025-02-15 | 2025-05-15 | 2025-02-12 | 2025-05-16 | 1,000,000.00 | 0.00 | 2,472.22 | True | 2,472.22 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 5 | 2025-05-15 | 2025-08-15 | 2025-05-13 | 2025-08-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 6 | 2025-08-15 | 2025-11-15 | 2025-08-13 | 2025-11-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 7 | 2025-11-15 | 2026-02-15 | 2025-11-12 | 2026-02-18 | 1,000,000.00 | 1,000,000.00 | 2,555.56 | True | 1,002,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
Otras Combinaciones de Períodos Irregulares¶
Las distintas combinaciones de períodos irregulares (de pago y fijación) permiten obtener tablas de desarrollo con muchas características.
SHORTFRONT con SHORTFRONT¶
params["start_date"] = qcf.QCDate(15, 3, 2024)
params["settlement_stub_period"] = qcf.StubPeriod.SHORTFRONT
params["fixing_stub_period"] = qcf.StubPeriod.SHORTFRONT
ibor_leg = qcf.LegFactory.build_bullet_ibor_leg(**params)
En este caso, las fechas de fijación se sincronizan con las fechas de inicio de los cupones. Notar además que el primer cupón es de dos meses mientras que el índice es de 3M.
aux.leg_as_dataframe(ibor_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_fixing | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | codigo_indice_tasa | valor_tasa | spread | gearing | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-03-15 | 2024-05-15 | 2024-03-13 | 2024-05-16 | 1,000,000.00 | 0.00 | 1,694.44 | True | 1,694.44 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 1 | 2024-05-15 | 2024-08-15 | 2024-05-13 | 2024-08-16 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 2 | 2024-08-15 | 2024-11-15 | 2024-08-13 | 2024-11-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 3 | 2024-11-15 | 2025-02-15 | 2024-11-13 | 2025-02-19 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 4 | 2025-02-15 | 2025-05-15 | 2025-02-12 | 2025-05-16 | 1,000,000.00 | 0.00 | 2,472.22 | True | 2,472.22 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 5 | 2025-05-15 | 2025-08-15 | 2025-05-13 | 2025-08-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 6 | 2025-08-15 | 2025-11-15 | 2025-08-13 | 2025-11-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 7 | 2025-11-15 | 2026-02-15 | 2025-11-12 | 2026-02-18 | 1,000,000.00 | 1,000,000.00 | 2,555.56 | True | 1,002,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
SHORTFRONT con LONGBACK¶
params["start_date"] = qcf.QCDate(31, 1, 2024)
params["end_date"] = qcf.QCDate(31, 3, 2026)
params["settlement_stub_period"] = qcf.StubPeriod.SHORTFRONT
params["fixing_stub_period"] = qcf.StubPeriod.LONGBACK
ibor_leg = qcf.LegFactory.build_bullet_ibor_leg(**params)
En este caso, las fechas de fijación también se desfasan respecto a las fechas de inicio de los cupones. Ahora las fechas de fijación de los primeros dos cupones coinciden.
aux.leg_as_dataframe(ibor_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_fixing | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | codigo_indice_tasa | valor_tasa | spread | gearing | tipo_tasa | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-01-31 | 2024-03-31 | 2024-01-29 | 2024-04-02 | 1,000,000.00 | 0.00 | 1,666.67 | True | 1,666.67 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 1 | 2024-03-31 | 2024-06-30 | 2024-01-29 | 2024-07-02 | 1,000,000.00 | 0.00 | 2,527.78 | True | 2,527.78 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 2 | 2024-06-30 | 2024-09-30 | 2024-04-26 | 2024-10-01 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 3 | 2024-09-30 | 2024-12-31 | 2024-07-29 | 2025-01-02 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 4 | 2024-12-31 | 2025-03-31 | 2024-10-29 | 2025-04-01 | 1,000,000.00 | 0.00 | 2,500.00 | True | 2,500.00 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 5 | 2025-03-31 | 2025-06-30 | 2025-01-29 | 2025-07-01 | 1,000,000.00 | 0.00 | 2,527.78 | True | 2,527.78 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 6 | 2025-06-30 | 2025-09-30 | 2025-04-28 | 2025-10-01 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 7 | 2025-09-30 | 2025-12-31 | 2025-07-29 | 2026-01-02 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
| 8 | 2025-12-31 | 2026-03-31 | 2025-10-29 | 2026-04-01 | 1,000,000.00 | 1,000,000.00 | 2,500.00 | True | 1,002,500.00 | USD | TERMSOFR3M | 0.0000% | 1.0000% | 1.00 | LinAct360 |
Construcción Asistida de un BulletIborMultiCurrencyLeg¶
Se construye un Leg con IborMultiCurrencyCashflow y amortización bullet.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagounsigned int: lag de pago expresado en díasTenor: periodicidad de fijaciónQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular para el calendario de fijacionesQCBusinessCalendar: calendario que aplica para las fechas de fijaciónunsigned int: lag de fijación expresado en díasInterestRateIndex: índice de tasa de interés utilizado en cadaIborCashflowfloat: nominalbool: si esTruesignifica que la amortización final es un flujo de caja efectivoQCCurrency: moneda del nominal y de los flujosfloat: spread aditivogearing: spread multiplicativo (tasa * gearing + spread)SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.
MultiCurrency
- QCCurrency: moneda de pago los flujos
- FXRateIndex: índice con el cual se transforma cada flujo a la moneda de pago
- int: lag de fijación del FXRateIndex.
- FxFixingLagPivot: este parámetro indica si el lag de fijación del índice FX se aplica sobre end_date o sobre settlement_date.
- FxFixingLagAppliesTo: indica si el lag se refiere a FIXING_DATE o PUBISHING_DATE del índice.
Vamos a un ejemplo.
ibor_mccy_leg = qcf.LegFactory.build_bullet_ibor_mccy_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad_pago,
settlement_stub_period=periodo_irregular_pago,
settlement_calendar=calendario,
settlement_lag=lag_pago,
fixing_periodicity=periodicidad_fijacion,
fixing_stub_period=periodo_irregular_fijacion,
fixing_calendar=calendario,
fixing_lag=lag_de_fijacion,
interest_rate_index=termsofr_3m,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
notional_currency=clp,
spread=spread,
gearing=gearing,
sett_lag_behaviour=sett_lag_behaviour,
# Parámetros MultiCurrency
settlement_currency=usd,
fx_rate_index=usdclp_obs,
fx_rate_index_fixing_lag=fx_rate_index_fixing_lag,
fx_fixing_lag_pivot=fx_fixing_lag_pivot,
fx_fixing_lag_applies_to=qcf.FxFixingLagAppliesTo.PUBLISHING_DATE,
)
aux.leg_as_dataframe(ibor_mccy_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_fixing | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | codigo_indice_tasa | spread | gearing | valor_tasa | tipo_tasa | fecha_fixing_fx | moneda_pago | codigo_indice_fx | valor_indice_fx | amortizacion_moneda_pago | interes_moneda_pago | flujo_moneda_pago | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-02-15 | 2024-05-15 | 2024-02-13 | 2024-05-16 | 1,000,000.00 | 0.00 | 2,500.00 | True | 2,500.00 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2024-05-15 | USD | USDOBS | 1.00 | 0.00 | 2,500.00 | 2,500.00 |
| 1 | 2024-05-15 | 2024-08-15 | 2024-05-13 | 2024-08-16 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2024-08-15 | USD | USDOBS | 1.00 | 0.00 | 2,555.56 | 2,555.56 |
| 2 | 2024-08-15 | 2024-11-15 | 2024-08-13 | 2024-11-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2024-11-15 | USD | USDOBS | 1.00 | 0.00 | 2,555.56 | 2,555.56 |
| 3 | 2024-11-15 | 2025-02-15 | 2024-11-13 | 2025-02-19 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2025-02-18 | USD | USDOBS | 1.00 | 0.00 | 2,555.56 | 2,555.56 |
| 4 | 2025-02-15 | 2025-05-15 | 2025-02-12 | 2025-05-16 | 1,000,000.00 | 0.00 | 2,472.22 | True | 2,472.22 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2025-05-15 | USD | USDOBS | 1.00 | 0.00 | 2,472.22 | 2,472.22 |
| 5 | 2025-05-15 | 2025-08-15 | 2025-05-13 | 2025-08-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2025-08-15 | USD | USDOBS | 1.00 | 0.00 | 2,555.56 | 2,555.56 |
| 6 | 2025-08-15 | 2025-11-15 | 2025-08-13 | 2025-11-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2025-11-17 | USD | USDOBS | 1.00 | 0.00 | 2,555.56 | 2,555.56 |
| 7 | 2025-11-15 | 2026-02-15 | 2025-11-12 | 2026-02-18 | 1,000,000.00 | 1,000,000.00 | 2,555.56 | True | 1,002,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2026-02-17 | USD | USDOBS | 1.00 | 1,000,000.00 | 2,555.56 | 1,002,555.56 |
Fijemos el valor del tipo de cambio en los cashflows para ver el efecto en las últimas dos columnas.
for cashflow in ibor_mccy_leg.get_cashflows():
cashflow.set_fx_rate_index_value(900.0)
aux.leg_as_dataframe(ibor_mccy_leg).style.format(aux.format_dict).set_properties(
**{'background-color': '#FFCFC9', 'color':'black'},
subset=['valor_indice_fx','amortizacion_moneda_pago', 'interes_moneda_pago'],
)
| fecha_inicial | fecha_final | fecha_fixing | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | codigo_indice_tasa | spread | gearing | valor_tasa | tipo_tasa | fecha_fixing_fx | moneda_pago | codigo_indice_fx | valor_indice_fx | amortizacion_moneda_pago | interes_moneda_pago | flujo_moneda_pago | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-02-15 | 2024-05-15 | 2024-02-13 | 2024-05-16 | 1,000,000.00 | 0.00 | 2,500.00 | True | 2,500.00 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2024-05-15 | USD | USDOBS | 900.00 | 0.00 | 2.78 | 2.78 |
| 1 | 2024-05-15 | 2024-08-15 | 2024-05-13 | 2024-08-16 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2024-08-15 | USD | USDOBS | 900.00 | 0.00 | 2.84 | 2.84 |
| 2 | 2024-08-15 | 2024-11-15 | 2024-08-13 | 2024-11-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2024-11-15 | USD | USDOBS | 900.00 | 0.00 | 2.84 | 2.84 |
| 3 | 2024-11-15 | 2025-02-15 | 2024-11-13 | 2025-02-19 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2025-02-18 | USD | USDOBS | 900.00 | 0.00 | 2.84 | 2.84 |
| 4 | 2025-02-15 | 2025-05-15 | 2025-02-12 | 2025-05-16 | 1,000,000.00 | 0.00 | 2,472.22 | True | 2,472.22 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2025-05-15 | USD | USDOBS | 900.00 | 0.00 | 2.75 | 2.75 |
| 5 | 2025-05-15 | 2025-08-15 | 2025-05-13 | 2025-08-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2025-08-15 | USD | USDOBS | 900.00 | 0.00 | 2.84 | 2.84 |
| 6 | 2025-08-15 | 2025-11-15 | 2025-08-13 | 2025-11-18 | 1,000,000.00 | 0.00 | 2,555.56 | True | 2,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2025-11-17 | USD | USDOBS | 900.00 | 0.00 | 2.84 | 2.84 |
| 7 | 2025-11-15 | 2026-02-15 | 2025-11-12 | 2026-02-18 | 1,000,000.00 | 1,000,000.00 | 2,555.56 | True | 1,002,555.56 | CLP | TERMSOFR3M | 1.0000% | 1.00 | 0.0000% | LinAct360 | 2026-02-17 | USD | USDOBS | 900.00 | 1,111.11 | 2.84 | 1,113.95 |
Construcción Asistida de un OvernightIndexLeg¶
En este ejemplo se construye un Leg con OvernightIndexCashflow y amortización bullet.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosBusyAdRules: tipo de ajuste en la fecha de fijación de los valores inicial y final del índice en cada cupónTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagoQCBusinessCalendar: calendario que aplica para las fechas de fijación del índiceunsigned int: lag de pago expresado en díasfloat: nominalbool: si esTruesignifica que la amortización final es un flujo de caja efectivofloat: spread aditivofloat: spread multiplicativo o gearing (tasa * gearing + spread)QCInterestRate: representa el tipo de tasa que se usará que se usará para la tasa equivalentestring: nombre del índice overnight a utilizarunsigned int: número de decimales de la tasa equivalenteQCCurrency: moneda del nocionalDatesForEquivalentRate: enum que indica qué fechas se utilizan en el cálculo de la tasa equivalente (fechas de devengo o de índice)SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.
NOTA: para construir un Leg con OvernightIndexCashflow y amortización customizada, sólo se debe cambiar el parámetro nominal por CustomNotionalAndAmort e invocar el método qcf.LegFactory.build_custom_amort_overnight_index_leg(...).
Vamos al ejemplo. Primeramente, se da de alta los parámetros requeridos
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(31, 1, 2024)
fecha_final = qcf.QCDate(31, 1, 2029)
bus_adj_rule = qcf.BusyAdjRules.NO
index_adj_rule = qcf.BusyAdjRules.FOLLOW
periodicidad_pago = qcf.Tenor('6M')
periodo_irregular_pago = qcf.StubPeriod.NO
calendario = aux.get_business_calendar('CL', range(2024, 2035))
num_decimales_tasa_eq = 8
lag_pago = 0
nominal = 100_000_000.0
amort_es_flujo = True
spread = .01
gearing = 1.0
interest_rate=qcf.QCInterestRate(0.0, qcf.QCAct360(), qcf.QCLinearWf())
nombre_indice = 'ICPCLP'
dates_for_eq_rate = qcf.DatesForEquivalentRate.ACCRUAL
sett_lag_behaviour = qcf.SettLagBehaviour.MOVE_TO_WORKING_DAY
Finalmente, se da de alta el objeto.
on_index_leg = qcf.LegFactory.build_bullet_overnight_index_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
fix_adj_rule=index_adj_rule,
settlement_periodicity=periodicidad_pago,
settlement_stub_period=periodo_irregular_pago,
settlement_calendar=calendario,
fixing_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
spread=spread,
gearing=gearing,
interest_rate=interest_rate,
index_name=nombre_indice,
eq_rate_decimal_places=num_decimales_tasa_eq,
notional_currency=clp,
dates_for_eq_rate=dates_for_eq_rate,
sett_lag_behaviour=sett_lag_behaviour,
)
Se visualiza.
aux.leg_as_dataframe(on_index_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_inicial_indice | fecha_final_indice | fecha_pago | nocional | amortizacion | amort_es_flujo | moneda_nocional | nombre_indice | valor_indice_inicial | valor_indice_final | valor_tasa | tipo_tasa | interes | flujo | spread | gearing | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-01-31 | 2024-07-31 | 2024-01-31 | 2024-07-31 | 2024-07-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 505,556.00 | 505,556.00 | 1.0000% | 1.00 |
| 1 | 2024-07-31 | 2025-01-31 | 2024-07-31 | 2025-01-31 | 2025-01-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 511,111.00 | 1.0000% | 1.00 |
| 2 | 2025-01-31 | 2025-07-31 | 2025-01-31 | 2025-07-31 | 2025-07-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 502,778.00 | 502,778.00 | 1.0000% | 1.00 |
| 3 | 2025-07-31 | 2026-01-31 | 2025-07-31 | 2026-02-02 | 2026-02-02 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 511,111.00 | 1.0000% | 1.00 |
| 4 | 2026-01-31 | 2026-07-31 | 2026-02-02 | 2026-07-31 | 2026-07-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 502,778.00 | 502,778.00 | 1.0000% | 1.00 |
| 5 | 2026-07-31 | 2027-01-31 | 2026-07-31 | 2027-02-01 | 2027-02-01 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 511,111.00 | 1.0000% | 1.00 |
| 6 | 2027-01-31 | 2027-07-31 | 2027-02-01 | 2027-08-02 | 2027-08-02 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 502,778.00 | 502,778.00 | 1.0000% | 1.00 |
| 7 | 2027-07-31 | 2028-01-31 | 2027-08-02 | 2028-01-31 | 2028-01-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 511,111.00 | 1.0000% | 1.00 |
| 8 | 2028-01-31 | 2028-07-31 | 2028-01-31 | 2028-07-31 | 2028-07-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 505,556.00 | 505,556.00 | 1.0000% | 1.00 |
| 9 | 2028-07-31 | 2029-01-31 | 2028-07-31 | 2029-01-31 | 2029-01-31 | 100,000,000.00 | 100,000,000.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 100,511,111.00 | 1.0000% | 1.00 |
Construcción Asistida de un OvernightIndexMultiCurrencyLeg¶
En este ejemplo se construye un Leg con OvernightIndexMultiCurrencyCashflow y amortización bullet.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosBusyAdRules: tipo de ajuste en la fecha de fijación de los valores inicial y final del índice en cada cupónTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagoQCBusinessCalendar: calendario que aplica para las fechas de fijación del índiceunsigned int: lag de pago expresado en díasfloat: nominalbool: si esTruesignifica que la amortización final es un flujo de caja efectivofloat: spread aditivofloat: spread multiplicativoQCInterestRate: representa el tipo de tasa que se usará que se usará para la tasa equivalentestring: nombre del índice overnight a utilizarunsigned int: número de decimales de la tasa equivalenteQCCurrency: moneda del nocionalDatesForEquivalentRate: enum que indica qué fechas se utilizan en el cálculo de la tasa equivalente (fechas de devengo o de índice)SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.
MultiCurrency
- QCCurrency: moneda de pago los flujos
- FXRateIndex: índice con el cual se transforma cada flujo a la moneda de pago
- int: lag de fijación del FXRateIndex (respecto a settlement date)
- FxFixingLagPivot: este parámetro indica si el lag de fijación del índice FX se aplica sobre end_date o sobre settlement_date.
- FxFixingLagAppliesTo: indica si el lag se refiere a FIXING_DATE o PUBISHING_DATE del índice.
NOTA: para construir un Leg con OvernightIndexMultiCurrencyCashflow y amortización customizada, sólo se debe cambiar el parámetro nominal por CustomNotionalAndAmort e invocar el método qcf.LegFactory.build_custom_amort_overnight_index_multi_currency_leg(...).
Vamos al ejemplo. Primeramente, se da de alta los parámetros requeridos.
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(31, 1, 2024)
fecha_final = qcf.QCDate(31, 1, 2029)
bus_adj_rule = qcf.BusyAdjRules.NO
index_adj_rule = qcf.BusyAdjRules.MODFOLLOW
periodicidad_pago = qcf.Tenor('6M')
periodo_irregular_pago = qcf.StubPeriod.NO
calendario = qcf.BusinessCalendar(fecha_inicio, 20)
num_decimales_tasa_eq = 8
lag_pago = 0
nominal = 100_000_000.0
amort_es_flujo = True
spread = .01
gearing = 1.0
interest_rate = qcf.QCInterestRate(0.0, qcf.QCAct360(), qcf.QCLinearWf())
dates_for_eq_rate = qcf.DatesForEquivalentRate.ACCRUAL
nombre_indice = 'ICPCLP'
fx_rate_index_fixing_lag = 2
sett_lag_behaviour = qcf.SettLagBehaviour.MOVE_TO_WORKING_DAY
fx_fixing_lag_pivot = qcf.FxFixingLagPivot.SETTLEMENT_DATE
Finalmente, se da de alta el objeto.
on_index_mccy_leg = qcf.LegFactory.build_bullet_overnight_index_multi_currency_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
fix_adj_rule=index_adj_rule,
settlement_periodicity=periodicidad_pago,
settlement_stub_period=periodo_irregular_pago,
settlement_calendar=calendario,
fixing_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
spread=spread,
gearing=gearing,
interest_rate=interest_rate,
index_name=nombre_indice,
eq_rate_decimal_places=num_decimales_tasa_eq,
notional_currency=clp,
dates_for_eq_rate=dates_for_eq_rate,
sett_lag_behaviour=sett_lag_behaviour,
# Parámetros MultiCurrency
settlement_currency=usd,
fx_rate_index=usdclp_obs,
fx_rate_index_fixing_lag=fx_rate_index_fixing_lag,
fx_fixing_lag_pivot=fx_fixing_lag_pivot,
fx_fixing_lag_applies_to=qcf.FxFixingLagAppliesTo.PUBLISHING_DATE,
)
Se visualiza.
aux.leg_as_dataframe(on_index_mccy_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_inicial_indice | fecha_final_indice | fecha_pago | nocional | amortizacion | amort_es_flujo | moneda_nocional | nombre_indice | valor_indice_inicial | valor_indice_final | valor_tasa | tipo_tasa | interes | flujo | spread | gearing | moneda_pago | indice_fx | fecha_fixing_fx | valor_indice_fx | interes_moneda_pago | amortizacion_moneda_pago | flujo_moneda_pago | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-01-31 | 2024-07-31 | 2024-01-31 | 2024-07-31 | 2024-07-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 505,556.00 | 505,556.00 | 1.0000% | 1.00 | USD | USDOBS | 2024-07-29 | 1.00 | 505,556.00 | 0.00 | 505,556.00 |
| 1 | 2024-07-31 | 2025-01-31 | 2024-07-31 | 2025-01-31 | 2025-01-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 511,111.00 | 1.0000% | 1.00 | USD | USDOBS | 2025-01-29 | 1.00 | 511,111.00 | 0.00 | 511,111.00 |
| 2 | 2025-01-31 | 2025-07-31 | 2025-01-31 | 2025-07-31 | 2025-07-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 502,778.00 | 502,778.00 | 1.0000% | 1.00 | USD | USDOBS | 2025-07-29 | 1.00 | 502,778.00 | 0.00 | 502,778.00 |
| 3 | 2025-07-31 | 2026-01-31 | 2025-07-31 | 2026-01-30 | 2026-02-02 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 511,111.00 | 1.0000% | 1.00 | USD | USDOBS | 2026-01-29 | 1.00 | 511,111.00 | 0.00 | 511,111.00 |
| 4 | 2026-01-31 | 2026-07-31 | 2026-01-30 | 2026-07-31 | 2026-07-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 502,778.00 | 502,778.00 | 1.0000% | 1.00 | USD | USDOBS | 2026-07-29 | 1.00 | 502,778.00 | 0.00 | 502,778.00 |
| 5 | 2026-07-31 | 2027-01-31 | 2026-07-31 | 2027-01-29 | 2027-02-01 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 511,111.00 | 1.0000% | 1.00 | USD | USDOBS | 2027-01-28 | 1.00 | 511,111.00 | 0.00 | 511,111.00 |
| 6 | 2027-01-31 | 2027-07-31 | 2027-01-29 | 2027-07-30 | 2027-08-02 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 502,778.00 | 502,778.00 | 1.0000% | 1.00 | USD | USDOBS | 2027-07-29 | 1.00 | 502,778.00 | 0.00 | 502,778.00 |
| 7 | 2027-07-31 | 2028-01-31 | 2027-07-30 | 2028-01-31 | 2028-01-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 511,111.00 | 1.0000% | 1.00 | USD | USDOBS | 2028-01-27 | 1.00 | 511,111.00 | 0.00 | 511,111.00 |
| 8 | 2028-01-31 | 2028-07-31 | 2028-01-31 | 2028-07-31 | 2028-07-31 | 100,000,000.00 | 0.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 505,556.00 | 505,556.00 | 1.0000% | 1.00 | USD | USDOBS | 2028-07-27 | 1.00 | 505,556.00 | 0.00 | 505,556.00 |
| 9 | 2028-07-31 | 2029-01-31 | 2028-07-31 | 2029-01-31 | 2029-01-31 | 100,000,000.00 | 100,000,000.00 | True | CLP | ICPCLP | 1.000000 | 1.000000 | 0.0000% | LinAct360 | 511,111.00 | 100,511,111.00 | 1.0000% | 1.00 | USD | USDOBS | 2029-01-29 | 1.00 | 511,111.00 | 100,000,000.00 | 100,511,111.00 |
Construcción Asistida de un CompoundedOvernightRateLeg¶
En este ejemplo se construye un Leg con CompoundedOvernightRateCashflow2 y amortización bullet.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagounsigned int: lag de pago expresado en díasQCBusinessCalendar: calendario que aplica para las fechas de fijación de la tasa overnightQCInterestRateIndex: índice overnight a utilizarfloat: nominalbool: si esTruesignifica que la amortización final es un flujo de caja efectivoQCCurrency: moneda del nocionalfloat: spread aditivofloat: spread multiplicativo o gearing (tasa * gearing + spread)QCInterestRate: representa el tipo de tasa que se usará que se usará para la tasa equivalenteunsigned int: número de decimales de la tasa equivalenteunsigned int: lookback (no implementado)unsigned int: lockout (no implementado)SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.
NOTA: para construir un Leg con CompoundedOvernightRateCashflow y amortización customizada, sólo se debe cambiar el parámetro nominal por CustomNotionalAndAmort e invocar el método qcf.LegFactory.build_custom_amort_compounded_overnight_rate_leg_2(...).
Vamos al ejemplo. Primeramente, se da de alta los parámetros requeridos
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(31, 1, 2024)
fecha_final = qcf.QCDate(31, 1, 2028)
bus_adj_rule = qcf.BusyAdjRules.MODFOLLOW
periodicidad_pago = qcf.Tenor('1Y')
periodo_irregular_pago = qcf.StubPeriod.NO
calendario = aux.get_business_calendar('US', range(2024, 2035))
lag_pago = 2
nominal = 10_000_000.0
amort_es_flujo = True
moneda = usd
spread = .01
gearing = 1.0
eq_rate_decimal_places = 8
lookback = 0
lockout = 0
sett_lag_behaviour = qcf.SettLagBehaviour.MOVE_TO_WORKING_DAY
Se define el índice.
codigo = 'SOFRRATE'
lin_act360 = qcf.QCInterestRate(.0, qcf.QCAct360(), qcf.QCLinearWf())
fixing_lag = qcf.Tenor('0d')
tenor = qcf.Tenor('1d')
fixing_calendar = calendario
settlement_calendar = calendario
usd = qcf.QCUSD()
oistest = qcf.InterestRateIndex(
codigo,
lin_act360,
fixing_lag,
tenor,
fixing_calendar,
settlement_calendar,
usd
)
Finalmente, se da de alta el objeto.
cor_leg = qcf.LegFactory.build_bullet_compounded_overnight_rate_leg_2(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad_pago,
settlement_stub_period=periodo_irregular_pago,
settlement_calendar=calendario,
settlement_lag=lag_pago,
fixing_calendar=calendario,
interest_rate_index=oistest,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
notional_currency=usd,
spread=spread,
gearing=gearing,
interest_rate=lin_act360,
eq_rate_decimal_places=8,
lookback=lookback,
lockout=lockout,
sett_lag_behaviour=sett_lag_behaviour,
)
aux.leg_as_dataframe(cor_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | codigo_indice_tasa | tipo_tasa | valor_tasa | spread | gearing | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-01-31 | 2025-01-31 | 2025-02-04 | 10,000,000.00 | 0.00 | 101,666.67 | True | 101,666.67 | USD | SOFRRATE | LinAct360 | 0.0000% | 1.0000% | 1.00 |
| 1 | 2025-01-31 | 2026-01-30 | 2026-02-03 | 10,000,000.00 | 0.00 | 101,111.11 | True | 101,111.11 | USD | SOFRRATE | LinAct360 | 0.0000% | 1.0000% | 1.00 |
| 2 | 2026-01-30 | 2027-01-29 | 2027-02-02 | 10,000,000.00 | 0.00 | 101,111.11 | True | 101,111.11 | USD | SOFRRATE | LinAct360 | 0.0000% | 1.0000% | 1.00 |
| 3 | 2027-01-29 | 2028-01-31 | 2028-02-02 | 10,000,000.00 | 10,000,000.00 | 101,944.44 | True | 10,101,944.44 | USD | SOFRRATE | LinAct360 | 0.0000% | 1.0000% | 1.00 |
Construcción Asistida de un CompoundedOvernightRateMultiCurrencyLeg¶
En este ejemplo se construye un Leg con CompoundedOvernightRateMultiCurrencyCashflow2 y amortización bullet.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagounsigned int: lag de pago expresado en díasQCBusinessCalendar: calendario que aplica para las fechas de fijación de la tasa overnightQCInterestRateIndex: índice overnight a utilizarfloat: nominalbool: si esTruesignifica que la amortización final es un flujo de caja efectivoQCCurrency: moneda del nocionalfloat: spread aditivofloat: spread multiplicativoQCInterestRate: representa el tipo de tasa que se usará que se usará para la tasa equivalenteunsigned int: número de decimales de la tasa equivalenteunsigned int: lookback (no implementado)unsigned int: lockout (no implementado)SettLagBehaviour: este parámetro indica cómo se calcula unsettlement_datecuando unend_datecae en un día festivo.
MultiCurrency
- QCCurrency: moneda de pago los flujos
- FXRateIndex: índice con el cual se transforma cada flujo a la moneda de pago
- int: lag de fijación del FXRateIndex (respecto a settlement date)
- FxFixingLagPivot: este parámetro indica si el lag de fijación del índice FX se aplica sobre end_date o sobre settlement_date.
- FxFixingLagAppliesTo: indica si el lag se refiere a FIXING_DATE o PUBISHING_DATE del índice.
NOTA: para construir un Leg con CompoundedOvernightRateMultiCurrencyCashflow y amortización customizada, sólo se debe cambiar el parámetro nominal por CustomNotionalAndAmort e invocar el método qcf.LegFactory.build_custom_amort_compounded_overnight_rate_multi_currency_leg_2(...).
Vamos al ejemplo. Primeramente, se da de alta los parámetros requeridos
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(31, 1, 2024)
fecha_final = qcf.QCDate(31, 1, 2028)
bus_adj_rule = qcf.BusyAdjRules.NO
periodicidad_pago = qcf.Tenor('6M')
periodo_irregular_pago = qcf.StubPeriod.NO
calendario = qcf.BusinessCalendar(fecha_inicio, 20)
lag_pago = 2
nominal = 1000000.0
amort_es_flujo = True
moneda = usd
spread = .01
gearing = 1.0
eq_rate_decimal_places = 8
lookback = 0
lockout = 0
fx_rate_index_fixing_lag = 1
sett_lag_behaviour = qcf.SettLagBehaviour.MOVE_TO_WORKING_DAY
fx_fixing_lag_pivot = qcf.FxFixingLagPivot.SETTLEMENT_DATE
Se define el índice.
codigo = 'OISTEST'
lin_act360 = qcf.QCInterestRate(.0, qcf.QCAct360(), qcf.QCLinearWf())
fixing_lag = qcf.Tenor('0d')
tenor = qcf.Tenor('1d')
fixing_calendar = calendario
settlement_calendar = calendario
usd = qcf.QCUSD()
oistest = qcf.InterestRateIndex(
codigo,
lin_act360,
fixing_lag,
tenor,
fixing_calendar,
settlement_calendar,
usd
)
Finalmente, se da de alta el objeto.
cor_mccy_leg = qcf.LegFactory.build_bullet_compounded_overnight_rate_mccy_leg_2(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad_pago,
settlement_stub_period=periodo_irregular_pago,
settlement_calendar=calendario,
settlement_lag=lag_pago,
fixing_calendar=calendario,
interest_rate_index=oistest,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
notional_currency=usd,
spread=spread,
gearing=gearing,
interest_rate=lin_act360,
eq_rate_decimal_places=8,
lookback=lookback,
lockout=lockout,
sett_lag_behaviour=sett_lag_behaviour,
# Parámetros MultiCurrency
fx_rate_index_fixing_lag=fx_rate_index_fixing_lag,
settlement_currency=usd,
fx_rate_index=usdclp_obs,
fx_fixing_lag_pivot=fx_fixing_lag_pivot,
fx_fixing_lag_applies_to=qcf.FxFixingLagAppliesTo.FIXING_DATE,
)
aux.leg_as_dataframe(cor_mccy_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | interes | amort_es_flujo | flujo | moneda_nocional | codigo_indice_tasa | tipo_tasa | spread | gearing | valor_tasa | moneda_pago | fx_rate_index | fecha_fixing_fx | valor_indice_fx | interes_moneda_pago | amortizacion_moneda_pago | flujo_moneda_pago | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-01-31 | 2024-07-31 | 2024-08-02 | 1,000,000.00 | 0.00 | 5,055.56 | True | 5,055.56 | USD | OISTEST | LinAct360 | 1.0000% | 1.00 | 0.0000% | USD | USDOBS | 2024-08-02 | 1.00 | 5,055.56 | 0.00 | 5,055.56 |
| 1 | 2024-07-31 | 2025-01-31 | 2025-02-04 | 1,000,000.00 | 0.00 | 5,111.11 | True | 5,111.11 | USD | OISTEST | LinAct360 | 1.0000% | 1.00 | 0.0000% | USD | USDOBS | 2025-02-04 | 1.00 | 5,111.11 | 0.00 | 5,111.11 |
| 2 | 2025-01-31 | 2025-07-31 | 2025-08-04 | 1,000,000.00 | 0.00 | 5,027.78 | True | 5,027.78 | USD | OISTEST | LinAct360 | 1.0000% | 1.00 | 0.0000% | USD | USDOBS | 2025-08-04 | 1.00 | 5,027.78 | 0.00 | 5,027.78 |
| 3 | 2025-07-31 | 2026-01-31 | 2026-02-04 | 1,000,000.00 | 0.00 | 5,111.11 | True | 5,111.11 | USD | OISTEST | LinAct360 | 1.0000% | 1.00 | 0.0000% | USD | USDOBS | 2026-02-04 | 1.00 | 5,111.11 | 0.00 | 5,111.11 |
| 4 | 2026-01-31 | 2026-07-31 | 2026-08-04 | 1,000,000.00 | 0.00 | 5,027.78 | True | 5,027.78 | USD | OISTEST | LinAct360 | 1.0000% | 1.00 | 0.0000% | USD | USDOBS | 2026-08-04 | 1.00 | 5,027.78 | 0.00 | 5,027.78 |
| 5 | 2026-07-31 | 2027-01-31 | 2027-02-03 | 1,000,000.00 | 0.00 | 5,111.11 | True | 5,111.11 | USD | OISTEST | LinAct360 | 1.0000% | 1.00 | 0.0000% | USD | USDOBS | 2027-02-03 | 1.00 | 5,111.11 | 0.00 | 5,111.11 |
| 6 | 2027-01-31 | 2027-07-31 | 2027-08-04 | 1,000,000.00 | 0.00 | 5,027.78 | True | 5,027.78 | USD | OISTEST | LinAct360 | 1.0000% | 1.00 | 0.0000% | USD | USDOBS | 2027-08-04 | 1.00 | 5,027.78 | 0.00 | 5,027.78 |
| 7 | 2027-07-31 | 2028-01-31 | 2028-02-02 | 1,000,000.00 | 1,000,000.00 | 5,111.11 | True | 1,005,111.11 | USD | OISTEST | LinAct360 | 1.0000% | 1.00 | 0.0000% | USD | USDOBS | 2028-02-02 | 1.00 | 5,111.11 | 1,000,000.00 | 1,005,111.11 |
Construcción Asistida de un IcpClfLeg¶
En este ejemplo se construye un Leg con IcpClfCashflow y amortización bullet.
Se requieren los siguientes parámetros:
RecPay: enum que indica si los flujos se reciben o paganQCDate: fecha de inicio del primer flujoQCDate: fecha final del último flujo sin considerar ajustes de días feriadosBusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriadosTenor: la periodicidad de pagoQCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)QCBusinessCalendar: calendario que aplica para las fechas de pagounsigned int: lag de pago expresado en díasfloat: nominalbool: si esTruesignifica que la amortización final es un flujo de caja efectivofloat: spread aditivogearing: spread multiplicativo o gearing (tasa * geraing + spread)
NOTA: para construir un Leg con IcpClfCashflow y amortización customizada, sólo se debe cambiar el parámetro nominal por CustomNotionalAndAmort e invocar el método qcf.LegFactory.build_custom_amort_icp_clf_leg(...).
Vamos al ejemplo.
Se da de alta los parámetros requeridos
rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(31, 1, 2024)
fecha_final = qcf.QCDate(31, 1, 2028)
bus_adj_rule = qcf.BusyAdjRules.MODFOLLOW
periodicidad_pago = qcf.Tenor('6M')
periodo_irregular_pago = qcf.StubPeriod.NO
calendario = qcf.BusinessCalendar(fecha_inicio, 20)
lag_pago = 2
nominal = 300_000.0
amort_es_flujo = True
spread = .01
gearing = 1.0
Se da de alta el objeto.
icp_clf_leg = qcf.LegFactory.build_bullet_icp_clf_leg(
rec_pay=rp,
start_date=fecha_inicio,
end_date=fecha_final,
bus_adj_rule=bus_adj_rule,
settlement_periodicity=periodicidad_pago,
settlement_stub_period=periodo_irregular_pago,
settlement_calendar=calendario,
settlement_lag=lag_pago,
initial_notional=nominal,
amort_is_cashflow=amort_es_flujo,
spread=spread,
gearing=gearing
)
aux.leg_as_dataframe(icp_clf_leg).style.format(aux.format_dict)
| fecha_inicial | fecha_final | fecha_pago | nocional | amortizacion | amort_es_flujo | flujo | moneda_nocional | icp_inicial | icp_final | uf_inicial | uf_final | valor_tasa | interes | spread | gearing | tipo_tasa | flujo_en_clp | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-01-31 | 2024-07-31 | 2024-08-02 | 300,000.00 | 0.00 | True | 1,516.67 | CLF | 10,000.00 | 10,000.00 | 35,000.00 | 35,000.00 | 1.0000% | 1,516.67 | 1.0000% | 1.00 | LinAct360 | 53,083,333.00 |
| 1 | 2024-07-31 | 2025-01-31 | 2025-02-04 | 300,000.00 | 0.00 | True | 1,533.33 | CLF | 10,000.00 | 10,000.00 | 35,000.00 | 35,000.00 | 1.0000% | 1,533.33 | 1.0000% | 1.00 | LinAct360 | 53,666,667.00 |
| 2 | 2025-01-31 | 2025-07-31 | 2025-08-04 | 300,000.00 | 0.00 | True | 1,508.33 | CLF | 10,000.00 | 10,000.00 | 35,000.00 | 35,000.00 | 1.0000% | 1,508.33 | 1.0000% | 1.00 | LinAct360 | 52,791,667.00 |
| 3 | 2025-07-31 | 2026-01-30 | 2026-02-03 | 300,000.00 | 0.00 | True | 1,525.00 | CLF | 10,000.00 | 10,000.00 | 35,000.00 | 35,000.00 | 1.0000% | 1,525.00 | 1.0000% | 1.00 | LinAct360 | 53,375,000.00 |
| 4 | 2026-01-30 | 2026-07-31 | 2026-08-04 | 300,000.00 | 0.00 | True | 1,516.67 | CLF | 10,000.00 | 10,000.00 | 35,000.00 | 35,000.00 | 1.0000% | 1,516.67 | 1.0000% | 1.00 | LinAct360 | 53,083,333.00 |
| 5 | 2026-07-31 | 2027-01-29 | 2027-02-02 | 300,000.00 | 0.00 | True | 1,516.67 | CLF | 10,000.00 | 10,000.00 | 35,000.00 | 35,000.00 | 1.0000% | 1,516.67 | 1.0000% | 1.00 | LinAct360 | 53,083,333.00 |
| 6 | 2027-01-29 | 2027-07-30 | 2027-08-03 | 300,000.00 | 0.00 | True | 1,516.67 | CLF | 10,000.00 | 10,000.00 | 35,000.00 | 35,000.00 | 1.0000% | 1,516.67 | 1.0000% | 1.00 | LinAct360 | 53,083,333.00 |
| 7 | 2027-07-30 | 2028-01-31 | 2028-02-02 | 300,000.00 | 300,000.00 | True | 301,541.67 | CLF | 10,000.00 | 10,000.00 | 35,000.00 | 35,000.00 | 1.0000% | 1,541.67 | 1.0000% | 1.00 | LinAct360 | 10,553,958,333.00 |