【问题标题】:Backtesting Trading Strategy in R using quantmod: Function and for loop within a Function使用 quantmod 在 R 中回测交易策略:函数内的函数和 for 循环
【发布时间】:2016-01-08 23:52:53
【问题描述】:

我正在使用 R、quantmod 和 Performanceanalystics 软件包。作为回测策略的一部分,我正在尝试创建一个信号/持股向量,根据 RSI 的值告诉我是否应该买入/卖出/持有股票。如果 RSI=50,卖出所有东西(所以持股变为零)。此后,使用 Performanceanalytics 的 dailyReturn() 函数计算并生成收益图。

注意,RSI() 是一个接受“价格”和“天”的函数,dailyReturn() 函数也接受“价格”

我已经能够很好地使用下面的以下代码。

library(quantmod)
library(PerformanceAnalytics)
getSymbols("IBM", src= "yahoo", from = "2000-01-01", to ="2015-09-25")

rsi<-RSI(Cl(IBM),14)
rsi<-lag(rsi,1)
rsi[is.na(rsi)] <- 0 

holdings1 <-c() #initialize the vector
holdings1[1:14+1]<-0  #Not holding any shares of IBM from 1st to the 15th day
for (i in 14+2: length(Cl(IBM))){ #assume start buying from the 16th day onwards since we are using RSI where n=14
 if (rsi[i]<30){ #if RSI<30, we buy one share of IBM
  holdings1[i]<-holdings1[i-1]+1  
  } else if (rsi[i]>50){ # if RSI>50, we sell all holdings
  holdings1[i]<-0
 } else 
   holdings1[i]<- holdings1[i-1] # remains the same: if 30<=RSI<=50 we don't do anything, so same holdings as prior
 }
size1<-reclass(holdings1,Cl(IBM))
ret1<-dailyReturn(Cl(IBM))*size1
charts.PerformanceSummary(ret1)

但我需要创建一个名为“size1()”的函数,它接受“价格”和“天”(教授说,我不做计算)。当我尝试这样做时,RStudio 告诉我“滞后错误(rsi,1):找不到对象'rsi'”。这是为什么?在函数中创建函数或向量是否不合法?或者我应该以与上面第一个不同的方式构建我的代码? function(price,day) 的代码如下:

library(quantmod)
library(PerformanceAnalytics)
getSymbols("IBM", src= "yahoo", from = "2000-01-01", to ="2015-09-25") #download IBM, from the stipulated range of dates

size1<-function(price,day){
  ris<-RSI(price,day)
  ris<-lag(rsi,1)
  rsi[is.na(rsi)] <- 0
  holdings1<-c()
  holdings1[1:day+1]<-0
 for (i in day+2: length(price)){ #assume start buying from the 15th day onwards since we are using RSI, n=14
  if (rsi[i]<30){ #if RSI<30, we buy one share of IBM
    holdings1[i]<-holdings1[i-1]+1  
  } else if (rsi[i]<50){ # if 30<RSI<50, we don't buy or sell, so that the holdings does not change
    holdings1[i]<-holdings1[i-1]
  } else 
    holdings1[i]<-0 # sell all if RSI>50
  size<-reclass(holdings1,price)
  }
}

ret1<-dailyReturn(Cl(IBM))*size1(Cl(IBM),14)
charts.PerformanceSummary(ret1) 

【问题讨论】:

  • 您的代码中有拼写错误:ris is not rsi
  • 您好,刚刚编辑,仍然无法正常工作。 ret1&lt;-dailyReturn(Cl(IBM))*size1(Cl(IBM),14)[.xts(rsi, i) 中的错误:下标越界)charts.PerformanceSummary(ret1)(继承中的错误(x,“xts”):找不到对象 'ret1')

标签: r quantmod


【解决方案1】:

day+2:length(price) 不是您所期望的。 : 优先于 +(参见 ?Syntax)。它评估为day + (2:length(price))。你想要(day+2):length(price)。另请注意,xts 对象是具有index 属性的矩阵,而矩阵只是具有dim 属性的向量。对矩阵调用 length 会返回观察总数(向量的 length)。你应该改用nrow

for 循环之前预分配整个结果向量也是一个好习惯。当i 大于holdings 的当前长度时,每次调用holdings[i] &lt;- 时,您当前的代码都会附加到holdings

此外,您的函数目前不返回任何内容。看起来您打算返回 size 对象。请注意,您不需要在每次循环迭代时重新创建该对象。

size1 <- function (price, day) {
    rsi <- RSI(price, day)
    rsi <- lag(rsi, 1)
    rsi[is.na(rsi)] <- 0
    holdings1 <- integer(nrow(price))
    # assume start buying from the 15th day onwards,
    # since we are using RSI, n=14
    for (i in (day+1):nrow(price)) {
        if (rsi[i] < 30) {
            # if RSI<30, we buy one share of IBM
            holdings1[i] <- holdings1[i - 1] + 1
        }
        else if (rsi[i] < 50) {
            # if 30<RSI<50, we don't buy or sell,
            # so that the holdings does not change
            holdings1[i] <- holdings1[i - 1]
        } else {
            # sell all if RSI>50
            holdings1[i] <- 0
        }
    }
    reclass(holdings1, price)
}

【讨论】:

  • 您好,谢谢! :) 有效。我不太擅长区分 c()、length() 和 nrow() 之类的东西,但我现在可以看到 nrow() 是更好用的东西。我想我会通过更多的练习变得更好。再次感谢!
  • @SiangEeEo:还要注意,在向量上调用nrow 将返回NULL,因此如果您不确定,使用NROW(和NCOL)会更安全。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-18
  • 1970-01-01
  • 2018-10-31
  • 2019-02-15
  • 2021-01-06
相关资源
最近更新 更多