2012-04-02 99 views
5

我正在模擬一個GARCH模型。模型本身並不太相關,我想問你的是如何優化R中的模擬。如果你看到有任何向量化空間,那麼最重要的是我已經考慮過了,但我看不到它。到目前爲止,我已經是這樣的:R中GARCH模擬

令:

# ht=cond.variance in t 
# zt= random number 
# et = error term 
# ret= return 
# Horizon= n periods ahead 

所以這是代碼:

randhelp= function(horizon=horizon){ 
    ret <- zt <- et <- rep(NA,horizon)#initialize ret and zt et 
    for(j in 1:horizon){ 
     zt[j]= rnorm(1,0,1) 
     et[j] = zt[j]*sqrt(ht[j]) 
     ret[j]=mu + et[j] 

     ht[j+1]= omega+ alpha1*et[j]^2 + beta1*ht[j] 
    } 
    return(sum(ret)) 
    } 

我想從現在起5期做回報的模擬,所以我將運行這個讓我們說10000.

#initial values of the simulation 
ndraws=10000 
horizon=5 #5 periods ahead 
ht=rep(NA,horizon) #initialize ht 
ht[1] = 0.0002 
alpha1=0.027 
beta1 =0.963 
mu=0.001 
omega=0 


sumret=sapply(1:ndraws,function(x) randhelp(horizon)) 

我認爲這是運行速度相當快,但我想問你是否有任何方式appr以更好的方式解決這個問題。

謝謝!

+1

貌似'mu'和'沒有定義omega'。你可以在循環外面移動'zt'並且一次生成所有的隨機值,然後索引它們嗎?你嘗試過'庫(編譯器)'嗎? – Chase 2012-04-02 02:03:51

+1

'library(compiler); f1 < - cmpfun(randhelp)'是所有它需要給它一個旋轉。有時它會有很大的提升,其他時間不會太多...但容易測試,所以值得一試IMHO。祝你好運 :) – Chase 2012-04-02 02:26:06

回答

4

除了在循環中使用數字之外,還可以使用大小爲N的矢量: 刪除隱藏在sapply中的循環。文森特的響應

randhelp <- function(
    horizon=5, N=1e4, 
    h0 = 2e-4, 
    mu = 0, omega=0, 
    alpha1 = 0.027, 
    beta1 = 0.963 
){ 
    ret <- zt <- et <- ht <- matrix(NA, nc=horizon, nr=N) 
    ht[,1] <- h0 
    for(j in 1:horizon){ 
    zt[,j] <- rnorm(N,0,1) 
    et[,j] <- zt[,j]*sqrt(ht[,j]) 
    ret[,j] <- mu + et[,j] 
    if(j < horizon) 
     ht[,j+1] <- omega+ alpha1*et[,j]^2 + beta1*ht[,j] 
    } 
    apply(ret, 1, sum) 
} 
x <- randhelp(N=1e5) 
5

建築,都讓我改變了一次性dfining zt和開關apply(ret, 1, sum)rowSums(ret),它加快了不少。我都嘗試編譯,但是沒有大的差異:

randhelp2 <- function(horizon = 5, N = 1e4, h0 = 2e-4, 
         mu = 0, omega = 0, alpha1 = 0.027, 
         beta1 = 0.963){ 
    ret <- et <- ht <- matrix(NA, nc = horizon, nr = N) 
    zt <- matrix(rnorm(N * horizon, 0, 1), nc = horizon) 
    ht[, 1] <- h0 
    for(j in 1:horizon){ 
     et[, j] <- zt[, j] * sqrt(ht[, j]) 
     ret[,j] <- mu + et[, j] 
     if(j < horizon) 
      ht[, j + 1] <- omega + alpha1 * et[, j]^2 + beta1 * ht[, j] 
    } 
    rowSums(ret) 
} 

system.time(replicate(10,randhelp(N=1e5))) 
    user system elapsed 
    7.413 0.044 7.468 

system.time(replicate(10,randhelp2(N=1e5))) 
    user system elapsed 
    2.096 0.012 2.112 

可能仍有提升空間:-)