Python: CIR过程蒙特卡洛模拟

Python: CIR过程蒙特卡洛模拟

众所周知,利率是随着时间的变化而随机变化的,本文简要说明了两种常用的随机利率过程,并基于Python用蒙特卡洛的方法对随机利率进行模拟。

(未完待续 …)

Introduction

最常用的随机利率模型包括:OU 过程和 CIR 过程:

  • The OU process:

d r t = α ( μ − r t ) d t + σ d W t (1) d r_{t}=\alpha\left(\mu-r_{t}\right) d t+\sigma d W_{t}\tag{1} drt=α(μrt)dt+σdWt(1)

  • The CIR process:

d r t = α ( μ − r t ) d t + σ r t d W t (2) d r_{t}=\alpha\left(\mu-r_{t}\right) d t+\sigma \sqrt{r_{t}} d W_{t}\tag{2} drt=α(μrt)dt+σrt dWt(2)

where μ \mu μ 是均值回归的水平 and α \alpha α 是均值回归的速度。

利率虽然是随机的,但不会长久偏离均值水平,因而是均值回归的。OU 过程服从正态分布,而 CIR 过程服从一个非中心的卡方分布(具体可以看维基上的说明)。CIR 过程优于OU过程之处在于, 可以保证利率的非负性。

Monte Carlo Simulation

对于以上两个随机过程的离散,通常有两种方法: Euler–Maruyama Method and the Milstein Method。和一般的不带随机变量的差分相似,两种方法的区别在于在不同的地方对泰勒展开公式进行截断,然而由于随机项的引入,我们需要用Ito-Taylor对其进行展开(具体的推导,我找到的最清楚(读得懂)的证明即参考文献中的’Ito Taylor Expansion’)。
X ( t i + 1 ) = X ( t i ) + a [ X ( t i ) ] Δ t + b [ X ( t i ) ] Δ W i + 1 2 b [ X ( t i ) ] b ′ [ X ( t i ) ] [ ( Δ W i ) 2 − Δ t ] + O ( Δ t ) X\left(t_{i+1}\right)=X\left(t_{i}\right)+a\left[X\left(t_{i}\right)\right] \Delta t+b\left[X\left(t_{i}\right)\right] \Delta W_{i}+\frac{1}{2} b\left[X\left(t_{i}\right)\right] b^{\prime}\left[X\left(t_{i}\right)\right]\left[\left(\Delta W_{i}\right)^{2}-\Delta t\right]+\mathcal{O}(\Delta t) X(ti+1)=X(ti)+a[X(ti)]Δt+b[X(ti)]ΔWi+21b[X(ti)]b[X(ti)][(ΔWi)2Δt]+O(Δt)
如上所示, Euler-Maruyama 是对上式的一阶截断, 而 Milstein 是对上式的二阶截断。这里的 O \mathcal{O} O 表示剩余的项是

Δ t \Delta t Δt 的高阶项。

因而,我们有以下的两个离散表达式:

Specifically, for the CIR process, we have a [ r ] = α ( μ − r ) a[r] = \alpha(\mu - r) a[r]=α(μr), b [ r ] = σ r b[r]=\sigma\sqrt{r} b[r]=σr , and b ′ [ r ] = 1 2 σ r b'[r]=\frac{1}{2}\frac{\sigma}{\sqrt{r}} b[r]=21r σ.

  • The Euler-Maruyama Method:

r j = r j − 1 + α ( μ − r j − 1 ) Δ t + σ r j − 1 Δ W j , j = 1 , 2 , … , L r_{j}=r_{j-1}+\alpha\left(\mu - r_{j-1}\right) \Delta t+\sigma\sqrt{r_{j-1}}\Delta W_j, \quad j=1,2, \ldots, L rj=rj1+α(μrj1)Δt+σrj1 ΔWj,j=1,2,,L

where Δ W j = Δ t N ( 1 , 0 ) \Delta W_j = \sqrt{\Delta t}N(1,0) ΔWj=Δt N(1,0).

  • The Milstein Method:

r j = r j − 1 + α ( μ − r j − 1 ) Δ t + σ r j − 1 Δ W j + σ 2 2 [ ( Δ W j ) 2 − Δ t ] , j = 1 , 2 , … , L r_{j}=r_{j-1}+\alpha\left(\mu - r_{j-1}\right) \Delta t+\sigma\sqrt{r_{j-1}}\Delta W_j+\frac{\sigma^2}{2}[(\Delta W_j)^2-\Delta t], \quad j=1,2, \ldots, L rj=rj1+α(μrj1)Δt+σrj1 ΔWj+2σ2[(ΔWj)2Δt],j=1,2,,L

The weak and strong convergence rate of Euler-Maruyama are \mathcal{} O ( Δ t ) \mathcal{O}(\Delta t) O(Δt). The Milstein scheme has the same weak convergence but better strong convergence rate of O ( Δ t ) \mathcal{O}(\sqrt{\Delta t)} O(Δt) . The detail definition of the weak and the strong convergence rate refer to Higham (2001). (这篇文章是我一个师兄推荐给我的,我学习蒙特卡洛模拟也是从这篇文章开始的,后来有个刚读博士的泰国美女询问我如何做随机过程的蒙特卡洛模拟时,我也把这篇文章推荐给了她,分享使我们快乐。)

Python Code

因为我觉得以后有时间可以在这个问题上玩出朵花来,所以我先写了一个类:

# -*- coding: utf-8 -*-
"""
Created on Wed Feb 26 22:42:55 2020

@author: Shecan

please save the file as CIR.py
"""
import numpy as np

class CIR(object):
    def __init__(self, alpha, mu, sigma, r0):
         self.alpha = alpha # mean-reverted speed
         self.mu = mu # mean-reverted level
         self.sigma = sigma # vol of interest rate
         self.r0 = r0 # initial interest rate
        
    def Euler(self,t_init,t_end,dt):
        np.random.seed(5)
        ts = np.arange(t_init, t_end, dt)
        dW = np.random.normal(loc=0.0, scale=np.sqrt(dt),size = ts.size)
        r = []
        r.append(self.r0)
        for i in range(1, ts.size):
            r.append(r[i-1] + self.alpha*(self.mu-r[i-1])*dt 
                     + self.sigma*np.sqrt(r[i-1])*dW[i-1])
        return r
    
    def Milstein(self,t_init,t_end,dt):
        np.random.seed(5)
        ts = np.arange(t_init, t_end, dt)
        dW = np.random.normal(loc=0.0, scale=np.sqrt(dt),size = ts.size)
        r = []
        r.append(self.r0)
        for i in range(1, ts.size):
            dw = dW[i-1]
            r.append(r[i-1] + self.alpha*(self.mu-r[i-1])*dt 
                     + self.sigma*np.sqrt(r[i-1])*dw + 
                     (self.sigma**2/2)*(dw**2 - dt))
        return r

然后我们在 Jupyter notebook中调用以上的类,

from CIR import CIR # from the module CIR load our class-file CIR
import matplotlib.pyplot as plt
# assume mean-reverted speed = 1, mean-reverted level = 0.05, vol of interest rate = 0.05, initial interest rate = 0.05, and pass to an object named C 
C = CIR(1,0.05,0.05,0.05)
# For Euler method
r = C.Euler(0,1,0.001) # start time = 0, end time = 1, dt = 0.01
# For Milstern method
r1 = C.Milstein(0,1,0.001)
# Plot and compare
plt.figure(figsize=(20,10))
l1,=plt.plot(r)
l2,=plt.plot(r1,'b*',markersize=4)
plt.ylabel('interest rate r',fontsize = 20)
plt.legend(handles=[l1, l2], labels=['Euler', 'Milstein'], fontsize = 16)

Visualizing the results:
Python: CIR过程蒙特卡洛模拟_第1张图片

Reference

CIR Modeling of Interest Rates

http://lnu.diva-portal.org/smash/get/diva2:1270329/FULLTEXT01.pdf

Enlightened reading material

Higham, D. J. (2001). An algorithmic introduction to numerical simulation of stochastic differential equations. SIAM review, 43(3), 525-546.

Ito-Taylor Expansion

https://www.math.nyu.edu/~cai/Courses/Derivatives/compfin_lecture_5.pdf

结束语:我做笔记博客主要有三个目的:1. 在疫情长假期间,闲下来有时间思考人生(睡觉),深刻意识到自己一直在追求一些浮名薄利,一味好高骛远却导致一事无成,却忽略了最根本的积累,因而通过博客逼迫自己把每一个小的问题搞清楚并记录下来。2. 虽然生活和事业收获了很多的帮助和良师益友,但是科研和学习主要靠自己摸索(仰视巨人的肩膀然后脑补),难免有一些异想天开的不足,希望各路大神走过路过飘过能留下足迹,让我进步。3. 希望我的行为能帮助到同行人,也算是一点贡献,不枉此生。

你可能感兴趣的:(笔记,python,概率论)