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)