quantstrat中添加两个自定义指标报错:列未找到
quantstrat添加自定义K线指标触发维度名错误排查与解决
错误信息
> applyStrategy(strategy = strategy.st, portfolios = portfolio.st) Error in `dimnames<-.xts`(`*tmp*`, value = dn) : length of 'dimnames' [2] not equal to array extent In addition: Warning messages: 1: In read.table(file = file, header = header, sep = sep, quote = quote, : incomplete final line found by readTableHeader on 'https://query1.finance.yahoo.com/v7/finance/download/SPY?period1=-2208988800&period2=1679097600&interval=1d&events=split' 2: In read.table(file = file, header = header, sep = sep, quote = quote, : incomplete final line found by readTableHeader on 'https://query2.finance.yahoo.com/v7/finance/download/SPY?period1=-2208988800&period2=1679097600&interval=1d&events=split' 3: In match.names(column, colnames(data)) : all columns not located in Hammer for SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted Hammer InvertedHammer
基础代码
require(quantstrat) require(quantmod) require(FinancialInstrument) require(candlesticks) symbols = c("SPY") initDate <- "1999-01-01" from <- "2003-01-01" to <- "2015-12-31" options(width=70) options("getSymbols.warning4.0"=FALSE) #set account currency and system timezone currency('USD') stock("SPY",currency="USD",multiplier=1) Sys.setenv(TZ="UTC") tradeSize <- 1e6 initEq <- tradeSize*length(symbols) getSymbols(symbols, from=from, to=to, src="yahoo", adjust=TRUE) # Define the names of your strategy, portfolio and account strategy.st <- "firststrat" portfolio.st <- "firststrat" account.st <- "firststrat" if (!exists('.blotter')) .blotter <- new.env() if (!exists('.strategy')) .strategy <- new.env() 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)
自定义指标代码(原错误版本)
HammerCandlestickIndicator <- function( mktdata ) { out <- candlesticks::CSPHammer( mktdata, minlowershadowCL=3/4, maxuppershadowCL=.1, minbodyCL=.1 ) colnames(out) <- 'Hammer' # lets create an xts object # the index are dates and the other column is hammer indicator dates <- index(mktdata) out <- xts(x = out, order.by = dates) return(out) } add.indicator( strategy = strategy.st, name = "HammerCandlestickIndicator", arguments = list(mktdata = quote(mktdata)), label = 'Hammer' ) HangingManInvertedHammerCandleStickIndicator <- function( mktdata ) { out <- candlesticks::CSPInvertedHammer( mktdata, minuppershadowCL=3/4, maxlowershadowCL=.1, minbodyCL=.1 ) colnames(out) <- 'InvertedHammer' # lets create an xts object # the index are dates and the other column is hammer indicator dates <- index(mktdata) out <- xts(x = out, order.by = dates) return(out) } add.indicator( strategy = strategy.st, name = "HangingManInvertedHammerCandleStickIndicator", arguments = list(mktdata = quote(mktdata)), label = 'InvertedHammer' ) add.signal( strategy.st, name = "sigThreshold", arguments = list( column = "Hammer", threshold = FALSE, relationship = "gt", cross = TRUE ), label = "HammerSigEnter" ) applyStrategy(strategy = strategy.st, portfolios = portfolio.st)
问题排查
核心问题来自警告3:candlesticks包的CSPHammer/CSPInvertedHammer函数需要标准OHLC列名(Open、High、Low、Close),但quantstrat传入的mktdata列名带标的前缀(如SPY.Open、SPY.High),导致函数无法找到所需列,返回异常结果,进而引发维度名不匹配的错误。
另外,原函数中给向量设置colnames的操作无效(向量没有列名属性),后续转xts时列名设置也不规范。
解决方案
修改自定义指标函数,先将mktdata的列名重命名为标准OHLC格式,再调用candlesticks的函数,同时规范xts对象的创建:
修正后的自定义指标代码
# 修正锤子线指标函数 HammerCandlestickIndicator <- function(mktdata) { # 移除列名中的标的前缀,转为标准OHLC列名 colnames(mktdata) <- gsub("^.*\\.", "", colnames(mktdata)) # 调用CSPHammer out <- candlesticks::CSPHammer( mktdata, minlowershadowCL=3/4, maxuppershadowCL=.1, minbodyCL=.1 ) # 创建带正确列名的xts对象 out <- xts(x = out, order.by = index(mktdata), colnames = "Hammer") return(out) } add.indicator( strategy = strategy.st, name = "HammerCandlestickIndicator", arguments = list(mktdata = quote(mktdata)), label = 'Hammer' ) # 修正倒锤子线指标函数 HangingManInvertedHammerCandleStickIndicator <- function(mktdata) { # 移除列名中的标的前缀,转为标准OHLC列名 colnames(mktdata) <- gsub("^.*\\.", "", colnames(mktdata)) # 调用CSPInvertedHammer out <- candlesticks::CSPInvertedHammer( mktdata, minuppershadowCL=3/4, maxlowershadowCL=.1, minbodyCL=.1 ) # 创建带正确列名的xts对象 out <- xts(x = out, order.by = index(mktdata), colnames = "InvertedHammer") return(out) } add.indicator( strategy = strategy.st, name = "HangingManInvertedHammerCandleStickIndicator", arguments = list(mktdata = quote(mktdata)), label = 'InvertedHammer' ) # 信号与策略执行部分不变 add.signal( strategy.st, name = "sigThreshold", arguments = list( column = "Hammer", threshold = FALSE, relationship = "gt", cross = TRUE ), label = "HammerSigEnter" ) applyStrategy(strategy = strategy.st, portfolios = portfolio.st)
额外说明
- 前两个警告是Yahoo Finance下载数据时的格式问题,不影响策略执行,可忽略;若要解决,可手动处理下载的CSV文件,或切换数据源。
- 确保
candlesticks包版本正确,若仍有问题,可检查mktdata的结构,确认OHLC列存在且格式正确。
内容的提问来源于stack exchange,提问作者mythicalprogrammer
相关产品推荐
相关产品推荐

