Python for finance
Python sample codes for finance
Simple random walk
Source code:
import numpy as np
import matplotlib.pyplot as plt
import seaborn
seaborn.set_style("whitegrid")
N = 100
X = np.random.choice([-1,1],N)
X[0]=0
RW = np.cumsum(X)
plt.figure(figsize=(19.2,10.8))
plt.plot(RW,label='Random Walk')
plt.legend()
Geometric simple random walk
Source code:
import numpy as np
import matplotlib.pyplot as plt
import seaborn
seaborn.set_style("whitegrid")
N = 2 ** 7
n = np.arange(0, N)
X = np.random.choice([-1,1],N)
X[0]=0
S0=200
RW = np.cumsum(X)
GRW=S0*np.exp(RW/100)
plt.figure(figsize=(19.2,10.8))
plt.plot(n,GRW,label='Geometric Random Walk')
plt.legend()
A sample path of a standard Brownian motion
Source code:
import numpy as np
import matplotlib.pyplot as plt
from pylab import *
import japanize_matplotlib
T = 1
N = 2 ** 20
dt = T / N
t = np.arange(0, T, dt)
dW = np.sqrt(dt) * np.random.randn(N)
dW[0] = 0
W = np.cumsum(dW)
plt.figure(figsize=(38.4,21.6))
plt.grid(True)
plt.title(r'ブラウン運動のサンプルパス$\{W_t\}_{t\in[0,1]}$',fontsize=60,y=1.025)
mpl.rcParams['axes.xmargin'] = 0.0
plt.xlabel("$t$",fontsize=60)
plt.ylabel("$W_t$",fontsize=60)
plt.yticks(fontsize=60)
plt.xticks(fontsize=60)
plt.plot(t, W, color='royalblue',lw=0.5)
plt.savefig('bm.pdf',transparent=True)
plt.show()
A sample path of a exponential Brownian motion (Black-Sholes-Merton model)
Source code:
import numpy as np
import matplotlib.pyplot as plt
from pylab import *
T = 1
S0 = 1.14514
sigma = 1.14514
mu = 0.810
N = 2 ** 15
dt = T / N
t = np.arange(0, T, dt)
dW = np.sqrt(dt) * np.random.randn(N)
dW[0] = 0
W = np.cumsum(dW)
GW = S0 * np.exp(mu * t -(1/2) * (sigma ** 2) * t + sigma * W)
plt.figure(figsize=(19.2,10.8))
plt.xlabel("$t$")
plt.ylabel("$S_t$")
plt.plot(t, GW, color='m')
title('A sample path of an exponential Brownian motion: $dS_t=\mu S_t dt+ \sigma S_t dW_t, \mu=0.810,\sigma=1.14514, S_0=1.14514,t\in [0,1].$')
grid(True)
plt.show()
plt.savefig('GBM.pdf')
A sample path of constant elasticity of variance model
source code:
import numpy as np
import matplotlib.pyplot as plt
from pylab import *
sigma = 0.810
mu = 0.05
S0 = 114.514
T = 1
N = 2**22
dt = T / N
gamma=0.60
t = np.arange(0.0, T, dt)
dW = np.sqrt(dt) * np.random.randn(N)
dW[0] = 0
W = np.cumsum(dW)
Sem = np.zeros(N)
Stemp = S0
Sem[0] = Stemp
for j in range(1, N):
Stemp = Stemp + dt * mu * (Stemp) + sigma * pow(Stemp,gamma) * dW[j]
Sem[j] = Stemp
plt.figure(figsize=(19.2,10.8))
title('$dS_t=\mu S_t dt+ \sigma S_t^{\gamma} dW_t, \mu=0.05,\sigma=0.810,\gamma=0.60, S_0=114.514,t\in [0,1].$')
grid(True)
plt.plot(t, Sem, color='b')
plt.xlabel("$t$")
plt.ylabel("$S_t$")
plt.show()
Black-Sholes-Merton model
Prices for call and put options
Price and Hedge for digital option
Source code:
import numpy as np
import matplotlib.pyplot as plt
import seaborn
seaborn.set_style("whitegrid")
from scipy import stats
T = 1
S0 = 1
K = 1.14
sigma = 1.14
mu = 0.514
r = 0.0114
N = 114514
dt = T / N
t = np.arange(0.0, T, dt)
tau = T-t
res = np.exp(-r*tau)
dW = np.sqrt(dt) * np.random.randn(N)
dW[0] = 0
W = np.cumsum(dW)
GW = S0*np.exp(mu*t-0.5*(sigma**2)*t+sigma*W)
bunbo1 = 1/(sigma*pow(2*np.pi*tau, 1/2))
sigma2 = sigma ** 2
bunbo2 = (-1)/(2*tau*sigma2)
bunsi = (np.log (GW/K)+(r-sigma2/2)*tau) ** 2
d1 = (np.log(GW/K) + (r + 0.5 * sigma ** 2)*tau)/(sigma*pow(tau, 1/2))
d2 = (np.log(GW/K) + (r - 0.5 * sigma ** 2)*tau)/(sigma*pow(tau, 1/2))
hedge = res*(1/GW)*bunbo1*np.exp(bunbo2*bunsi)
price = res*stats.norm.cdf(d2)
call = GW * stats.norm.cdf(d1) - K * np.exp(-r*tau) * stats.norm.cdf(d2)
put = K * np.exp(-r*T) * stats.norm.cdf(-d2) - GW * stats.norm.cdf(-d1)
parity=call-put-GW+K * np.exp(-r*tau)
plt.figure(figsize=(16,10))
plt.xlabel("Time")
plt.ylabel("Value")
plt.plot(t, GW, label='Price of stock')
plt.plot(t, price, label='Price of digital option')
plt.plot(t, hedge, label='Hedging for digital option')
plt.plot(t, call, label='Price of call option')
plt.plot(t, put, label='Price of put option')
plt.plot(t, parity, label='Put-Call parity')
plt.legend()
Black–Scholes formula
T: maturity
S: stock price at T
K: strike price
r: interest rate
sigma: volatility
If (S,K,r,sigma,T)=(1.1, 1.2, 0.810,1.14, 1), then,
(Price of digital option, Price of European call option, Price of European put option)
=(0.2338150547042821, 0.6937402932060835, 0.12756997267361284).
Source code:
#Black–Scholes formula
import numpy as np
import scipy.stats as stat
def BS_model(S,K,r,sigma,T):
d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
d2 = (np.log(S/K) + (r - 0.5 * sigma ** 2)*T)/(sigma*pow(T, 1/2))
digital = np.exp(-r*T) * stat.norm.cdf(d2)
#Price of digital option
call = S * stat.norm.cdf(d1) - K * np.exp(-r * T) * stat.norm.cdf(d2)
#Price of the European call option
put = K * np.exp(-r*T) * stat.norm.cdf(-d2) - S * stat.norm.cdf(-d1)
#Price of the European put option
return digital,call,put
BS_model(1.1, 1.2, 0.810,1.14, 1)