2016-03-22 9 views
1

Я пытаюсь проверить некоторые торговые стратегии с использованием цифровой валюты. Одна из таких стратегий включает переходы MACD, но я хотел бы оптимизировать параметры nSlow & nFast.Оптимизация Quanstrat MACD с apply.paramset возвращает ошибку

Вот воспроизводимый пример (который работает):

library(httr) 
library(plyr) 
library(quantstrat) 
library(PerformanceAnalytics) 
library(IKTrading) # install_github("IlyaKipnis/IKTrading") 

poloniex.ohlc.30m <- content(GET("https://poloniex.com/public?command=returnChartData&currencyPair=BTC_ETH&start=1439010600&end=9999999999&period=1800")) # https://poloniex.com/support/api/ 
ETHBTC.30m <- ldply(poloniex.ohlc.30m, data.frame) # Convert OHLCV to data.frame 
ETHBTC.30m$date <- as.POSIXct(ETHBTC.30m$date, origin = "1970-01-01") 

# Create 'xts' object: 
ethbtc.30m.xts <- xts(ETHBTC.30m[, 2:8], order.by = ETHBTC.30m$date) # is.OHLCV(ETHBTC.30m) 

# Rebuild empty environments if RStudio's "Clear All" has been used: 
if (!exists('.instrument')) .instrument <- new.env() 
if (!exists('.blotter')) .blotter <- new.env() 
if (!exists('.strategy')) .strategy <- new.env() 

## Optional: Subset timeframe 
ETHBTC <- ethbtc.30m.xts[,c("open", "high", "low", "close", "volume")]["2016-02-01::"] 

## Define instruments 
currency(c('BTC', 'ETH')) # ls_currencies() 
exchange_rate('ETHBTC', currency = 'BTC', counter_currency = 'ETH', tick_size = 0.00001) 

initDate = '2016-02-01' 
initBTC <- 100 
initETH <- 0 

portfolio.name <- "crypto" 
account.name <- "poloniex" 
strategy.name <- "accumulator" 
symbols <- "ETHBTC" 

## To rerun 
rm.strat(portfolio.name) 
rm.strat(account.name) 
rm.strat(strategy.name) 

## Initialize Portfolio, Account, and Orderbook 
initPortf(name = portfolio.name, symbols = symbols, initPosQty = 0, initDate = initDate, currency = "BTC") # getPortfolio(portfolio.name) 
initAcct(name = account.name, portfolios = portfolio.name, initDate = initDate, initEq = 0, currency = "BTC") # getAccount(account.name) 
initOrders(portfolio = portfolio.name, symbols = symbols, initDate = initDate) # getOrderBook(portfolio.name) 
strategy(strategy.name, store = TRUE) # summary(getStrategy(strategy.name)) 

## Indicators 
# Parameters 
.nFast = 60 # 90 
.nSlow = 130 
.nSig = 45 # 75 

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

## Signals 
# See Also: applySignals add.indicator link{add.rule} sigComparison sigCrossover sigFormula sigPeak sigThreshold 
# MACD 
add.signal(strategy.name, "sigCrossover", 
      arguments = list(columns = c("macd.MACD.ind", "signal.MACD.ind"), relationship = "gt"), 
      label = 'longEntry') 
add.signal(strategy.name, "sigCrossover", 
      arguments = list(columns = c("signal.MACD.ind", "macd.MACD.ind"), relationship = "gt"), 
      label = 'signal.gt.macd') 
add.signal(strategy.name, "sigThreshold", 
      arguments = list(column = "macd.MACD.ind", threshold = 0, relationship = "gte"), 
      label = 'macd.gte.threshold') 
add.signal(strategy.name, "sigAND", 
      arguments=list(columns=c('signal.gt.macd', 'macd.gte.threshold'), cross=FALSE), 
      label="longExit") 

# Order sizing 
osFixedDollar <- function(timestamp, orderqty, portfolio, symbol, ruletype, ...) 
{ 
    ClosePrice <- as.numeric(Cl(mktdata[timestamp,])) 
    orderqty <- round(tradeSize/ClosePrice,-2) 
    return(orderqty) 
} 
tradeSize <- initBTC/2 

## Rules 
# Entry 
add.rule(strategy.name,name='ruleSignal', 
     arguments = list(sigcol="longEntry", 
          sigval=TRUE, 
          orderqty=1000, 
          ordertype='market', 
          orderside='long', 
          osFUN='osFixedDollar'), 
     type='enter', 
     label='EnterLONG', 
     storefun=FALSE) 

# Exit 
add.rule(strategy.name,name='ruleSignal', 
     arguments = list(sigcol="longExit", 
          sigval=TRUE, 
          orderqty='all', 
          ordertype='market', 
          orderside='long', 
          osFUN='osFixedDollar'), 
     type='exit', 
     label='ExitLONG', 
     storefun=FALSE) 

## Run it 
applyStrategy(strategy.name, 
       portfolios=portfolio.name, 
       parameters=list(nFast = .nFast, nSlow = .nSlow, nSig = .nSig, maType = 'EMA'), 
       verbose=TRUE) 

updatePortf(Portfolio=portfolio.name,Dates=paste('::',as.Date(Sys.time()),sep='')) 
updateAcct(account.name) 
updateEndEq(account.name) 

## Evaluate 
t(tradeStats(portfolio.name)) 
getTxns(portfolio.name, Symbol = 'ETHBTC') 
perTradeStats(portfolio.name, "ETHBTC") 

chart.Posn(Portfolio=portfolio.name,Symbol=symbols, type = "line", log.scale = T) 
plot(add_Vo()) 
plot(add_MACD(fast=.nFast, slow=.nSlow, signal=.nSig,maType="EMA")) # nFast = 60, nSlow = 180, nSig = 40, maType = 'EMA' 

Вышеприведенные работает отлично-хорошо. Тем не менее, я хочу менять nFast и nSlow параметры функции MACD():

## Parameter distribution testing 
add.distribution(strategy.name, 
       paramset.label = 'optEMA', 
       component.type = 'indicator', 
       component.label = 'nFast', 
       variable = list(nFast = 60:80), 
       label = 'NFAST') 

add.distribution(strategy.name, 
       paramset.label = 'optEMA', 
       component.type = 'indicator', 
       component.label = 'nSlow', 
       variable = list(nFast = 180:200), 
       label = 'NSLOW') 

library(doMC) 
registerDoMC(cores=detectCores()) 

results <- apply.paramset(strategy.name, paramset.label = "optEMA", portfolio=portfolio.name, account=account.name, nsamples=0) 

Это дает мне следующую ошибку, которую я не уверен, как отлаживать:

error calling combine function: 
<simpleError in fun(result.1, result.2, result.3, result.4, result.5, result.6, ... attempt to select less than one element> 

Что я делать не так? FWIW, я использую Ubuntu 12.04/14.04. Буду признателен за любую оказанную помощь. Благодаря!!

+0

Пожалуйста, не [кросс пост] (https://stat.ethz.ch/pipermail/r-sig-finance/2016q1/013837.html). Или, по крайней мере, расскажите людям, что вы перекрестно размещаете, чтобы они не тратили время на ответ на вопрос, на который уже был дан ответ на форуме, на котором они не следуют. –

+0

@JoshuaUlrich Извините. Я запомню это в будущем. – Ray

ответ

1

ОК, я понял это.

Аргумент component.label в функции add.distribution должен соответствовать аргументу label от add.indicator. Таким образом, в данном конкретном случае, я изменил мой add.indicator на:

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

А потом изменил мой add.distribution на:

add.distribution(strategy.name, 
       paramset.label = 'optEMA', 
       component.type = 'indicator', 
       component.label = 'MACD', 
       variable = list(nFast = 60:80), 
       label = 'NFAST') 

add.distribution(strategy.name, 
       paramset.label = 'optEMA', 
       component.type = 'indicator', 
       component.label = 'MACD', 
       variable = list(nSlow = 180:200), 
       label = 'NSLOW') 

И это работает. Оставив это здесь, в случае, если кто-то еще споткнется на подобную ошибку.

0

я имею более или менее та же проблема с этим кодом

################################# MACD PARAMETERS OPTIMIZATION 

.fastMA = (30:60) 
.slowMA = (50:80) 
.nsamples = 10 

# Paramset 

add.distribution(volStrat, 
       paramset.label = 'optEMA', 
       component.type = 'indicator', 
       component.label = 'macd.out', 
       variable = list(n = .fastMA), 
       label = 'nFAST' 
) 

add.distribution(volStrat, 
       paramset.label = 'optEMA', 
       component.type = 'indicator', 
       component.label = 'macd.out', 
       variable = list(n = .slowMA), 
       label = 'nSLOW' 
) 

add.distribution.constraint(volStrat, 
          paramset.label = 'optEMA', 
          distribution.label.1 = 'nFAST', 
          distribution.label.2 = 'nSLOW', 
          operator = '<', 
          label = 'optEMA' 
) 

results <- apply.paramset(volStrat, 
          paramset.label = 'optEMA', 
          portfolio = portfolio2.st, 
          account = account.st, 
          nsamples = .nsamples, 
          verbose = TRUE) 

stats <- results$tradeStats 

print(stats) 

Ошибка, которая приходит в:

Error in must.be.paramset(strategy, paramset.label) : 
    optEMA : no such paramset in strategy VIXSPY_MACD 

Я действительно не понимаю, как SELCT значение paramset.label.

Спасибо большое