Optimizing Signal Parameters with Quantstrat results in error: attempt to select less than one element

Optimizing Signal Parameters with Quantstrat results in error: attempt to select less than one element

我在 quantstrat 中实施了一个简单的多头布林线策略(下面的可重现示例)。代码运行正常,但现在我想优化 sigThreshold 值(即 0.3 和 0.7)。 apply.paramset函数运行遍历定义的参数范围但最后显示错误

error calling combine function:
<simpleError in fun(result.1, result.2, 

...

result.137, result.138): attempt to select less than one element>

我不知道如何解释。 我很高兴得到任何建议。 请在下面找到代码:

require(quantstrat)
require(foreach)
require(doParallel)

startDate <- '2010-01-01'  
endDate <-  '2015-01-01'   
symbols = c('XLF')
Sys.setenv(TZ='UTC')       


getSymbols(symbols, 
           src='yahoo', 
           index.class=c('POSIXt','POSIXct'),
           from=startDate, to=endDate, 
           adjust=TRUE)


initDate <- startDate
initEq <- 1000000
currency('USD')
stock(symbols, currency='USD',multiplier=1)


rm.strat('bbands') 
initPortf(name='bbands', symbols, initDate=initDate)
initAcct(name='bbands', portfolios='bbands',
         initDate=initDate, initEq=initEq)
initOrders(portfolio='bbands', initDate=initDate)


strategy.st <- 'bbands'
account.st <- 'my.account'
portfolio.st <- 'bollinger'
strategy(strategy.st, store=TRUE)


# add indicators
add.indicator(strategy.st, name = 'BBands',
              arguments = list(HLC = quote(Cl(mktdata)), 
                               maType='SMA', 
                               n=40, 
                               sd=2), 
              label='BBands')


#add signals
add.signal(strategy.st, name='sigThreshold',
           arguments=list(column='pctB', 
                          threshold = 1.0, 
                          relationship='gt', 
                          cross=TRUE),
           label='Cl.gt.UpperBand')

add.signal(strategy.st, name='sigThreshold',
           arguments=list(column ='pctB', 
                          threshold = 0, 
                          relationship='lt', 
                          cross=TRUE),
           label='Cl.lt.LowerBand')

add.signal(strategy.st, name='sigThreshold',
           arguments=list(column ='pctB', 
                          threshold = 0.7, 
                          relationship='gte', 
                          cross = TRUE),
           label='Cl.gte.0.7')

add.signal(strategy.st, name='sigThreshold',
           arguments=list(column ='pctB', 
                          threshold = 0.3, 
                          relationship='lte', 
                          cross = TRUE),
           label='Cl.lt.0.3')



#add rules
add.rule(strategy.st, name='ruleSignal',
         arguments=list(sigcol='Cl.gt.UpperBand',
                        TxnFees = -5,
                        sigval=TRUE, 
                        orderqty= 'all',
                        ordertype='market', 
                        orderside=NULL),

         type='exit')

add.rule(strategy.st, name='ruleSignal',
         arguments=list(sigcol='Cl.lt.LowerBand',
                        TxnFees = -5,
                        sigval=TRUE, 
                        orderqty= 500, 
                        ordertype='market', 
                        orderside=NULL, 
                        osFUN=osMaxPos),
         type='enter')

add.rule(strategy.st, name='ruleSignal',
         arguments=list(sigcol='Cl.gte.0.7',
                        TxnFees = -5,
                        sigval=TRUE, 
                        orderqty= 500,
                        ordertype='market', 
                        orderside=NULL, 
                        osFUN=osMaxPos),
         type='enter')

add.rule(strategy.st, name='ruleSignal',
         arguments=list(sigcol='Cl.lt.0.3',
                        TxnFees = -5,
                        sigval=TRUE, 
                        orderqty='all',
                        ordertype='market', 
                        orderside=NULL),
         type='exit')

# add positon limit
addPosLimit('bbands', 'XLF', timestamp=initDate, maxpos=500, minpos=0)


SD = 2
N = 40

out <- applyStrategy('bbands',
  portfolios='bbands',parameters=list(sd=SD,n=N))


updatePortf('bbands')
updateAcct('bbands')
updateEndEq('bbands')

现在,这就是整个问题的内容

# start optimization here
.upper.range.distribution = seq(0.4, 0.9, by = 0.05)
.lower.range.distribution = seq(0, 0.7, by = 0.05)

add.distribution(strategy.st,
                 paramset.label = 'sigThreshold',
                 component.type = 'signal',
                 component.label = 'Cl.lt.0.3',
                 variable = list(threshold = .lower.range.distribution),
                 label = 'LOWER'
)


add.distribution(strategy.st,
                 paramset.label = 'sigThreshold',
                 component.type = 'signal',
                 component.label = 'Cl.gte.0.7',
                 variable = list(threshold = .upper.range.distribution),
                 label = 'UPPER'
)


add.distribution.constraint(strategy.st,
                            paramset.label = 'sigThreshold',
                            distribution.label.1 = 'LOWER',
                            distribution.label.2 = 'UPPER',
                            operator = '<',
                            label = 'RANGE'
)


rm.strat(portfolio.st)
rm.strat(account.st)

initPortf(portfolio.st, symbols='XLF', initDate=initDate, currency='USD')
initAcct(account.st, portfolios=portfolio.st,
         initDate=initDate, currency='USD')
initOrders(portfolio.st, initDate=initDate)



apply.paramset(strategy.st, paramset.label='sigThreshold',
               portfolio.st=portfolio.st, account.st=account.st, nsamples=0)

您需要在调用 apply.paramset 之前将头寸限制添加到您的投资组合中。您可能想将 apply.paramset 的输出分配给某些东西。使用 blotter 和 quantstrat 的最新版本对我有用。

addPosLimit(portfolio.st, 'XLF', timestamp=initDate, maxpos=500, minpos=0)
ap <- apply.paramset(strategy.st, paramset.label='sigThreshold',
    portfolio.st=portfolio.st, account.st=account.st, nsamples=0)