1

在使用自定义指标时,我正在寻找 Quantstrat 中的参数优化代码示例。我可以在网上找到的大多数示例都使用 SMA、MACD 和其他经典指标。这对我没有多大帮助,因为我主要希望使用自定义指标优化交易系统。

有没有人有相关的链接或材料?

更具体地说,我第一次尝试指标优化选项。我使用的指标是 MACD 森林的动量。我正在尝试评估该指标与通常的 MACD 交叉信号线的有效性。但我不想过多关注这个特定指标,因为我的目标是为我将使用的未来自定义指标提供可行的优化代码。

这是代码,数据是日内 EURUSD 报价(5 分钟蜡烛):

library(quantstrat)


Sys.setenv(TZ = "UTC")

currency(c('EUR', 'USD'))

exchange_rate(c('EURUSD'), tick_size=0.0001)


init_date <- "2018-01-07"
start_date <- "2018-01-08"
end_date <- "2018-01-08"
init_equity <- 1e8 # $100,000,000
adjustment <- FALSE

basic_symbols <- function() {
  symbols <- c(
       "EUR" 
      )
}

  symbols <- basic_symbols()


portfolio.st <- "Port.Luxor.Opt"  
account.st <- "Acct.Luxor.Opt"
strategy.st <- "Strat.Luxor.Opt"

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

initPortf(name = portfolio.st, 
          symbols = symbols,
          initDate = init_date)

initAcct(name = account.st,
         portfolios = portfolio.st,
         initDate = init_date,
         initEq = init_equity)

initOrders(portfolio = portfolio.st,
           symbols = symbols,
           initDate = init_date)

strategy(strategy.st, store = TRUE) 

fastMA_custom = 12
fastMA_custom2 = 12
slowMA_custom = 26
slowMA_custom2 = 26
signalMA_custom = 9
signalMA_custom2 = 9
maType="EMA"
MAforest = 3

forest <- function(x){
  step1 <- EMA(x,fastMA_custom)
  step2 <- EMA(x,slowMA_custom)
  step3 <- step1-step2
  step4 <- EMA(step3,signalMA_custom)
  step5 <- step3-step4
  return(step5)
}

smaforest <- function(x){
  step1 <- EMA(x,fastMA_custom2)
  step2 <- EMA(x,slowMA_custom2)
  step3 <- step1-step2
  step4 <- EMA(step3,signalMA_custom2)
  step5 <- step3-step4
  step6 <- EMA(step5,MAforest)
  return(step6)
}

add.indicator(strategy = strategy.st,
              name ="forest",
              arguments = list(x=quote(Cl(mktdata))),
              label="forest")

add.indicator(strategy=strategy.st,
              name ="smaforest",
              arguments = list(x=quote(Cl(mktdata))),
              label="smaforest")

add.distribution(strategy.st,
                 paramset.label = "forestopt",
                 component.type = "indicator",
                 component.label = "forest",
                 variable = list(fastMA_custom= 8:14),
                 label = "fastMA_custom")

add.signal(strategy = strategy.st,
           name="sigCrossover",
           arguments = list(columns = c("forest", "smaforest"),
                            relationship = "gte"),
           label = "long")

add.signal(strategy = strategy.st,
           name="sigCrossover",
           arguments = list(columns = c("forest", "smaforest"),
                            relationship = "lte"),
           label = "short")

add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(sigcol = "long",
                          sigval = TRUE,
                          orderqty = 100000,
                          ordertype = "market",
                          orderside = "long", 
                          TxnFees = -1, 
                          replace = FALSE),
         type = "enter",
         label = "EnterLONG")

add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(sigcol = "short",
                          sigval = TRUE,
                          orderqty = -100000,
                          ordertype = "market",
                          orderside = "short", 
                          replace = FALSE, 
                          TxnFees = -1
                          ),
         type = "enter",
         label = "EnterSHORT")

add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "short", 
                          sigval = TRUE, 
                          orderside = "long", 
                          ordertype = "market", 
                          orderqty = "all", 
                          TxnFees = -1, 
                          replace = TRUE), 
         type = "exit", 
         label = "Exit2SHORT")


add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "long", 
                          sigval = TRUE, 
                          orderside = "short", 
                          ordertype = "market", 
                          orderqty = "all", 
                          TxnFees = -1, 
                          replace = TRUE), 
         type = "exit", 
         label = "Exit2LONG")

addPosLimit(portfolio.st, 'EUR', timestamp=initDate, maxpos=500, minpos=0)


resultsopt <- apply.paramset(strategy.st,
                          paramset.label = "forestopt",
                          portfolio.st = portfolio.st,
                          account.st = account.st, 
                          nsamples = 0)

没有优化部分的回测工作完美。这实际上是导致错误的优化位。

这是我得到的错误:

调用组合函数时出错:“有趣的simpleError(result.1,result.2,result.3,result.4,result.5,result.6,result.7):尝试选择少于一个元素”

4

1 回答 1

0

下次请提供可重现的数据集。

这是与您的代码非常相似的示例代码,可用于优化自定义指标。希望您应该如何调整代码变得清晰。你做错了一些事情。特别是,您必须为forest或您要在 quantstrat 中优化的任何其他自定义函数提供形式参数。通常,默认情况下全局定义所有“n”变量是个坏主意。将它们直接提供到add.indicator调用中的参数中。就像下面为forest函数所做的一样。

library(quantstrat)


Sys.setenv(TZ = "UTC")

currency(c('USD'))

symbols <- "AAPL"
getSymbols(symbols)

stock(symbols, currency = "USD")


AAPL <- AAPL["2016/"]

init_date <- "2017-01-07"
start_date <- "2018-01-31"
end_date <- "2018-01-31"
init_equity <- 1e8 # $100,000,000
adjustment <- FALSE


portfolio.st <- "Luxor.Opt"  
account.st <- "Luxor.Opt"
strategy.st <- "Luxor.Opt"

rm.strat(name = portfolio.st)   

initPortf(name = portfolio.st, 
          symbols = symbols)

initAcct(name = account.st,
         portfolios = portfolio.st,
         initEq = init_equity)

initOrders(portfolio = portfolio.st,
           symbols = symbols)

strategy(strategy.st, store = TRUE) 


fastMA_custom2 = 12

slowMA_custom2 = 26

signalMA_custom2 = 9
maType="EMA"
MAforest = 3

forest <- function(x, fastMA_custom, slowMA_custom, signalMA_custom){
  step1 <- EMA(x,fastMA_custom)
  step2 <- EMA(x,slowMA_custom)
  step3 <- step1-step2
  step4 <- EMA(step3,signalMA_custom)
  step5 <- step3-step4
  return(step5)
}

smaforest <- function(x){
  step1 <- EMA(x,fastMA_custom2)
  step2 <- EMA(x,slowMA_custom2)
  step3 <- step1-step2
  step4 <- EMA(step3,signalMA_custom2)
  step5 <- step3-step4
  step6 <- EMA(step5,MAforest)
  return(step6)
}

add.indicator(strategy = strategy.st,
              name ="forest",
              arguments = list(x=quote(Cl(mktdata)),
                               fastMA_custom = 12,
                               slowMA_custom = 26,
                               signalMA_custom = 9
                               ),
              label="forest")

add.indicator(strategy=strategy.st,
              name ="smaforest",
              arguments = list(x=quote(Cl(mktdata))),
              label="smaforest")


add.signal(strategy = strategy.st,
           name="sigCrossover",
           arguments = list(columns = c("forest", "smaforest"),
                            relationship = "gte"),
           label = "long")

add.signal(strategy = strategy.st,
           name="sigCrossover",
           arguments = list(columns = c("forest", "smaforest"),
                            relationship = "lte"),
           label = "short")

add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(sigcol = "long",
                          sigval = TRUE,
                          orderqty = 100000,
                          ordertype = "market",
                          orderside = "long", 
                          TxnFees = -1, 
                          replace = FALSE),
         type = "enter",
         label = "EnterLONG")

add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(sigcol = "short",
                          sigval = TRUE,
                          orderqty = -100000,
                          ordertype = "market",
                          orderside = "short", 
                          replace = FALSE, 
                          TxnFees = -1
         ),
         type = "enter",
         label = "EnterSHORT")

add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "short", 
                          sigval = TRUE, 
                          orderside = "long", 
                          ordertype = "market", 
                          orderqty = "all", 
                          TxnFees = -1, 
                          replace = TRUE), 
         type = "exit", 
         label = "Exit2SHORT")


add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "long", 
                          sigval = TRUE, 
                          orderside = "short", 
                          ordertype = "market", 
                          orderqty = "all", 
                          TxnFees = -1, 
                          replace = TRUE), 
         type = "exit", 
         label = "Exit2LONG")

addPosLimit(portfolio.st, symbols[], timestamp=init_date, maxpos=500, minpos=0)

# applyStrategy(strategy.st, portfolio.st)
# 
# updatePortf(portfolio.st)
# tradeStats(portfolio.st, symbols)


# Portfolio Symbol Num.Txns Num.Trades Net.Trading.PL Avg.Trade.PL Med.Trade.PL Largest.Winner Largest.Loser Gross.Profits Gross.Losses Std.Dev.Trade.PL Std.Err.Trade.PL Percent.Positive Percent.Negative Profit.Factor
# AAPL Luxor.Opt   AAPL      127         63       -45123.5    -28493.01     -46000.1        1328999      -1047001      10371975    -12167035           474783         59817.04         42.85714         57.14286     0.8524653
# Avg.Win.Trade Med.Win.Trade Avg.Losing.Trade Med.Losing.Trade Avg.Daily.PL Med.Daily.PL Std.Dev.Daily.PL Std.Err.Daily.PL Ann.Sharpe Max.Drawdown Profit.To.Max.Draw Avg.WinLoss.Ratio Med.WinLoss.Ratio Max.Equity Min.Equity
# AAPL      384147.2      305999.5        -337973.2        -298000.6    -28493.01     -46000.1           474783         59817.04  -0.952672     -3182097        -0.01418043           1.13662          1.026842   985976.4   -2196121
# End.Equity
# AAPL   -45123.5

add.distribution(strategy.st,
                 paramset.label = "forestopt",  #The label we will use when we want to run this optimisation in paramset
                 component.type = "indicator", # The custom function is of indicator type (not other alternatives including signal or rule)
                 component.label = "forest", #this is the name of your custom function
                 variable = list(fastMA_custom = seq(8, 12, by = 2)),
                 label = "myForestOptLabel") #choose whatever you want

resultsopt <- apply.paramset(strategy.st,
                             paramset.label = "forestopt",
                             portfolio.st = portfolio.st,
                             account.st = account.st, 
                             nsamples = 0)

# Check, results are equal in the case where fastMA_custom = 12 compared to when running `applyStrategy`:

resultsopt$tradeStats
# myForestOptLabel   Portfolio Symbol Num.Txns Num.Trades Net.Trading.PL Avg.Trade.PL Med.Trade.PL Largest.Winner Largest.Loser Gross.Profits Gross.Losses Std.Dev.Trade.PL Std.Err.Trade.PL Percent.Positive Percent.Negative
# 1                8 Luxor.Opt.1   AAPL       97         48      2609902.7     23790.64    -34500.75        1405999      -1055001       9615975     -8474024         492362.4         71066.39         43.75000         56.25000
# 2               10 Luxor.Opt.2   AAPL      105         52      -340106.5    -34770.27    -52500.75        1405999      -1047001       8538977    -10347031         480790.5         66673.64         40.38462         59.61538
# 3               12 Luxor.Opt.3   AAPL      127         63       -45123.5    -28493.01    -46000.10        1328999      -1047001      10371975    -12167035         474783.0         59817.04         42.85714         57.14286
# Profit.Factor Avg.Win.Trade Med.Win.Trade Avg.Losing.Trade Med.Losing.Trade Avg.Daily.PL Med.Daily.PL Std.Dev.Daily.PL Std.Err.Daily.PL Ann.Sharpe Max.Drawdown Profit.To.Max.Draw Avg.WinLoss.Ratio Med.WinLoss.Ratio Max.Equity
# 1     1.1347590      457903.6      386998.5        -313852.8        -237000.5     23790.64    -34500.75         492362.4         71066.39  0.7670464     -2444032         1.06786773          1.458976          1.632902  3585933.7
# 2     0.8252586      406617.9      334998.1        -333775.2        -245002.2    -34770.27    -52500.75         480790.5         66673.64 -1.1480282     -3152090        -0.10789872          1.218239          1.367327  1343982.9
# 3     0.8524653      384147.2      305999.5        -337973.2        -298000.6    -28493.01    -46000.10         474783.0         59817.04 -0.9526720     -3182097        -0.01418043          1.136620          1.026842   985976.4
# Min.Equity End.Equity
# 1   -1122012  2609902.7
# 2   -1808107  -340106.5
# 3   -2196121   -45123.5

# Results for  fastMA_custom = 12 are identical.

上面我还展示了如何apply.paramsets通过 for n = 12 将输出与个别情况进行比较来快速检查输出。进行apply.Strategy此类检查是个好主意。

于 2018-02-08T05:32:35.010 回答