[英]R to Python stochastic process translation
我想将下面的 R 代码翻译成 Python。
这主要是一个随机过程,我需要将其转换为 Python。
该代码实现了具有两个波动阶段的跳跃过程的马尔可夫链模拟。
set.seed(42)
nSim <- 1E5
tau <- 3
K <- 105
S0 <- 100
rf <- 0.05
vol_lo <- 0.25
vol_hi <- 0.75
lambda <- c(3,2) # away-from-lo, away-from-hi
sim_time_in_lo <- function(state0){
t <- 0
s <- state0
time_lo <- 0
while (t<tau){
dt <- rexp(n=1,lambda[s])
if ((t+dt)>tau){ dt <- tau - t}
if (s==1){time_lo <- time_lo + dt }
if (s==1){s<-2} else {s <-1}
t <- t+ dt
}
time_lo
}
tau_lo <- sapply(1:nSim,function(i){sim_time_in_lo(1)})
tau_hi <- tau - tau_lo
total_var <- tau_lo * vol_lo^2 + tau_hi * vol_hi^2
drift <- rf * tau-0.5*total_var
randomness <- sqrt(total_var)*rnorm(nSim,)
Python 尝试如下:
我认为我在 pandas 中使用了像 function 这样的 sapply。
import numpy as np
import pandas as pd
np.random.seed(42)
nSim = 1000
tau = 3
K = 105
S0 = 100
r = 0.05
vol_lo = 0.25
vol_hi = 0.75
lambd = [3,2] # away-from-lo, away-from-hi
def sim_time_in_lo(state0):
t = 0
s = state0
time_lo = 0
while (t<tau):
dt = np.random.exponential(scale = lambd[s],size = nSim)
if (t+dt)>tau:
dt = tau - t
elif s == 1:
time_lo = time_lo + dt
elif s == 1:
s = 2
else : s = 1
t = t+ dt
time_lo
df = pd.DataFrame([sim_time_in_lo(1) for i in range(1,nSim)]);df
tau_hi = tau - tau_lo
total_var = tau_lo * vol_lo**2 + tau_hi * vol_hi**2
drift = r * tau-0.5*total_var
randomness = np.sqrt(total_var)*np.random.normal(size=nSim)
但我收到一个错误
df = pd.DataFrame([sim_time_in_lo(1) for i in range(1,nSim)]);df
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我的错误是什么?
您的错误是if (t+dt)>tau
。 dt
是一个数组,它使(t+dt)>tau
成为 boolean 值的数组。
使用((t+dt)>tau).any()
或((t+dt)>tau).all()
来赋予 if 语句的含义。 .all()
表示您希望t+dt
的每个值都大于 tau,而.any()
表示如果只有一个值更大,这就足够了。
以下是使其运行的一些改进:
nSim = int(1e5)
tau = 3
K = 105
S0 = 100
r = 0.05
vol_lo = 0.25
vol_hi = 0.75
lambd = [3, 2] # away-from-lo, away-from-hi
def sim_time_in_lo(state0):
t = 0
s = state0
time_lo = 0
while t < tau:
dt = np.random.exponential(size=1, scale=1/lambd[s])
if (t + dt) > tau:
dt = tau - t
if s == 0:
time_lo = time_lo + dt
s = 1
else:
s = 0
t = t + dt
if isinstance(time_lo, np.ndarray):
return time_lo[0]
return time_lo
tau_lo = np.array([sim_time_in_lo(0) for i in range(nSim)])
tau_hi = tau - tau_lo
total_var = tau_lo * vol_lo ** 2 + tau_hi * vol_hi ** 2
drift = r * tau - 0.5 * total_var
randomness = np.sqrt(total_var) * np.random.normal(size=nSim)
nSim
是 1e5,而不是 1000。此语法也适用于 Python,但您需要转换为 int。lambd
获取值。size
参数应该是 1,返回一个标量,而不是nSim
- 这就是你得到错误的原因。return
语句,这与 R 不同(否则 Python 函数返回None
)。time_lo
初始化为大小为 1 的数组,否则有时会返回标量。 然后稍后从 size-1 arrays 中提取标量(在列表理解中)np.random.exponential
的scale
参数是 $\Beta$,即 $\frac{1}{\lambda}$。 R 的rexp
的rate
是 $\lambda$。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.