def diferencia_dias_convencion(convencion, fechaini, fechafin): """Entrega la diferencia de días entre fechaini y fechafin según la convencion. Es importante para el caso 30/360, ya que usa 30/360 USA :param convencion: Sring indicando la convención :param fechaini: datetime.date con fecha inicial :param fechafin: datetime.date con fecha final :return: int cantidad de días entre fechaini y fechafin con la convención """ y1 = fechaini.year y2 = fechafin.year m1 = fechaini.month m2 = fechafin.month d1 = fechaini.day d2 = fechafin.day conv = cast_convencion(convencion) if conv == "30/360": if add_days(fechaini, 1).day == 1 and m1 == 2: d1 = 30 if add_days(fechafin, 1).day == 1 and m2 == 2: d2 = 30 if d2 == 31 and 31 >= d1 >= 30: d2 = 30 if d1 == 31: d1 = 30 plazo = (360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1)) elif conv in ["ACT360", "LACT360", "ACT365", "ACTACT", "LACT30"]: plazo = (fechafin - fechaini).days else: print("ERROR") pass # todo return plazo
def genera_flujos(fecha, fecha_efectiva, fecha_venc, tasa, frecuencia, convencion, si_principal=1): i = 0 fechai = fecha_venc arr = [] while fechai > fecha and fechai > add_days(fecha_efectiva, 10): arr.append([None] * 7) fecha_cupon_ant = max(delta_frecuencia(fechai, frecuencia, -1), fecha_efectiva) arr[i][0] = fechai arr[i][1] = (1 / factor_descuento(tasa / 100, fecha_cupon_ant, fechai, convencion, 0) - 1) * 100 arr[i][2] = arr[i][0] arr[i][3] = 0 arr[i][4] = arr[i][1] arr[i][5] = 0 if fecha_cupon_ant <= fecha: arr[i][6] = arr[i][1] * (fecha - fecha_cupon_ant).days / (fechai - fecha_cupon_ant).days else: arr[i][6] = 0 if i == 0 and si_principal == 1: arr[i][1] = arr[i][1] + 100 arr[i][3] = arr[i][3] + 100 i += 1 fechai = delta_frecuencia(fechai, frecuencia, -1) arr.reverse() return arr
def genera_flujos(fecha, fecha_efectiva, fecha_venc, tasa, frecuencia, convencion, amortiza=True): i = 0 fechai = fecha_venc arr = [] while fechai > fecha and fechai > add_days(fecha_efectiva, 10): arr.append([None] * 7) fecha_cupon_ant = max(delta_frecuencia(fechai, frecuencia, -1), fecha_efectiva) arr[i][0] = fechai arr[i][1] = (1 / factor_descuento(tasa / 100, fecha_cupon_ant, fechai, convencion, 0) - 1) * 100 arr[i][2] = arr[i][0] arr[i][3] = 0 arr[i][4] = arr[i][1] arr[i][5] = 0 if fecha_cupon_ant <= fecha: arr[i][6] = arr[i][1] * (fecha - fecha_cupon_ant).days / (fechai - fecha_cupon_ant).days else: arr[i][6] = 0 i += 1 fechai = delta_frecuencia(fechai, frecuencia, -1) if amortiza: for i in arr: i[3] += 100/len(arr) i[1] += 100/len(arr) arr.reverse() return arr
def buscar_pivote(self, fecha_pago): """ Funcion encargada de buscar los pivotes entre donde se encuentra la fecha de pago :param fecha_pago: Fecha que se desea pivotear :return: Vector de dos dimensiones con los dos pivotes calculados """ pivotes = self.get_plazos() largo_pivotes = len(pivotes) fecha_valorizacion = self.get_fecha_valorizacion_date() for i in range(largo_pivotes): pos_pivote = pivotes[i] fecha_pivote = add_days(fecha_valorizacion, int(pos_pivote * 360)) # Se encuentra en el primer pivote (caso borde) if i == 0 and fecha_pago < fecha_pivote: return [pivotes[i], pivotes[i]] # Se encuentra entre dos pivotes elif fecha_pivote > fecha_pago: return [pivotes[i - 1], pivotes[i]] # Se encuentra en el ultimo pivote (caso borde) else: return [pivotes[i], pivotes[i]]
def siguiente_habil_pais(fecha, pais, cn): """Retorna el día hábil siguiente a la fecha en el país indicado :param fecha: datetime.date con la fecha que se desea el día hábil siguiente :param pais: String con el código de país ("BR","MX","US"...) :param cn: pyodbc.connect conexión a base de datos :return: datetime.date con el día hábil siguiente """ # Si la fecha es inválida if fecha == datetime.date(1900, 1, 1): return datetime.date(1900, 1, 1) # Países en TdFeriados paises = ["BR", "MX", "US", "CO", "UK", "PE", "CR", "RD"] if pais in paises: # Hábil mínimo y máximo en TdFeriados sql = ("SELECT MAX(fecha) AS maxi, MIN(fecha) AS mini " "FROM dbAlgebra.dbo.TdFeriados " "WHERE Pais='" + pais + "' AND SiHabil=1") else: # elseif pais = 'CL' # Hábil mínimo y máximo en TdIndicadores sql = ("SELECT MAX(fecha) AS maxi, MIN(fecha) AS mini " "FROM dbAlgebra.dbo.TdIndicadores " "WHERE Feriado = 0") # Se consulta y extrae hábil máximo y mínimo fechas = pd.io.sql.read_sql(sql, cn) fecha_max = fechas.iloc[0]['maxi'].to_pydatetime().date() fecha_min = fechas.iloc[0]['mini'].to_pydatetime().date() if fecha_min <= fecha <= fecha_max and pais != "--": sql += " AND Fecha > " + fecha_str(fecha) fecha = pd.io.sql.read_sql(sql, cn).iloc[0]['mini'].to_pydatetime().date() else: fecha = add_days(fecha, 1) # Si es domingo if fecha.weekday() == 6: fecha = add_days(fecha, 1) # Si es sábado elif fecha.weekday() == 5: fecha = add_days(fecha, 2) return fecha
def proyectar_flujo(fecha, hora, fecha_fixing, fecha_pago, mercado, moneda, flujo, moneda_base, cn): plazo_descuento = (fecha_pago - fecha).days fecha_fwd = add_days(fecha, (fecha_fixing - fecha).days) tipo_cambio_fwd = tipo_cambio(moneda, moneda_base, fecha_fwd, hora, cn) tipo_cambio_spot = tipo_cambio(moneda, moneda_base, fecha, hora, cn) factor_desc_mon_base = factor_descuento_monedas(moneda_base, mercado, fecha, hora, plazo_descuento, cn) return flujo / (tipo_cambio_spot/tipo_cambio_fwd * factor_desc_mon_base)
def coeficiente_peso(self, pivote1, pivote2, fecha_actual_flujo): """ Funcion encargada de calcular el alfa_0 :param pivote1: int con el valor del pivote1 en años :param pivote2: int con el valor del pivote2 en años :param fecha_actual_flujo: Fecha con el flujo que se desea pivotear """ fecha_valorizacion = self.get_fecha_valorizacion_date() fecha_pivote1 = add_days(fecha_valorizacion, int(pivote1 * 360)) fecha_pivote2 = add_days(fecha_valorizacion, int(pivote2 * 360)) numerador = diferencia_dias_convencion("ACT360", fecha_pivote1, fecha_actual_flujo) denominador = diferencia_dias_convencion("ACT360", fecha_pivote1, fecha_pivote2) return numerador / denominador
def calcular_historico(self): """ Define el historico de las curvas de TIR en virtud de la moneda y el riesgo del bono. """ curvas = self.curvas_historico() plazos = self.get_plazos() convencion = self.get_convencion() fecha_aux = self.cast_day(self.get_fecha_valorizacion()) nombre_columna = self.get_nombres_columnas() cant_curvas = np.size(curvas, 0) historico = np.zeros([cant_curvas, len(plazos)]) caso_parametro = self.get_parametroInterpolado() # Para cada plazo for i in range(len(plazos)): # Para cada curva for j in range(cant_curvas): if (caso_parametro): tir = self.TIR_p(curvas.iloc[j], [plazos[i]])[0] historico[j][i] = factor_descuento( tir, self.cast_day(self.get_fecha_valorizacion()), add_days(self.cast_day(self.get_fecha_valorizacion()), plazos[i] * 360), convencion, 0) else: fecha_ini = curvas.iloc[j]['Fecha'].date() fecha_fin = add_days(fecha_ini, plazos[i] * 360) c = parsear_curva(curvas.iloc[j]['StrCurva'], fecha_aux) tir = self.analisisCasoBorde(plazos[i], c) historico[j][i] = factor_descuento(tir / 100, fecha_ini, fecha_fin, convencion, 0) self.historicos = pd.DataFrame(historico, columns=nombre_columna) return self.historicos
def delta_frecuencia(fecha, frecuencia, n): fecha_aux = fecha signo = n/abs(n) for i in range(1, abs(n) + 1): fecha_aux = { '6M': add_months(fecha_aux, signo * 6), '3M': add_months(fecha_aux, signo * 3), '1A': add_years(fecha_aux, signo), '28D': add_days(fecha_aux, signo * 28), '1M': add_months(fecha_aux, signo), 'Cero': datetime.date(1900, 1, 1), }.get(cast_frecuencia(frecuencia), "") return fecha_aux
def tipo_cambio_FWD(moneda1, moneda2, mercado, fecha, hora, plazo, cn): res = [0, 0, 0, 0] if plazo <= 0: res[0] = tipo_cambio(moneda1, moneda2, add_days(fecha, plazo), hora, cn) res[1] = res[0] res[2] = 1 res[3] = 1 else: tc = tipo_cambio(moneda1, moneda2, fecha, hora, cn) fd1 = factor_descuento_monedas(moneda1, mercado, fecha, hora, plazo, cn) fd2 = factor_descuento_monedas(moneda2, mercado, fecha, hora, plazo, cn) res[0] = tc * fd1 / fd2 res[1] = tc res[2] = fd1 res[3] = fd2 return res
def factor_descuento_inv_arr(fecha, arr, convencion): for i in range(len(arr)): plazo = plazo_anual_convencion(convencion, fecha, add_days(fecha, int(float(arr[i][0])))) if plazo == 0: arr[i][1] = -1000 else: if convencion == "LACT360" or convencion == "LACT30": arr[i][1] = 100 * ((1 / float(arr[i][1])) - 1) / plazo else: arr[i][1] = 100 * (float(arr[i][1])**(-1 / plazo) - 1) if len(arr) > 0 and arr[0][0] == 0: arr[0][1] = arr[1][1] if len(arr) > 0 and int(float(arr[0][0])) == 0: arr[0][1] = arr[1][1] return arr
def tir_plazos(self, p): """ Calcula el TIR para dos plazos, en base a la moneda y riesgo asociados. :param p: Arreglo con los indices de los plazos a calcular. :return: Arreglo de tamaño 2 con el TIR. """ riesgo = self.get_riesgo() moneda = self.get_moneda() plazos = self.get_plazos() fecha = self.get_fecha_valorizacion() curva = self.curvaBono(fecha) tir = np.zeros(2) if (((riesgo == 'AAA' or riesgo == 'A') and moneda == 'CLP') or moneda == 'USD'): tir = self.TIR_p(curva, [plazos[p[0]], plazos[p[1]]]) else: for i in range(2): c = parsear_curva( curva["StrCurva"][0], add_days(self.cast_day(fecha), int(plazos[p[i]]))) tir[i] = self.interpolacion_log_escalarBonos(plazos[p[i]], c) return tir
def genera_flujos(self): hora = self.hora cn = self.cn fechaActual = self.fechaActual fechaValores = self.fechaValores fondo = self.info_cartera.Fondo[0] id = self.info_cartera.ID[0] fecha_efectiva = pd.to_datetime( datetime.datetime.strptime( self.info_cartera.FechaEfectiva[0].split(" ")[0], "%d/%m/%Y").strftime("%Y-%m-%d")).date() fecha_venc = pd.to_datetime( pd.to_datetime( datetime.datetime.strptime( self.info_cartera.FechaVenc[0].split(" ")[0], "%d/%m/%Y").strftime("%Y-%m-%d")).date()).date() ajuste_feriados = self.info_cartera.AjusteFeriados[0] paises_feriados = ajuste_feriados.split(',') moneda = self.info_cartera.MonedaActivo[0] if self.info_cartera.TipoTasaActivo[0] == 'Fija': factor_recibo_fijo = 1 tasa = self.info_cartera.TasaActivo[0] else: factor_recibo_fijo = -1 tasa = self.info_cartera.TasaPasivo[0] #tasa = float(tasa.replace(",",".")) nocional = self.info_cartera.NocionalActivo[0] frecuencia = cast_frecuencia(self.info_cartera.FrecuenciaActivo[0]) if frecuencia == cast_frecuencia("Semi annual"): convencion = "ACT360" else: convencion = "LACT360" flujos_f = genera_flujos(max(fechaActual, fecha_efectiva), fecha_efectiva, fecha_venc, tasa, frecuencia, convencion) fecha_cupon = flujos_f[0][0] fecha_aux = delta_frecuencia(fecha_cupon, frecuencia, -1) fecha_aux = max(fecha_aux, fecha_efectiva) fecha_cupon_anterior = ultimo_habil_pais(fecha_aux, "CL", cn) if fechaActual < fecha_cupon_anterior: vpv = 1 else: vpv = ( "SELECT ICP1.ICP / ICP0.ICP AS Cupon FROM (SELECT ICP FROM dbAlgebra.dbo.TdIndicadores " "WHERE (Fecha = " + fecha_str(fechaValores) + ")) ICP1 CROSS JOIN (" "SELECT ICP FROM dbAlgebra.dbo.TdIndicadores " "WHERE (Fecha = " + fecha_str(fecha_cupon_anterior) + ")) " "ICP0") vpv = pd.io.sql.read_sql(vpv, cn) vpv = vpv.Cupon[0] flujos_v = proyectar_flujos_tabla(fechaActual, fechaValores, vpv, hora, fecha_efectiva, fecha_venc, frecuencia, moneda, 0, "Local", ajuste_feriados, cn) # Simulamos los insert a base de datos col_flujos_derivados = [ 'Fecha', 'Fondo', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFixing', 'FechaFlujo', 'FechaPago', 'Moneda', 'Flujo', 'Amortizacion', 'Interes', 'Sensibilidad', 'InteresDevengado' ] col_flujos_nosensibles = [ 'Fecha', 'Fondo', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFlujoNoSensible', 'Moneda', 'FlujoNoSensible' ] flujos_derivados = pd.DataFrame(columns=col_flujos_derivados) flujos_nosensibles = pd.DataFrame(columns=col_flujos_nosensibles) for i in flujos_v: flujos_derivados = flujos_derivados.append( pd.DataFrame([[ fechaActual, fondo, 'SCC', id, -factor_recibo_fijo, i[0], i[0], i[2], moneda, i[1] / 100 * nocional, i[3] / 100 * nocional, i[4] / 100 * nocional, i[5] / 100 * nocional, i[6] / 100 * nocional ]], columns=col_flujos_derivados)) flujos_nosensibles = flujos_nosensibles.append( pd.DataFrame([[ fechaActual, fondo, 'SCC', id, -factor_recibo_fijo, max(fechaActual, fecha_efectiva), moneda, vpv * nocional ]], columns=col_flujos_nosensibles)) for i in flujos_f: flujo_fijo = i[1] / 100 * nocional amortizacion = i[3] / 100 * nocional interes_fijo = i[4] / 100 * nocional fecha_flujo_f = i[0] devengo = i[6] / 100 * nocional fecha_pago = siguiente_habil_paises(add_days(fecha_flujo_f, -1), paises_feriados, cn) test = pd.DataFrame([fecha_flujo_f], columns=["fech"]) flujos_derivados = flujos_derivados.append( pd.DataFrame([[ fechaActual, fondo, 'SCC', id, factor_recibo_fijo, fecha_flujo_f, fecha_flujo_f, fecha_pago, moneda, flujo_fijo, amortizacion, interes_fijo, 0, devengo ]], columns=col_flujos_derivados)) flujos_nosensibles = flujos_nosensibles.append( pd.DataFrame([[ fechaActual, fondo, 'SCC', id, factor_recibo_fijo, fecha_flujo_f, moneda, flujo_fijo ]], columns=col_flujos_nosensibles)) self.flujos_nosensibles = flujos_nosensibles self.flujos_derivados = flujos_derivados self.set_status("INFO: Flujos generados para SCC con ID " + str(self.info_cartera.ID.iloc[0]))
def agrega_cambio_spot(self): fechas_tipo_cambio_spot = list() for i in range(len(self.flujos_valorizados)): plazo_pago = (self.flujos_valorizados.FechaPago.iloc[i] - self.fechaActual).days plazo_flujo = (self.flujos_valorizados.FechaFlujo.iloc[i] - self.fechaActual).days plazo_fixing = (self.flujos_valorizados.FechaFixing.iloc[i] - self.fechaActual).days if plazo_flujo > 0: plazo_flujo = 0 if plazo_pago > 0: plazo_pago = 0 if plazo_fixing > 0: plazo_fixing = 0 fechas_tipo_cambio_spot.append(fecha_str(add_days(self.fechaActual, plazo_fixing))) fechas_tipo_cambio_spot.append(fecha_str(add_days(self.fechaActual, plazo_pago))) fechas_tipo_cambio_spot.append(fecha_str(add_days(self.fechaActual, plazo_flujo))) fechas_tipo_cambio_spot = list(set(fechas_tipo_cambio_spot)) fechas_tipo_cambio_spot = str(fechas_tipo_cambio_spot)[1:-1].replace('"', "") sql_monedas_cierre = ("SELECT M.Fecha, M.FechaDato, M.MonedaActiva, M.MonedaPasiva, M.Valor, " "'Spot' as SpotObservado FROM dbDerivados.dbo.VwMonedasDia M " "WHERE (M.Plazo360 = 0) AND (M.Hora = '" + self.hora + "') AND (M.Tipo = 'TipoCambio') " "AND (M.Fecha in (" + fechas_tipo_cambio_spot + ")) AND (M.Campo = 'PX_LAST')") sql_monedas_observadas = ("SELECT Fecha, FechaDato, MonedaActiva, MonedaPasiva, Valor " "FROM dbDerivados.dbo.VwMonedasObservadas " "WHERE Fecha in (" + fechas_tipo_cambio_spot + ")") sql_monedas_observadas_parchadas = ("SELECT DISTINCT Coalesce(O.Fecha, S.Fecha) as Fecha, " "Coalesce(O.FechaDato, S.FechaDato) as FechaDato, " "Coalesce(O.MonedaActiva, S.MonedaActiva) as MonedaActiva, " "Coalesce(O.MonedaPasiva, S.MonedaPasiva) as MonedaPasiva, " "Coalesce(O.Valor, S.Valor) as Valor, 'Observado' as SpotObservado " "FROM (" + sql_monedas_cierre + ") AS S " "FULL OUTER JOIN (" + sql_monedas_observadas + ") AS O " "ON S.Fecha = O.Fecha AND S.MonedaActiva = O.MonedaActiva " "AND S.MonedaPasiva = O.MonedaPasiva") camino_monedas = ("SELECT * FROM dbDerivados.dbo.FnCaminoMonedas()") sql_monedas = sql_monedas_observadas_parchadas + " UNION " + sql_monedas_cierre cast_monedas = {'UF': 'CLF', 'CLN': 'COP'} valores_monedas = pd.io.sql.read_sql(sql_monedas, self.cn) camino_monedas = pd.io.sql.read_sql(camino_monedas, self.cn) for i in range(len(self.flujos_valorizados)): d1 = self.flujos_valorizados.FactorDescMonBase.iloc[i] d2 = self.flujos_valorizados.FactorDescMonFlujoFix.iloc[i] d3 = self.flujos_valorizados.FactorDescMonBaseFix.iloc[i] flujo = self.flujos_valorizados.Flujo.iloc[i] moneda = cast_monedas.get(self.flujos_valorizados.Moneda.iloc[i], self.flujos_valorizados.Moneda.iloc[i]) moneda_base = cast_monedas.get(self.flujos_valorizados.MonedaBase.iloc[i], self.flujos_valorizados.MonedaBase.iloc[i]) valores_monedas_t = valores_monedas.loc[valores_monedas['Fecha'] == pd.Timestamp(self.fechaActual)] valores_monedas_t = valores_monedas_t.loc[valores_monedas_t['SpotObservado'] == 'Spot'] tipo_cambio_t = valor_moneda(moneda, moneda_base, camino_monedas, valores_monedas_t) if tipo_cambio_t is None: self.set_status("ERROR: valor_moneda: No se encontró camino para " + moneda + " " + moneda_base + " en derivado con ID: " + str(self.info_cartera.ID.iloc[0])) return plazo_fixing = (self.flujos_valorizados.FechaFixing.iloc[i] - self.fechaActual).days if plazo_fixing > 0: plazo_fixing = 0 valores_monedas_fix = valores_monedas.loc[valores_monedas['Fecha'] == pd.Timestamp(add_days(self.fechaActual, plazo_fixing))] if plazo_fixing >= 0: valores_monedas_fix = valores_monedas_fix.loc[valores_monedas_fix['SpotObservado'] == 'Spot'] else: valores_monedas_fix = valores_monedas_fix.loc[valores_monedas_fix['SpotObservado'] == 'Observado'] tipo_cambio_fix = valor_moneda(moneda, moneda_base, camino_monedas, valores_monedas_fix) if tipo_cambio_fix is None: self.set_status("ERROR: valor_moneda: No se encontró camino para " + moneda + " " + moneda_base + " en derivado con ID: " + str(self.info_cartera.ID.iloc[0])) return self.flujos_valorizados.TipoCambioSpot.iloc[i] = tipo_cambio_t self.flujos_valorizados.TipoCambioSpotFix.iloc[i] = tipo_cambio_fix valor_presente_mon_base = d1 * flujo * (d2 / d3) * tipo_cambio_t self.flujos_valorizados.ValorPresenteMonBase.iloc[i] = valor_presente_mon_base self.flujos_valorizados.TipoCambioFwd.iloc[i] = (d2 / d3) * tipo_cambio_t # Agregando valores CLP y USD cambio_usd_base = valor_moneda(moneda_base, "USD", camino_monedas, valores_monedas) cambio_clp_base = valor_moneda(moneda_base, "CLP", camino_monedas, valores_monedas) self.flujos_valorizados.TipoCambioCLPBase.iloc[i] = cambio_clp_base self.flujos_valorizados.TipoCambioUSDBase.iloc[i] = cambio_usd_base self.flujos_valorizados.ValorPresenteUSD.iloc[i] = valor_presente_mon_base * cambio_usd_base self.flujos_valorizados.ValorPresenteCLP.iloc[i] = valor_presente_mon_base * cambio_clp_base self.set_status("INFO: Cambio Spot agregado con éxito")
def genera_flujos_aux(self, info): cn = self.cn fechaActual = self.fechaActual fechaValores = self.fechaValores hora_insert = "--" fondo = info["Fondo"] id = info["ID"] fecha_efectiva = info["FechaEfectiva"] fecha_venc = info["FechaVenc"] ajuste_feriados = info["AjusteFeriados"] paises_feriados = ajuste_feriados.split(",") activo_pasivo = info["ActivoPasivo"] moneda = info["Moneda"] tipo_tasa = info["TipoTasa"] tasa = info["Tasa"] spread = info["Spread"] frecuencia = info["Frecuencia"] nocional = info["Nocional"] flujos_f_DV01 = -1000 if tipo_tasa[0:4] == "Fija": if len(tipo_tasa) == 4: convencion = "30/360" else: convencion = cast_convencion(tipo_tasa[-5:]) if convencion == "": convencion = "30/360" #Conversion a float flujos_f = genera_flujos(max(fechaActual, fecha_efectiva), fecha_efectiva, fecha_venc, tasa + spread / 100, frecuencia, convencion) for i in flujos_f: i[0] = siguiente_habil_paises(add_days(i[0], -1), paises_feriados, cn) flujos_f_ns = np.array(flujos_f) elif moneda == "USD": hora_insert = self.hora arr_factor_descuento = ( "SELECT Curva FROM dbDerivados.dbo.TdCurvasDerivados " "WHERE Hora = '" + hora_insert + "' AND Fecha = " + fecha_str(fechaValores) + " AND Tipo = 'CurvaCero_SwapUSD_V2_6M'") arr_factor_descuento = pd.io.sql.read_sql(arr_factor_descuento, cn).Curva.iloc[0] arr_factor_descuento = parsear_curva(arr_factor_descuento) fecha_aux = add_days(max(fechaActual, fecha_efectiva), -1) fecha_aux = add_days( ultimo_habil_paises(fecha_aux, paises_feriados, cn), 1) flujos_f = genera_flujos(fecha_aux, fecha_efectiva, fecha_venc, 0, frecuencia, "ACT360") flujos_f_DV01 = np.array(flujos_f) flujos_f_ns = np.array(flujos_f) for j in range(len(flujos_f)): fecha_anterior = delta_frecuencia(flujos_f[j][0], frecuencia, -1) fecha_fijacion_libor = ultimo_habil_pais( add_days( ultimo_habil_pais(add_days(fecha_anterior, -1), "UK", cn), -1), "UK", cn) fecha_fijacion_libor_siguiente = ultimo_habil_pais( add_days( ultimo_habil_pais(add_days(flujos_f[j][0], -1), "UK", cn), -1), "UK", cn) flujos_f[j][0] = siguiente_habil_paises( add_days(flujos_f[j][0], -1), paises_feriados, cn) flujos_f_DV01[j][0] = flujos_f[j][0] flujos_f_ns[j][0] = flujos_f[j][0] max_fecha_libor = ( "SELECT Max(T.Fecha) as FechaMax " "FROM dbAlgebra.dbo.TdInfoTasas I " "INNER JOIN dbAlgebra.dbo.TdTasas T " "ON I.TickerCorto = T.Tasa WHERE (T.SiValida = 1) " "AND (T.Hora = 'CIERRE') " "AND (I.Plazo = '" + frecuencia + "') " "AND (I.TipoTasa = 'LIBOR') " "AND (I.MonedaActiva = 'USD') " "AND (T.Fecha <= " + fecha_str(fecha_fijacion_libor) + ")") max_fecha_libor = pd.io.sql.read_sql( max_fecha_libor, cn).FechaMax.iloc[0].to_pydatetime().date() if fecha_fijacion_libor <= fechaActual: libor = ("SELECT T.Valor " "FROM dbAlgebra.dbo.TdInfoTasas I " "INNER JOIN dbAlgebra.dbo.TdTasas T " "ON I.TickerCorto = T.Tasa " "WHERE (T.SiValida = 1) AND (T.Hora = 'CIERRE') " "AND (I.Plazo = '" + frecuencia + "') AND (I.TipoTasa = 'LIBOR') " "AND (I.MonedaActiva = 'USD') " "AND (T.Fecha = " + fecha_str(max_fecha_libor) + ") ORDER BY I.Plazo360") libor = pd.io.sql.read_sql(libor, cn).Valor.iloc[0] tasa = libor + spread / 100 tasa_DV01 = tasa if fecha_fijacion_libor_siguiente > fechaActual or len( flujos_f) == j: flujos_f_ns[j][1] = 100 + tasa * ( flujos_f_ns[j][0] - fecha_anterior).days / 360 flujos_f[j][6] = tasa * ( (flujos_f[j][0] - fecha_anterior).days) / 360 * ( fechaActual - fecha_anterior).days / ( flujos_f[j][0] - fecha_anterior).days else: flujos_f_ns[j][1] = tasa * (flujos_f_ns[j][0] - fecha_anterior).days / 360 flujos_f[j][6] = 0 else: plazo_ini = (fecha_fijacion_libor - fechaActual).days plazo_fin = (fecha_fijacion_libor_siguiente - fechaActual).days tasa_arr = tasa_FRA_y_tasa_DV01(plazo_ini, plazo_fin, spread, arr_factor_descuento) tasa = tasa_arr[0] tasa_DV01 = tasa_arr[1] flujos_f_ns[j][1] = (spread / 100) * ( flujos_f_ns[j][0] - fecha_anterior).days / 360 flujos_f[j][6] = 0 flujos_f[j][1] += tasa * (flujos_f[j][0] - fecha_anterior).days / 360 flujos_f[j][4] = tasa * (flujos_f[j][0] - fecha_anterior).days / 360 flujos_f_DV01[j][1] += tasa_DV01 * (flujos_f_DV01[j][0] - fecha_anterior).days / 360 elif moneda == "CLP": hora_insert = self.hora if tipo_tasa == "Flotante_Tab30dNom" or tipo_tasa == "Flotante_Tab": arr_factor_descuento = curva_cero_CLP_TAB( fechaValores, hora_insert, cn) fecha_aux = add_days(max(fechaActual, fecha_efectiva), -1) fecha_aux = add_days( ultimo_habil_paises(fecha_aux, paises_feriados, cn), 1) flujos_f = genera_flujos(fecha_aux, fecha_efectiva, fecha_venc, 0, frecuencia, "ACT360") flujos_f_DV01 = np.array(flujos_f) flujos_f_ns = np.array(flujos_f) for j in range(len(flujos_f)): if j == 0: fecha_anterior = delta_frecuencia( flujos_f[j][0], frecuencia, -1) else: fecha_anterior = flujos_f[j - 1][0] fecha_fijacion_tab = ultimo_habil_pais( add_days( ultimo_habil_pais(add_days(fecha_anterior, -1), "CL", cn), -1), "CL", cn) fecha_fijacion_tab_siguiente = ultimo_habil_pais( add_days( ultimo_habil_pais(add_days(flujos_f[j][0], -1), "CL", cn), -1), "CL", cn) flujos_f[j][0] = siguiente_habil_paises( add_days(flujos_f[j][0], -1), paises_feriados, cn) flujos_f_DV01[j][0] = flujos_f[j][0] # REVISAR flujos_f_ns[j][0] = flujos_f[j][0] if fecha_fijacion_tab <= fechaActual: if frecuencia == "1M": campo = "TabNominal30" elif frecuencia == "3M": campo = "TabNominal90" elif frecuencia == "6M": campo = "TabNominal180" elif frecuencia == "1A": campo = "TabNominal360" else: pass #TODO ERROR tab = ("SELECT Top 1 " + campo + " FROM [dbAlgebra].[dbo].[TdIndicadores] " "Where Fecha <= " + fecha_str(fecha_fijacion_tab) + " and " + campo + " <> -1000 Order by Fecha desc") tab = pd.io.sql.read_sql(tab, cn) tasa = tab + spread / 100 tasa_DV01 = tasa if fecha_fijacion_tab_siguiente > fechaActual or len( flujos_f) == j: flujos_f_ns[j][1] = 100 + tasa * ( flujos_f_ns[j][0] - fecha_anterior).days / 360 flujos_f[j][6] = tasa * ( (flujos_f[j][0] - fecha_anterior).days / 360) * (fechaActual - fecha_anterior).days / ( flujos_f[j][0] - fecha_anterior).days else: flujos_f_ns[j][1] = tasa * ( flujos_f_ns[j][0] - fecha_anterior).days / 360 flujos_f[j][6] = 0 else: plazo_ini = (fecha_fijacion_tab - fechaActual).days plazo_fin = (fecha_fijacion_tab_siguiente - fechaActual).days tasa_arr = tasa_FRA_y_tasa_DV01( plazo_ini, plazo_fin, spread, arr_factor_descuento) tasa = tasa_arr[0] tasa_DV01 = tasa_arr[1] flujos_f_ns[j][1] = (spread / 100) * ( flujos_f_ns[j][0] - fecha_anterior).days / 360 flujos_f[j][6] = 0 flujos_f[j][1] += tasa * (flujos_f[j][0] - fecha_anterior).days / 360 flujos_f[j][4] = tasa * (flujos_f[j][0] - fecha_anterior).days / 360 flujos_f_DV01[j][1] += tasa_DV01 * ( flujos_f_DV01[j][0] - fecha_anterior).days / 360 else: arr_factor_descuento = ( "SELECT Curva FROM dbDerivados.dbo.TdCurvasDerivados " "WHERE Hora = '" + hora_insert + "' AND Fecha = " + fecha_str(fechaValores) + " AND Tipo = 'CurvaCero_CLP_LibreRiesgo'") arr_factor_descuento = pd.io.sql.read_sql( arr_factor_descuento, cn).Curva.iloc[0] arr_factor_descuento = parsear_curva(arr_factor_descuento) flujos_f = genera_flujos(max(fechaActual, fecha_efectiva), fecha_efectiva, fecha_venc, 0, frecuencia, "ACT360") flujos_f_DV01 = np.array(flujos_f) for j in range(len(flujos_f)): fecha_IPC_inicial = delta_frecuencia( flujos_f[j][0], frecuencia, -1) fecha_IPC_inicial = siguiente_habil_paises( fecha_IPC_inicial, paises_feriados, cn) fecha_IPC_final = siguiente_habil_paises( flujos_f[j][0], paises_feriados, cn) flujos_f[j][0] = fecha_IPC_final flujos_f_DV01[j][0] = flujos_f[j][0] plazo_ini = (fecha_IPC_inicial - fechaActual).days plazo_fin = (fecha_IPC_final - fechaActual).days if fecha_IPC_inicial <= fechaActual: vpv = ( "SELECT ICP1.ICP / ICP0.ICP AS Cupon FROM (SELECT ICP FROM dbAlgebra.dbo.TdIndicadores " "WHERE (Fecha = " + fecha_str(fechaValores) + ")) ICP1 " "CROSS JOIN (SELECT ICP FROM dbAlgebra.dbo.TdIndicadores " "WHERE (Fecha = " + fecha_str(fecha_IPC_inicial) + ")) ICP0") vpv = pd.io.sql.read_sql(vpv, cn).Cupon.iloc[0] tasa = ( (vpv / interpolacion_log_escalar( plazo_fin, arr_factor_descuento[1:]))** (360 / (plazo_fin - plazo_ini)) - 1) * 100 + spread / 100 tasa_DV01 = tasa if fechaActual < fecha_IPC_final: flujos_f_ns = [[fechaActual, vpv * 100]] flujos_f[j][6] = tasa * ( (flujos_f[j][0] - fecha_IPC_inicial).days / 360) * (fechaActual - fecha_IPC_inicial).days / ( flujos_f[j][0] - fecha_IPC_inicial).days else: tasa_arr = tasa_FRA_y_tasa_DV01( plazo_ini, plazo_fin, spread, arr_factor_descuento) tasa = tasa_arr[0] tasa_DV01 = tasa_arr[1] flujos_f_ns = [[fecha_IPC_inicial, 100]] flujos_f[j][6] = 0 flujos_f[j][1] += tasa * (flujos_f[j][0] - fecha_IPC_inicial).days / 360 flujos_f[j][4] = tasa * (flujos_f[j][0] - fecha_IPC_inicial).days / 360 flujos_f_DV01[j][1] += tasa_DV01 * ( flujos_f_DV01[j][0] - fecha_IPC_inicial).days / 360 else: send_msg( "ERROR: Moneda '" + moneda + "' no soportada para tasa flotante", self.filename) if fecha_efectiva >= fechaActual: flujos_f = np.append( [[fecha_efectiva, -100, fecha_efectiva, -100, 0, 0, 0]], flujos_f, axis=0) if type(flujos_f_DV01) != int: flujos_f_DV01 = np.append( [[fecha_efectiva, -100, fecha_efectiva, -100, 0, 0, 0]], flujos_f_DV01, axis=0) insert = dict() insert["Fecha"] = fechaActual insert["Fondo"] = fondo insert["Tipo"] = "XCCY" insert["ID"] = id insert["Hora"] = hora_insert insert["ActivoPasivo"] = activo_pasivo insert["Moneda"] = moneda for j in range(len(flujos_f)): insert["Flujo"] = flujos_f[j][1] / 100 * nocional insert["Amortizacion"] = flujos_f[j][3] / 100 * nocional insert["Interes"] = flujos_f[j][4] / 100 * nocional insert["FechaFixing"] = flujos_f[j][0] insert["FechaFlujo"] = flujos_f[j][0] insert["FechaPago"] = flujos_f[j][0] insert["InteresDevengado"] = flujos_f[j][6] / 100 * nocional try: insert["Sensibilidad"] = (flujos_f_DV01[j][1] - flujos_f[j][1]) / 100 * nocional except: insert["Sensibilidad"] = 0 self.flujos_derivados = self.flujos_derivados.append( insert, ignore_index=True) insert = dict() insert["Fecha"] = fechaActual insert["Fondo"] = fondo insert["Tipo"] = "XCCY" insert["ID"] = id insert["ActivoPasivo"] = activo_pasivo insert["Moneda"] = moneda for j in range(len(flujos_f_ns)): insert["FlujoNoSensible"] = flujos_f_ns[j][1] / 100 * nocional insert["FechaFlujoNoSensible"] = flujos_f_ns[j][0] self.flujos_nosensibles = self.flujos_nosensibles.append( insert, ignore_index=True)
def genera_flujos(self): hora = self.hora cn = self.cn fecha = self.fecha admin = self.info_cartera.Administradora[0] fondo = self.info_cartera.Fondo[0] contraparte = self.info_cartera.Contraparte[0] id = self.info_cartera.ID[0] fecha_efectiva = pd.to_datetime(self.info_cartera.FechaEfectiva[0]).date() fecha_venc = pd.to_datetime(self.info_cartera.FechaVenc[0]).date() ajuste_feriados = self.info_cartera.AjusteFeriados[0] paises_feriados = ajuste_feriados.split(',') moneda = self.info_cartera.MonedaActivo[0] if self.info_cartera.TipoTasaActivo[0] == 'Fija': factor_recibo_fijo = 1 tasa = self.info_cartera.TasaActivo[0] else: factor_recibo_fijo = -1 tasa = self.info_cartera.TasaPasivo[0] nocional = self.info_cartera.NocionalActivo[0] frecuencia = cast_frecuencia(self.info_cartera.FrecuenciaActivo[0]) id_key = self.info_cartera.ID_Key[0] convencion = "LACT360" flujos_f = genera_flujos(max(fecha, fecha_efectiva), fecha_efectiva, fecha_venc, tasa, frecuencia, convencion) fecha_cupon = flujos_f[0][0] fecha_aux = delta_frecuencia(fecha_cupon, frecuencia, -1) fecha_aux = max(fecha_aux, fecha_efectiva) fecha_cupon_anterior = ultimo_habil_pais(fecha_aux, "CL", cn) if fecha < fecha_cupon_anterior: vpv = 1 else: vpv = ("SELECT (ICP1.ICP / ICP0.ICP)/(ICP1.UF / ICP0.UF) AS Cupon FROM " "(SELECT ICP, UF FROM dbAlgebra.dbo.TdIndicadores " "WHERE (Fecha = " + fecha_str(fecha) + ")) ICP1 CROSS JOIN (" "SELECT ICP, UF FROM dbAlgebra.dbo.TdIndicadores " "WHERE (Fecha = " + fecha_str(fecha_cupon_anterior) + ")) " "ICP0") vpv = pd.io.sql.read_sql(vpv, cn) vpv = vpv.Cupon[0] flujos_v = proyectar_flujos_tabla(fecha, fecha, vpv, hora, fecha_efectiva, fecha_venc, frecuencia, moneda, 0, "Local", ajuste_feriados, cn) # Simulamos los insert a base de datos col_flujos_derivados = ['Fecha', 'Administradora', 'Fondo', 'Contraparte', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFixing', 'FechaFlujo', 'FechaPago', 'Moneda', 'Flujo', 'Amortizacion', 'Interes', 'Sensibilidad', 'InteresDevengado', 'Id_Key_Cartera'] col_flujos_nosensibles = ['Fecha', 'Administradora', 'Fondo', 'Contraparte', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFlujoNoSensible', 'Moneda', 'FlujoNoSensible', 'Id_Key_Cartera'] flujos_derivados = pd.DataFrame(columns=col_flujos_derivados) flujos_nosensibles = pd.DataFrame(columns=col_flujos_nosensibles) for i in flujos_v: flujos_derivados = flujos_derivados.append(pd.DataFrame([[fecha, admin, fondo, contraparte, 'SUC', id, -factor_recibo_fijo, i[0], i[0], i[2], moneda, i[1] / 100 * nocional, i[3] / 100 * nocional, i[4] / 100 * nocional, i[5] / 100 * nocional, i[6] / 100 * nocional, id_key]], columns=col_flujos_derivados)) flujos_nosensibles = flujos_nosensibles.append(pd.DataFrame([[fecha, admin, fondo, contraparte, 'SUC', id, -factor_recibo_fijo, max(fecha, fecha_efectiva), moneda, vpv * nocional, id_key]], columns=col_flujos_nosensibles)) for i in flujos_f: flujo_fijo = i[1] / 100 * nocional amortizacion = i[3] / 100 * nocional interes_fijo = i[4] / 100 * nocional fecha_flujo_f = i[0] devengo = i[6] / 100 * nocional fecha_pago = siguiente_habil_paises(add_days(fecha_flujo_f, -1), paises_feriados, cn) flujos_derivados = flujos_derivados.append(pd.DataFrame([[fecha, admin, fondo, contraparte, 'SUC', id, factor_recibo_fijo, fecha_flujo_f, fecha_flujo_f, fecha_pago, moneda, flujo_fijo, amortizacion, interes_fijo, 0, devengo, id_key]], columns=col_flujos_derivados)) flujos_nosensibles = flujos_nosensibles.append(pd.DataFrame([[fecha, admin, fondo, contraparte, 'SUC', id, factor_recibo_fijo, fecha_flujo_f, moneda, flujo_fijo, id_key]], columns=col_flujos_nosensibles)) self.flujos_nosensibles = flujos_nosensibles self.flujos_derivados = flujos_derivados self.set_status("INFO: Flujos generados para SUC con ID " + str(self.info_cartera.ID.iloc[0]))
def proyectar_flujos_tabla(fecha, fecha_curva, devengo, hora, fecha_efectiva, fecha_venc, frecuencia, moneda, hay_flujo_fecha_efectiva, mercado, ajuste_feriados, cn): """ :param fecha: Fecha del proceso :param fecha_curva: Fecha de la curva a utilizar :param devengo: El devengo acumulado desde el flujo anterior a la fecha del proceso :param hora: Hora del proceso :param fecha_efectiva: Fecha efectiva del contrato :param fecha_venc: Fecha vencimiento del contrato :param frecuencia: Frecuencia con la que se pagan los cupones :param moneda: La moneda de los flujos :param hay_flujo_fecha_efectiva: (1 => Flujo inicial en la fecha efectiva (XCCY)) :param mercado: Tipo de mercado (Sólo con algunos países) :param ajuste_feriados: Arreglo de países para ajustar feriados :param cn: Conexión con permiso a base de datos :return: array con la proyeccion de flujos en la tabla """ # Evita casos de borde en que la fecha efectiva ya pasó if fecha_efectiva <= fecha: hay_flujo_fecha_efectiva = 0 # Se guardan los plazos y factores de descuento para flujos en la moneda correspondiente arr_factor_descuento = remove_col(remove_col(curva_efectiva(moneda, fecha_curva, mercado, hora, -1, cn), 0), 2) if int(arr_factor_descuento.values[0][0]) == 0: # Se elimina el plazo 0 arr_factor_descuento = arr_factor_descuento.drop([arr_factor_descuento.index[0]]) if int(arr_factor_descuento.values[0][0]) != 1: # Si no hay plazo 1, se calcula valor_plazo1 = interpolacion_log_escalar(1, arr_factor_descuento.values) # Se dejan los factores de descuento agregando el plazo 1 arr_factor_descuento = np.append(np.array([[1, valor_plazo1]]), arr_factor_descuento.values, axis=0) else: # Si no, el arreglo ya tiene el plazo 1 arr_factor_descuento = arr_factor_descuento.values paises = ajuste_feriados.split(",") # 'Recordar que Genera flujos crea los flujos desde la fecha de vencimiento hacia atrás usando la frecuencia como # paso, hasta inmediatamente después de la fechaInicioGeneraFlujos, # 'por lo que si no hay flujo en la fecha efectiva no se considerará esta fecha para los flujos, en cambio si hay # flujo en esta fecha, se considerará esta fecha en caso de ser posterior a la fecha de proceso if hay_flujo_fecha_efectiva == 0: fecha_inicio_genera_flujos = max(fecha, fecha_efectiva) else: fecha_inicio_genera_flujos = max(fecha, ultimo_habil_paises(add_days(fecha_efectiva, -1), paises, cn)) flujos_f = genera_flujos(fecha_inicio_genera_flujos, fecha_efectiva, fecha_venc, 0, frecuencia, "ACT360", 1) # 'Recorro todos los flujos for i in range(len(flujos_f)): # 'Hay que ajustar el devengo y las fechas de tasas para cuando el cupón se fija con anticipación. Es esos casos # ', el primer cupon no es necesario proyectarlo y los que vienen se usa la curva con los fix corridos # 'Quizas basta con incluir el parametro siFijacionCupunAnticipadamente, que sería 1 para las libor y # 'cero para las del día. fecha_aux = max(delta_frecuencia(flujos_f[i][0], frecuencia, -1), fecha_efectiva) fecha_aux = add_days(fecha_aux, -1) fecha_tasa_inicial = siguiente_habil_paises(fecha_aux, paises, cn) # Ajuste día hábil siguiente fecha_aux = max(flujos_f[i][0], fecha_efectiva) fecha_aux = add_days(fecha_aux, -1) fecha_tasa_final = siguiente_habil_paises(fecha_aux, paises, cn) # Ajuste día hábil siguiente if fecha_tasa_final == False: print("ERROR") print(paises) print(fecha_aux) flujos_f[i][2] = fecha_tasa_final # Ajuste día hábil siguiente para la fechaPago plazo_ini = (fecha_tasa_inicial - fecha_curva).days plazo_fin = (fecha_tasa_final - fecha_curva).days fd_ini = interpolacion_log_escalar(plazo_ini, arr_factor_descuento) fd_fin = interpolacion_log_escalar(plazo_fin, arr_factor_descuento) if i - hay_flujo_fecha_efectiva == 0: fd_ini = devengo flujos_f[i][6] = (devengo-1) * 100 else: flujos_f[i][6] = 0 flujos_f[i][4] = ((fd_ini/fd_fin)-1)*100 flujos_f[i][1] = flujos_f[i][3] + flujos_f[i][4] if plazo_ini <= 0: fd_ini_DV01 = fd_ini else: tasa_eq_comp_act_360_ini = (((1/fd_ini)**(360/plazo_ini))-1)*100 tasa_eq_comp_act_360_ini_DV01 = tasa_eq_comp_act_360_ini + 0.01 fd_ini_DV01 = (tasa_eq_comp_act_360_ini_DV01 / 100 + 1)**(-plazo_ini/360) tasa_eq_comp_act_360_fin = (((1/fd_fin)**(360/plazo_fin))-1)*100 tasa_eq_comp_act_360_fin_DV01 = tasa_eq_comp_act_360_fin + 0.01 fd_fin_DV01 = (tasa_eq_comp_act_360_fin_DV01 / 100 + 1)**(-plazo_fin/360) flujos_f[i][5] = ((fd_ini_DV01/fd_fin_DV01)-(fd_ini/fd_fin)) * 100 if hay_flujo_fecha_efectiva == 1: flujos_f[0][4] = 100 flujos_f[0][4] = 0 flujos_f[0][5] = 0 return flujos_f
def genera_flujos(self): hora = self.hora cn = self.cn fecha = self.fecha fondo = self.info_cartera.Fondo[0] id = self.info_cartera.ID[0] fecha_efectiva = pd.to_datetime(self.info_cartera.FechaEfectiva[0]).date() fecha_venc = pd.to_datetime(self.info_cartera.FechaVenc[0]).date() ajuste_feriados = self.info_cartera.AjusteFeriados[0] paises_feriados = ajuste_feriados.split(',') moneda = self.info_cartera.MonedaActivo[0] if self.info_cartera.TipoTasaActivo[0] == 'Fija': factor_recibo_fijo = 1 tasa = self.info_cartera.TasaActivo[0] else: factor_recibo_fijo = -1 tasa = self.info_cartera.TasaPasivo[0] nocional = self.info_cartera.NocionalActivo[0] frecuencia = self.info_cartera.FrecuenciaActivo[0] id_key = self.info_cartera.ID_Key[0] flujos_f = genera_flujos(max(fecha, fecha_efectiva), fecha_efectiva, fecha_venc, tasa, frecuencia, "LACT360") fecha_cupon = flujos_f[0][0] fecha_aux = delta_frecuencia(fecha_cupon, frecuencia, -1) fecha_aux = max(fecha_aux, fecha_efectiva) fecha_cupon_anterior = ultimo_habil_pais(fecha_aux, "CO", cn) fecha_aux1 = fecha_str(add_months(max(fecha_efectiva, fecha_cupon_anterior), -1)) fecha_aux2 = fecha_str(add_days(ultimo_habil_pais(max(fecha_efectiva, fecha), "CO", cn), -1)) fecha_aux3 = fecha_str(max(fecha_efectiva, fecha_cupon_anterior)) fecha_aux4 = fecha_str(add_days(ultimo_habil_pais(max(fecha_efectiva, fecha), "CO", cn), -1)) ibr_acum = ("SELECT COALESCE (EXP(SUM(LOG(1 + T.Valor / CAST(36000 as float)))), 1) AS IbrAcum " "FROM (" "SELECT MAX(T.Fecha) AS FechaMax, I.Fecha " "FROM dbAlgebra.dbo.TdTasas T INNER JOIN dbAlgebra.dbo.TdIndicadores I " "ON T.Fecha <= I.Fecha " "WHERE T.SiValida = 1 AND T.Hora = 'CIERRE' AND T.Tasa = 'COOVIBR' " "AND T.Fecha BETWEEN " + fecha_aux1 + " AND " + fecha_aux2 + "" "AND I.Fecha BETWEEN " + fecha_aux3 + " AND " + fecha_aux4 + "" "AND T.SiValida = 1 " "GROUP BY I.Fecha) F " "INNER JOIN dbAlgebra.dbo.TdTasas T " "ON F.FechaMax = T.Fecha " "WHERE T.SiValida = 1 AND T.Hora = 'CIERRE' AND T.Tasa = 'COOVIBR'") ibr_acum = pd.io.sql.read_sql(ibr_acum, cn) ibr_acum = ibr_acum.IbrAcum[0] flujos_v = proyectar_flujos_tabla(fecha, fecha, ibr_acum, hora, fecha_efectiva, fecha_venc, frecuencia, moneda, 0, "Local", ajuste_feriados, cn) # Simulamos los insert a base de datos col_flujos_derivados = ['Fecha', 'Fondo', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFixing', 'FechaFlujo', 'FechaPago', 'Moneda', 'Flujo', 'Amortizacion', 'Interes', 'Sensibilidad', 'InteresDevengado', 'Id_Key_Cartera'] col_flujos_nosensibles = ['Fecha', 'Fondo', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFlujoNoSensible', 'Moneda', 'FlujoNoSensible', 'Id_Key_Cartera'] flujos_derivados = pd.DataFrame(columns=col_flujos_derivados) flujos_nosensibles = pd.DataFrame(columns=col_flujos_nosensibles) c = 0 for i in flujos_v: flujos_derivados = flujos_derivados.append(pd.DataFrame([[fecha, fondo, 'IBR', id, -factor_recibo_fijo, i[0], i[0], i[2], moneda, i[1]/100*nocional, i[3]/100 * nocional, i[4]/100*nocional, i[5] / 100 * nocional, i[6] / 100 * nocional, id_key]], columns=col_flujos_derivados)) flujos_nosensibles = flujos_nosensibles.append(pd.DataFrame([[fecha, fondo, 'IBR', id, -factor_recibo_fijo, max(fecha, fecha_efectiva), moneda, ibr_acum*nocional, id_key]], columns=col_flujos_nosensibles)) for i in flujos_f: flujo_fijo = i[1] / 100 * nocional amortizacion = i[3] / 100 * nocional interes_fijo = i[4] / 100 * nocional fecha_flujo_f = i[0] devengo = i[6] / 100 * nocional fecha_pago = siguiente_habil_paises(add_days(fecha_flujo_f, -1), paises_feriados, cn) flujos_derivados = flujos_derivados.append(pd.DataFrame([[fecha, fondo, 'IBR', id, factor_recibo_fijo, fecha_flujo_f, fecha_flujo_f, fecha_pago, moneda, flujo_fijo, amortizacion, interes_fijo, 0, devengo, id_key]], columns=col_flujos_derivados)) flujos_nosensibles = flujos_nosensibles.append(pd.DataFrame([[fecha, fondo, 'IBR', id, factor_recibo_fijo, fecha_flujo_f, moneda, flujo_fijo, id_key]], columns=col_flujos_nosensibles)) self.flujos_nosensibles = flujos_nosensibles self.flujos_derivados = flujos_derivados self.set_status("INFO: Flujos generados para IBR con ID " + str(self.info_cartera.ID.iloc[0]))
def genera_flujos(self): hora = self.hora cn = self.cn fecha = self.fecha admin = self.info_cartera.Administradora[0] fondo = self.info_cartera.Fondo[0] contraparte = self.info_cartera.Contraparte[0] id = self.info_cartera.ID[0] fecha_efectiva = pd.to_datetime( self.info_cartera.FechaEfectiva[0]).date() fecha_venc = pd.to_datetime(self.info_cartera.FechaVenc[0]).date() ajuste_feriados = self.info_cartera.AjusteFeriados[0] paises_feriados = ajuste_feriados.split(',') moneda = self.info_cartera.MonedaActivo[0] if self.info_cartera.TipoTasaActivo[0] == 'Fija': factor_recibo_fijo = 1 tasa = self.info_cartera.TasaActivo[0] frecuencia_fija = self.info_cartera.FrecuenciaActivo[0] frecuencia_variable = self.info_cartera.FrecuenciaPasivo[0] else: factor_recibo_fijo = -1 tasa = self.info_cartera.TasaPasivo[0] frecuencia_fija = self.info_cartera.FrecuenciaPasivo[0] frecuencia_variable = self.info_cartera.FrecuenciaActivo[0] nocional = self.info_cartera.NocionalActivo[0] frecuencia_fija = cast_frecuencia(frecuencia_fija) frecuencia_variable = cast_frecuencia(frecuencia_variable) id_key = self.info_cartera.ID_Key[0] fecha_aux = add_days(max(fecha, fecha_efectiva), -1) fecha_aux = add_days(ultimo_habil_pais(fecha_aux, "US", cn), 1) flujos_f = genera_flujos(fecha_aux, fecha_efectiva, fecha_venc, tasa, frecuencia_fija, "ACT360") arr_factor_descuento = curva_cero_swapUSD(fecha, hora, frecuencia_variable, "ACT360", cn) print("arr", arr_factor_descuento) flujos_v = genera_flujos(fecha_aux, fecha_efectiva, fecha_venc, 0, frecuencia_variable, "ACT360") flujos_v_DV01 = flujos_v flujos_f_ns = flujos_v for i in range(len(flujos_v)): fecha_anterior = delta_frecuencia(flujos_v[i][0], frecuencia_variable, -1) print(flujos_v[i][0]) fecha_fijacion_libor = add_days( ultimo_habil_pais(add_days(fecha_anterior, -1), "UK", cn), -1) fecha_fijacion_libor = ultimo_habil_pais(fecha_fijacion_libor, "UK", cn) fecha_fijacion_libor_siguiente = add_days( ultimo_habil_pais(add_days(flujos_v[i][0], -1), "UK", cn), -1) fecha_fijacion_libor_siguiente = ultimo_habil_pais( fecha_fijacion_libor_siguiente, "UK", cn) flujos_v[i][0] = siguiente_habil_pais(add_days(flujos_v[i][0], -1), "US", cn) flujos_v_DV01[i][0] = flujos_v[i][0] flujos_f_ns[i][0] = flujos_v[i][0] max_fecha_libor = ( "SELECT Max(T.Fecha) as FechaMax " "FROM dbAlgebra.dbo.TdInfoTasas I " "INNER JOIN " "dbAlgebra.dbo.TdTasas T " "ON I.TickerCorto = T.Tasa " "WHERE T.SiValida = 1 AND T.Hora = 'CIERRE' AND I.Plazo = '" + frecuencia_variable + "' " "AND I.TipoTasa = 'LIBOR' AND I.MonedaActiva = 'USD' " "AND T.Fecha <= " + fecha_str(fecha_fijacion_libor) + "") max_fecha_libor = pd.io.sql.read_sql(max_fecha_libor, self.cn).FechaMax.iloc[0] if fecha_fijacion_libor <= fecha: libor = ( "SELECT T.Valor " "FROM dbAlgebra.dbo.TdInfoTasas I " "INNER JOIN " "dbAlgebra.dbo.TdTasas T " "ON I.TickerCorto = T.Tasa " "WHERE T.SiValida = 1 AND T.Hora = 'CIERRE' AND I.Plazo = '" + frecuencia_variable + "' " "AND I.TipoTasa = 'LIBOR' AND I.MonedaActiva = 'USD' " "AND T.Fecha = " + fecha_str(max_fecha_libor) + " ORDER BY I.Plazo360") libor = pd.io.sql.read_sql(libor, self.cn).Valor.iloc[0] tasa = libor tasaDV01 = tasa if fecha_fijacion_libor_siguiente > fecha or len( flujos_v) - 1 == i: flujos_f_ns[i][1] = 100 + tasa * ( flujos_f_ns[i][0] - fecha_anterior).days / 360 else: flujos_f_ns[i][1] = tasa * (flujos_f_ns[i][0] - fecha_anterior).days / 360 flujos_v[i][6] = tasa * (fecha - fecha_anterior).days / 360 else: plazo_ini = (fecha_fijacion_libor - fecha).days plazo_fin = (fecha_fijacion_libor_siguiente - fecha).days tasa_arr = tasa_FRA_y_tasa_DV01(plazo_ini, plazo_fin, 0, arr_factor_descuento) tasa = tasa_arr[0] tasaDV01 = tasa_arr[1] flujos_f_ns[i][1] = 0 flujos_v[i][6] = 0 flujos_v[i][1] = flujos_v[i][1] + tasa * ( flujos_v[i][0] - fecha_anterior).days / 360 flujos_v[i][4] = tasa * (flujos_v[i][0] - fecha_anterior).days / 360 flujos_v_DV01[i][1] = flujos_v_DV01[i][1] + tasaDV01 * ( flujos_v_DV01[i][0] - fecha_anterior).days / 360 insert = dict() insert["Fecha"] = fecha insert["Administradora"] = admin insert["Fondo"] = fondo insert["Contraparte"] = contraparte insert["Tipo"] = "SDL" insert["ID"] = id insert["Hora"] = hora insert["ActivoPasivo"] = -factor_recibo_fijo insert["Id_Key_Cartera"] = id_key for i in range(len(flujos_v)): insert["FechaFixing"] = flujos_v[i][0] insert["FechaFlujo"] = flujos_v[i][0] insert["FechaPago"] = siguiente_habil_paises( add_days(flujos_v[i][0], -1), paises_feriados, cn) insert["Moneda"] = moneda insert["Flujo"] = flujos_v[i][1] / 100 * nocional insert["Amortizacion"] = flujos_v[i][3] / 100 * nocional insert["Interes"] = flujos_v[i][4] / 100 * nocional insert["Sensibilidad"] = (flujos_v_DV01[i][1] - flujos_v[i][1]) / 100 * nocional insert["InteresDevengado"] = flujos_v[i][6] / 100 * nocional self.flujos_derivados = self.flujos_derivados.append(insert) insert_nosensible = dict() insert_nosensible["Fecha"] = fecha insert_nosensible["Administradora"] = admin insert_nosensible["Fondo"] = fondo insert_nosensible["Contraparte"] = contraparte insert_nosensible["Tipo"] = "SDL" insert_nosensible["ID"] = id insert_nosensible["Hora"] = hora insert_nosensible["ActivoPasivo"] = factor_recibo_fijo insert_nosensible["Id_Key_Cartera"] = id_key insert["ActivoPasivo"] = factor_recibo_fijo for i in flujos_f: insert["FechaFixing"] = i[0] insert["FechaFlujo"] = i[0] insert["FechaPago"] = siguiente_habil_paises( add_days(i[0], -1), paises_feriados, cn) insert["Moneda"] = moneda insert["Flujo"] = i[1] / 100 * nocional insert["Amortizacion"] = i[3] / 100 * nocional insert["Interes"] = i[4] / 100 * nocional insert["InteresDevengado"] = i[6] / 100 * nocional self.flujos_derivados = self.flujos_derivados.append(insert) insert_nosensible["FechaFlujoNoSensible"] = i[0] insert_nosensible["Moneda"] = moneda insert_nosensible["FlujoNoSensible"] = i[1] / 100 * nocional self.flujos_nosensibles = self.flujos_nosensibles.append( insert_nosensible) insert_nosensible["ActivoPasivo"] = -factor_recibo_fijo for i in flujos_f_ns: insert_nosensible["FechaFlujoNoSensible"] = i[0] insert_nosensible["FlujoNoSensible"] = i[1] / 100 * nocional self.flujos_nosensibles = self.flujos_nosensibles.append( insert_nosensible) self.set_status("INFO: Flujos generados para SDL con ID " + str(self.info_cartera.ID.iloc[0]))
def plazo360_a_plazo(plazo360, fecha): dias = int(plazo360) % 30 meses = int((plazo360-dias)/30 % 12) anhos = int((plazo360-dias-meses*30) / 360) return (add_days(add_months(add_years(fecha, anhos), meses), dias) - fecha).days
def genera_flujos(self): hora = self.hora cn = self.cn fecha = self.fecha admin = self.info_cartera.Administradora[0] fondo = self.info_cartera.Fondo[0] contraparte = self.info_cartera.Contraparte[0] id = self.info_cartera.ID[0] fecha_efectiva = pd.to_datetime(self.info_cartera.FechaEfectiva[0]).date() fecha_venc = pd.to_datetime(self.info_cartera.FechaVenc[0]).date() ajuste_feriados = self.info_cartera.AjusteFeriados[0] paises_feriados = ajuste_feriados.split(',') moneda = self.info_cartera.MonedaActivo[0] if self.info_cartera.TipoTasaActivo[0] == 'Fija': factor_recibo_fijo = 1 tasa = self.info_cartera.TasaActivo[0] else: factor_recibo_fijo = -1 tasa = self.info_cartera.TasaPasivo[0] nocional = self.info_cartera.NocionalActivo[0] frecuencia = cast_frecuencia(self.info_cartera.FrecuenciaActivo[0]) id_key = self.info_cartera.ID_Key[0] convencion = "ACT360" flujos_f = genera_flujos(max(fecha, fecha_efectiva), fecha_efectiva, fecha_venc, tasa, frecuencia, convencion) fecha_cupon = flujos_f[0][0] fecha_aux = delta_frecuencia(fecha_cupon, frecuencia, -1) fecha_aux = max(fecha_aux, fecha_efectiva) fecha_cupon_anterior = ultimo_habil_pais(fecha_aux, "MX", cn) flujos_v = proyectar_flujos_tabla(fecha, fecha, 1, hora, fecha_efectiva, fecha_venc, frecuencia, moneda, 0, "Local", ajuste_feriados, cn) if fecha >= fecha_cupon_anterior: tasaV = ("SELECT T.Valor FROM dbAlgebra.dbo.TdInfoTasas I " "INNER JOIN dbAlgebra.dbo.TdTasas T " "ON I.TickerCorto = T.Tasa " "INNER JOIN (SELECT MAX(T.Fecha) AS Fecha FROM " "dbAlgebra.dbo.TdInfoTasas I INNER JOIN " "dbAlgebra.dbo.TdTasas T ON I.TickerCorto = T.Tasa " "WHERE (T.SiValida = 1) AND (T.Hora = 'CIERRE') AND (I.TipoTasa = 'TIIE') " "AND (I.MonedaActiva = 'MXN') AND (T.Fecha <= " + fecha_str(fecha_cupon_anterior) + ") " "AND (I.Plazo = '28D')) F ON T.Fecha = F.Fecha " "WHERE (T.SiValida = 1) AND (T.Hora = 'CIERRE') AND (I.TipoTasa = 'TIIE') " "AND (I.MonedaActiva = 'MXN') AND (I.Plazo = '28D')") tasaV = pd.io.sql.read_sql(tasaV, cn) tasaV = tasaV.Valor[0] cupon = (1/factor_descuento(tasaV/100, fecha_cupon_anterior, fecha_cupon, "ACT360", 0)-1) * 100 devengo = cupon * (fecha_cupon_anterior-fecha).days / (fecha_cupon_anterior-fecha_cupon).days fecha_flujo_variable = fecha_cupon fecha_pago = siguiente_habil_paises(add_days(fecha_flujo_variable, -1), paises_feriados, cn) flujos_v[0][0] = fecha_flujo_variable flujos_v[0][1] = cupon flujos_v[0][2] = fecha_pago flujos_v[0][3] = 0 flujos_v[0][4] = cupon flujos_v[0][5] = 0 flujos_v[0][6] = devengo fecha_FNS = fecha_flujo_variable flujo_FNS = nocional * ((cupon/100)+1) else: fecha_FNS = fecha_cupon_anterior flujo_FNS = nocional col_flujos_derivados = ['Fecha', 'Administradora', 'Fondo', 'Contraparte', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFixing', 'FechaFlujo', 'FechaPago', 'Moneda', 'Flujo', 'Amortizacion', 'Interes', 'Sensibilidad', 'InteresDevengado', 'Id_Key_Cartera'] col_flujos_nosensibles = ['Fecha', 'Administradora', 'Fondo', 'Contraparte', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFlujoNoSensible', 'Moneda', 'FlujoNoSensible', 'Id_Key_Cartera'] flujos_derivados = pd.DataFrame(columns=col_flujos_derivados) flujos_nosensibles = pd.DataFrame(columns=col_flujos_nosensibles) for i in flujos_v: flujos_derivados = flujos_derivados.append(pd.DataFrame([[fecha, admin, fondo, contraparte, 'SMT', id, -factor_recibo_fijo, i[0], i[0], i[2], moneda, i[1] / 100 * nocional, i[3] / 100 * nocional, i[4] / 100 * nocional, i[5] / 100 * nocional, i[6] / 100 * nocional, id_key]], columns=col_flujos_derivados)) flujos_nosensibles = flujos_nosensibles.append(pd.DataFrame([[fecha, admin, fondo, contraparte, 'SMT', id, -factor_recibo_fijo, fecha_FNS, moneda, flujo_FNS, id_key]], columns=col_flujos_nosensibles)) for i in flujos_f: flujo_fijo = i[1] / 100 * nocional amortizacion = i[3] / 100 * nocional interes_fijo = i[4] / 100 * nocional fecha_flujo_f = i[0] devengo = i[6] / 100 * nocional fecha_pago = siguiente_habil_paises(add_days(fecha_flujo_f, -1), paises_feriados, cn) flujos_derivados = flujos_derivados.append(pd.DataFrame([[fecha, admin, fondo, contraparte, 'SMT', id, factor_recibo_fijo, fecha_flujo_f, fecha_flujo_f, fecha_pago, moneda, flujo_fijo, amortizacion, interes_fijo, 0, devengo, id_key]], columns=col_flujos_derivados)) flujos_nosensibles = flujos_nosensibles.append(pd.DataFrame([[fecha, admin, fondo, contraparte, 'SMT', id, factor_recibo_fijo, fecha_flujo_f, moneda, flujo_fijo, id_key]], columns=col_flujos_nosensibles)) self.flujos_nosensibles = flujos_nosensibles self.flujos_derivados = flujos_derivados self.set_status("INFO: Flujos generados para SMT con ID " + str(self.info_cartera.ID.iloc[0]))
def genera_flujos(self): fondo = self.info_cartera.Fondo[0] id = self.info_cartera.ID[0] fecha_fixing = pd.to_datetime( datetime.datetime.strptime( self.info_cartera.FechaFixing[0].split(" ")[0], "%d/%m/%Y").strftime("%Y-%m-%d")).date() fecha_venc = pd.to_datetime( datetime.datetime.strptime( self.info_cartera.FechaVenc[0].split(" ")[0], "%d/%m/%Y").strftime("%Y-%m-%d")).date() ajuste_feriados = self.info_cartera.AjusteFeriados[0] paises_feriados = ajuste_feriados.split(',') nocional_act = self.info_cartera.NocionalActivo[0] nocional_pas = self.info_cartera.NocionalPasivo[0] fecha_fixing_ajustada = ultimo_habil_paises(fecha_fixing, paises_feriados, self.cn) fecha_pago = siguiente_habil_paises(add_days(fecha_venc, -1), paises_feriados, self.cn) moneda_act = self.info_cartera.MonedaActivo[0] moneda_pas = self.info_cartera.MonedaPasivo[0] col_flujos_derivados = [ 'Fecha', 'Fondo', 'Tipo', 'ID', 'ActivoPasivo', 'FechaFixing', 'FechaFlujo', 'FechaPago', 'Moneda', 'Flujo', 'Amortizacion', 'Interes' ] # Se inserta activopasivo = 1 self.flujos_derivados = self.flujos_derivados.append(pd.DataFrame( [[ self.fechaActual, fondo, 'FWD', id, 1, fecha_fixing_ajustada, fecha_venc, fecha_pago, moneda_act, nocional_act, nocional_act, 0 ]], columns=col_flujos_derivados), sort='False') # Se inserta activopasivo = -1 self.flujos_derivados = self.flujos_derivados.append(pd.DataFrame( [[ self.fechaActual, fondo, 'FWD', id, -1, fecha_fixing_ajustada, fecha_venc, fecha_pago, moneda_pas, nocional_pas, nocional_pas, 0 ]], columns=col_flujos_derivados), sort='False') self.flujos_nosensibles = self.flujos_nosensibles.append(pd.DataFrame( [[ self.fechaActual, fondo, 'FWD', id, 1, fecha_venc, moneda_act, nocional_act ]], columns=self.col_flujos_nosensibles), sort='False') self.flujos_nosensibles = self.flujos_nosensibles.append(pd.DataFrame( [[ self.fechaActual, fondo, 'FWD', id, -1, fecha_venc, moneda_pas, nocional_pas ]], columns=self.col_flujos_nosensibles), sort='False') self.set_status("INFO: Flujos generados para FWD con ID " + str(self.info_cartera.ID.iloc[0]))
def genera_flujos(self): hora = self.hora cn = self.cn fecha = self.fecha admin = self.info_cartera.Administradora[0] fondo = self.info_cartera.Fondo[0] contraparte = self.info_cartera.Contraparte[0] id = self.info_cartera.ID[0] fecha_efectiva = pd.to_datetime( self.info_cartera.FechaEfectiva[0]).date() fecha_venc = pd.to_datetime(self.info_cartera.FechaVenc[0]).date() ajuste_feriados = self.info_cartera.AjusteFeriados[0] paises_feriados = ajuste_feriados.split(',') moneda = self.info_cartera.MonedaActivo[0] if self.info_cartera.TipoTasaActivo[0] == 'Fija': factor_recibo_fijo = 1 tasa = self.info_cartera.TasaActivo[0] else: factor_recibo_fijo = -1 tasa = self.info_cartera.TasaPasivo[0] nocional = self.info_cartera.NocionalActivo[0] mercado = self.info_cartera.Mercado[0] id_key = self.info_cartera.ID_Key[0] moneda_base = self.info_cartera.MonedaBase[0] if moneda_base == "--": moneda_base = moneda fecha_aux1 = fecha_str(add_days(fecha_efectiva, 1)) fecha_aux2 = fecha_str(fecha_venc) fecha_aux3 = fecha_str(add_days(max(fecha_efectiva, fecha), 1)) fecha_aux4 = fecha_str(fecha_venc) plazo_ini = ("SELECT SUM(SiHabil) AS Lab " "FROM dbAlgebra.dbo.TdFeriados " "WHERE Pais = 'BR' AND (Fecha BETWEEN " + fecha_aux1 + " AND " + fecha_aux2 + ")") plazo_ini = pd.io.sql.read_sql(plazo_ini, cn).Lab[0] plazo = ("SELECT SUM(SiHabil) AS Lab " "FROM dbAlgebra.dbo.TdFeriados " "WHERE Pais = 'BR' AND (Fecha BETWEEN " + fecha_aux3 + " AND " + fecha_aux4 + ")") plazo = pd.io.sql.read_sql(plazo, cn).Lab[0] pv = nocional / (1 + tasa / 100)**(plazo_ini / 252) if fecha < fecha_efectiva: vpv = 1 flujo_variable_presente = vpv * pv fecha_flujo_variable_presente = fecha_efectiva else: fecha_aux1 = fecha_str(add_days(fecha_efectiva, 1)) fecha_aux2 = fecha_str(add_days(max(fecha_efectiva, fecha), -1)) arr_di = ( "SELECT COALESCE ((EXP(SUM(LOG(POWER(1 + T.Valor / 100, 1 / CAST(252 AS float))))) - 1) * 100, 0) " "AS DIAcum, COUNT(*) AS N " "FROM dbAlgebra.dbo.TdTasas T " "INNER JOIN dbAlgebra.dbo.TdInfoTasas I " "ON T.Tasa = I.TickerCorto " "INNER JOIN dbAlgebra.dbo.TdFeriados F " "ON T.Fecha = F.Fecha " "WHERE (T.SiValida = 1) AND (T.Hora = 'CIERRE') AND (I.Plazo = '1D') AND (I.TipoTasa = 'SWAP') " "AND (I.MonedaActiva = 'BRL') AND (T.Fecha BETWEEN " + fecha_aux1 + " " "AND " + fecha_aux2 + ") AND (T.Valor >= 0) AND (F.Pais = 'BR') AND (F.SiHabil = 1)") arr_di = pd.io.sql.read_sql(arr_di, self.cn) if ultimo_habil_pais(fecha, "BR", cn) == fecha and plazo_ini != plazo: fecha_aux1 = fecha_str( ultimo_habil_pais(add_days(max(fecha_efectiva, fecha), -1), "BR", cn)) di_dia = ( "SELECT T.Valor AS DIDia " "FROM dbAlgebra.dbo.TdTasas T " "INNER JOIN dbAlgebra.dbo.TdInfoTasas I " "ON T.Tasa = I.TickerCorto WHERE (T.SiValida = 1) AND (T.Hora = 'CIERRE') " "AND (I.Plazo = '1D') AND (I.TipoTasa = 'SWAP') AND (I.MonedaActiva = 'BRL') " "AND (T.Fecha = " + fecha_aux1 + ")") di_dia = pd.io.sql.read_sql(di_dia, self.cn).DIDia.iloc[0] di_acum = (((arr_di.DIAcum.iloc[0] / 100) + 1) * ((1 + di_dia / 100)**(1 / 252)) - 1) * 100 else: di_acum = arr_di.DIAcum.iloc[0] vpv = (di_acum / 100) + 1 flujo_variable_presente = vpv * pv fecha_flujo_variable_presente = fecha fecha_pago = add_days(fecha_venc, -1) fecha_pago = siguiente_habil_paises(fecha_pago, paises_feriados, cn) fecha_flujo_variable = fecha_venc flujo_variable = proyectar_flujo(fecha_flujo_variable_presente, hora, fecha_venc, fecha_venc, mercado, moneda, flujo_variable_presente, moneda_base, cn) insert = dict() insert_nosensible = dict() insert["Fecha"] = fecha insert["Administradora"] = admin insert["Fondo"] = fondo insert["Contraparte"] = contraparte insert["Tipo"] = "SPD" insert["ID"] = id insert["ActivoPasivo"] = -factor_recibo_fijo insert["FechaFixing"] = fecha_flujo_variable insert["FechaFlujo"] = fecha_flujo_variable insert["FechaPago"] = fecha_pago insert["Moneda"] = moneda insert["Flujo"] = flujo_variable insert["Amortizacion"] = flujo_variable insert["Interes"] = 0 insert["Id_Key_Cartera"] = id_key self.flujos_derivados = self.flujos_derivados.append(insert, ignore_index=True) insert_nosensible["Fecha"] = fecha insert_nosensible["Administradora"] = admin insert_nosensible["Fondo"] = fondo insert_nosensible["Contraparte"] = contraparte insert_nosensible["Tipo"] = "SPD" insert_nosensible["ID"] = id insert_nosensible["ActivoPasivo"] = -factor_recibo_fijo insert_nosensible[ "FechaFlujoNoSensible"] = fecha_flujo_variable_presente insert_nosensible["Moneda"] = moneda insert_nosensible["FlujoNoSensible"] = flujo_variable insert_nosensible["Id_Key_Cartera"] = id_key self.flujos_nosensibles = self.flujos_nosensibles.append( insert_nosensible, ignore_index=True) insert["Flujo"] = nocional insert["Amortizacion"] = nocional insert_nosensible["FlujoNoSensible"] = nocional insert["FechaFixing"] = fecha_venc insert["FechaFlujo"] = fecha_venc insert_nosensible["FechaFlujoNoSensible"] = fecha_venc insert["FechaPago"] = siguiente_habil_paises(add_days(fecha_venc, -1), paises_feriados, cn) insert_nosensible["ActivoPasivo"] = factor_recibo_fijo insert["ActivoPasivo"] = factor_recibo_fijo self.flujos_derivados = self.flujos_derivados.append(insert, ignore_index=True) self.flujos_nosensibles = self.flujos_nosensibles.append( insert_nosensible, ignore_index=True) self.set_status("INFO: Flujos generados para SPD con ID " + str(self.info_cartera.ID.iloc[0]))