Skip to content

Instantly share code, notes, and snippets.

@jaymon0703
Created July 13, 2020 01:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaymon0703/7a36a05c3af8a3635e089695335aa302 to your computer and use it in GitHub Desktop.
Save jaymon0703/7a36a05c3af8a3635e089695335aa302 to your computer and use it in GitHub Desktop.
macd_sig fun - silly maybe not so silly strategy
# 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