2016-11-30 4 views
3

original post이 이미 너무 길어서 내가 도착한 해결책이 그 게시물을 거의 무효로 만들기 때문에 새로운 질문을 열었습니다.퀀트 트랫 : 신호 값이 유효하더라도 전략이 포지션을 취하지 않습니까?

다음은 데이터의 주기성과 다른 지표를 추가 할 때 발견 된 해결 방법입니다. 이 솔루션은 this post on the R-SIG-Finance mailing list by Brian Peterson을 기반으로 작성되었습니다.

코드에는 두 가지 주요 문제가 있습니다.

1) indMerge() 명시 "SPY.SMA"add.signal(columns = c("SPY.Close", SPY.SMA"))에 SMA 항목의 이름을 변경하지 않는 경우의 신호에도 불구하고, 위치를 고려하지 않는 전략 이상하게 전략)

2)를 실행 한 후 적절한 열 mktdata 존재 (생성되는 이 B이기 때문에 내가이 오류를 해결하기 위해 찾은 유일한 방법으로

Warning message: 
In match.names(columns, colnames(data)) : 
    all columns not located in Close SMA for SPY.Open SPY.High SPY.Low SPY.Close 
SPY.Volume SPY.Adjusted SMA Cl.gt.SMA 

코드입니다 : 다음과 같은 오류가 발생합니다 다음 사용된다 (즉, 내가 columns = c("Close", "SMA")add.signal에서 것은 전달할 수 없습니다 말을하는 것입니다 아래의 솔루션은 하나 이상의 심볼이있는 포트폴리오에서 효과적으로 쓸모가 없습니다. 나는 모든 우려 주소를 희망 조정과 (테스트를위한 예를 더 관리 할 수 ​​있도록 단지 2017 데이터를 하나 개 이상의 악기)

require(quantstrat) 
require(quantmod) 
require(FinancialInstrument) 

symbols = "SPY" 

initDate="2000-01-01" 
from="2003-01-01" 
to="2016-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") 

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

#Brians code 
#>> http://r.789695.n4.nabble.com/R-Quantstrat-package-question-td3772989.html 
indMerge <- function(x, period, k, SMAlength, maType){ 
    mktdata <- getSymbols(x, auto.assign = FALSE) 

    xW = to.period(mktdata, period = period, k = k, indexAt = "startof") 
    smaW = wSMA = SMA(Cl(xW), n = SMAlength, maType = maType) 

    x <- cbind(mktdata, smaW[paste(first(index(mktdata)) , 
           last(index(mktdata)) , sep='/')]) 
    colnames(x)[ncol(x)] = paste("SPY", ".", "SMA", sep = "") 
    x <- na.locf(x) 
    x 
} 

#get the data 
getSymbols(symbols, from=from, to=to, src="yahoo", adjust=TRUE) 

#apply the weekly SMA to the data without the use of add.indicator 
SPY = indMerge(x = symbols, period = "weeks", k = 1, SMAlength = 14, maType = "SMA") 

#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) 

#add signals 
add.signal(strategy.st, name = "sigComparison", arguments = list(columns = 
       c("SPY.Close", "SPY.SMA"), relationship = "gt"), label = "Cl.gt.SMA") 
add.signal(strategy.st, name = "sigComparison", arguments = list(columns = 
       c("SPY.Close", "SPY.SMA"), relationship = "lt"), label = "Cl.lt.SMA") 

#test = applySignals(strategy.st, mktdata = SPY) 

#add.rules 
add.rule(strategy.st, name = "ruleSignal", arguments = list(sigCol = "Cl.gt.SMA", 
       sigval = 1, orderqty = 900, ordertype = "market", orderside = "long"), 
       type = "enter") 

add.rule(strategy.st, name = "ruleSignal", arguments = list(sigCol = "Cl.lt.SMA", 
       sigval = 1, orderqty = "all", ordertype = "market", orderside = "long"), 
       type = "exit") 


strat = getStrategy(strategy.st) 
summary(strat) 

#apply the strategy and get the transactions 
applyStrategy(strategy = strategy.st, portfolios = portfolio.st) 
getTxns(Portfolio = portfolio.st, Symbol = "SPY") 

답변

0

이 코드의 작동 예를입니다 : 어쨌든, 여기에 코드입니다 :

require(quantstrat) 
require(quantmod) 
require(FinancialInstrument) 

symbols = c("SPY", "GOOG") 

initDate="2000-01-01" 
from="2017-01-01" 
to=Sys.Date() 
options(width=70) 

options("getSymbols.warning4.0"=FALSE) 

#set account currency and system timezone 
currency('USD') 
stock("SPY",currency="USD",multiplier=1) 
stock("GOOG", currency = "USD") 
Sys.setenv(TZ="UTC") 

tradeSize <- 1e6 
initEq <- tradeSize*length(symbols) 

getSymbols(symbols, from=from, to=to, src="yahoo", adjust=TRUE) 

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) 



#SPY = indMerge(x = symbols, period = "weeks", k = 1, SMAlength = 14, maType = "SMA") 
#Brians code 
#>> http://r.789695.n4.nabble.com/R-Quantstrat-package-question-td3772989.html 
AddWeeklyMA <- function(x, period, k, SMAlength, maType){ 
    # Don't use getSymbols here. It is redundant. Use x, which is the daily OHLC for the symbol you've selected 
    #mktdata <- getSymbols(x, auto.assign = FALSE) 

    # YOU MUST USE indexAt as "endof" instead of "startof" otherwise you introduce look ahead bias in your weekly indicator signal. (Sees the future in the backtest) Bad!!! 
    xW <- to.period(x, period = period, k = k, indexAt = "endof") 
    wSMA <- SMA(Cl(xW), n = SMAlength, maType = maType) 

    y <- merge(wSMA, xts(, order.by = index(x)), fill = na.locf) 
    x <- y[index(x)] # just to be safe, in case any extra timestamps where generated in the merge above to make y. 
    # Note that the column name of x is simply "SMA" rather than "SPY.SMA" etc. You can of course relabel the column name here if you wish. 
    x 
} 

add.indicator(strategy = strategy.st, 
       name = "AddWeeklyMA", 
       arguments = list(x = quote(mktdata), 
           period = "weeks", 
           k = 1, 
           SMAlength = 14, 
           maType = "SMA"), 
       label = "weeklyMA") 


#add signals. 
# one way to handle column names is simply rename the OHLC columns, removing the name of the symbol. e.g. .Open .High .Low .Close, then pass columns = c(".Close", "SMA.weeklyMA") which will work for multiple symbols. 
#add.signal(strategy.st, name = "sigCrossover", arguments = list(columns = 
#                 c("SPY.Close", "SMA.weeklyMA"), relationship = "gt"), label = "Cl.gt.SMA") 

sigCrossoverWrapper <- function(x, label, col1 = "Close", col2 = "weeklyMA", relationship) { 
    Col1 <- grep(pattern = col1, colnames(x), value = TRUE)[1] 
    Col2 <- grep(pattern = col2, colnames(x), value = TRUE)[1] 
    # Basic checks. If we can't find a column name like col1, col2, throw an error. also use the [1] index, particular for col1 values like "Close", in case multiple column labels are returned that all contain "Close". The assumption is that the OHLC data are always the first for columns in the symbol data object. 
    stopifnot(length(Col1) == 1) 
    stopifnot(length(Col2) == 1) 
    columns <- c(Col1, Col2) 
    r <- sigCrossover(data = x, label = label, columns = columns, relationship = relationship) 
    r 
} 

add.signal(strategy.st, name = "sigCrossoverWrapper", arguments = list(x = quote(mktdata), 
                     col1 = "Close", 
                     col2 = "weeklyMA", 
                     relationship = "gt"), 
      label = "Cl.gt.SMA") 

add.signal(strategy.st, name = "sigCrossoverWrapper", arguments = list(x = quote(mktdata), 
                     col1 = "Close", 
                     col2 = "weeklyMA", 
                     relationship = "lt"), 
      label = "Cl.lt.SMA") 

add.rule(strategy.st, name = "ruleSignal", arguments = list(sigcol = "Cl.gt.SMA", 
                  sigval = 1, 
                  orderqty = 900, 
                  ordertype = "market", 
                  orderside = "long"), 
     label = "enterL", # Add label names for rules. 
     type = "enter") 

add.rule(strategy.st, name = "ruleSignal", arguments = list(sigcol = "Cl.lt.SMA", 
                  sigval = 1, 
                  orderqty = "all", 
                  ordertype = "market", 
                  orderside = "long"), 
     label = "exitL", # Add label names for rules. 
     type = "exit") 


applyStrategy(strategy = strategy.st, portfolios = portfolio.st) 

# [1] "2017-07-06 00:00:00 GOOG 900 @ 906.690002" 
# [1] "2017-07-07 00:00:00 GOOG -900 @ 918.590027" 
# [1] "2017-07-10 00:00:00 GOOG 900 @ 928.799988" 
# [1] "2017-07-28 00:00:00 GOOG -900 @ 941.530029" 
# [1] "2017-09-14 00:00:00 GOOG 900 @ 925.109985" 
# [1] "2017-09-15 00:00:00 GOOG -900 @ 920.289978" 
# [1] "2017-09-28 00:00:00 GOOG 900 @ 949.5" 
# [1] "2017-04-18 00:00:00 SPY 900 @ 231.585741736316" 
# [1] "2017-08-21 00:00:00 SPY -900 @ 241.70049982835" 
# [1] "2017-08-23 00:00:00 SPY 900 @ 243.352306359548" 

for (sym in symbols) { 
    print(paste0("txns for ", sym, ":")) 
    print(getTxns(Portfolio = portfolio.st, Symbol = sym) ) 
} 

당신은 당신의 코드에 몇 가지 문제가 있었다 : 당신이 add.rulessigCol 대신 sigcol을 사용하기 때문에

어떤 규칙이 트리거되지되고 있었다. 이것은 기본적으로 오류이며 테스트 할 규칙이 없습니다. (직접 확인하려면 ruleSignal 버전에 browser()을 붙이고 디버거를 실행하십시오.)

변경 sigComparison에서 sigCrossover으로 변경하십시오. Sys 비교는 relationship = gt 일 때 다른 열보다 큰 한 열의 모든 값에 대해 1/TRUE를 반환합니다. 당신은 클로즈업과 MA의 크로스 오버에 들어가고 싶습니다.

규칙에 고유 한 레이블을 지정하는 것이 좋습니다.

위의 코드는 코드를 여러 기호로 일반화합니다. 이 작업을 수행하는 과정 중에 사용자 지정 표시기를 일반화하는 작업이 포함되어 있습니다. 사용자 지정 표시기의 이름은 AddWeeklyMA입니다.

"일반"열 이름 columns = c("Close", "SMA")을 전달할 수있는 의견에 관해서는 원하는 영향을 얻는 한 가지 방법은 sigCrossoverWrapper과 같이 래퍼 기능을 만드는 것입니다. 또한 위의 코드에서 언급했듯이 각 심볼 객체 안에 문제가되는 열의 이름을 바꾸면 (즉, OHLC 열 이름에 티커 이름을 놓는 것만으로) 양식의 열 이름 [symbol].Close에 대해 테스트하려는 문제를 피할 수 있습니다).