【问题标题】:Generating indicators of different periodicity in quantstrat在 quantstrat 中生成不同周期的指标
【发布时间】:2023-03-05 19:58:01
【问题描述】:

我想使用与我正在使用的数据不同的时间框架指标。我已经看到这个问题问了几次,但目前还没有解决方案(至少对我来说是这样)。

以下示例使用每日股票数据,但实际项目使用日内货币数据。我现在可以轻松导入日内 csv 数据,因此示例和现实世界应该可以互换。

library(quantstrat)
initDate="2000-01-01"
from="2003-01-01"
to="2016-12-31"

#set account currency and system timezone
currency('USD')
Sys.setenv(TZ="UTC")

#get data
symbols <- "SPY"
getSymbols(symbols, from=from, to=to, src="yahoo", adjust=TRUE)
stock(symbols, "USD")

#trade sizing and initial equity settings
tradeSize <- 100000
initEq <- tradeSize*length(symbols)

#set up the portfolio, account and strategy
strategy.st <- portfolio.st <- account.st <- "mtf.strat"
rm.strat(strategy.st)
initPortf(portfolio.st, symbols=symbols, initDate=initDate, currency='USD')
initAcct(account.st, portfolios=portfolio.st, initDate=initDate, currency='USD',initEq=initEq)
initOrders(portfolio.st, initDate=initDate)
strategy(strategy.st, store=TRUE)

#SMA length
nSMA <- 14

将 SMA 添加为,在这种情况下,每日指标是一种享受

add.indicator(strategy.st, name="SMA",
              arguments=list(x=quote(Cl(mktdata)), n=nSMA, maType = "SMA"),
              label="SMA")
test <- applyIndicators(strategy.st, mktdata=OHLC(SPY))

但尝试添加,在本例中为每周 SMA

add.indicator(strategy.st, name="SMA",
              arguments=list(x=quote(to.period(Cl(mktdata), period = "weeks", k = 1, indexAt = "startof")), n=nSMA, maType = "SMA"),
              label="SMAw1")
## Or this    
add.indicator(strategy.st, name="SMA",
              arguments=list(x=quote(to.weekly(Cl(mktdata))), n=nSMA, maType = "SMA"),
              label="SMAw1")
test <- applyIndicators(strategy.st, mktdata=OHLC(SPY))
# Error in runSum(x, n) : ncol(x) > 1. runSum only supports univariate 'x'

在没有Cl(x) 的情况下直接调用关闭列会导致相同的错误。我这样做是因为TTR:::runSum 如果给出多于一列的数据,将抛出上述错误。

我不完全确定问题出在哪里,所以一些帮助会很好。

【问题讨论】:

    标签: r indicator quantstrat periodicity


    【解决方案1】:

    问题在于to.period(因此to.weekly)返回OHLC 对象,而不是像TTR::SMA 期望的单变量系列。所以你需要将to.period的输出包装在Cl中。

    add.indicator(strategy.st, name="SMA",
                  arguments=list(x=quote(Cl(to.weekly(Cl(mktdata)))), n=nSMA, maType = "SMA"),
                  label="SMAw1")
    test <- applyIndicators(strategy.st, mktdata=OHLC(SPY))
    

    现在代码运行了,但它可能仍然是您的策略的问题。当该指标与每日mktdata 合并时,将会有很多NA

    R> tail(merge(SPY, test$SMA))
               SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted SMA.SMAw1
    2016-11-25   221.10   221.56  221.01    221.52   37861800       221.52  215.0720
    2016-11-28   221.16   221.48  220.36    220.48   70284100       220.48        NA
    2016-11-29   220.52   221.44  220.17    220.91   67079400       220.91        NA
    2016-11-30   221.63   221.82  220.31    220.38   99783700       220.38        NA
    2016-12-01   220.73   220.73  219.15    219.57   77230500       219.57        NA
    2016-12-02   219.67   220.25  219.26    219.68   70863400       219.68  215.3207
    

    因此,最好创建自己的 SMA 包装函数来处理所有这些步骤。然后使用您的包装函数调用add.indicator

    mySMA <- function(x, on = "days", k = 1, n = 10) {
      agg <- x[endpoints(x, on, k)]
      sma <- SMA(agg, n)
      # merge with zero-width xts object w/original index, filling NA
      result <- merge(sma, xts(,index(x)), fill = na.locf)
      return(result)
    }
    add.indicator(strategy.st, name = "mySMA",
                  arguments = list(x = quote(Cl(mktdata)),
                                   on = "weeks",
                                   n = nSMA),
                  label = "SMAw1")
    test <- applyIndicators(strategy.st, mktdata = OHLC(SPY))
    

    现在,当指标合并时,mktdata 中的每个观察值都会有一个值。

    > tail(merge(SPY, test$SMA))
               SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted SMA.SMAw1
    2016-11-25   221.10   221.56  221.01    221.52   37861800       221.52  215.0720
    2016-11-28   221.16   221.48  220.36    220.48   70284100       220.48  215.0720
    2016-11-29   220.52   221.44  220.17    220.91   67079400       220.91  215.0720
    2016-11-30   221.63   221.82  220.31    220.38   99783700       220.38  215.0720
    2016-12-01   220.73   220.73  219.15    219.57   77230500       219.57  215.0720
    2016-12-02   219.67   220.25  219.26    219.68   70863400       219.68  215.3207
    

    【讨论】:

    • 感谢光临。我喜欢你的解决方案,但是我希望使用标准的外汇时间,例如 15 分钟或 4 小时。这就是我使用to.period() 的原因。有没有办法在这些时期使用endpoints(),或者修改您的解决方案以使用to.period()
    • mySMA &lt;- function(x, t.period, k, n = 7) { agg = to.period(x, period = t.period, k = k, indexAt = "startof") sma &lt;- SMA(Cl(agg), n) # merge with zero-width xts object w/original index, filling NA result &lt;- merge(sma, xts(,index(x)), fill = na.locf) return(result) } add.indicator(strategy.st, name = "mySMA", arguments = list(x = quote(mktdata), t.period = "hours", n = 7, k = 4), label = "h4SMA")
    • ^^抱歉以上。我不知道如何以正确的格式在 cmets 中输入代码:/ 所以我用to.period 替换了endpoints(),它可以工作,但有点乱。正如您所指出的 to.period() & co 返回一个 OHLC 对象,这意味着现在必须在包装器中处理它(如 Cl(agg))。为了尝试减少开销,我现在将所有 x 传递给 mySMA 并让包装器处理它。有没有更好的办法?这是我能想到的最佳解决方案,因为我的自定义指标需要 HLC 而不仅仅是 C;那我需要按照上面的方法处理非砑光期
    • @user3180258: to.period 在内部使用 endpoints。如果您想要每隔 15 分钟的 8 周期 SMA,请使用 mySMA(x, "minutes", 15, 8),其中 mySMA 是我编写的版本。您不能在 cmets 中对代码进行块格式编码,因为 cmets 不适合存放大块代码。 :)
    • 该死,我被endpoints() 文档蒙蔽了双眼,甚至没有正确阅读您的代码关于标准周期乘法(尽管现在已经指出它是多么明显)。谢谢你的帮助约书亚。尽管问题很大,但您在这里向我展示了很多。大起大落:)
    猜你喜欢
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    相关资源
    最近更新 更多