Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
2846 views
Kernel: Python 2 (system-wide)

Восстановление кривой из цены свопа

S2Y=1D24M0.5(D6M+D12M+D18M+D24M)S_{2Y} = \frac{1 - D_{24M}}{0.5 (D_{6M} + D_{12M} + D_{18M} + D_{24M}) }
import numpy as np import collections import matplotlib.pyplot as plt import scipy.interpolate import scipy.optimize
# Дискаунт фактор из процентной ставки # для простоты капитализация процентов не учитывается def DF(L,m): return 1.0 / (1.0 + L*0.01*m/12) # Процентная ставка из дискаунт фактора # zero coupon кривая def rate(D,m): return (1/D - 1)*100*12/m global tenors tenors = [3, 6, 9, 12, 15, 18, 21, 24] L3 = 1.120 L6 = 1.430 L12 = 1.814 S2 = 1.684
# получить по 4м значениям LIBOR интерполированный промежуточные точки def getLibors(L3, L6, L12, L24, method): if (method =='loglinear'): D18 = np.sqrt(DF(L24,24)*DF(L12,12)) L18 = rate(D18,18) D9 = np.sqrt(DF(L12,12)*DF(L6,6)) L9 = rate(D9,9) D15 = np.sqrt(DF(L12,12)*DF(L18,18)) L15 = rate(D15,15) D21 = np.sqrt(DF(L18,18)*DF(L24,24)) L21 = rate(D21,21) return [L3, L6, L9, L12, L15, L18, L21, L24.tolist()] elif method in ('cubic', 'linear', 'quadratic'): knownMonths = [3, 6, 12, 24] knownY = [L3, L6, L12, L24] f = scipy.interpolate.interp1d(knownMonths, knownY, method) return f(tenors) # посчитаем с кривой будем 3х месячные депозиты def get3M(libor, step=3): monthly = [] for i in xrange(len(libors)-1): df1=DF(libor[i],(i+1)*step) df2=DF(libor[i+1],(i+2)*step) r = (df1 / df2 - 1)/step*12*100 monthly.append(r) return monthly def showPlot(tenors, libors): plt.title('USD yield curve') plt.xlabel('Month') plt.ylabel('USD_rate') plt.plot(tenors, libors) plt.plot(tenors[0:-1], get3M(libors))

Лог-линейная интерполяция

D18M=D24MD12MD_{18M} = \sqrt{D_{24M}D_{12M}}
# x - LIBOR 24M def F(x, S2, L6, L12): S2 = 0.01*S2 D6 = DF(L6,6) D12 = DF(L12,12) D24 = DF(x,24) D18 = np.sqrt(D12*D24) return 0.5*S2*(D6 + D12 + D18 + D24) - 1 + D24 L24 = scipy.optimize.broyden1(lambda x: F(x,S2,L6,L12), 1.0, f_tol=1e-6) D18 = np.sqrt(DF(L12,12)*DF(L24,24)) libors=getLibors(L3, L6, L12, L24, 'loglinear') showPlot(tenors, libors)
1.705143874804221
Image in a Jupyter notebook

Кубические сплайны

def F(x, S2, L3, L6, L12): S2 = 0.01*S2 D6 = DF(L6,6) D12 = DF(L12,12) f = scipy.interpolate.interp1d([3,6,12,24], [L3,L6,L12,x], 'cubic') L18 = f(18) D18 = DF(L18, 18) D24 = DF(x, 24) return 0.5*S2*(D6 + D12 + D18 + D24) - 1 + D24 L24 = scipy.optimize.broyden1(lambda x: F(x,S2,L3,L6,L12), 1.0, f_tol=1e-6) libors=getLibors(L3, L6, L12, L24, 'cubic') showPlot(tenors, libors)
Image in a Jupyter notebook

Квадратичная интерполяция

def F(x, S2, L3, L6, L12): S2 = 0.01*S2 D6 = DF(L6,6) D12 = DF(L12,12) f = scipy.interpolate.interp1d([3,6,12,24], [L3,L6,L12,x], 'quadratic') L18 = f(18) D18 = DF(L18, 18) D24 = DF(x, 24) return 0.5*S2*(D6 + D12 + D18 + D24) - 1 + D24 L24 = scipy.optimize.broyden1(lambda x: F(x,S2,L3,L6,L12), 1.0, f_tol=1e-6) libors = getLibors(L3, L6, L12, L24, 'quadratic') showPlot(tenors, libors)
Image in a Jupyter notebook