Cashflows¶
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
qcf.id()
'version: 0.12.1, build: 2024-07-21 13:10'
Simple Cashflow¶
Un objeto de tipo SimpleCashflow
representa un flujo de caja cierto en una fecha y moneda. Para instanciar un objeto de este tipo se requiere:
QCDate
: fecha del flujofloat
: monto del flujoQCCurrency
: moneda del flujo
Veamos un ejemplo. Primero se define los parámetros.
fecha1 = qcf.QCDate(24, 8, 2024)
monto = 1_000_000
clp = qcf.QCCLP()
Luego, se instancia el objeto.
simple_cashflow = qcf.SimpleCashflow(
fecha1,
monto,
clp,
)
Métodos amount
, ccy
y date
¶
Permiten obtener el monto, la moneda y la fecha del flujo.
print(f"Monto: {simple_cashflow.amount():,.0f}")
Monto: 1,000,000
print(f"Moneda: {simple_cashflow.ccy()}")
Moneda: CLP
print(f"Fecha: {simple_cashflow.date()}")
Fecha: 2024-08-24
Método is_expired
¶
Todos los cashflows tienen el método de conveniencia is_expired
que sirve para indicar si un flujo ya ocurrió o está vencido.
simple_cashflow.is_expired(qcf.QCDate("2024-09-01"))
True
Notar que no se considera vencido si la fecha de referencia es menor o igual a la fecha de vencimiento.
simple_cashflow.is_expired(fecha1)
False
simple_cashflow.is_expired(qcf.QCDate("2024-01-01"))
False
Función show
¶
Esta función envuelve de forma cómoda todo el flujo en un objeto tuple
. La función show
está sobrecargada y admite todos los tipos de flujo de qcfinancial
.
qcf.show(simple_cashflow)
('2024-08-24', 1000000.0, 'CLP')
Función get_column_names
¶
Para nombrar los elementos de la tupla anterior, se puede utilizar la función get_column_names
.
qcf.get_column_names('SimpleCashflow')
('fecha_pago', 'monto', 'moneda')
Con ella podemos, por ejemplo, estructurar aún más el output de show
utilizando un pandas.DataFrame
.
df = pd.DataFrame([qcf.show(simple_cashflow)])
df.columns = list(qcf.get_column_names('SimpleCashflow'))
df.style.format({'monto':'{:,.0f}'})
fecha_pago | monto | moneda | |
---|---|---|---|
0 | 2024-08-24 | 1,000,000 | CLP |
Simple Multicurrency Cashflow¶
Un objeto de tipo SimpleMultiCurrencyCashflow
representa un flujo de caja cierto en una fecha y moneda, el cual, sin embargo, se liquidará en una segunda moneda utilizando el valor de un índice de tipo de cambio a una fecha futura. Para dar de alta uno de estos objetos se requiere:
QCDate
: fecha finalfloat
: monto nominalQCCurrency
: la moneda del monto nominalQCDate
: la fecha de publicación delFXRateIndex
que se usará en la conversiónQCCurrency
: la moneda final del flujoFXRateIndex
: el índice de tipo de cambio a utilizarfloat
: el valor del índice de tipo de cambio
Ejemplo 1¶
Se da de alta los objetos que el constructor del índice de tipo de cambio necesita.
# moneda
usd = qcf.QCUSD()
# tipo de cambio
usdclp = qcf.FXRate(usd, clp)
# tenor
_1d = qcf.Tenor('1D')
Aquí utilizamos aux.get_business_calendar
para apoyarnos en la librería holidays
y obtener el calendario de Santiago.
# calendario Santiago
scl = aux.get_business_calendar("CL", range(2024, 2035))
# dólar observado
usdclp_obs = qcf.FXRateIndex(usdclp, "USDOBS", _1d, _1d, scl)
# valor del índice
fx_rate_value = 900.0
Se da de alta el cashflow.
simple_mccy_cashflow = qcf.SimpleMultiCurrencyCashflow(
fecha1,
monto,
clp, # nominal en CLP
fecha1,
usd, # pago en USD
usdclp_obs,
fx_rate_value
)
Este objeto hereda de SimpleCashflow
y por lo tanto, los métodos amount
, date
y ccy
siguen disponibles.
print(f"Monto: {simple_mccy_cashflow.amount():,.2f}")
print(f"Fecha: {simple_mccy_cashflow.date()}")
print(f"Moneda: {simple_mccy_cashflow.ccy()}")
Monto: 1,000,000.00
Fecha: 2024-08-24
Moneda: CLP
Para obtener el monto en la moneda de pago y la moneda de pago están los métodos settlement_amount
y settlement_ccy
.
print(f"Monto de pago: {simple_mccy_cashflow.settlement_amount():,.0f}")
Monto de pago: 1,111
print(f"Moneda de pago: {simple_mccy_cashflow.settlement_ccy()}")
Moneda de pago: USD
El valor del índice de tipo de cambio se puede alterar con el método set_fx_rate_index_value
.
simple_mccy_cashflow.set_fx_rate_index_value(800.00)
print(f"Flujo: {simple_mccy_cashflow.settlement_amount():,.2f} {simple_mccy_cashflow.settlement_ccy()}")
Flujo: 1,250.00 USD
Ejemplo 2¶
Aquí, las monedas están invertidas respecto al caso anterior. El valor del índice se usa de la forma correcta.
simple_mccy_cashflow = qcf.SimpleMultiCurrencyCashflow(
fecha1,
1_000_000,
usd, # nominal en USD
fecha1,
clp, # pago en CLP
usdclp_obs,
fx_rate_value,
)
Se repite los cálculos del ejemplo anterior.
print(f"Fecha: {simple_mccy_cashflow.date()}")
print(f"Nominal: {simple_mccy_cashflow.nominal():,.2f}")
print(f"Moneda nominal: {simple_mccy_cashflow.ccy().get_iso_code()}")
print(f"Flujo: {simple_mccy_cashflow.settlement_amount():,.0f}")
print(f"Moneda flujo: {simple_mccy_cashflow.settlement_ccy().get_iso_code()}")
Fecha: 2024-08-24
Nominal: 1,000,000.00
Moneda nominal: USD
Flujo: 900,000,000
Moneda flujo: CLP
Ejemplo 3¶
En este caso, hay inconsistencia entre las monedas y el tipo de cambio del índice y vemos que se produce un error.
eur = qcf.QCEUR()
try:
simple_mccy_cashflow = qcf.SimpleMultiCurrencyCashflow(
fecha1,
1_000_000,
usd, # nominal en USD
fecha1,
eur, # pago en EUR
usdclp_obs, # ¡usamos el dólar observado!
fx_rate_value,
)
except ValueError as e:
print("Error:", e)
Error: Fx Rate Index provided is not compatible with nominal and settlement currency.
Funciones show
y get_columns
¶
qcf.show(simple_mccy_cashflow)
('2024-08-24',
1000000.0,
'USD',
'2024-08-24',
'CLP',
'USDOBS',
900.0,
900000000.0)
qcf.get_column_names('SimpleMultiCurrencyCashflow')
('fecha_pago',
'monto_nominal',
'moneda_nominal',
'fecha_fixing',
'moneda_pago',
'codigo_indice_fx',
'valor_indice_fx',
'monto_moneda_pago')
Nuevamente, usando estas funciones podemos visualizar el flujo utilizando un pandas.DataFrame
.
df = pd.DataFrame([qcf.show(simple_mccy_cashflow)])
df.columns = list(qcf.get_column_names('SimpleMultiCurrencyCashflow'))
df.style.format({
'monto_nominal':'{:,.0f}',
'monto_moneda_pago':'{:,.0f}',
'valor_indice_fx':'{:,.2f}'
})
fecha_pago | monto_nominal | moneda_nominal | fecha_fixing | moneda_pago | codigo_indice_fx | valor_indice_fx | monto_moneda_pago | |
---|---|---|---|---|---|---|---|---|
0 | 2024-08-24 | 1,000,000 | USD | 2024-08-24 | CLP | USDOBS | 900.00 | 900,000,000 |
Fixed Rate Cashflow¶
Un objeto de tipo FixedRateCashflow
representa un flujo de caja calculado a partir de la aplicación de una tasa prefijada, entre dos fechas prefijadas a un nominal prefijado. Para dar de alta uno de estos objetos se requiere:
QCDate
: fecha inicio (para la aplicación de la tasa)QCDate
: fecha final (para la aplicación de la tasa)QCDate
: fecha de pagofloat
: nominal (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalQCInterestRate
: la tasa de interés a aplicar (su valor y convenciones)QCCurrency
: moneda del nominal y del flujo de caja
Construcción¶
Se define los parámetros requeridos.
fecha_inicio = qcf.QCDate(20, 5, 2024)
fecha_final = qcf.QCDate(20, 5, 2025)
fecha_pago = qcf.QCDate(22, 5, 2025)
nominal = 1_000_000_000.0
amortizacion = 100_000_000.0
amort_is_cashflow = False
Se define la yearFraction, wealthFunction el valor de la tasa y finalmente la tasa de interés.
act360 = qcf.QCAct360()
lin_wf = qcf.QCLinearWf()
valor_tasa_fija = .1
tasa = qcf.QCInterestRate(valor_tasa_fija, act360, lin_wf)
Se instancia el cashflow.
fixed_rate_cashflow = qcf.FixedRateCashflow(
fecha_inicio,
fecha_final,
fecha_pago,
nominal,
amortizacion,
amort_is_cashflow,
tasa,
clp,
)
Getters¶
print(f"Tipo de flujo: {fixed_rate_cashflow.get_type()}")
print(f"Fecha Inicio: {fixed_rate_cashflow.get_start_date()}")
print(f"Fecha Final: {fixed_rate_cashflow.get_end_date()}")
print(f"Fecha Pago: {fixed_rate_cashflow.get_settlement_date()}")
print(f"Moneda: {fixed_rate_cashflow.ccy()}") # __str__ devuelve el ISO Code de la moneda
print(f"Nominal: {fixed_rate_cashflow.get_nominal():,.0f}")
print(f"Amortización: {fixed_rate_cashflow.get_amortization():,.0f}")
print(f"Tasa de interés: {fixed_rate_cashflow.get_rate()}")
Tipo de flujo: FixedRateCashflow
Fecha Inicio: 2024-05-20
Fecha Final: 2025-05-20
Fecha Pago: 2025-05-22
Moneda: CLP
Nominal: 1,000,000,000
Amortización: 100,000,000
Tasa de interés: 0.100000 Act360 Lin
Para obtener el valor de la tasa fija, se usa además un getter de QCInterestRate
.
print(f"Tasa de interés: {fixed_rate_cashflow.get_rate().get_value():.2%}")
Tasa de interés: 10.00%
Setters¶
Cambiar el nominal.
nuevo_nominal = 2_000_000_000.0
fixed_rate_cashflow.set_nominal(nuevo_nominal)
print(f"Nuevo nominal: {fixed_rate_cashflow.get_nominal():,.0f}")
Nuevo nominal: 2,000,000,000
Cambiar la amortización.
nueva_amortizacion = 200_000_000.0
fixed_rate_cashflow.set_amortization(nueva_amortizacion)
print(f"Nueva amortización: {fixed_rate_cashflow.get_amortization():,.0f}")
Nueva amortización: 200,000,000
Cambiar el valor de la tasa.
fixed_rate_cashflow.set_rate_value(new_rate_value:=.12)
print(f"Nuevo valor de la tasa: {fixed_rate_cashflow.get_rate().get_value():.2%}")
Nuevo valor de la tasa: 12.00%
Cálculos¶
Se devuelve el valor de la tasa fija al original.
fixed_rate_cashflow.set_rate_value(valor_tasa_fija)
Método amount
.
print(f"Flujo Total: {fixed_rate_cashflow.amount():,.0f}")
Flujo Total: 202,777,778
Vemos que el flujo incluye los intereses, pero no la amortización (amort_is_cashflow = False
). Podemos verificar a mano este resultado.
dias_devengo = fecha_inicio.day_diff(fecha_final)
print(f"Días de devengo: {dias_devengo}")
print(f"Check: {fixed_rate_cashflow.get_nominal() * valor_tasa_fija * dias_devengo / 360:,.0f}")
Días de devengo: 365
Check: 202,777,778
Método accrued_interest
. Calcula el interés devengado a una cierta fecha.
fecha_intermedia = qcf.QCDate(15, 1, 2025)
print(f"Interés Devengado: {fixed_rate_cashflow.accrued_interest(fecha_intermedia):,.0f}")
dias_devengo = fecha_inicio.day_diff(fecha_intermedia)
print(f"Días de devengo: {dias_devengo}")
print(f"Check: {fixed_rate_cashflow.get_nominal() * valor_tasa_fija * dias_devengo / 360.0:,.0f}")
Interés Devengado: 133,333,333
Días de devengo: 240
Check: 133,333,333
Con este método, utilizando la fecha final del flujo se puede obtener el interés total.
print(f"Interés total: al {fixed_rate_cashflow.accrued_interest(fixed_rate_cashflow.get_end_date()):,.0f}")
Interés total: al 202,777,778
Función show
¶
print(qcf.show(fixed_rate_cashflow))
('2024-05-20', '2025-05-20', '2025-05-22', 2000000000.0, 200000000.0, 202777777.77777794, False, 202777777.77777794, 'CLP', 0.1, 'LinAct360')
Función get_column_names
¶
qcf.get_column_names(fixed_rate_cashflow.get_type())
('fecha_inicial',
'fecha_final',
'fecha_pago',
'nominal',
'amortizacion',
'interes',
'amort_es_flujo',
'flujo',
'moneda',
'valor_tasa',
'tipo_tasa')
Nuevamente, juntando las últimas dos funciones se obtiene una representación tabular del flujo usando pandas.DataFrame
.
df = pd.DataFrame(
[qcf.show(fixed_rate_cashflow)],
columns=qcf.get_column_names(fixed_rate_cashflow.get_type())
)
df.style.format({
'nominal':'{:,.0f}',
'amortizacion':'{:,.0f}',
'interes':'{:,.0f}',
'flujo':'{:,.0f}',
'valor_tasa':'{:.2%}'
})
fecha_inicial | fecha_final | fecha_pago | nominal | amortizacion | interes | amort_es_flujo | flujo | moneda | valor_tasa | tipo_tasa | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2024-05-20 | 2025-05-20 | 2025-05-22 | 2,000,000,000 | 200,000,000 | 202,777,778 | False | 202,777,778 | CLP | 10.00% | LinAct360 |
Fixed Rate Multi Currency Cashflow¶
Un objeto de tipo FixedRateMultiCurrencyCashflow
representa un flujo de caja a tasa fija (FixedRateCashflow
) que se liquidará en una moneda distinta de la moneda del nominal utilizando el valor a una cierta fecha de un índice de tipo de cambio prefijado. Para dar de alta uno de estos objetos se requiere:
QCDate
: fecha inicio (para la aplicación de la tasa)QCDate
: fecha final (para la aplicación de la tasa)QCDate
: fecha de pagofloat
: nominal (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalQCInterestRate
: la tasa de interés a aplicar (su valor y convenciones)QCCurrency
: moneda del nominalQCDate
: fecha de fijación del índice de tipo de cambioQCCurrency
: moneda en la que se liquida el flujoFXRateIndex
: índice de tipo de cambio a utilizarfloat
: valor del índice de tipo de cambio
Construcción¶
Cuando coinciden, se usan los mismos parámetros que en el ejemplo anterior y agregamos los nuevos parámetros requeridos.
fecha_fijacion = fecha_final
usd = qcf.QCUSD()
indice = usdclp_obs
valor_indice = 900.0
nominal = 1_000_000.0
amort = 100_000.0
amort_is_cashflow = True
Se instancia el objeto.
fixed_rate_mccy_cashflow = qcf.FixedRateMultiCurrencyCashflow(
fecha_inicio,
fecha_final,
fecha_pago,
nominal,
amort,
amort_is_cashflow,
tasa,
usd,
fecha_fijacion,
clp,
indice,
valor_indice,
)
Getters¶
La clase FixedRateMultiCurrencyCashflow
es una subclase de FixedRateCashflow
y por lo tanto, hereda todos sus métodos y variables.
print(f"Tipo de flujo: {fixed_rate_mccy_cashflow.get_type()}")
print(f"Fecha Inicio: {fixed_rate_mccy_cashflow.get_start_date()}")
print(f"Fecha Final: {fixed_rate_mccy_cashflow.get_end_date()}")
print(f"Fecha Pago: {fixed_rate_mccy_cashflow.get_settlement_date()}")
print(f"Fecha Fijación Índice FX: {fixed_rate_mccy_cashflow.get_fx_fixing_date()}")
print(f"Moneda del Nominal: {fixed_rate_mccy_cashflow.ccy()}")
print(f"Nominal: {fixed_rate_mccy_cashflow.get_nominal():,.0f}")
print(f"Amortización: {fixed_rate_mccy_cashflow.get_amortization():,.0f}")
print(f"Moneda de Liquidación: {fixed_rate_mccy_cashflow.settlement_currency()}")
# Aquí se usa un getter de QCInterestRate
print(f"Tasa de interés: {fixed_rate_mccy_cashflow.get_rate().get_value():.2%}")
Tipo de flujo: FixedRateMultiCurrencyCashflow
Fecha Inicio: 2024-05-20
Fecha Final: 2025-05-20
Fecha Pago: 2025-05-22
Fecha Fijación Índice FX: 2025-05-20
Moneda del Nominal: USD
Nominal: 1,000,000
Amortización: 100,000
Moneda de Liquidación: CLP
Tasa de interés: 10.00%
Setters¶
Nuevo nominal.
nuevo_nominal = 100.0
fixed_rate_mccy_cashflow.set_nominal(nuevo_nominal)
print(f"Nuevo nominal: {fixed_rate_mccy_cashflow.get_nominal():,.1f}")
Nuevo nominal: 100.0
Nueva amortización.
nueva_amortizacion = 10.0
fixed_rate_mccy_cashflow.set_amortization(nueva_amortizacion)
print(f"Nueva amortización: {fixed_rate_mccy_cashflow.get_amortization():,.1f}")
Nueva amortización: 10.0
Cambiar el valor de la tasa.
fixed_rate_mccy_cashflow.set_rate_value(new_rate_value)
print(f"Nuevo valor de la tasa: {fixed_rate_mccy_cashflow.get_rate().get_value():.2%}")
Nuevo valor de la tasa: 12.00%
Cálculos¶
Se vuelve al nominal, amortización y valor de la tasa iniciales.
fixed_rate_mccy_cashflow.set_nominal(nominal)
fixed_rate_mccy_cashflow.set_amortization(amort)
fixed_rate_mccy_cashflow.set_rate_value(valor_tasa_fija)
Método amount
. En este caso sí se incluye la amortización (amort_is_cashflow = True
).
print(f"Flujo Total: {fixed_rate_mccy_cashflow.amount():,.2f}")
dias_devengo = fecha_inicio.day_diff(fecha_final)
print(
f"Check: {fixed_rate_mccy_cashflow.get_nominal() * valor_tasa_fija * dias_devengo / 360 + fixed_rate_mccy_cashflow.get_amortization():,.2f}"
)
Flujo Total: 201,388.89
Check: 201,388.89
Método accrued_interest
.
fecha_intermedia = qcf.QCDate(15, 1, 2025)
print(f"Interés Devengado: {(interes_devengado:=fixed_rate_mccy_cashflow.accrued_interest(fecha_intermedia)):,.02f}")
print(f"Check: {fixed_rate_mccy_cashflow.get_nominal() * valor_tasa_fija * fecha_inicio.day_diff(fecha_intermedia) / 360.0:,.02f}")
Interés Devengado: 66,666.67
Check: 66,666.67
Método accrued_interest_in_sett_currency
. Retorna el interés devengado en moneda de pago. Para esto requiere de un objeto de tipo time_series
que contenga el valor del índice a la fecha de devengo solicitada.
ts = qcf.time_series()
ts[fecha_inicio] = 900
ts[fecha_intermedia] = 950
print(f"Interés devengado en moneda de pago: {fixed_rate_mccy_cashflow.accrued_interest_in_sett_ccy(fecha_intermedia, ts):,.2f}")
print(f"Check: {interes_devengado * ts[fecha_intermedia]:,.2f}")
Interés devengado en moneda de pago: 63,333,333.33
Check: 63,333,333.33
Funciones show
y get_column_names
¶
Juntando estas dos funciones se obtiene una representación tabular del flujo usando pandas.DataFrame
.
df = pd.DataFrame(
[qcf.show(fixed_rate_mccy_cashflow)],
columns=qcf.get_column_names(fixed_rate_mccy_cashflow.get_type())
)
df.style.format({
'nominal':'{:,.2f}',
'amortizacion':'{:,.2f}',
'amortizacion_moneda_pago':'{:,.0f}',
'interes':'{:,.2f}',
'interes_moneda_pago':'{:,.0f}',
'flujo':'{:,.2f}',
'valor_tasa':'{:.2%}',
'valor_indice_fx':'{:.2f}'
})
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-05-20 | 2025-05-20 | 2025-05-22 | 1,000,000.00 | 100,000.00 | 101,388.89 | True | 201,388.89 | USD | 10.00% | LinAct360 | 2025-05-20 | CLP | USDOBS | 900.00 | 90,000,000 | 91,250,000 |
Ibor Cashflow¶
Un objeto de tipo IborCashflow
representa un flujo de caja calculado a partir de la aplicación de una tasa flotante fijada en una cierta fecha (TERMSOFR, Euribor, ...) , entre dos fechas prefijadas a un nominal prefijado. Para dar de alta uno de estos objetos se requiere:
InterestRateIndex
: el índice de tasa de interés prefijadoQCDate
: fecha inicio (para la aplicación de la tasa)QCDate
: fecha final (para la aplicación de la tasa)QCDate
: fecha de fijación del índice de tasa de interésQCDate
: fecha de pagofloat
: nominal (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalQCCurrency
: moneda del nominal y del flujo de cajafloat
: spread aditivo a aplicar a la fijación del índicefloat
: spread multiplicativo o gearing a aplicar a la fijación del índice
Para dar de alta un InterestRateIndex
se requiere:
str
: código del índiceQCInterestRate
: un objeto tasa de interés que contenga las convenciones del índiceTenor
: el lag de inicio del índice respecto a la fecha de fixing (por ejemplo 2d para Libor USD)Tenor
: el tenor del índice (3M por ejemplo para Libor USD 3M)QCBusinessCalendar
: el calendario de fixingQCBusinessCalendar
: el calendario de pagoQCCurrency
: la moneda a la que corresponde el índice (por ejemplo EUR para EURIBOR 3M)
Construcción¶
Se define primero el índice de tasa de interés.
codigo = "TERMSOFR6M"
lin_act360 = qcf.QCInterestRate(0.0, act360, lin_wf)
fixing_lag = qcf.Tenor("2D")
tenor = qcf.Tenor("6M")
fixing_calendar = aux.get_business_calendar('US', range(2024, 2035))
settlement_calendar = fixing_calendar
term_sofr_6m = qcf.InterestRateIndex(
codigo,
lin_act360,
fixing_lag,
tenor,
fixing_calendar,
settlement_calendar,
usd
)
Getters del objeto InterestRateIndex
.
print(f"Code: {term_sofr_6m.get_code()}")
print(f"Tenor: {term_sofr_6m.get_tenor()}")
print(f"Tasa: {term_sofr_6m.get_rate()}")
Code: TERMSOFR6M
Tenor: 6M
Tasa: 0.000000 Act360 Lin
Para fijar el valor del índice en una fecha en particular.
term_sofr_6m.set_rate_value(0.01)
print(f"Fixing Tasa: {term_sofr_6m.get_rate().get_value():.2%}")
Fixing Tasa: 1.00%
fecha_fixing = qcf.QCDate(20, 9, 2018)
print(f"Fecha Inicio: {term_sofr_6m.get_start_date(fecha_fixing)}")
print(f"Fecha Final: {term_sofr_6m.get_end_date(fecha_fixing)}")
Fecha Inicio: 2018-09-24
Fecha Final: 2019-03-25
Con esto, veamos un ejemplo de construcción y uso de un IborCashflow
.
fecha_inicio = qcf.QCDate(20, 9, 2018)
fecha_final = qcf.QCDate(20, 9, 2019)
fecha_pago = qcf.QCDate(23, 9, 2019)
fecha_fixing = qcf.QCDate(18, 9, 2018)
nominal = 1_000_000.0
amort = 100_000.0
amort_is_cashflow = True
spread = 0.0
gearing = 1.0
ibor_cashflow = qcf.IborCashflow(
term_sofr_6m,
fecha_inicio,
fecha_final,
fecha_fixing,
fecha_pago,
nominal,
amort,
amort_is_cashflow,
usd,
spread,
gearing,
)
Getters¶
print(f"Tipo Cashflow:\t{ibor_cashflow.get_type()}")
print(f"Fecha Fixing:\t{ibor_cashflow.get_fixing_date()}")
print(f"Fecha Inicio:\t{ibor_cashflow.get_start_date()}")
print(f"Fecha Final:\t{ibor_cashflow.get_end_date()}")
print(f"Fecha Pago:\t{ibor_cashflow.get_settlement_date()}")
print(f"Nominal:\t{ibor_cashflow.get_nominal():,.0f}")
print(f"Amortización:\t{ibor_cashflow.get_amortization():,.0f}")
print(f"Moneda:\t\t{ibor_cashflow.ccy()}")
print(f"Valor Tasa:\t{ibor_cashflow.get_interest_rate_value():.2%}")
print(f"Valor Spread:\t{ibor_cashflow.get_spread():.2%}")
print(f"Valor Gearing:\t{ibor_cashflow.get_gearing():.2f}")
Tipo Cashflow: IborCashflow
Fecha Fixing: 2018-09-18
Fecha Inicio: 2018-09-20
Fecha Final: 2019-09-20
Fecha Pago: 2019-09-23
Nominal: 1,000,000
Amortización: 100,000
Moneda: USD
Valor Tasa: 1.00%
Valor Spread: 0.00%
Valor Gearing: 1.00
Setters¶
Nuevo nominal.
nuevo_nominal = 2_000_000.0
ibor_cashflow.set_nominal(nuevo_nominal)
print(f"Nominal: {ibor_cashflow.get_nominal():,.0f}")
Nominal: 2,000,000
Nueva amortización.
nueva_amortizacion = 200_000.0
ibor_cashflow.set_amortization(nueva_amortizacion)
print(f"Amortización: {ibor_cashflow.get_amortization():,.0f}")
Amortización: 200,000
Cambia el valor del índice.
ibor_cashflow.set_interest_rate_value(nuevo_valor_indice:=.02)
print(f"Valor Tasa: {ibor_cashflow.get_interest_rate_value():.2%}")
Valor Tasa: 2.00%
Cambia el valor del sepread.
ibor_cashflow.set_spread(.01)
print(f"Valor Spread: {ibor_cashflow.get_spread():.2%}")
Valor Spread: 1.00%
Cálculos¶
Método amount
. Retorna el flujo total incluyendo la amortización si corresponde.
print(f"Flujo: {ibor_cashflow.amount():,.2f}")
Flujo: 240,555.56
Método accrued_interest
. Retorna el interés devengado a una cierta fecha.
fecha_devengo = qcf.QCDate(20, 7, 2019)
print(f"Interés Devengado al {fecha_devengo}: {ibor_cashflow.accrued_interest(fecha_devengo):,.2f}")
# La tasa es el valor del índice más el spread
tasa = ibor_cashflow.get_interest_rate_value() * ibor_cashflow.get_gearing() + ibor_cashflow.get_spread()
check = tasa * fecha_inicio.day_diff(fecha_devengo) / 360.0 * ibor_cashflow.get_nominal()
print(f"Check: {check:,.2f}")
Interés Devengado al 2019-07-20: 50,500.00
Check: 50,500.00
Funciones show
y get_column_names
¶
Al igual que en casos anteriores, juntando estas dos funciones se obtiene una representación tabular del flujo usando pandas.DataFrame
.
df = pd.DataFrame(
[qcf.show(ibor_cashflow)],
columns=qcf.get_column_names(ibor_cashflow.get_type())
)
df.style.format({
'nominal':'{:,.2f}',
'amortizacion':'{:,.2f}',
'interes':'{:,.2f}',
'flujo':'{:,.2f}',
'valor_tasa':'{:.2%}',
'spread':'{:.2%}',
'gearing':'{:.2f}',
})
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 | 2018-09-20 | 2019-09-20 | 2018-09-18 | 2019-09-23 | 2,000,000.00 | 200,000.00 | 40,555.56 | True | 240,555.56 | USD | TERMSOFR6M | 2.00% | 1.00% | 1.00 | LinAct360 |
Ibor Multi Currency Cashflow¶
Un objeto de tipo IborMultiCurrencyCashflow
representa un flujo de caja a tasa variable (IborCashflow
) que se liquidará en una moneda distinta de la moneda del nominal utilizando el valor a una cierta fecha de un índice de tipo de cambio prefijado. Para dar de alta uno de estos objetos se requiere:
InterestRateIndex
: el índice de tasa de interés prefijadoQCDate
: fecha inicio (para la aplicación de la tasa)QCDate
: fecha final (para la aplicación de la tasa)QCDate
: fecha de fijación del índice de tasa de interésQCDate
: fecha de pagofloat
: nominal (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalQCCurrency
: moneda del nominal y del flujo de cajafloat
: spread aditivo a aplicar a la fijación del índicefloat
: spread multiplicativo o gearing a aplicar a la fijación del índiceQCDate
: fecha de publicación del índice de tipo de cambioQCCurrency
: moneda en la que se liquida el flujoFXRateIndex
: índice de tipo de cambio a utilizarfloat
: valor del índice de tipo de cambio
Construcción¶
Parámetros iniciales, sólo agregamos los parámetros relacionados al MultiCurrency y fijamos el valor del índice de tasa de interés en 1.00%.
valor_indice_fx = 900.0
fecha_publicacion = qcf.QCDate(20, 9, 2019)
term_sofr_6m.set_rate_value(0.01)
Se da de alta el objeto.
ibor_mccy_cashflow = qcf.IborMultiCurrencyCashflow(
term_sofr_6m,
fecha_inicio,
fecha_final,
fecha_fixing,
fecha_pago,
nominal,
amort,
amort_is_cashflow,
usd,
spread,
gearing,
fecha_publicacion,
clp,
indice,
valor_indice,
)
Getters¶
El objeto IborMultiCurrencyCashflow
es una subclase de IborCashflow
y por lo tanto, hereda todos sus métodos y variables.
print(f"Tipo Cashflow:\t {ibor_mccy_cashflow.get_type()}")
print(f"Fecha Fixing:\t {ibor_mccy_cashflow.get_fixing_date()}")
print(f"Fecha Inicio:\t {ibor_mccy_cashflow.get_start_date()}")
print(f"Fecha Final:\t {ibor_mccy_cashflow.get_end_date()}")
print(f"Fecha Pago:\t {ibor_mccy_cashflow.get_settlement_date()}")
print(f"Nominal:\t {ibor_mccy_cashflow.get_nominal():,.0f}")
print(f"Amortización:\t {ibor_mccy_cashflow.get_amortization():,.0f}")
print(f"Moneda:\t\t {ibor_mccy_cashflow.ccy()}")
print(f"Valor Tasa:\t {ibor_mccy_cashflow.get_interest_rate_value():.2%}")
print(f"Valor Spread:\t {ibor_mccy_cashflow.get_spread():.2%}")
print(f"Valor Gearing:\t {ibor_mccy_cashflow.get_gearing():.2f}")
Tipo Cashflow: IborMultiCurrencyCashflow
Fecha Fixing: 2018-09-18
Fecha Inicio: 2018-09-20
Fecha Final: 2019-09-20
Fecha Pago: 2019-09-23
Nominal: 1,000,000
Amortización: 100,000
Moneda: USD
Valor Tasa: 1.00%
Valor Spread: 0.00%
Valor Gearing: 1.00
Adicionalmente tenemos:
print(f"Fecha Fixing FX: {ibor_mccy_cashflow.get_fx_fixing_date()}")
print(f"Valor Índice FX: {ibor_mccy_cashflow.get_fx_rate_index_value():,.2f}")
Fecha Fixing FX: 2019-09-20
Valor Índice FX: 900.00
Setters¶
Nuevo nominal.
nuevo_nominal = 2_000_000.0
ibor_mccy_cashflow.set_nominal(nuevo_nominal)
print(f"Nominal: {ibor_mccy_cashflow.get_nominal():,.0f}")
Nominal: 2,000,000
Nueva amortización.
nueva_amortizacion = 200_000.0
ibor_mccy_cashflow.set_amortization(nueva_amortizacion)
print(f"Amortización: {ibor_mccy_cashflow.get_amortization():,.0f}")
Amortización: 200,000
Cambia el valor del índice de tasa de interés.
ibor_mccy_cashflow.set_interest_rate_value(nuevo_valor_indice:=.02)
print(f"Valor Tasa: {ibor_mccy_cashflow.get_interest_rate_value():.2%}")
Valor Tasa: 2.00%
Nuevo valor para el índice FX.
ibor_mccy_cashflow.set_fx_rate_index_value(950.0)
print(f"Valor Índice FX: {ibor_mccy_cashflow.get_fx_rate_index_value():,.2f}")
Valor Índice FX: 950.00
Cálculos¶
Método amount
. Retorna el flujo total incluyendo la amortización si corresponde.
print(f"Flujo: {ibor_mccy_cashflow.amount():,.2f}")
check = ibor_mccy_cashflow.get_nominal() * fecha_inicio.day_diff(fecha_final) / 360.0 * (
ibor_mccy_cashflow.get_interest_rate_value() * ibor_mccy_cashflow.get_gearing() + spread) + ibor_mccy_cashflow.get_amortization()
print(f"Check: {check:,.2f}")
Flujo: 240,555.56
Check: 240,555.56
Método accrued_interest
. Retorna el interés devengado a una cierta fecha.
fecha_devengo = qcf.QCDate(20, 7, 2019)
print(f"Interés Devengado al {fecha_devengo}: {ibor_mccy_cashflow.accrued_interest(fecha_devengo):,.2f}")
tasa = ibor_mccy_cashflow.get_interest_rate_value() * ibor_mccy_cashflow.get_gearing() + ibor_mccy_cashflow.get_spread()
check = tasa * fecha_inicio.day_diff(fecha_devengo) / 360.0 * ibor_cashflow.get_nominal()
print(f"Check: {check:,.2f}")
Interés Devengado al 2019-07-20: 33,666.67
Check: 33,666.67
Se agrega el método accrued_interest_in_sett_ccy
que retorna el interés devengado en moneda de pago. Para utilizarlo se requiere un objeto de tipo time_series
.
ts[fecha_inicio] = 800.0
ts[fecha_devengo] = 950.0
print(f"Interés devengado en moneda de pago: {ibor_mccy_cashflow.accrued_interest_in_sett_ccy(fecha_devengo, ts):,.0f}")
print(f"Check: {check * 950.0:,.0f}")
Interés devengado en moneda de pago: 31,983,333
Check: 31,983,333
Funciones show
y get_column_names
¶
Al igual que en casos anteriores, juntando estas dos funciones se obtiene una representación tabular del flujo usando pandas.DataFrame
.
df = pd.DataFrame(
[qcf.show(ibor_mccy_cashflow)],
columns=qcf.get_column_names(ibor_mccy_cashflow.get_type())
)
df.style.format({
'nocional':'{:,.2f}',
'amortizacion':'{:,.2f}',
'amortizacion_moneda_pago':'{:,.2f}',
'interes':'{:,.2f}',
'interes_moneda_pago':'{:,.2f}',
'flujo':'{:,.2f}',
'flujo_moneda_pago':'{:,.2f}',
'valor_tasa':'{:.2%}',
'spread':'{:.2%}',
'valor_indice_fx':'{:,.2f}',
})
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 | 2018-09-20 | 2019-09-20 | 2018-09-18 | 2019-09-23 | 2,000,000.00 | 200,000.00 | 40,555.56 | True | 240,555.56 | USD | TERMSOFR6M | 0.00% | 1.000000 | 2.00% | LinAct360 | 2019-09-20 | CLP | USDOBS | 950.00 | 190,000,000.00 | 38,527,777.78 |
Overnight Index Cashflow¶
Un objeto de tipo OvernightIndexCashflow
representa un flujo de caja del tipo de la pata flotante de un swap ICPCLP (cámara promedio) de Chile usando cualquier tipo de índice similar (por ejemplo SOFRINDX) y cualquier moneda. Adicionalmente, permite definir en forma independiente a start_date
y end_date
las fechas inicial y final utilizadas para los valores del índice. Esto puede resultar útil cuando una de estas operaciones se utiliza para cubrir créditos o bonos a tasa fija y tiene, por lo tanto, vencimientos en fechas inhábiles. Para dar de alta uno de estos objetos se requiere:
QCDate
: fecha inicio devengo (para la aplicación de la tasa)QCDate
: fecha final devengo (para la aplicación de la tasa)QCDate
: fecha inicio índice (para el valor del índice)QCDate
: fecha final índice (para el valor del índice)QCDate
: fecha de pagoQCCurrency
: moneda del nocionalfloat
: nocional (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalfloat
: spread aditivo a aplicar a la fijación de la tasa equivalente (TNA en el caso de un ICPCLP)float
: spread multiplicativo o gearing a aplicar a la fijación de la tasa equivalenteQCInterestRate
: con este objeto se especifica en qué convención se calcula la tasa equivalentestring
: nombre del índice overnight a utilizarunsigned int
: número de decimales a utilizar para determinar la tasa equivalenteDatesForEquivalentRate
: enum que indica qué fechas se utilizan en el cálculo de la tasa equivalente.
Construcción¶
Alta de parámetros iniciales.
# Fecha inicio de devengo es un domingo
fecha_inicio_devengo = qcf.QCDate(12, 11, 2023)
# Fecha final de devengo es sábado
fecha_final_devengo = qcf.QCDate(18, 11, 2023)
# Estas fechas deben corresponder a días hábiles
# En ambos casos vamos a la fecha hábil siguiente
fecha_inicio_indice = qcf.QCDate(13, 11, 2023)
fecha_final_indice = qcf.QCDate(20, 11, 2023)
# La fecha de pago es el lunes siguiente
fecha_pago = qcf.QCDate(20, 11, 2023)
# Se usan las fechas de inicio y fin de devengo para
# el cálculo de la tasa equivalente
dates_for_eq_rate = qcf.DatesForEquivalentRate.ACCRUAL
moneda_nocional = qcf.QCUSD()
nocional = 1_000_000_000.0
amort = 100_000_000.0
amort_es_flujo = True
spread = 0.0
gearing = 1.0
tasa = qcf.QCInterestRate(0.0, qcf.QCAct360(), qcf.QCLinearWf())
nombre_indice = 'INDICE'
num_decimales = 8 # decimales como número <-> 6 decimales como porcentaje
Se da de alta el objeto.
overnight_index_cashflow = qcf.OvernightIndexCashflow(
fecha_inicio_devengo,
fecha_final_devengo,
fecha_inicio_indice,
fecha_final_indice,
fecha_pago,
moneda_nocional,
nocional,
amort,
amort_es_flujo,
spread,
gearing,
tasa,
nombre_indice,
num_decimales,
dates_for_eq_rate,
)
Getters¶
print(f"Tipo Cashflow:\t\t\t{overnight_index_cashflow.get_type()}")
print(f"Nominal:\t\t\t{overnight_index_cashflow.get_nominal():,.0f}")
print(f"Amortización:\t\t\t{overnight_index_cashflow.get_amortization():,.0f}")
print(f"Fecha Inicio Devengo:\t\t{overnight_index_cashflow.get_start_date()}")
print(f"Fecha Final Devengo:\t\t{overnight_index_cashflow.get_end_date()}")
print(f"Fecha Inicio Índice:\t\t{overnight_index_cashflow.get_index_start_date()}")
print(f"Fecha Final Índice:\t\t{overnight_index_cashflow.get_index_end_date()}")
print(f"Fecha Pago:\t\t\t{overnight_index_cashflow.get_settlement_date()}")
print(f"Valor Índice Fecha Inicio:\t{overnight_index_cashflow.get_start_date_index():,.8f}")
print(f"Valor Índice Fecha Final:\t{overnight_index_cashflow.get_end_date_index():,.8f}")
print(f"Valor Tasa Eq:\t\t\t{overnight_index_cashflow.get_rate_value():.4%}")
print(f"Tipo de Tasa:\t\t\t{overnight_index_cashflow.get_type_of_rate()}")
print(f"Moneda:\t\t\t\t{overnight_index_cashflow.ccy()}")
Tipo Cashflow: OvernightIndexCashflow
Nominal: 1,000,000,000
Amortización: 100,000,000
Fecha Inicio Devengo: 2023-11-12
Fecha Final Devengo: 2023-11-18
Fecha Inicio Índice: 2023-11-13
Fecha Final Índice: 2023-11-20
Fecha Pago: 2023-11-20
Valor Índice Fecha Inicio: 1.00000000
Valor Índice Fecha Final: 1.00000000
Valor Tasa Eq: 0.0000%
Tipo de Tasa: LinAct360
Moneda: USD
Setters¶
Se fijan los valores inicial y final del índice.
valor_indice_inicio = 10_000.0
overnight_index_cashflow.set_start_date_index(valor_indice_inicio)
print(f"Valor Índice Fecha Inicio: {overnight_index_cashflow.get_start_date_index():,.2f}")
Valor Índice Fecha Inicio: 10,000.00
valor_indice_final = valor_indice_inicio * (1 + .051234 * 7 / 360.0)
overnight_index_cashflow.set_end_date_index(valor_indice_final)
print(f"Valor Índice Fecha Final: {overnight_index_cashflow.get_end_date_index():,.8f}")
Valor Índice Fecha Final: 10,009.96216667
Decimales para el cálculo de la tasa equivalente.
decimales_para_tasa_eq = 4
overnight_index_cashflow.set_eq_rate_decimal_places(decimales_para_tasa_eq)
print(f"Nueva Tasa Eq: {overnight_index_cashflow.get_rate_value():.4%}")
Nueva Tasa Eq: 5.9800%
decimales_para_tasa_eq = 6
overnight_index_cashflow.set_eq_rate_decimal_places(decimales_para_tasa_eq)
print(f"Nueva Tasa Eq: {overnight_index_cashflow.get_rate_value():.4%}")
Nueva Tasa Eq: 5.9773%
Nuevo nocional.
new_notional = 123_456
overnight_index_cashflow.set_nominal(new_notional)
print(f"Nuevo Nocional: {overnight_index_cashflow.get_nominal():,.2f}")
Nuevo Nocional: 123,456.00
Nueva amortización.
new_amortization = 100_000
overnight_index_cashflow.set_amortization(new_amortization)
print(f"Nueva Amortización: {overnight_index_cashflow.get_amortization():,.2f}")
Nueva Amortización: 100,000.00
Cálculos¶
Tasa equivalente del período.
print(f"Valor Tasa Equivalente Todo el Período: {overnight_index_cashflow.get_rate_value():.4%}")
check = round((
valor_indice_final / valor_indice_inicio - 1
) * 360.0 / fecha_inicio_devengo.day_diff(fecha_final_devengo), decimales_para_tasa_eq)
print(f"Check: {check:.4%}")
Valor Tasa Equivalente Todo el Período: 5.9773%
Check: 5.9773%
Se cambian las fechas utilizadas para el cálculo de la tasa equivalente.
overnight_index_cashflow.set_dates_for_eq_rate(qcf.DatesForEquivalentRate.INDEX)
print(f"Valor Tasa Equivalente Todo el Período: {overnight_index_cashflow.get_rate_value():.4%}")
check = round((
valor_indice_final / valor_indice_inicio - 1
) * 360.0 / fecha_inicio_indice.day_diff(fecha_final_indice), decimales_para_tasa_eq)
print(f"Check: {check:.4%}")
Valor Tasa Equivalente Todo el Período: 5.1234%
Check: 5.1234%
Método accrued_interest
. Este método tiene dos sobrecargas. En la primera, el valor del índice se entrega explícitamente. En el ejemplo se utilizan las dos opciones para el parámetro dates_for_eq_rate
.
# Volvemos el nocional y la amortización al valor inicial
overnight_index_cashflow.set_nominal(nocional)
overnight_index_cashflow.set_amortization(amort)
fecha_devengo = qcf.QCDate(17, 11, 2023)
valor_indice_devengo = 10_000.0 * (1 + .051234 * 4 / 360)
overnight_index_cashflow.set_dates_for_eq_rate(qcf.DatesForEquivalentRate.ACCRUAL)
print(f"Interés devengado (dates_for_eq_rate = ACCRUAL): {overnight_index_cashflow.accrued_interest(fecha_devengo, valor_indice_devengo): ,.4f}")
tasa = round((
valor_indice_devengo / valor_indice_inicio - 1
) * 360.0 / fecha_inicio_devengo.day_diff(fecha_devengo), decimales_para_tasa_eq)
print(f"Check: {nocional * fecha_inicio_devengo.day_diff(fecha_devengo) * tasa / 360.0:,.4f}\n")
Interés devengado (dates_for_eq_rate = ACCRUAL): 569,263.8889
Check: 569,263.8889
overnight_index_cashflow.set_dates_for_eq_rate(qcf.DatesForEquivalentRate.INDEX)
print(f"Interés devengado (dates_for_eq_rate = INDEX): {overnight_index_cashflow.accrued_interest(fecha_devengo, valor_indice_devengo): ,.4f}")
tasa = round((
valor_indice_devengo / valor_indice_inicio - 1
) * 360.0 / fecha_inicio_indice.day_diff(fecha_devengo), decimales_para_tasa_eq)
print(f"Check: {nocional * fecha_inicio_devengo.day_diff(fecha_devengo) * tasa / 360.0:,.4f}")
Interés devengado (dates_for_eq_rate = INDEX): 711,583.3333
Check: 711,583.3333
La segunda sobrecarga de accrued_interest
permite empaquetar el valor del índice a fecha de devengo en un objeto de tipo time_series
.
data = qcf.time_series()
data[fecha_devengo] = valor_indice_devengo
overnight_index_cashflow.set_dates_for_eq_rate(qcf.DatesForEquivalentRate.ACCRUAL)
# El segundo parámetro de accrued_interest es ahora data
print(f"Interés devengado (dates_for_eq_rate = ACCRUAL): {overnight_index_cashflow.accrued_interest(fecha_devengo, data): ,.4f}")
# En este caso, en los dias para el cálculo de la tasa equivalente
# coinciden con los días de devengo, aunque cualquiera de las dos
# fechas de devengo sea inhábil.
dias_calculo_tasa_eq = fecha_inicio_devengo.day_diff(fecha_devengo)
tasa = (valor_indice_devengo / valor_indice_inicio - 1) * 360.0 / dias_calculo_tasa_eq
tasa = round(tasa, decimales_para_tasa_eq)
dias_devengo = dias_calculo_tasa_eq
print(f"Check: {nocional * tasa * dias_devengo / 360.0:,.4f}\n")
overnight_index_cashflow.set_dates_for_eq_rate(qcf.DatesForEquivalentRate.INDEX)
Interés devengado (dates_for_eq_rate = ACCRUAL): 569,263.8889
Check: 569,263.8889
# El segundo parámetro de accrued_interest es ahora data
print(f"Interés devengado (dates_for_eq_rate = INDEX): {overnight_index_cashflow.accrued_interest(fecha_devengo, data): ,.4f}")
# En este caso, en los días para el cálculo de la tasa equivalente
# se utiliza las fecha de inicio del índice.
dias_calculo_tasa_eq = fecha_inicio_indice.day_diff(fecha_devengo)
tasa = (valor_indice_devengo / valor_indice_inicio - 1) * 360.0 / dias_calculo_tasa_eq
tasa = round(tasa, decimales_para_tasa_eq)
# Para el devengo siempre se utiliza, los días de devengo
print(f"Check: {nocional * tasa * dias_devengo / 360.0:,.4f}\n")
Interés devengado (dates_for_eq_rate = INDEX): 711,583.3333
Check: 711,583.3333
Método amount
overnight_index_cashflow.set_dates_for_eq_rate(qcf.DatesForEquivalentRate.ACCRUAL)
print(f"Amount (ACCRUAL): {overnight_index_cashflow.amount():,.4f}")
dias_calculo_tasa_eq = fecha_inicio_devengo.day_diff(fecha_final_devengo)
tasa = (valor_indice_final / valor_indice_inicio - 1) * 360.0 / dias_calculo_tasa_eq
dias_devengo = dias_calculo_tasa_eq
print(f"Check: {nocional * (1 + tasa * dias_devengo / 360.0):,.4f}\n")
Amount (ACCRUAL): 100,996,216.6667
Check: 1,000,996,216.6667
overnight_index_cashflow.set_dates_for_eq_rate(qcf.DatesForEquivalentRate.INDEX)
print(f"Amount (INDEX): {overnight_index_cashflow.amount():,.4f}")
dias_calculo_tasa_eq = fecha_inicio_indice.day_diff(fecha_final_indice)
tasa = (valor_indice_final / valor_indice_inicio - 1) * 360.0 / dias_calculo_tasa_eq
print(f"Check: {nocional * (1 + tasa * dias_devengo / 360.0):,.4f}\n")
Amount (INDEX): 100,853,900.0000
Check: 1,000,853,900.0000
Funciones show
y get_column_names
¶
Al igual que en casos anteriores, juntando estas dos funciones se obtiene una representación tabular del flujo usando pandas.DataFrame
.
df = pd.DataFrame(
[qcf.show(overnight_index_cashflow)],
columns=qcf.get_column_names(overnight_index_cashflow.get_type())
)
df.style.format({
'nocional':'{:,.2f}',
'amortizacion':'{:,.2f}',
'amortizacion_moneda_pago':'{:,.2f}',
'interes':'{:,.2f}',
'interes_moneda_pago':'{:,.2f}',
'flujo':'{:,.2f}',
'flujo_moneda_pago':'{:,.2f}',
'valor_tasa_equivalente':'{:.6%}',
'spread':'{:.2%}',
'valor_indice_inicial':'{:,.2f}',
'valor_indice_final':'{:,.2f}',
})
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 | 2023-11-12 | 2023-11-18 | 2023-11-13 | 2023-11-20 | 2023-11-20 | 1,000,000,000.00 | 100,000,000.00 | True | USD | INDICE | 10,000.00 | 10,009.96 | 5.123400% | LinAct360 | 1,195,466.67 | 101,195,466.67 | 0.00% | 1.000000 |
Overnight Index Multi Currency Cashflow¶
Un objeto de tipo OvernightIndexMultiCurrencyCashflow
hereda de OvernightIndexCashflow
y representa un flujo de caja del tipo de la pata flotante de un swap ICPCLP (cámara promedio) de Chile usando cualquier tipo de índice similar (por ejemplo SOFRINDX), cualquier moneda de nocional, pero con flujos de caja en una moneda distinta a la del nocional, por ejemplo un ICPCLP con contraparte en USA que compensa en USD. Al heredar de OvernightIndexCashflow
, también permite definir en forma independiente a start_date
y end_date
las fechas inicial y final utilizadas para los valores del índice. Para dar de alta uno de estos objetos se requiere:
QCDate
: fecha inicio devengo (para la aplicación de la tasa)QCDate
: fecha final devengo (para la aplicación de la tasa)QCDate
: fecha inicio índice (para el valor del índice)QCDate
: fecha final índice (para el valor del índice)QCDate
: fecha de pagoQCCurrency
: moneda del nocionalfloat
: nocional (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalfloat
: spread aditivo a aplicar a la fijación de la tasa equivalente (TNA en el caso de un ICPCLP)float
: spread multiplicativo o gearing a aplicar a la fijación de la tasa equivalenteQCInterestRate
: con este objeto se especifica en qué convención se calcula la tasa equivalentestring
: nombre del índice overnight a utilizarunsigned int
: número de decimales a utilizar para determinar la tasa equivalenteDatesForEquivalentRate
: enum que indica qué fechas se utilizan en el cálculo de la tasa equivalente.
Hasta acá son los mismos argumentos necesarios para construir un OvernightIndexCashflow
. Se añaden los siguientes argumentos:
- QCDate
: fecha de fixing del índice de tipo de cambio. Esta fecha se refiere a la fecha de publicación del índice, no a la fecha de fixing en sentido financiero.
- QCCurrency
: moneda de pago de los flujos de caja
- FXRateIndex
: índice de tipo de cambio utilizado para la conversión de los flujos a moneda de pago
Ejemplo¶
fecha_inicio_devengo = qcf.QCDate(13, 11, 2023)
# Notar que la fecha final de devengo es sábado
fecha_final_devengo = qcf.QCDate(18, 11, 2023)
fecha_inicio_indice = qcf.QCDate(13, 11, 2023)
# Notar que la fecha final de índice es el viernes
fecha_final_indice = qcf.QCDate(17, 11, 2023)
# La fecha de pago es el lunes siguiente
fecha_pago = qcf.QCDate(20, 11, 2023)
moneda_nocional = qcf.QCUSD()
nocional = 10_000_000.0
amort = 1_000_000.0
amort_es_flujo = True
spread = 0.0
gearing = 1.0
tasa = qcf.QCInterestRate(0.0, qcf.QCAct360(), qcf.QCLinearWf())
nombre_indice = 'INDICE'
num_decimales = 8
dates_for_eq_rate = qcf.DatesForEquivalentRate.ACCRUAL
Parámetros para la parte MultiCurrency.
fecha_fixing_fx_index = fecha_final_devengo
moneda_pago = qcf.QCCLP()
indice_fx = usdclp_obs
overnight_index_mccy_cashflow = qcf.OvernightIndexMultiCurrencyCashflow(
fecha_inicio_devengo,
fecha_final_devengo,
fecha_inicio_indice,
fecha_final_indice,
fecha_pago,
moneda_nocional,
nocional,
amort,
amort_es_flujo,
spread,
gearing,
tasa,
nombre_indice,
num_decimales,
dates_for_eq_rate,
fecha_fixing_fx_index,
moneda_pago,
indice_fx,
)
Nuevos Getters¶
print(f"Tipo de flujo: {overnight_index_mccy_cashflow.get_type()}")
Tipo de flujo: OvernightIndexMultiCurrencyCashflow
Este getter retorna todo el objeto FXRateIndex
.
overnight_index_mccy_cashflow.get_fx_rate_index()
<qcfinancial.FXRateIndex at 0x112b09b30>
print(f"Código del índice FX: {overnight_index_mccy_cashflow.get_fx_rate_index_code()}")
Código del índice FX: USDOBS
print(f"Valor del índice FX: {overnight_index_mccy_cashflow.get_fx_rate_index_value():,.2f}")
Valor del índice FX: 1.00
Nuevos Cálculos¶
Primero se fijan los valores del índice overnight.
valor_indice_inicio = 1.0
valor_indice_final = 1 + .1234 * 4 / 360 # Suponemos un valor constante de 12.34% por 4 días del índice
overnight_index_mccy_cashflow.set_start_date_index(valor_indice_inicio)
overnight_index_mccy_cashflow.set_end_date_index(valor_indice_final)
print(f"Amount: {overnight_index_mccy_cashflow.amount():,.2f}")
Amount: 1,013,711.11
print(f"Interés en moneda de pago: {overnight_index_mccy_cashflow.settlement_ccy_interest():,.0f}")
Interés en moneda de pago: 13,711
print(f"Amortización en moneda de pago {overnight_index_mccy_cashflow.settlement_ccy_amortization():,.0f}")
Amortización en moneda de pago 1,000,000
Funciones show
y get_column_names
¶
Se envuelve el resultado de la función show
en un pd.DataFrame
.
df = pd.DataFrame(
[qcf.show(overnight_index_mccy_cashflow),],
columns=qcf.get_column_names("OvernightIndexMultiCurrencyCashflow", "")
)
df.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 | 2023-11-13 | 2023-11-18 | 2023-11-13 | 2023-11-17 | 2023-11-20 | 10,000,000.00 | 1,000,000.00 | True | USD | INDICE | 1.000000 | 1.001371 | 9.8720% | LinAct360 | 13,711.11 | 1,013,711.11 | 0.0000% | 1.00 | CLP | USDOBS | 2023-11-18 | 1.00 | 13,711.00 | 1,000,000.00 | 1,013,711.00 |
Nuevo Setter¶
Valor del índice de tipo de cambio.
overnight_index_mccy_cashflow.set_fx_rate_index_value(900.0)
Ver el efecto en las últimas dos columnas.
pd.DataFrame(
[qcf.show(overnight_index_mccy_cashflow),],
columns=qcf.get_column_names("OvernightIndexMultiCurrencyCashflow", "")
).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 | 2023-11-13 | 2023-11-18 | 2023-11-13 | 2023-11-17 | 2023-11-20 | 10,000,000.00 | 1,000,000.00 | True | USD | INDICE | 1.000000 | 1.001371 | 9.8720% | LinAct360 | 13,711.11 | 1,013,711.11 | 0.0000% | 1.00 | CLP | USDOBS | 2023-11-18 | 900.00 | 12,339,999.00 | 900,000,000.00 | 912,339,999.00 |
Compounded Overnight Rate Cashflow 2¶
Un objeto de tipo CompoundedOvernightRateCashflow2
representa un flujo de caja calculado como un cupón de la pata flotante de un OIS sobre cualquier índice overnight (SOFR, FF, ESTR). Para dar de alta uno de estos objetos se requiere:
InterestRateIndex
: el índice de tasa de interés prefijadoQCDate
: fecha inicio (para la aplicación de la tasa)QCDate
: fecha final (para la aplicación de la tasa)QCDate
: fecha de pagoDateList
: fechas de fixing del índicefloat
: nominal (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalQCCurrency
: moneda del nocional de la operaciónfloat
: spread aditivo a aplicar a la fijación de la tasa equivalentefloat
: spread multiplicativo o gearing a aplicar a la fijación de la tasa equivalenteQCInterestRate
: permite especificar cuál es la convención de cálculo de la tasa equivalenteunsigned int
: número de decimales a usar en el cálculo de la tasa equivalente. Por ejemplo para 0.12345678% este valor debe ser 10.unsigned int
: número de días de lookbackunsigned int
: número de días de lockout
El efecto de lookback y lockout aún no está implementado.
Constructor¶
Se da de alta un índice overnight ficiticio de test.
codigo = "OITEST"
lin_act360 = qcf.QCInterestRate(0.0, act360, lin_wf)
fixing_lag = qcf.Tenor("0d")
tenor = qcf.Tenor("1d")
fixing_calendar = aux.get_business_calendar("US", range(2024, 2035))
settlement_calendar = fixing_calendar
oitest = qcf.InterestRateIndex(
codigo,
lin_act360,
fixing_lag,
tenor,
fixing_calendar,
settlement_calendar,
usd
)
Al dar de alta directamente este cashflow es necesario entregar explícitamente las fechas de fijación. En el capítulo relacionado a construcción de qcf.Leg
veremos cómo este proceso se simplifica.
fixing_dates = qcf.DateList()
fixing_dates.append(qcf.QCDate(27, 12, 2021))
fixing_dates.append(qcf.QCDate(28, 12, 2021))
fixing_dates.append(qcf.QCDate(29, 12, 2021))
fixing_dates.append(qcf.QCDate(30, 12, 2021))
Damos de alta las variables que faltan.
fecha_inicio = qcf.QCDate(27, 12, 2021)
fecha_final = qcf.QCDate(31, 12, 2021)
fecha_pago = qcf.QCDate(2, 1, 2022)
nocional = 10_000_000.0
amortizacion = 100_000.0
amort_is_cashflow = True
notional_currency = qcf.QCUSD()
spread = 0.001
gearing = 1.5
interest_rate = qcf.QCInterestRate(0.0, qcf.QCAct360(), qcf.QCLinearWf())
eq_rate_decimal_places = 8
Se da de alta el cashflow.
cor_cashflow_2 = qcf.CompoundedOvernightRateCashflow2(
oitest,
fecha_inicio,
fecha_final,
fecha_pago,
fixing_dates,
nocional,
amortizacion,
amort_is_cashflow,
notional_currency,
spread,
gearing,
interest_rate,
eq_rate_decimal_places,
lookback := 0,
lockout := 0,
)
Getters¶
print(f"Type of cashflow:\t\t{cor_cashflow_2.get_type()}")
print(f"Fecha Inicio:\t\t\t{cor_cashflow_2.get_start_date()}")
print(f"Fecha Final:\t\t\t{cor_cashflow_2.get_end_date()}")
print(f"Fecha Pago:\t\t\t{cor_cashflow_2.get_settlement_date()}")
print(f"Nocional:\t\t\t{cor_cashflow_2.get_nominal():,.0f}")
print(f"Amortización:\t\t\t{cor_cashflow_2.get_amortization():,.0f}")
print(f"Moneda del nocional:\t\t{cor_cashflow_2.ccy()}")
print(f"Spread:\t\t\t\t{cor_cashflow_2.get_spread():.2%}")
print(f"Gearing:\t\t\t{cor_cashflow_2.get_gearing():.2f}")
print(f"Número de decimales de tasa:\t{cor_cashflow_2.get_eq_rate_decimal_places()}")
Type of cashflow: CompoundedOvernightRateCashflow2
Fecha Inicio: 2021-12-27
Fecha Final: 2021-12-31
Fecha Pago: 2022-01-02
Nocional: 10,000,000
Amortización: 100,000
Moneda del nocional: USD
Spread: 0.10%
Gearing: 1.50
Número de decimales de tasa: 8
print("Fechas de fijación:")
for d in cor_cashflow_2.get_fixing_dates():
print(d)
Fechas de fijación:
2021-12-27
2021-12-28
2021-12-29
2021-12-30
Setters¶
cor_cashflow_2.set_notional(1_000)
print(f"Nocional: {cor_cashflow_2.get_nominal():,.0f}")
Nocional: 1,000
cor_cashflow_2.set_amortization(0)
print(f"Amortización: {cor_cashflow_2.get_amortization()}")
Amortización: 0.0
Se reversa el ejemplo.
cor_cashflow_2.set_notional(nocional)
cor_cashflow_2.set_amortization(amortizacion)
Cálculos¶
El accrued_fixing
corresponde a la fijación de tasa equivalente en una fecha anterior a la fecha final del cashflow. Para el cálculo de accrued_fixing
se requiere un objeto de tipo TimeSeries
que contenga los datos históricos del índice overnight.
ts = qcf.time_series()
ts[qcf.QCDate(27, 12, 2021)] = 0.01
ts[qcf.QCDate(28, 12, 2021)] = 0.02
ts[qcf.QCDate(29, 12, 2021)] = 0.03
ts[qcf.QCDate(30, 12, 2021)] = 0.04
print(f"Accrued fixing: {cor_cashflow_2.accrued_fixing(qcf.QCDate(29, 12, 2021), ts):.6%}")
Accrued fixing: 1.500028%
check = ((1 + 0.01 / 360) * (1 + 0.02 / 360.0) - 1) * 360 / 2.0
print(f"Check: {check:.6%}")
Check: 1.500028%
El accrued_interest
corresponde a los intereses devengados en una fecha anterior a la fecha final del cashflow. Para el cálculo de accrued_interest
también se requiere un objeto de tipo TimeSeries
que contenga los datos históricos del índice overnight.
print(f"Accrued interest: {cor_cashflow_2.accrued_interest(qcf.QCDate(29, 12, 2021), ts):,.2f}")
Accrued interest: 1,305.58
check = (
cor_cashflow_2.get_nominal()
* (cor_cashflow_2.accrued_fixing(qcf.QCDate(29, 12, 2021), ts) * gearing + spread) * 2 / 360.0
)
print(f"Check: {check:,.2f}")
Check: 1,305.58
Para que el método amount
retorne el resultado correcto, es necesario ejecutar primero el método fixings
que realiza la fijación de todas las tasas overnight necesarias.
fixing = cor_cashflow_2.fixing(ts)
print(f"Fixing: {fixing:.6%}")
Fixing: 2.500243%
De esa forma.
print(f"Amount: {cor_cashflow_2.amount():,.2f}")
Amount: 104,278.18
check = ((1 + 0.01 / 360) * (1 + 0.02 / 360.0) * (1 + 0.03 / 360.0) * (1 + 0.04 / 360.0) - 1) * 360 / 4.0
print(f"Check: {nocional * (check * gearing + spread) * 4 / 360 + amortizacion:,.2f}")
Check: 104,278.18
Se puede calcular el interés que depende del spread.
print(f"Interés del spread: {cor_cashflow_2.interest_from_spread():,.2f}")
Interés del spread: 111.11
print(f"Check: {nocional * spread * 4 / 360:,.2f}")
Check: 111.11
Funciones show
y get_column_names
¶
df = pd.DataFrame(
[qcf.show(cor_cashflow_2)],
columns=qcf.get_column_names("CompoundedOvernightRateCashflow2", "")
)
df.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 | 2021-12-27 | 2021-12-31 | 2022-01-02 | 10,000,000.00 | 100,000.00 | 4,278.18 | True | 104,278.18 | USD | OITEST | LinAct360 | 2.5002% | 0.1000% | 1.50 |
Compounded Overnight Rate Multi Currency Cashflow 2¶
Un objeto de tipo CompoundedOvernightRateMultiCurrencyCashflow2
representa un flujo de caja calculado como un cupón de la pata flotante de un OIS sobre cualquier índice overnight (SOFR, FF, EONIA) con la característica adicional de liquidar sus flujos en una moneda distina a la del nocional. Para dar de alta uno de estos objetos se requiere:
InterestRateIndex
: el índice de tasa de interés prefijadoQCDate
: fecha inicio (para la aplicación de la tasa)QCDate
: fecha final (para la aplicación de la tasa)QCDate
: fecha de pagoDateList
: fechas de fixing del índicefloat
: nominal (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalQCCurrency
: moneda del nocional de la operaciónfloat
: spread aditivo a aplicar a la fijación de la tasa equivalentefloat
: spread multiplicativo o gearing a aplicar a la fijación de la tasa equivalenteQCInterestRate
: permite especificar cuál es la convención de cálculo de la tasa equivalenteunsigned int
: número de decimales a usar en el cálculo de la tasa equivalente. Por ejemplo para 0.12345678% este valor debe ser 10.unsigned int
: número de días de lookbackunsigned int
: número de días de lockout
Estos argumentos son los heredados de un CompoundedOvernightRateCashflow
. También en este caso, el efecto de lookback y lockout aún no está implementado.
A estos argumentos se debe agregar:
QCDate
: fecha de fixing del índice de tipo de cambio. Esta fecha se refiere a la fecha de publicación del índice, no a la fecha de fixing en sentido financiero.QCCurrency
: moneda de pago de los flujos de cajaFXRateIndex
: índice de tipo de cambio utilizado para la conversión de los flujos a moneda de pago
Constructor¶
Se da de alta un índice overnight ficiticio de test.
codigo = "OITEST"
lin_act360 = qcf.QCInterestRate(0.0, act360, lin_wf)
fixing_lag = qcf.Tenor("0d")
tenor = qcf.Tenor("1d")
fixing_calendar = scl
settlement_calendar = scl
oitest = qcf.InterestRateIndex(
codigo,
lin_act360,
fixing_lag,
tenor,
fixing_calendar,
settlement_calendar,
usd
)
Al dar de alta directamente este cashflow es necesario entregar explícitamente las fechas de fijación. En el capítulo relacionado a construcción de qcf.Leg
veremos cómo este proceso se simplifica.
fixing_dates = qcf.DateList()
fixing_dates.append(qcf.QCDate(27, 12, 2021))
fixing_dates.append(qcf.QCDate(28, 12, 2021))
fixing_dates.append(qcf.QCDate(29, 12, 2021))
fixing_dates.append(qcf.QCDate(30, 12, 2021))
Damos de alta las variables que faltan.
fecha_inicio = qcf.QCDate(27, 12, 2021)
fecha_final = qcf.QCDate(31, 12, 2021)
fecha_pago = qcf.QCDate(2, 1, 2022)
nocional = 10_000_000.0
amortizacion = 100_000.0
amort_is_cashflow = True
notional_currency = qcf.QCUSD()
spread = 0.001
gearing = 1.5
interest_rate = qcf.QCInterestRate(0.0, qcf.QCAct360(), qcf.QCLinearWf())
eq_rate_decimal_places = 8
# ---------------------Para el MultiCurrency ----------------------------
fecha_fixing_fx = fecha_pago
moneda_pago = qcf.QCCLP()
Se da de alta el objeto.
cor_cashflow_mccy_2 = qcf.CompoundedOvernightRateMultiCurrencyCashflow2(
oitest,
fecha_inicio,
fecha_final,
fecha_pago,
fixing_dates,
nocional,
amortizacion,
amort_is_cashflow,
notional_currency,
spread,
gearing,
interest_rate,
eq_rate_decimal_places,
lookback,
lockout,
fecha_fixing_fx,
moneda_pago,
usdclp_obs,
)
Nuevos Getters¶
print(f"Fx Rate Index: {cor_cashflow_mccy_2.get_fx_rate_index()}")
print(f"Fx Rate Index Value: {cor_cashflow_mccy_2.get_fx_rate_index_value()}")
print(f"Fx Rate Index Code: {cor_cashflow_mccy_2.get_fx_rate_index_code()}")
print(f"Fx Rate Index Fxing Date: {cor_cashflow_mccy_2.get_fx_rate_index_fixing_date()}")
Fx Rate Index: <qcfinancial.FXRateIndex object at 0x112b09b30>
Fx Rate Index Value: 1.0
Fx Rate Index Code: USDOBS
Fx Rate Index Fxing Date: 2022-01-02
Nuevo Setter¶
cor_cashflow_mccy_2.set_fx_rate_index_value(900.0)
print(f"Fx Rate Index Value: {cor_cashflow_mccy_2.get_fx_rate_index_value()}")
Fx Rate Index Value: 900.0
Nuevos Cálculos¶
print(f"Interest: {cor_cashflow_mccy_2.interest(ts):,.2f}")
Interest: 4,278.18
print(f"To settlement currency: {cor_cashflow_mccy_2.to_settlement_currency(cor_cashflow_mccy_2.interest(ts)):,.0f}")
To settlement currency: 3,850,364
Funciones show
y get_column_names
¶
df = pd.DataFrame(
[qcf.show(cor_cashflow_mccy_2)],
columns=qcf.get_column_names("CompoundedOvernightRateMultiCurrencyCashflow2", "")
)
df.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 | 2021-12-27 | 2021-12-31 | 2022-01-02 | 10,000,000.00 | 100,000.00 | 4,278.18 | True | 104,278.18 | USD | OITEST | LinAct360 | 0.1000% | 1.50 | 2.5002% | CLP | USDOBS | 2022-01-02 | 900.00 | 3,850,364.60 | 90,000,000.00 | 93,850,364.50 |
Icp Clf Cashflow¶
Un objeto de tipo IcpClfCashflow
representa un flujo de caja calculado como un cupón de la pata flotante de un swap ICP (cámara promedio) en UF de Chile. Para dar de alta uno de estos objetos se requiere:
QCDate
: fecha inicio (para la aplicación de la tasa)QCDate
: fecha final (para la aplicación de la tasa)QCDate
: fecha de pagofloat
: nominal (monto al que se le aplica la tasa)float
: amortización (eventual flujo de caja que corresponde a una porción del nominal)bool
: indica si la amortización anterior es un flujo de caja o sólo una disminución de nominalfloat
: spread aditivo a aplicar a la fijación de la TRAfloat
: spread multiplicativo o gearing a aplicar a la fijación de la TRAvector<float>
: objetodouble_vec
(en Python) que contiene ICP Inicio, ICP Final, UF Inicio, UF Final (se debe respetar el orden)
Recordar que TRA significa Tasa Real Anual y se determina utilizando los valores del índice ICP y los valores de la UF en la fecha de inicio y fecha final del IcpClfCashflow
.
Constructor¶
Parámetros iniciales.
fecha_inicio = qcf.QCDate(20, 9, 2018)
fecha_final = qcf.QCDate(20, 9, 2019)
fecha_pago = qcf.QCDate(23, 9, 2019)
nominal = 300_000.0
amort = 100_000.0
spread = 0.0
gearing = 1.0
icp_uf = qcf.double_vec()
# Los primeros dos valores corresponden a icp_inicial e icp_final.
# Los segundos dos valores corresponden a uf_inicial y uf_final
icp_uf.append(10_000.0)
icp_uf.append(10_250.0)
icp_uf.append(35_000.0)
icp_uf.append(35_500.0)
Alta del objeto.
icp_clf_cashflow = qcf.IcpClfCashflow(
fecha_inicio,
fecha_final,
fecha_pago,
nominal,
amort,
True,
spread,
gearing,
icp_uf
)
Getters¶
print("Fecha Inicio:", icp_clf_cashflow.get_start_date())
print("Fecha Final:", icp_clf_cashflow.get_end_date())
print(f"ICP Fecha Inicio: {icp_clf_cashflow.get_start_date_icp():,.2f}")
print(f"ICP Fecha Final: {icp_clf_cashflow.get_end_date_icp():,.2f}")
print(f"UF Fecha Inicio: {icp_clf_cashflow.get_start_date_uf():,.2f}")
print(f"UF Fecha Final: {icp_clf_cashflow.get_end_date_uf():,.2f}")
print(f"Valor TRA Todo el Período: {icp_clf_cashflow.get_rate_value():.4%}")
tna = icp_clf_cashflow.get_tna(fecha_final, 10_250.0)
dias = fecha_inicio.day_diff(fecha_final)
tra = ((1 + tna * dias / 360.0) * icp_uf[2]/ icp_uf[3] - 1) * 360.0 / dias
print(f"Check TRA: {round(tra, 6):.4%}")
print(f"Nominal: {icp_clf_cashflow.get_nominal():,.0f}")
print(f"Amortización: {icp_clf_cashflow.get_amortization():,.0f}")
print("Tipo de Tasa:", icp_clf_cashflow.get_type_of_rate())
print("Moneda:", icp_clf_cashflow.ccy())
Fecha Inicio: 2018-09-20
Fecha Final: 2019-09-20
ICP Fecha Inicio: 10,000.00
ICP Fecha Final: 10,250.00
UF Fecha Inicio: 35,000.00
UF Fecha Final: 35,500.00
Valor TRA Todo el Período: 1.0461%
Check TRA: 1.0461%
Nominal: 300,000
Amortización: 100,000
Tipo de Tasa: LinAct360
Moneda: CLF
Setters¶
decimales_para_tra = 8
icp_clf_cashflow.set_tra_decimal_places(decimales_para_tra)
print(f"Nueva TRA: {icp_clf_cashflow.get_rate_value():.6%}")
nuevo_nominal = 100_000.0
icp_clf_cashflow.set_nominal(nuevo_nominal)
print(f"Nuevo Nominal: {icp_clf_cashflow.get_nominal():,.0f}")
nueva_amortizacion = 10_000.0
icp_clf_cashflow.set_amortization(nueva_amortizacion)
print(f"Nueva Amortización: {icp_clf_cashflow.get_amortization():,.0f}")
nuevo_icp_inicio = 20_000.0
icp_clf_cashflow.set_start_date_icp(nuevo_icp_inicio)
print(f"Nuevo ICP Inicio: {icp_clf_cashflow.get_start_date_icp():,.2f}")
nuevo_icp_final = 20_500.0
icp_clf_cashflow.set_end_date_icp(nuevo_icp_final)
print(f"Nuevo ICP Final: {icp_clf_cashflow.get_end_date_icp():,.2f}")
print(f"Check TNA Final: {icp_clf_cashflow.get_tna(fecha_final, nuevo_icp_final):.6%}")
Nueva TRA: 1.046054%
Nuevo Nominal: 100,000
Nueva Amortización: 10,000
Nuevo ICP Inicio: 20,000.00
Nuevo ICP Final: 20,500.00
Check TNA Final: 2.470000%
Funciones show
y get_column_names
¶
df = pd.DataFrame([qcf.show(icp_clf_cashflow)], columns=qcf.get_column_names("IcpClfCashflow", ""))
df.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 | 2018-09-20 | 2019-09-20 | 2019-09-23 | 100,000.00 | 10,000.00 | True | 11,060.58 | CLF | 20,000.00 | 20,500.00 | 35,000.00 | 35,500.00 | 1.0461% | 1,060.58 | 0.0000% | 1.00 | LinAct360 | 392,650,680.00 |