R - quantstrat:如何创建多个指标,信号规则



我想根据不同的信号(如SMA50 > SMA10MACD > 0)添加多个规则。但是,我在使用sigComparision时收到错误。谁能提出更好的方法?

您可以使用两种明显的方法:您可以在添加规则中构建复合信号函数,也可以使用sigFormula。 众所周知,后者很慢。 例如,请参阅此线程:

https://stat.ethz.ch/pipermail/r-sig-finance/2012q1/009310.html

我在这里强调一个关键部分:

sigFormula 使用 R 语法功能,允许您使用列 直接命名为公式中的变量。 它不做部分 匹配,因为列成为公式变量。

....

我会警告你,虽然 sigFormula 非常灵活,但 R 不是很灵活。 快速使用这种方法。 这似乎是方式的副作用 data.frames被存储为列表,并且 eval(parse(text=formula),x) 语法由 R 在内部管理。

对于每日或较低频率的数据,这可能没问题,但对于 更高的频率我通常发现编写自定义是有意义的 信号函数指示器,用于更复杂的比较。

在以下示例(基于 quantstrat 包中的macd.R演示)中,您可以尝试这两种方法:

require(quantstrat)
suppressWarnings(rm("order_book.macd",pos=.strategy))
suppressWarnings(rm("account.macd","portfolio.macd",pos=.blotter))
suppressWarnings(rm("account.st","portfolio.st","stock.str","stratMACD","startDate","initEq",'start_t','end_t'))
stock.str='AAPL' # what are we trying it on

fastMA = 12 
slowMA = 26 
signalMA = 8
maType="EMA"
currency('USD')
stock(stock.str,currency='USD',multiplier=1)
startDate='2006-12-31'
initEq=1000000
portfolio.st='macd'
account.st='macd'
getSymbols(stock.str,from=startDate)

initPortf(portfolio.st,symbols=stock.str)
initAcct(account.st,portfolios=portfolio.st)
initOrders(portfolio=portfolio.st)
strat.st<-portfolio.st
# define the strategy
strategy(strat.st, store=TRUE)
#one indicator
add.indicator(strat.st, name = "MACD", 
arguments = list(x=quote(Cl(mktdata)),
nFast=fastMA, 
nSlow=slowMA),
label='_' 
)
add.indicator(strat.st, name = "SMA", 
arguments = list(x=quote(Cl(mktdata)),
n=10),
label='SMA10' 
)

add.indicator(strat.st, name = "SMA", 
arguments = list(x=quote(Cl(mktdata)),
n = 50),
label='SMA50' 
)
# Create your own signal for entry:
macdSMAsig <- function(data) {
# first condition:
sig <- data[, "SMA.SMA50"] > data[, "SMA.SMA10"] & data[, "macd._"] > 0
colnames(sig) <- "upSig"
sig
}

# Activate (uncomment) only ONE of the following signals.  Both do the same thing:
#OPTION 1 for entry signal based on combining signals:
add.signal(strat.st,name="macdSMAsig",
arguments = list(data = quote(mktdata)),
label="enterSig"
)
#OPTION 2 for entry signal based on combining signals:
# add.signal(strat.st, name = "sigFormula",
#            arguments = list(data = quote(mktdata),
#                             formula = "SMA.SMA50 > SMA.SMA10 & macd._ > 0"),
#            label = "upSig.enterSig"
#            )

add.signal(strat.st,name="sigThreshold",
arguments = list(column="signal._",
relationship="lt",
threshold=0,
cross=TRUE),
label="signal.lt.zero"
)
####
# add rules
# entry
add.rule(strat.st,name='ruleSignal', 
# be careful to get the label of the signal column correct:
arguments = list(sigcol="upSig.enterSig",
sigval=TRUE, 
orderqty=100, 
ordertype='market', 
orderside='long', 
threshold=NULL),
type='enter',
label='enter',
storefun=FALSE
)
# exit
add.rule(strat.st,name='ruleSignal', 
arguments = list(sigcol="signal.lt.zero",
sigval=TRUE, 
orderqty='all', 
ordertype='market', 
orderside='long', 
threshold=NULL,
orderset='exit2'),
type='exit',
label='exit'
)
#end rules
####

out<-applyStrategy(strat.st , portfolios=portfolio.st,verbose=TRUE)

updatePortf(Portfolio=portfolio.st,Dates=paste('::',as.Date(Sys.time()),sep=''))
chart.Posn(Portfolio=portfolio.st,Symbol=stock.str)
tx <- getTxns(portfolio.st, stock.str)
sum(tx$Net.Txn.Realized.PL)

我尝试了您的代码,但似乎收到此错误:

应用规则中的错误(投资组合 = 投资组合,交易品种 = 交易品种,策略 = 策略,:mktdata 不包含 'sigcol': entersig

这是我所做的:

library(quantmod)
library(FinancialInstrument)
library(PerformanceAnalytics)
library(foreach)
library(blotter)
library(quantstrat)
options("getSymbols.yahoo.warning"=FALSE)
options("getSymbols.warning4.0"=FALSE)
initDate="1990-01-01"
from ="2003-01-01"
to ="2012-12-31"
symbols = c("AAPL")
currency("USD")
getSymbols(symbols, from=from, to=to, adjust=TRUE)
stock(symbols, currency="USD", multiplier=1)
initEq=1000000
strategy.st <- portfolio.st <- account.st <- "mystrat"
rm.strat("mystrat")

initPortf(name=portfolio.st,
symbols=symbols,
initDate=initDate,
currency='USD')
initAcct(name=account.st,
portfolios=portfolio.st,
initDate=initDate,
currency='USD',
initEq=initEq)
initOrders(portfolio=portfolio.st,
initDate=initDate)
strategy(strategy.st, store=TRUE)
### Add Indicators
nRSI <- 21
buyThresh <- 50
sellThresh <- 50
#Indicator for EMA long medium short
nEMAL<- 80
nEMAM<- 21
nEMAS<- 13
nEMAF<- 5
add.indicator(strategy.st, name="RSI",
arguments=list(price=quote(Cl(mktdata)), n=nRSI),
label="rsi")
add.indicator(strategy.st, name="EMA",
arguments=list(x=quote(Cl(mktdata)), n=nEMAL),
label="EMAL")
add.indicator(strategy.st, name="EMA",
arguments=list(x=quote(Cl(mktdata)), n=nEMAM),
label="EMAM")
add.indicator(strategy.st, name="EMA",
arguments=list(x=quote(Cl(mktdata)), n=nEMAS),
label="EMAS")
add.indicator(strategy.st, name="EMA",
arguments=list(x=quote(Cl(mktdata)), n=nEMAF),
label="EMAF")
#customsig <- function(data) {
sig <- data[, "EMA.EMAF"] > data[, "EMA.EMAS"] & data[, "EMA.EMAF"] > data[, "EMA.EMAM"] & data[, "rsi"] >50 & data[, "EMA.EMAM"] > data[, "EMA.EMAL"] & data[, "EMA.EMAS"] > data[, "EMA.EMAL"]  
colnames(sig) <- "upSig"
sig
}
#downsig <- function(data) {
sig <- data[, "EMA.EMAF"] < data[, "EMA.EMAS"] & data[, "EMA.EMAF"] < data[, "EMA.EMAM"] & data[, "rsi"] <50 & data[, "EMA.EMAM"] < data[, "EMA.EMAL"] & data[, "EMA.EMAS"] < data[, "EMA.EMAL"]  
colnames(sig) <- "downSig"
sig
}

### Add Signal- Enter
add.signal(strategy.st, name="customsig",
arguments=list(data = quote(mktdata)),
label = "entersig")
add.signal(strategy.st, name="downsig",
arguments=list(data = quote(mktdata)),
label = "downsig.exitsig")
### Add rule - Enter
add.rule(strategy.st,
name='ruleSignal',
arguments = list(sigcol="entersig",
sigval=TRUE,
orderqty=1000,
ordertype='market',
orderside='long',
threshold=NULL),
type='enter',
path.dep=TRUE)

### Add rule- Exit
add.rule(strategy.st,
name='ruleSignal',
arguments = list(sigcol="downsig.exitsig",
sigval=TRUE,
orderqty=1000,
ordertype='market',
orderside='long',
pricemethod='market',
replace=FALSE),
type='exit',
path.dep=TRUE)
start_t<-Sys.time()
out<-try(applyStrategy(strategy=strategy.st,
portfolios=portfolio.st))

updatePortf(portfolio.st)
updateAcct(portfolio.st)
updateEndEq(account.st)
for(symbol in symbols) {
chart.Posn(
Portfolio=portfolio.st,
Symbol=symbol,
log=TRUE)
}

最新更新