Saltar a contenido

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
import aux_functions as aux
import pandas as pd

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_vcto = qcf.QCDate(23, 9, 2024)

simple_cashflow_1 = qcf.SimpleCashflow(
    fecha_vcto,    # fecha del flujo
    1_000,         # monto
    qcf.QCUSD()    # moneda
) 

simple_cashflow_2 = qcf.SimpleCashflow(
    fecha_vcto,    # 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()

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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados (FOLLOW, MOD_FOLLOW)
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para los ajustes de fechas y fechas de pago
  • unsigned int: lag de pago expresado en días
  • float: nominal inicial
  • bool: si es True significa que la amortización es un flujo de caja efectivo
  • QCInterestRate: la tasa a aplicar en cada flujo
  • QCCurrency: moneda del nominal y de los flujos
  • bool: si es True fuerza 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 la Leg represente un bono a tasa fija.
  • SettLagBehaviour: este parámetro indica cómo se calcula un settlement_date cuando un end_date cae en un día festivo y no se ha definido un ajuste en las fechas finales. Las alternativas son dos, se calcula sumando el settlement_lag desde end_date o se calcula sumando settlement_lag a partir de la primera fecha hábil posterior a end_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 nominal amortizacion interes amort_es_flujo flujo moneda 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • unsigned int: lag de pago expresado en días
  • CustomNotionalAndAmort: vector de capital vigente y amortizaciones customizado
  • bool: si es True significa que la amortización es un flujo de caja efectivo
  • QCInterestRate: la tasa a aplicar en cada flujo
  • QCCurrency: moneda del nominal y de los flujos
  • SettLagBehaviour: este parámetro indica cómo se calcula un settlement_date cuando un end_date cae 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('CL', 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=['nominal','amortizacion', 'flujo']
).set_properties(
    **{'background-color': '#FFCFA9', 'color':'black'},
    subset=['flujo']
)
  fecha_inicial fecha_final fecha_pago nominal amortizacion interes amort_es_flujo flujo moneda 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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • unsigned int: lag de pago expresado en días
  • float: nominal inicial
  • bool: si es True significa que la amortización es un flujo de caja efectivo
  • QCInterestRate: la tasa a aplicar en cada flujo
  • QCCurrency: moneda del nominal
  • bool: si es True fuerza 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 la Leg represente un bono a tasa fija.
  • SettLagBehaviour: este parámetro indica cómo se calcula un settlement_date cuando un end_date cae 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.

El parámetro FxFixingLagPivot aparece en la versión 0.14.0.

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', # Vamos a suponer que es el Dólar Observado
    one_d, 
    one_d, 
    calendario  # Es Santiago
)

Luego se dan de alta los otros parámetros requeridos para la construcción

rp = qcf.RecPay.RECEIVE
fecha_inicio = qcf.QCDate(29, 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("5Y")
fecha_final = fecha_inicio.add_months(plazo.get_years() * 12 + plazo.get_months())
print(f"Fecha final: {fecha_final}")
Fecha final: 2029-07-29

Vamos con el resto de parámetros.

bus_adj_rule = qcf.BusyAdjRules.NO
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
sett_lag_behaviour = qcf.SettLagBehaviour.DONT_MOVE

fx_rate_index_fixing_lag = 1  # lag de fijación del índice FX
fx_fixing_lag_pivot = qcf.FxFixingLagPivot.SETTLEMENT_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=calendario,
    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,
)

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 nominal 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-29 2025-01-29 2025-01-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2025-01-29 CLP USDOBS 1.00 0.00 1,500,000.00
1 2025-01-29 2025-07-29 2025-07-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2025-07-29 CLP USDOBS 1.00 0.00 1,500,000.00
2 2025-07-29 2026-01-29 2026-01-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2026-01-29 CLP USDOBS 1.00 0.00 1,500,000.00
3 2026-01-29 2026-07-29 2026-07-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2026-07-29 CLP USDOBS 1.00 0.00 1,500,000.00
4 2026-07-29 2027-01-29 2027-02-01 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2027-01-29 CLP USDOBS 1.00 0.00 1,500,000.00
5 2027-01-29 2027-07-29 2027-07-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2027-07-29 CLP USDOBS 1.00 0.00 1,500,000.00
6 2027-07-29 2028-01-29 2028-01-31 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2028-01-28 CLP USDOBS 1.00 0.00 1,500,000.00
7 2028-01-29 2028-07-29 2028-07-31 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2028-07-28 CLP USDOBS 1.00 0.00 1,500,000.00
8 2028-07-29 2029-01-29 2029-01-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2029-01-29 CLP USDOBS 1.00 0.00 1,500,000.00
9 2029-01-29 2029-07-29 2029-07-30 100,000,000.00 100,000,000.00 1,500,000.00 True 101,500,000.00 USD 3.0000% Lin30360 2029-07-27 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 nominal 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-29 2025-01-29 2025-01-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2025-01-28 CLP USDOBS 1.00 0.00 1,500,000.00
1 2025-01-29 2025-07-29 2025-07-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2025-07-28 CLP USDOBS 1.00 0.00 1,500,000.00
2 2025-07-29 2026-01-29 2026-01-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2026-01-28 CLP USDOBS 1.00 0.00 1,500,000.00
3 2026-01-29 2026-07-29 2026-07-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2026-07-28 CLP USDOBS 1.00 0.00 1,500,000.00
4 2026-07-29 2027-01-29 2027-02-01 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2027-01-28 CLP USDOBS 1.00 0.00 1,500,000.00
5 2027-01-29 2027-07-29 2027-07-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2027-07-28 CLP USDOBS 1.00 0.00 1,500,000.00
6 2027-07-29 2028-01-29 2028-01-31 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2028-01-28 CLP USDOBS 1.00 0.00 1,500,000.00
7 2028-01-29 2028-07-29 2028-07-31 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2028-07-28 CLP USDOBS 1.00 0.00 1,500,000.00
8 2028-07-29 2029-01-29 2029-01-30 100,000,000.00 0.00 1,500,000.00 True 1,500,000.00 USD 3.0000% Lin30360 2029-01-26 CLP USDOBS 1.00 0.00 1,500,000.00
9 2029-01-29 2029-07-29 2029-07-30 100,000,000.00 100,000,000.00 1,500,000.00 True 101,500,000.00 USD 3.0000% Lin30360 2029-07-27 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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • unsigned int: lag de pago expresado en días
  • float: nominal inicial
  • bool: si es True significa que la amortización es un flujo de caja efectivo
  • QCInterestRate: la tasa a aplicar en cada flujo
  • QCCurrency: moneda del nominal
  • QCCurrency: moneda de los flujos
  • FXRateIndex: índice con el cual se transforma cada flujo a la moneda de pago.
  • bool: si es True fuerza 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 la Leg represente un bono a tasa fija.
  • SettLagBehaviour: este parámetro indica cómo se calcula un settlement_date cuando un end_date cae en un día festivo.
  • FxFixingLagPivot: este parámetro indica si el lag de fijación del índice FX se aplica sobre end_date o sobre settlement_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']
)
  fecha_inicial fecha_final fecha_pago nominal 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 1968-07-12 1969-01-12 1969-01-13 1,200.00 100.00 18.00 True 118.00 USD 3.0000% Lin30360 1969-01-10 CLP USDOBS 1.00 100.00 18.00
1 1969-01-12 1969-07-12 1969-07-14 1,100.00 100.00 16.50 True 116.50 USD 3.0000% Lin30360 1969-07-11 CLP USDOBS 1.00 100.00 16.50
2 1969-07-12 1970-01-12 1970-01-13 1,000.00 100.00 15.00 True 115.00 USD 3.0000% Lin30360 1970-01-12 CLP USDOBS 1.00 100.00 15.00
3 1970-01-12 1970-07-12 1970-07-13 900.00 100.00 13.50 True 113.50 USD 3.0000% Lin30360 1970-07-10 CLP USDOBS 1.00 100.00 13.50
4 1970-07-12 1971-01-12 1971-01-13 800.00 100.00 12.00 True 112.00 USD 3.0000% Lin30360 1971-01-12 CLP USDOBS 1.00 100.00 12.00
5 1971-01-12 1971-07-12 1971-07-13 700.00 100.00 10.50 True 110.50 USD 3.0000% Lin30360 1971-07-12 CLP USDOBS 1.00 100.00 10.50
6 1971-07-12 1972-01-12 1972-01-13 600.00 100.00 9.00 True 109.00 USD 3.0000% Lin30360 1972-01-12 CLP USDOBS 1.00 100.00 9.00
7 1972-01-12 1972-07-12 1972-07-13 500.00 100.00 7.50 True 107.50 USD 3.0000% Lin30360 1972-07-12 CLP USDOBS 1.00 100.00 7.50
8 1972-07-12 1973-01-12 1973-01-15 400.00 100.00 6.00 True 106.00 USD 3.0000% Lin30360 1973-01-12 CLP USDOBS 1.00 100.00 6.00
9 1973-01-12 1973-07-12 1973-07-13 300.00 100.00 4.50 True 104.50 USD 3.0000% Lin30360 1973-07-12 CLP USDOBS 1.00 100.00 4.50
10 1973-07-12 1974-01-12 1974-01-14 200.00 100.00 3.00 True 103.00 USD 3.0000% Lin30360 1974-01-11 CLP USDOBS 1.00 100.00 3.00
11 1974-01-12 1974-07-12 1974-07-15 100.00 100.00 1.50 True 101.50 USD 3.0000% Lin30360 1974-07-12 CLP USDOBS 1.00 100.00 1.50

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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • unsigned int: lag de pago expresado en días
  • Tenor: periodicidad de fijación
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular para el calendario de fijaciones
  • QCBusinessCalendar: calendario que aplica para las fechas de fijación
  • unsigned int: lag de fijación expresado en días
  • InterestRateIndex: índice de tasa de interés utilizado en cada IborCashflow
  • float: nominal
  • bool: si es True significa que la amortización final es un flujo de caja efectivo
  • QCCurrency: moneda del nominal y de los flujos
  • float: spread aditivo
  • gearing: spread multiplicativo (tasa * gearing + spread)
  • SettLagBehaviour: este parámetro indica cómo se calcula un settlement_date cuando un end_date cae 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • unsigned int: lag de pago expresado en días
  • Tenor: periodicidad de fijación
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular para el calendario de fijaciones
  • QCBusinessCalendar: calendario que aplica para las fechas de fijación
  • unsigned int: lag de fijación expresado en días
  • InterestRateIndex: índice de tasa de interés utilizado en cada IborCashflow
  • float: nominal
  • bool: si es True significa que la amortización final es un flujo de caja efectivo
  • QCCurrency: moneda del nominal y de los flujos
  • float: spread aditivo
  • gearing: spread multiplicativo (tasa * gearing + spread)
  • SettLagBehaviour: este parámetro indica cómo se calcula un settlement_date cuando un end_date cae 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.

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,
)
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
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
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 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
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
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
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
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
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

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
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
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 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
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
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
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
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
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

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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • BusyAdRules: tipo de ajuste en la fecha de fijación de los valores inicial y final del índice en cada cupón
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • QCBusinessCalendar: calendario que aplica para las fechas de fijación del índice
  • unsigned int: lag de pago expresado en días
  • float: nominal
  • bool: si es True significa que la amortización final es un flujo de caja efectivo
  • float: spread aditivo
  • float: spread multiplicativo o gearing (tasa * gearing + spread)
  • QCInterestRate: representa el tipo de tasa que se usará que se usará para la tasa equivalente
  • string: nombre del índice overnight a utilizar
  • unsigned int: número de decimales de la tasa equivalente
  • QCCurrency: moneda del nocional
  • DatesForEquivalentRate: 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 un settlement_date cuando un end_date cae 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_devengo fecha_final_devengo 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_equivalente 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,555.56 505,555.56 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.11 511,111.11 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,777.78 502,777.78 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.11 511,111.11 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,777.78 502,777.78 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.11 511,111.11 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,777.78 502,777.78 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.11 511,111.11 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,555.56 505,555.56 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.11 100,511,111.11 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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • BusyAdRules: tipo de ajuste en la fecha de fijación de los valores inicial y final del índice en cada cupón
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • QCBusinessCalendar: calendario que aplica para las fechas de fijación del índice
  • unsigned int: lag de pago expresado en días
  • float: nominal
  • bool: si es True significa que la amortización final es un flujo de caja efectivo
  • float: spread aditivo
  • float: spread multiplicativo
  • QCInterestRate: representa el tipo de tasa que se usará que se usará para la tasa equivalente
  • string: nombre del índice overnight a utilizar
  • unsigned int: número de decimales de la tasa equivalente
  • QCCurrency: moneda del nocional
  • DatesForEquivalentRate: 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 un settlement_date cuando un end_date cae 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.

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,
)

Se visualiza.

aux.leg_as_dataframe(on_index_mccy_leg).style.format(aux.format_dict)
  fecha_inicial_devengo fecha_final_devengo 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_equivalente tipo_tasa interes flujo spread gearing moneda_pago indice_fx fecha_fijacion_indice_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,555.56 505,555.56 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.11 511,111.11 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,777.78 502,777.78 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.11 511,111.11 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,777.78 502,777.78 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.11 511,111.11 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,777.78 502,777.78 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.11 511,111.11 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,555.56 505,555.56 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.11 100,511,111.11 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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • unsigned int: lag de pago expresado en días
  • QCBusinessCalendar: calendario que aplica para las fechas de fijación de la tasa overnight
  • QCInterestRateIndex: índice overnight a utilizar
  • float: nominal
  • bool: si es True significa que la amortización final es un flujo de caja efectivo
  • QCCurrency: moneda del nocional
  • float: spread aditivo
  • float: spread multiplicativo o gearing (tasa * gearing + spread)
  • QCInterestRate: representa el tipo de tasa que se usará que se usará para la tasa equivalente
  • unsigned int: número de decimales de la tasa equivalente
  • unsigned int: lookback (no implementado)
  • unsigned int: lockout (no implementado)
  • SettLagBehaviour: este parámetro indica cómo se calcula un settlement_date cuando un end_date cae 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 nominal amortizacion interes amort_es_flujo flujo moneda 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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • unsigned int: lag de pago expresado en días
  • QCBusinessCalendar: calendario que aplica para las fechas de fijación de la tasa overnight
  • QCInterestRateIndex: índice overnight a utilizar
  • float: nominal
  • bool: si es True significa que la amortización final es un flujo de caja efectivo
  • QCCurrency: moneda del nocional
  • float: spread aditivo
  • float: spread multiplicativo
  • QCInterestRate: representa el tipo de tasa que se usará que se usará para la tasa equivalente
  • unsigned int: número de decimales de la tasa equivalente
  • unsigned int: lookback (no implementado)
  • unsigned int: lockout (no implementado)
  • SettLagBehaviour: este parámetro indica cómo se calcula un settlement_date cuando un end_date cae 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.

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,
)
aux.leg_as_dataframe(cor_mccy_leg).style.format(aux.format_dict)
  fecha_inicial fecha_final fecha_pago nominal amortizacion interes amort_es_flujo flujo moneda 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-01 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-03 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-01 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-03 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-03 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-02 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-03 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-01 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 pagan
  • QCDate: fecha de inicio del primer flujo
  • QCDate: fecha final del último flujo sin considerar ajustes de días feriados
  • BusyAdRules: enum que representa el tipo de ajuste en la fecha final para días feriados
  • Tenor: la periodicidad de pago
  • QCInterestRateLeg::QCStubPeriod: enum que representa el tipo de período irregular (si aplica)
  • QCBusinessCalendar: calendario que aplica para las fechas de pago
  • unsigned int: lag de pago expresado en días
  • float: nominal
  • bool: si es True significa que la amortización final es un flujo de caja efectivo
  • float: spread aditivo
  • gearing: 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 nominal amortizacion amort_es_flujo flujo moneda 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