如何在 quantstrat 中使用 sigPeak() 函数

Posted

技术标签:

【中文标题】如何在 quantstrat 中使用 sigPeak() 函数【英文标题】:How to use sigPeak() function in quantstrat 【发布时间】:2019-03-26 12:40:11 【问题描述】:

我无法掌握如何在quantstrat 中正确使用sigPeak()

下面是一个(不工作的)示例。

我给mktdata添加了一个指标:

add.indicator(strategy = name,
              name = 'WinDoPar',
              arguments = list(x = quote(OHLC(mktdata)),
                               n = 300,
                               w = 'run',
                               fun = RSI_dens),
              label = 'pti',
              store = TRUE)

由于标签,它应该生成一个名为X1.pti 的列,实际上确实如此。那我想用sigPeak()加个信号:

add.signal(strategy = name,
           name = 'sigPeak',
           arguments = list(data = mktdata,
                            column = 'pti',
                            direction = 'peak'),
           label = 'pti.buy',
           store = TRUE)

sigPeak() 需要一个额外的参数,即label:但是,我不知道如何使用它。因此,当我添加这样的规则并应用该策略时,它会失败:

add.rule(strategy = name,
         name = 'ruleSignal',
         arguments = list(sigcol = 'pti.buy',
                          sigval = TRUE,
                          orderqty = 1,
                          ordertype = 'market',
                          orderside = 'long',
                          replace = TRUE,
                          osFUN = osTotSize,
                          acct.name = name,
                          TxnFees = TxnFees),
         label = 'pti.buy.enter',
         type = 'enter',
         store = TRUE)

抛出错误:

Error in applyRules(portfolio = portfolio, symbol = symbol, strategy = strategy,  : 
  mktdata does not contain 'sigcol': pti.buy

仔细查看mktdatarevelas,有一列标记如下:pti.buy.peak.sig.pti.buy,看起来很奇怪。

那么我应该如何使用sigPeak() 在指标达到峰值后生成买入信号?

【问题讨论】:

【参考方案1】:

查看源代码,sigPeak 在底层时间序列中有效地具有“三角形”模式时会生成一个信号,并在“三角形”完成时触发一个信号。将此信号与其他信号结合使用以生成有意义的交易信号是有意义的(可能使用EMA 等平滑 sigPeak 时间序列以使其更加稳健,并对其采取行动,突破 0 和 1 之间的某个阈值等)

您的错误是告诉您“pti.buy”不是mktdata 中的列名。因此,您的 add.rule 需要将 sigcol = "pti.buy" 参数更改为包含您的进入信号的列的名称。听起来应该是sigcol = "pti.buy.peak.sig.pti.buy",然后一切就可以正常工作了。

仔细检查sigPeak,当direction = "peak" 或[label].valley.sig 时,sigPeak 的列输出的名称似乎采用 [label].peak.sig.[label] 形式.[label] 当direction = "valley" 时(使用direction = "bottom" 电流会在sigPeak 中产生错误,因为sigPeak 内部的开关代码有错误)。不完全直观。

使用sigPeak 的一种简单方法是修改函数并将其作为add.signal 的函数传入。我在下面使用sigPeak2 来执行此操作。

这是一个使用 sigPeak 的可重现示例,可能会有所帮助:

library(quantstrat)
strategy.st <- "RSI"
initEq=100000
port.st<-'RSI'

rm.strat(strategy.st)
stratRSI <- strategy(strategy.st, store = TRUE)

add.indicator(strategy = strategy.st, name = "RSI", arguments = list(price = quote(getPrice(mktdata))), label="pti")


sigPeak2 <- function (label, data, column, direction = c("peak", "bottom"))  
    if (!is.numeric(column)) 
        colNum <- match.names(column, colnames(data))
    
    else colNum <- column
    direction = direction[1]
    switch(direction, peak = 
        ret_sig <- Lag(data[, colNum], 2) < Lag(data[, colNum],
                                                1) & Lag(data[, colNum], 1) > data[, colNum]
    , bottom = , valley = 
        ret_sig <- Lag(data[, colNum], 2) > Lag(data[, colNum],
                                                1) & Lag(data[, colNum], 1) < data[, colNum]
    )
    if (!missing(label))
        colnames(ret_sig) <- label
    return(ret_sig)



add.signal(strategy = strategy.st,
           name = 'sigPeak',
           arguments = list(data = quote(mktdata),
                            column = 'pti',
                            direction = 'peak'),
           label = 'drop')

add.signal(strategy = strategy.st,
           name = 'sigPeak2',
           arguments = list(data = quote(mktdata),
                            column = 'pti',
                            direction = 'bottom'),
           label = 'jump')

add.signal(strategy = strategy.st, name="sigThreshold",
           arguments = list(threshold=70, column="pti",relationship="gt", cross= TRUE),
           label="RSI.gt.70")

add.signal(strategy = strategy.st, name="sigThreshold",
           arguments = list(threshold=60, column="pti",relationship="lt", cross= TRUE),
           label="RSI.lt.60")

add.signal(strategy = strategy.st, name="sigFormula",arguments = list(formula = "RSI.gt.70 == 1 & jump == 1"),label="enterLong")

add.signal(strategy = strategy.st, name="sigFormula",arguments = list(formula = "RSI.lt.60 == 1 & drop.peak.sig.drop == 1"),label="exitLong")


add.rule(strategy = strategy.st, name='ruleSignal',
         arguments = list(sigcol="enterLong",
                          sigval=TRUE,
                          orderqty= 100,
                          TxnFees=0,
                          ordertype='market',
                          orderside='long',
                          pricemethod='market',
                          replace=FALSE),
         type='enter', path.dep=TRUE)

add.rule(strategy = strategy.st, name='ruleSignal',
         arguments = list(sigcol="exitLong",
                          sigval=TRUE,
                          orderqty='all',
                          TxnFees=0,
                          ordertype='market',
                          orderside='long',
                          pricemethod='market',
                          replace=FALSE),
         type='exit', path.dep=TRUE)



currency("USD")
symbols = c("SPY")
stock.str = symbols

startDate <- "2013-01-01"


getSymbols(stock.str,from=startDate, to= Sys.Date())


for(symbol in symbols)
    stock(symbol, currency="USD",multiplier=1)



initPortf(port.st, symbols=symbols)
initAcct(port.st, portfolios=port.st, initEq=initEq)
initOrders(portfolio=port.st)


for(symbol in symbols) addPosLimit(port.st, symbol, timestamp = startDate, maxpos = 1000) 

applyStrategy(strategy=strategy.st, portfolios=port.st)

updatePortf(strategy.st)
updateAcct(strategy.st)
updateEndEq(strategy.st)


chart.Posn(strategy.st, Symbol = 'SPY', Dates = '2000::')

【讨论】:

以上是关于如何在 quantstrat 中使用 sigPeak() 函数的主要内容,如果未能解决你的问题,请参考以下文章

quantstrat:尽管信号值似乎有效,但策略不采取立场?

r quantStrat样板.R

每月收费的再平衡策略

Quantitative Trading with R:两个简单的策略

如何安装R语言中的goseq包

(非常)使用逻辑回归的简单量子交易模型