2016-11-29 12 views
2

Я хотел бы использовать индикаторы таймфреймов, отличных от данных, которые я использую. Я видел, как это просило несколько раз, но пока нет решений (по крайней мере, для меня в любом случае).Создание индикаторов различной периодичности в квантстрате

В приведенном ниже примере используются ежедневные данные о запасах, однако фактический проект использует данные внутридневной валюты. У меня есть легкая работа для импорта внутридневных данных csv, поэтому пример и реальный мир должны быть взаимозаменяемыми.

library(quantstrat) 
initDate="2000-01-01" 
from="2003-01-01" 
to="2016-12-31" 

#set account currency and system timezone 
currency('USD') 
Sys.setenv(TZ="UTC") 

#get data 
symbols <- "SPY" 
getSymbols(symbols, from=from, to=to, src="yahoo", adjust=TRUE) 
stock(symbols, "USD") 

#trade sizing and initial equity settings 
tradeSize <- 100000 
initEq <- tradeSize*length(symbols) 

#set up the portfolio, account and strategy 
strategy.st <- portfolio.st <- account.st <- "mtf.strat" 
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) 

#SMA length 
nSMA <- 14 

Добавление SMA, как в этом случае ежедневный индикатор работает лакомство

add.indicator(strategy.st, name="SMA", 
       arguments=list(x=quote(Cl(mktdata)), n=nSMA, maType = "SMA"), 
       label="SMA") 
test <- applyIndicators(strategy.st, mktdata=OHLC(SPY)) 

же пытается добавить, в этом случае еженедельно SMA

add.indicator(strategy.st, name="SMA", 
       arguments=list(x=quote(to.period(Cl(mktdata), period = "weeks", k = 1, indexAt = "startof")), n=nSMA, maType = "SMA"), 
       label="SMAw1") 
## Or this  
add.indicator(strategy.st, name="SMA", 
       arguments=list(x=quote(to.weekly(Cl(mktdata))), n=nSMA, maType = "SMA"), 
       label="SMAw1") 
test <- applyIndicators(strategy.st, mktdata=OHLC(SPY)) 
# Error in runSum(x, n) : ncol(x) > 1. runSum only supports univariate 'x' 

Calling Закрыть столбец напрямую без Cl(x) приводит к той же ошибке. Я сделал это, так как TTR:::runSum выбросит вышеуказанную ошибку, если будет предоставлено более одного столбца данных.

Я не совсем уверен, в чем проблема, поэтому некоторая помощь будет отличной.

ответ

3

Проблема в том, что to.period (и поэтому to.weekly) возврат OHLC объектов, а не одномерный ряд, такой как TTR::SMA ожидает. Поэтому вам нужно обернуть вывод to.period в Cl.

add.indicator(strategy.st, name="SMA", 
       arguments=list(x=quote(Cl(to.weekly(Cl(mktdata)))), n=nSMA, maType = "SMA"), 
       label="SMAw1") 
test <- applyIndicators(strategy.st, mktdata=OHLC(SPY)) 

Теперь, когда код работает, но это может быть проблемой для вашей стратегии. Там будет много NA, когда этот индикатор будет объединен с ежедневным mktdata.

R> tail(merge(SPY, test$SMA)) 
      SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted SMA.SMAw1 
2016-11-25 221.10 221.56 221.01 221.52 37861800  221.52 215.0720 
2016-11-28 221.16 221.48 220.36 220.48 70284100  220.48  NA 
2016-11-29 220.52 221.44 220.17 220.91 67079400  220.91  NA 
2016-11-30 221.63 221.82 220.31 220.38 99783700  220.38  NA 
2016-12-01 220.73 220.73 219.15 219.57 77230500  219.57  NA 
2016-12-02 219.67 220.25 219.26 219.68 70863400  219.68 215.3207 

Так что это хорошая идея создать свою собственную оболочку SMA для обработки всех этих шагов. Затем вызовите add.indicator, используя вашу функцию обертки.

mySMA <- function(x, on = "days", k = 1, n = 10) { 
    agg <- x[endpoints(x, on, k)] 
    sma <- SMA(agg, n) 
    # merge with zero-width xts object w/original index, filling NA 
    result <- merge(sma, xts(,index(x)), fill = na.locf) 
    return(result) 
} 
add.indicator(strategy.st, name = "mySMA", 
       arguments = list(x = quote(Cl(mktdata)), 
           on = "weeks", 
           n = nSMA), 
       label = "SMAw1") 
test <- applyIndicators(strategy.st, mktdata = OHLC(SPY)) 

Теперь индикатор будет иметь значение для каждого наблюдения в mktdata, когда она объединилась.

> tail(merge(SPY, test$SMA)) 
      SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted SMA.SMAw1 
2016-11-25 221.10 221.56 221.01 221.52 37861800  221.52 215.0720 
2016-11-28 221.16 221.48 220.36 220.48 70284100  220.48 215.0720 
2016-11-29 220.52 221.44 220.17 220.91 67079400  220.91 215.0720 
2016-11-30 221.63 221.82 220.31 220.38 99783700  220.38 215.0720 
2016-12-01 220.73 220.73 219.15 219.57 77230500  219.57 215.0720 
2016-12-02 219.67 220.25 219.26 219.68 70863400  219.68 215.3207 
+0

спасибо, что ушли. Мне нравится ваше решение, однако я хочу использовать стандартные периоды обмена валюты, такие как 15 минут или 4 часа. Вот почему я использовал 'to.period()'. Есть ли способ использовать 'endpoints()' либо эти периоды, или было бы легче изменить ваше решение, чтобы использовать 'to.period()' – user3180258

+0

'mySMA <- function (x, t.period, k, n = 7) { agg = to.period (x, period = t.period, k = k, indexAt = "startof") sma <- SMA (Cl (agg), n) # слияние с объективом xts с нулевой шириной w/оригинальный индекс, заполняя NA результата <- слияния (сМА, XTS (индекс, (х)), заполнить = na.locf) возврата (результат) } add.indicator (strategy.st, имя = " mySMA ", arguments = list (x = quote (mktdata), t.period =" hours ", n = 7, k = 4), label = "h4SMA") ' – user3180258

+0

^^ Извините за вышесказанное. Я не могу понять, как ввести код в комментарии с правильным форматированием:/ Итак, я заменил 'endpoints()' на 'to.period', и он работает, но это немного грязно. Как вы указали 'to.period() '& co возвращает объект OHLC, означающий, что теперь это нужно обрабатывать внутри оболочки (как' Cl (agg) '). Чтобы попытаться уменьшить накладные расходы, я передаю все x в 'mySMA', и пусть оболочка справится с этим. Есть ли способ лучше? Это лучшее решение, которое я могу придумать, поскольку мой пользовательский индикатор требует HLC, а не только C; и мне нужно работать с некаландерными периодами, как указано выше – user3180258