You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:10:03