我正在尝试使用“quantstrat”包对交易策略进行回测。我的策略由 4 个指标、3 个不同的 EMA 和 1 个滞后 EMA 组成。
我想在以下情况下做多:EMA1 > EMA2 & EMA1 > EMA3 & EMA1_lag < EMA1 我想在以下情况下平仓平仓:EMA1 < EMA3
这很简单,但我无法将其写入 quantstrat 环境。
这是两个示例中使用的数据完整性检查功能:
# Data integrity check
checkBlotterUpdate <- function(port.st,account.st,verbose=TRUE)
{
ok <- TRUE
p <- getPortfolio(port.st)
a <- getAccount(account.st)
syms <- names(p$symbols)
port.tot <- sum(sapply(syms,FUN = function(x) eval(parse(
text=paste("sum(p$symbols",x,"posPL.USD$Net.Trading.PL)",sep="$")))))
port.sum.tot <- sum(p$summary$Net.Trading.PL)
if( !isTRUE(all.equal(port.tot,port.sum.tot)) ) {
ok <- FALSE
if( verbose )
print("portfolio P&L doesn't match sum of symbols P&L")
}
initEq <- as.numeric(first(a$summary$End.Eq))
endEq <- as.numeric(last(a$summary$End.Eq))
if( !isTRUE(all.equal(port.tot,endEq-initEq)) ) {
ok <- FALSE
if( verbose )
print("portfolio P&L doesn't match account P&L")
}
if( sum(duplicated(index(p$summary))) ) {
ok <- FALSE
if( verbose )
print("duplicate timestamps in portfolio summary")
}
if( sum(duplicated(index(a$summary))) ) {
ok <- FALSE
if( verbose )
print("duplicate timestamps in account summary")
}
return(ok)
}
这是我想要的吸墨纸代码:
# Working Strategy
# it works well only with one portfolio
library(quantstrat)
suppressWarnings({
try(rm(list=ls(FinancialInstrument:::.instrument),
pos=FinancialInstrument:::.instrument), silent=TRUE)
try(rm(list=c("account.bGiulio","portfolio.bGiulio","order_book"),
pos=.blotter), silent=TRUE)
try(rm(list=c("b.strategy","myTheme","SPY",".getSymbols")), silent=TRUE)
})
#### all currency instruments must be defined
#### before instruments of other types can be defined
# Initialize a currency and a stock instrument
currency("USD")
stock("SPY",currency="USD",multiplier=1)
#Fetch historic data
# system settings
initDate <- '1997-12-31'
startDate <- '1998-01-01'
endDate <- '2014-06-30'
initEq <- 1e6
Sys.setenv(TZ="UTC")
getSymbols('SPY', from=startDate, to=endDate, index.class="POSIXct", adjust=T)
# convert data to weekly
SPY=to.weekly(SPY, indexAt='endof', drop.time=FALSE)
SPY$EMA_1<-EMA(na.locf(Cl(SPY)),10) # 10 o 3
SPY$EMA_2<-EMA(na.locf(Cl(SPY)),25) # 50 o 10
SPY$EMA_3<-EMA(na.locf(Cl(SPY)),30) # 200 o 50
SPY$EMA_1_lag<-lag(EMA(na.locf(Cl(SPY)),10),1) # 200 o 50
# inizialization on both
b.strategy <- "bGiulio"
initPortf(b.strategy, 'SPY', initDate=initDate)
initAcct(b.strategy, portfolios=b.strategy, initDate=initDate, initEq=initEq)
initOrders(portfolio=b.strategy,initDate=initDate)
# trading algo
for( i in 1:nrow(SPY) )
{
# update values for this date
CurrentDate <- time(SPY)[i]
equity = getEndEq(b.strategy, CurrentDate)
ClosePrice <- as.numeric(Cl(SPY[i,]))
Posn <- getPosQty(b.strategy, Symbol='SPY', Date=CurrentDate)
UnitSize = as.numeric(trunc(equity/ClosePrice))
EMA1 <- as.numeric(SPY[i,'EMA_1'])
EMA2 <- as.numeric(SPY[i,'EMA_2'])
EMA3 <- as.numeric(SPY[i,'EMA_3'])
EMA1_lag <- as.numeric(SPY[i,'EMA_1_lag'])
# change market position if necessary
if( !is.na(EMA1) & # if the moving average has begun
!is.na(EMA2) & # if the moving average has begun
!is.na(EMA3) &
!is.na(EMA1_lag) ) # if the moving average has begun
{
if( Posn == 0 ) { # No position, test to go Long
if( EMA1 > EMA2 & EMA1 > EMA3 & EMA1_lag<EMA1) {
# enter long position
addTxn(b.strategy, Symbol='SPY', TxnDate=CurrentDate,
TxnPrice=ClosePrice, TxnQty = UnitSize , TxnFees=0)
}
} else { # Have a position, so check exit
if( EMA1 < EMA3) {
# exit position
addTxn(b.strategy, Symbol='SPY', TxnDate=CurrentDate,
TxnPrice=ClosePrice, TxnQty = -Posn , TxnFees=0)
} else {
if( i==nrow(SPY) ) # exit on last day
addTxn(b.strategy, Symbol='SPY', TxnDate=CurrentDate,
TxnPrice=ClosePrice, TxnQty = -Posn , TxnFees=0)
}
}
}
updatePortf(b.strategy,Dates=CurrentDate)
updateAcct(b.strategy,Dates=CurrentDate)
updateEndEq(b.strategy,CurrentDate)
} # End dates loop
# transactions
#getTxns(Portfolio=b.strategy, Symbol="SPY")
checkBlotterUpdate(b.strategy,b.strategy)
## [1] TRUE
tstats <- t(tradeStats(b.strategy))
perTradeStats(b.strategy)
library(lattice)
a <- getAccount(b.strategy)
xyplot(a$summary,type="h",col=4)
equity <- a$summary$End.Eq
plot(equity,main="Giulio Strategy Equity Curve")
ret <- Return.calculate(equity,method="log")
charts.PerformanceSummary(ret, colorset = bluefocus,
main="Giulio Strategy Performance")
我尝试使用 quantstrat(使用add.indicator
, add.signal
, add.rule
)复制上述策略,但结果肯定不同。这里是 quantstrat 的第二个代码:
# Here the code that does not work
library(quantstrat)
#Initialize a currency and a stock instrument
currency("USD")
stock("SPY",currency="USD",multiplier=1)
# system settings
initDate <- '1997-12-31'
startDate <- '1998-01-01'
endDate <- '2014-06-30'
initEq <- 1e6
Sys.setenv(TZ="UTC")
getSymbols('SPY', from=startDate, to=endDate, index.class="POSIXct", adjust=T)
SPY <- to.weekly(SPY, indexAt='endof', drop.time=FALSE)
SPY$EMA1<-EMA(na.locf(Cl(SPY)),10) # 10 o 3
SPY$EMA2<-EMA(na.locf(Cl(SPY)),25) # 50 o 10
SPY$EMA3<-EMA(na.locf(Cl(SPY)),30) # 200 o 50
SPY$EMA1_lag<-lag(EMA(na.locf(Cl(SPY)),10)) # 200 o 50
# initialize portfolio/account
qs.strategy <- "qsGiulio"
rm.strat(qs.strategy) # remove strategy etc. if this is a re-run
initPortf(qs.strategy,'SPY', initDate=initDate)
initAcct(qs.strategy,portfolios=qs.strategy, initDate=initDate, initEq=initEq)
# initialize orders container
initOrders(portfolio=qs.strategy,initDate=initDate)
# instantiate a new strategy object
strategy(qs.strategy,store=TRUE)
strat <-getStrategy(qs.strategy)
add.indicator(strategy = qs.strategy, name = "EMA",
arguments = list(x = quote(na.locf(Cl(mktdata))), n=10), label="EMA1")
add.indicator(strategy = qs.strategy, name = "EMA",
arguments = list(x = quote(na.locf(Cl(mktdata))), n=25), label="EMA2")
add.indicator(strategy = qs.strategy, name = "EMA",
arguments = list(x = quote(na.locf(Cl(mktdata))), n=30), label="EMA3")
add.indicator(strategy = qs.strategy, name = "EMA",
arguments = list(x = quote(lag(na.locf(Cl(mktdata)))), n=10), label="EMA1_lag")
# entry signals
add.signal(qs.strategy,name="sigComparison",
arguments = list(columns=c("EMA1","EMA2"),relationship="gt"),
label="EMA1.gt.EMA2")
add.signal(qs.strategy,name="sigComparison",
arguments = list(columns=c("EMA1","EMA3"),relationship="gt"),
label="EMA1.gt.EMA3")
add.signal(qs.strategy,name="sigComparison",
arguments = list(columns=c("EMA1","EMA1_lag"),relationship="gt"),
label="EMA1.gt.EMA1_lag")
add.signal(qs.strategy, name = "sigFormula",
arguments = list(formula="EMA1.gt.EMA2 & EMA1.gt.EMA3 & EMA1.gt.EMA1_lag"),
label="longEntry")
# exit signals
add.signal(qs.strategy,name="sigComparison",
arguments = list(columns=c("EMA1","EMA3"),relationship="lt"),
label="EMA1.lt.EMA3")
# RULES
# go long when 3 condition
add.rule(qs.strategy, name='ruleSignal',
arguments =
list(sigcol="longEntry", sigval=TRUE, orderqty=900,
ordertype='market', orderside='long'),
type='enter')
# exit when 1 condition
add.rule(qs.strategy, name='ruleSignal',
arguments = list(sigcol="EMA1.lt.EMA3", sigval=TRUE, orderqty='all',
ordertype='market', orderside='long'),
type='exit')
applyStrategy(strategy=qs.strategy , portfolios=qs.strategy)
# transactions
#getTxns(Portfolio=qs.strategy, Symbol="SPY")
checkBlotterUpdate(b.strategy,b.strategy)
## [1] TRUE
# update portfolio/account
updatePortf(qs.strategy)
updateAcct(qs.strategy)
updateEndEq(qs.strategy)
tstats <- t(tradeStats(qs.strategy))
perTradeStats(qs.strategy)
library(lattice)
a <- getAccount(qs.strategy)
xyplot(a$summary,type="h",col=4)
equity <- a$summary$End.Eq
plot(equity,main="Giulio Strategy Equity Curve")
ret <- Return.calculate(equity,method="log")
charts.PerformanceSummary(ret, colorset = bluefocus,
main="Giulio Strategy Performance")
谁能帮我理解为什么第二个代码没有给出相同的结果?我认为我的错误在add.indicator
, add.signal
,add.rule
设置中,但我无法准确地弄清楚。