Created
July 13, 2020 01:20
-
-
Save jaymon0703/7a36a05c3af8a3635e089695335aa302 to your computer and use it in GitHub Desktop.
macd_sig fun - silly maybe not so silly strategy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Simple MACD signal strategy | |
# | |
# blotter v 0.10.0 | |
# quantstrat v 0.9.1739 | |
# FinancialInstrument v 1.2.0 | |
# Rblpapi v 0.3.4 | |
# | |
# | |
# Author: Jasen | |
############################################################################### | |
t1 <- Sys.time() | |
options(width=81,continue=" ",digits=8) | |
#options(error = recover) | |
require(quantstrat) | |
require(PerformanceAnalytics) | |
require(quantmod) | |
require(TTR) | |
# require(Rblpapi) | |
# blpConnect() | |
# Set initial values | |
initDate <- as.Date("1998-02-01") | |
#startDate <- as.Date("2007-06-10") | |
#bbgstartDate <- as.Date("2009-01-01") | |
#endDate <- as.Date("2016-06-24") | |
initEq <- 1000000 | |
tradeSize <- initEq | |
#initEq <- tradeSize*length(symbols) | |
currency("USD") | |
currency("EUR") | |
symbols = c("XLF", "XLP", "XLE", "XLY", "XLV", "XLI", "XLB", "XLK", "XLU") | |
#symbols = "XLI" | |
for(symbol in symbols){ # establish trade-able instruments | |
stock(symbol, currency="USD",multiplier=1) | |
} | |
getSymbols(symbols, src='yahoo', index.class=c("POSIXt","POSIXct"), from='1998-01-01') | |
# Delete portfolio, account, and order book if they already exist | |
rm.strat("macdX") | |
suppressWarnings(rm("account.macdX","portfolio.macdX",pos=.blotter)) | |
suppressWarnings(rm("order_book.macdX",pos=.strategy)) | |
# Initialize portfolio and account | |
initPortf("macdX", symbols=symbols, initDate=initDate) | |
initAcct("macdX", portfolios="macdX", initDate=initDate, initEq=initEq) | |
initOrders(portfolio="macdX", initDate=initDate) | |
# set intial position limits | |
posval<-initEq/length(symbols) | |
for(symbol in symbols){ | |
pos<-round((posval/first(getPrice(get(symbol)))[,1]),-2) | |
addPosLimit("macdX",symbol,initDate, maxpos=pos,minpos=-pos) | |
} | |
print("setup completed") | |
# Initialize a strategy object | |
strat.macdX <- strategy("macdX") | |
ATRperiod = 14 | |
#one indicator (ok more than one indicator :)) | |
strat.macdX <- add.indicator(strategy=strat.macdX, name="ATR", | |
arguments=list(HLC=quote(HLC(mktdata)), n=ATRperiod), | |
label="atrX") | |
#MA parameters for short MACD | |
fastMA = 12 | |
slowMA = 26 | |
signalMA = 9 | |
maType="EMA" | |
#MA parameters for short MACD | |
longfastMA = 240 | |
longslowMA = 520 | |
longsignalMA = 180 | |
# parameters for stop and position sizing | |
nATR = 4 | |
mper=30 | |
nSMA = 200 | |
strat.macdX <- add.indicator(strat.macdX, name = "MACD", | |
arguments = list(x=quote(Ad(mktdata)), nFast=fastMA, nSlow=slowMA, nSig=signalMA, maType=maType), | |
label='_shortper' | |
) | |
strat.macdX <- add.indicator(strat.macdX, name = "MACD", | |
arguments = list(x=quote(Ad(mktdata)), nFast=longfastMA, nSlow=longslowMA, nSig=longsignalMA, maType=maType), | |
label='_longper' | |
) | |
strat.macdX <- add.indicator(strat.macdX, name = "SMA", | |
arguments = list(x=quote(Ad(mktdata)), n=nSMA), | |
label='sma200' | |
) | |
test <- applyIndicators(strat.macdX, mktdata=OHLC(NPN)) | |
head(test) | |
# # Jasen's custom indicator | |
# macdtrend <- function(x=Cl(mktdata), nFast=fastMA, nSlow=slowMA, nSig=signalMA, maType=maType){ | |
# m5 <- MACD(x, nFast, nSlow, nSig, maType) | |
# m4 <- MACD(x[1:(nrow(x)-1)], nFast, nSlow, nSig, maType) | |
# | |
# if(m5*m4 > 0){ | |
# macdtrend <- 1 | |
# } else { | |
# macdtrend <- 0 | |
# } | |
# return(macdtrend) | |
# } | |
#two signals | |
JsigFormula <- function(label, data=mktdata, formula ,cross=FALSE, mper){ | |
# Vijay's PAST/AAII/SIPRO example | |
# fieldVals <- try(eval(parse(text=expression), data)) | |
ret_sig=NULL | |
ret_sig <- try(.xts(eval(parse(text=formula), as.list(data)),index=.index(data))) | |
if(is.xts(ret_sig)){ | |
if(isTRUE(cross)) ret_sig <- diff(ret_sig)==1 | |
colnames(ret_sig)<-label | |
} | |
#return(ret_sig) | |
#ret_sig <- ifelse(ret_sig == TRUE, FALSE, TRUE) # do this if you looking for short signal | |
# ret_sig <- rollapply(ret_sig, 10, sum) | |
# return(ret_sig) | |
ret_sig[is.na(ret_sig)] <- 0 | |
ret_sig[mper:length(ret_sig)] <- rollsum(ret_sig, mper) | |
return(ret_sig) | |
} | |
strat.macdX <- add.signal(strat.macdX, name="JsigFormula", | |
arguments=list(columns=c("signal._shortper", | |
"signal._longper"), | |
formula="(signal._shortper > 0) & (signal._longper > 0)", | |
cross=FALSE, mper=30), label="ENTRY") | |
# SMA200 signal | |
strat.macdX <- add.signal(strat.macdX, name="sigComparison", | |
arguments=list(columns=c("Adjusted","sma200"), | |
relationship="lte"), | |
label="Cl.lte.sma200") | |
testSignals <- applySignals(strat.macdX, mktdata=OHLC(NPN)) | |
head(test) | |
# strat.macdX <- add.signal(strat.macdX, name="sigFormula", | |
# arguments=list(columns=c("signal._shortper", | |
# "signal._longper"), | |
# formula="(signal._shortper > 0) & (signal._longper > 0)", | |
# cross=FALSE), label="ENTRY") | |
# strat.macdX <- add.signal(strat.macdX, name="sigFormula", | |
# arguments=list(columns=c("signal._shortper", | |
# "signal._longper"), | |
# formula="(signal._shortper > 2) & (signal._longper > 0)", | |
# cross=TRUE), label="ENTRY2") | |
# strat.macdX <- add.signal(strat.macdX,name="sigThreshold", | |
# arguments = list(column="signal._", | |
# relationship="gt", | |
# threshold=0, | |
# cross=TRUE), | |
# label="signal.gt.zero" | |
# ) | |
# | |
# strat.macdX <- add.signal(strat.macdX,name="sigThreshold", | |
# arguments = list(column="signal._shortper", | |
# relationship="lt", | |
# threshold=0, | |
# cross=FALSE), | |
# label="signal.lt.zero" | |
# ) | |
#### | |
# add rules | |
# orderqty | |
# ORDQTY <- function(data, timestamp, orderqty, ordertype, orderside, | |
# portfolio, symbol, prefer="Close", | |
# integerQty=TRUE, | |
# ...) { | |
# if(prefer=="Close") { | |
# price <- as.numeric(Cl(mktdata[timestamp,])) | |
# } else { | |
# price <- as.numeric(Op(mktdata[timestamp,])) | |
# } | |
# dollarsToTransact <- initEq * 0.02 | |
# if (orderside=="short") { | |
# qty <- -dollarsToTransact / price | |
# } else { | |
# qty <- dollarsToTransact / price | |
# } | |
# if(integerQty) { | |
# qty <- trunc(qty) | |
# } | |
# return(qty) | |
# } | |
ORDQTY2 <- function(data, timestamp, orderqty, ordertype, orderside, | |
portfolio, symbol, prefer="Open", | |
integerQty=TRUE, | |
...) { | |
if(getPosQty("macdX", symbol, timestamp) == 0){ | |
if(prefer=="Close") { | |
price <- as.numeric() | |
} else { | |
price <- as.numeric(Op(mktdata[timestamp,])) | |
} | |
sharesToTransact <- (initEq * 0.01) / (nATR * mktdata$atr.atrX[timestamp]) | |
if (orderside=="short") { | |
#qty <- -dollarsToTransact / price | |
qty <- -sharesToTransact | |
} else { | |
qty <- sharesToTransact | |
} | |
if(integerQty) { | |
qty <- trunc(sharesToTransact) | |
} | |
return(qty) | |
} | |
} | |
# entry | |
# strat.macdX <- add.rule(strat.macdX,name='ruleSignal', | |
# arguments = list(sigcol="signal.gt.zero", | |
# sigval=TRUE, | |
# osFUN = ORDQTY, | |
# ordertype='market', | |
# orderside='long', | |
# threshold=NULL), | |
# type='enter', | |
# label='enter', | |
# storefun=FALSE | |
# ) | |
strat.macdX <- add.rule(strat.macdX,name='ruleSignal', | |
arguments = list(sigcol="ENTRY", | |
sigval=mper, | |
#tradeSize = initEq * 0.2 / quote(mktdata$atr.atrX[timestamp]), | |
#addPosLimit("macdX", symbol, timestamp, maxpos = tradeSize), | |
osFUN = ORDQTY2, #osMaxPos, | |
ordertype='market', | |
orderside='long', | |
threshold=NULL, | |
prefer='Open'), | |
#TxnFees = -(ORDQTY2 * quote(mktdata$Cl[timestamp]) * 0.01)), | |
type='enter', | |
label='enter', | |
storefun=FALSE | |
) | |
# strat.macdX <- add.rule(strat.macdX,name='ruleSignal', | |
# arguments = list(sigcol="ENTRY2", | |
# sigval=TRUE, | |
# osFUN = ORDQTY, | |
# ordertype='market', | |
# orderside='long', | |
# threshold=NULL, | |
# prefer='Open'), | |
# type='enter', | |
# #type='chain', | |
# #parent='enter', | |
# label='enter', | |
# storefun=FALSE | |
# ) | |
#alternatives for risk stops: | |
# strat.macdX <- add.rule(strat.macdX,name='ruleSignal', | |
# arguments = list(sigcol="ENTRY", | |
# sigval=TRUE, orderqty='all', | |
# ordertype='stoptrailing', | |
# orderside='long', tmult=FALSE, threshold=quote(-2 * (mktdata$atr.atrX[timestamp])), orderset='exit2'), | |
# type='chain', parent='enter', label='trailingexit') | |
# strat.macdX <- add.rule(strat.macdX,name='ruleSignal', | |
# arguments = list(sigcol="ENTRY", | |
# sigval=TRUE, orderqty='all', | |
# ordertype='stoptrailing', | |
# orderside='long', tmult=FALSE, threshold=quote(-nATR * (mktdata$atr.atrX[timestamp])), orderset='exit2'), | |
# type='chain', parent='enter', label='trailingexit') | |
# exit | |
strat.macdX <- add.rule(strat.macdX,name='ruleSignal', | |
arguments = list(sigcol="Cl.lte.sma200", | |
sigval=TRUE, | |
orderqty='all', | |
ordertype='market', | |
orderside='long', | |
threshold=NULL, | |
prefer='Open'), | |
type='exit', | |
label='exit' | |
) | |
testRules <- applyRules("macdX", "NPN", strat.macdX, mktdata=mktdata) | |
#end rules | |
#### | |
out <- applyStrategy(strategy=strat.macdX, portfolios="macdX") | |
updatePortf("macdX") | |
updateAcct("macdX") | |
updateEndEq("macdX") | |
# chart.Posn(Portfolio="macdX",Symbol="AGL") | |
# plot(add_MACD(fast=fastMA, slow=slowMA, signal=signalMA,maType="EMA")) | |
#look at the order book | |
obook<-getOrderBook('macdX') | |
# create custom theme | |
myTheme<-chart_theme() | |
myTheme$col$dn.col<-'lightgray' | |
myTheme$col$up.col<-'lightgray' | |
myTheme$col$dn.border <- 'lightgray' | |
myTheme$col$up.border <- 'lightgray' | |
# c <- chart_Series( | |
# x=AGL, | |
# theme=myTheme, | |
# name="AGL", | |
# TA=c("add_SMA(n=nSMA,col=8)") | |
# ) | |
# c | |
# chart.Posn(Portfolio="R2",Symbol=symbol,theme=myTheme, | |
# TA=c('add_SMA(n=100,col=4, on=1)')) | |
for(symbol in symbols) | |
{ | |
if (length(getTxns("macdX", symbol)[,1]) > 1){ | |
chart.Posn(Portfolio="macdX",Symbol=symbol,theme=myTheme, | |
TA=c('add_EMA(n=26,col=4, on=1)','add_EMA(n=12,col=2, on=1)'), | |
prefer='Adjusted') | |
} | |
} | |
Account <- "macdX" | |
Portfolio <- "macdx" | |
a <- getAccount(Account) | |
p <- getPortfolio("macdX") | |
equity <- a$summary$End.Eq | |
#p$summary$Long.Value | |
plot(equity,main="macdX") | |
charts.PerformanceSummary(ROC(equity)) | |
############################################################################### | |
# R (http://r-project.org/) Quantitative Strategy Model Framework | |
# | |
# Copyright (c) 2009-2012 | |
# Peter Carl, Dirk Eddelbuettel, Brian G. Peterson, Jeffrey Ryan, and Joshua Ulrich | |
# | |
# This library is distributed under the terms of the GNU Public License (GPL) | |
# for full details see the file COPYING | |
# | |
# $Id$ | |
# | |
############################################################################## | |
##### PLACE THIS BLOCK AT END OF DEMO SCRIPT ################### | |
book = getOrderBook("macdX") | |
# stats = tradeStats(port) | |
# rets = PortfReturns(acct) | |
################################################################ | |
################### Lets analyse ################### | |
# assign account and portfolio data to variables "a" and "p" | |
a <- getAccount("macdX") | |
p <- getPortfolio("macdX") | |
names(p$symbols) | |
# save tradeStats and charts as pdf - for porfolio then for stocks | |
PDFPath = "C:/Users/jasen/Personal/Personal Work/tradeStats_macd_sig_yahoo.pdf" | |
pdf(file=PDFPath, onefile=T) | |
# PORTFOLIO | |
# tradeStats | |
#notional <- 0 | |
longs <- 0 | |
longwins <- 0 | |
longloss <- 0 | |
longpl <- 0 | |
longnot <- 0 # long notional | |
longplpct <- 0 | |
shorts <- 0 | |
shortwins <- 0 | |
shortloss <- 0 | |
shortpl <- 0 | |
shortnot <- 0 # short notional | |
shortplpct <- 0 | |
for(s in symbols){ | |
if(length(getTxns("macdX", s)[,1]) > 1){ | |
#txn <- p$symbols[[s]]$txn | |
netPL <- perTradeStats("macdX", Symbol=s)$Net.Trading.PL | |
notional <- perTradeStats("macdX", Symbol=s)$Max.Notional.Cost | |
initpos <- perTradeStats("macdX", Symbol=s)$Init.Pos | |
longs <- longs + sum(sign(perTradeStats("macdX", Symbol=s)$Init.Pos) > 0) | |
#long_wins <- length(txn$Net.Txn.Realized.PL[txn$Net.Txn.Realized.PL > 0]) | |
longwins <- longwins + sum(ifelse(initpos>0 & netPL > 0, TRUE, FALSE)) | |
#long_loss <- length(txn$Net.Txn.Realized.PL[txn$Net.Txn.Realized.PL < 0]) | |
longloss <- longloss + sum(ifelse(initpos>0 & netPL < 0, TRUE, FALSE)) | |
longpl <- longpl + sum(ifelse(initpos>0, netPL, 0)) | |
longnot <- longnot + sum(ifelse(initpos>0, notional, 0)) | |
shorts <- shorts + sum(sign(perTradeStats("macdX", Symbol=s)$Init.Pos) < 0) | |
shortwins <- shortwins + sum(ifelse(initpos<0 & netPL > 0, TRUE, FALSE)) | |
shortloss <- shortloss + sum(ifelse(initpos<0 & netPL < 0, TRUE, FALSE)) | |
shortpl <- shortpl + sum(ifelse(initpos<0, netPL, 0)) | |
shortnot <- shortnot + sum(ifelse(initpos<0, notional, 0)) | |
print(perTradeStats("macdX", Symbol=s)$Init.Pos) | |
} | |
} | |
longplpct <- paste(format(longpl / longnot * 100, digits = 4), "%", sep = "") | |
shortplpct <- paste(format(shortpl / abs(shortnot) * 100, digits = 4), "%", sep = "") | |
#trades <- sum(tradeStats("macdX")[,"Num.Trades"]) | |
#numwin <- sum(tradeStats("macdX")[,"Percent.Positive"] * tradeStats("macdX")[,"Num.Trades"]) / 100 | |
wins <- longwins + shortwins | |
#numloss <- sum(tradeStats("macdX")[,"Percent.Negative"] * tradeStats("macdX")[,"Num.Trades"]) / 100 | |
losses <- longloss + shortloss | |
trades <- wins + losses | |
#pnl <- tail(a$summary$End.Eq, 1) - initEq | |
pnl <- format(sum(p$summary$Net.Trading.PL), digits = 0, big.mark = " ", scientific=FALSE) | |
pnlpct <- paste(format(sum(p$summary$Net.Trading.PL) / initEq * 100, digits = 4), "%", sep = "") | |
summary_headings <- c("Trades", "Wins", "Losses", "PnL", "%PnL") | |
longpl <- format(round(longpl, 0), big.mark = " ", scientific=FALSE) | |
long_stats <- data.frame(cbind(longs, longwins, longloss, longpl, longplpct)) | |
names(long_stats) <- summary_headings | |
shortpl <- format(round(shortpl, 0), big.mark = " ", scientific=FALSE) | |
short_stats <- data.frame(cbind(shorts, shortwins, shortloss, shortpl, shortplpct)) | |
names(short_stats) <- summary_headings | |
port_stats <- data.frame(cbind(trades, wins, losses, pnl, pnlpct)) | |
names(port_stats) <- summary_headings | |
df <- as.data.frame(cbind(t(long_stats), t(short_stats), t(port_stats))) | |
names(df) <- c("LONGS", "SHORTS", "TOTAL") | |
textplot(df) | |
# chart | |
e <- ROC(equity)[-(1:700)] | |
colnames(e) <- Account | |
# bench_equity <- xts(indx$PX_LAST, indx$date) | |
# bench <- ROC(bench_equity)[-(1:700)] | |
# colnames(bench) <- benchmark | |
# charts.PerformanceSummary(merge(e,bench)) | |
charts.PerformanceSummary(e) | |
getSymbols('^GSPC', src='yahoo', index.class=c("POSIXt","POSIXct"),from='1998-02-01') | |
SNP <- ROC(Cl(GSPC))[-(1:700)] | |
charts.PerformanceSummary(merge(e,SNP)) | |
# equity <- a$summary$End.Eq[-(1:700)] | |
# plot(equity,main="macdX Equity Curve") | |
#textplot(cbind(table.AnnualizedReturns(e), table.AnnualizedReturns(bench))) | |
textplot(table.AnnualizedReturns(e)) | |
monthly_equity <- to.monthly(equity[-(1:700)], OHLC = FALSE) | |
mon_ret <- ROC(monthly_equity) | |
textplot(t(table.CalendarReturns(mon_ret))) | |
title(main = Account) | |
# monthly_bench <- to.monthly(bench_equity[-(1:700)], OHLC = FALSE) | |
# bench_ret <- ROC(monthly_bench) | |
# colnames(bench_ret) <- benchmark | |
# textplot(t(table.CalendarReturns(bench_ret))) | |
# title(main = benchmark) | |
chart.Bar(p$summary$Long.Value) | |
#mcsim("macdX", "macdX", n=1000, l=1, gap = 700) | |
# tradestats ("Additional Stats" equivalent) | |
# STOCKS | |
# how many stocks per pdf page? | |
par(mfrow=c(2,1)) | |
k <- 8 | |
if(length(symbols) > k){ | |
for (i in 1:ceiling(length(symbols)/k)){ | |
textplot(t(tradeStats("macdX", symbols[(i*k-(k-1)):(i*k)]))) | |
#title("tradeStats") | |
} | |
} else { | |
textplot(t(tradeStats("macdX", symbols[]))) | |
#title("tradeStats") | |
} | |
par(mfrow=c(1,1)) | |
for(symbol in symbols) | |
{ | |
if (length(getTxns("macdX", symbol)[,1]) > 1){ | |
chart.Posn(Portfolio="macdX",Symbol=symbol,theme=myTheme, | |
TA=c('add_SMA(n=200,col=4, on=1)')) | |
} | |
} | |
par(mfrow=c(1,1)) | |
#textplot(t(tradeStats("macdX"))) | |
dev.off() | |
t2 <- Sys.time() | |
difftime(t2,t1) | |
t1 <- Sys.time() | |
macdX.wr.equity.mcsim <- mcsim("macdX", n=10, replacement = TRUE, use = "equity", gap = 700, l = 10) | |
macdX.wr.txns.mcsim <- mcsim("macdX", n=10, replacement = TRUE, use = "txns", l = 1) | |
t2 <- Sys.time() | |
difftime(t2,t1) | |
plot(macdX.wr.mcsim) | |
blog.seed <- macdX.wr.mcsim$seed | |
set.seed(blog.seed) | |
t1 <- Sys.time() | |
macdX.nr.mcsim <- mcsim("macdX", n=1000, replacement = FALSE, gap = 700, l = 10) | |
t2 <- Sys.time() | |
difftime(t2,t1) | |
plot(macdX.nr.mcsim) | |
t1 <- Sys.time() | |
macdX.wr.txnsim <- txnsim("macdX", n=1000, replacement = TRUE, tradeDef = "flat.to.flat") | |
t2 <- Sys.time() | |
difftime(t2,t1) | |
plot(macdX.wr.txnsim) | |
t1 <- Sys.time() | |
macdX.nr.txnsim <- txnsim("macdX", n=1000, replacement = FALSE, tradeDef = "flat.to.flat") | |
t2 <- Sys.time() | |
difftime(t2,t1) | |
plot(macdX.nr.txnsim) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment