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)