#Install SIT package
devtools::install_github('systematicinvestor/SIT.date', force = T) 
## Downloading GitHub repo systematicinvestor/SIT.date@HEAD
## 
## ── R CMD build ─────────────────────────────────────────────────────────────────
##   
   checking for file ‘/tmp/RtmpsEEzo4/remotes39ce304c66/systematicinvestor-SIT.date-6263da6/DESCRIPTION’ ...
  
✔  checking for file ‘/tmp/RtmpsEEzo4/remotes39ce304c66/systematicinvestor-SIT.date-6263da6/DESCRIPTION’ (397ms)
## 
  
─  preparing ‘SIT.date’:
##    checking DESCRIPTION meta-information ...
  
✔  checking DESCRIPTION meta-information
## 
  
─  checking for LF line-endings in source and make files and shell scripts
## ─  checking for empty or unneeded directories
##    Omitted ‘LazyData’ from DESCRIPTION
## 
  
─  building ‘SIT.date_0.1.tar.gz’
## 
  
   Warning: invalid uid value replaced by that for user 'nobody'
## 
  
   
## 
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
rm(list=ls())
#setInternet2(TRUE)
con = gzcon(url('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', 'rb'))
source(con)
close(con)
curl::curl_download('https://github.com/systematicinvestor/SIT/raw/master/SIT.tar.gz','SIT.tar.gz',mode = 'wb',quiet=T)
install.packages('SIT.tar.gz', repos=NULL, type='source')
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
library(SIT)
## Loading required package: SIT.date
## 
## Attaching package: 'SIT.date'
## The following objects are masked _by_ '.GlobalEnv':
## 
##     apply.business.days, business.days, business.days.location.end,
##     business.days.since.end, business.days.till.end, custom.date,
##     custom.date.bus, date.all, date.day, date.dayofweek, date.end,
##     date.ends, date.ends.fn, date.ends.index, date.ends.n, date.month,
##     date.month.ends, date.periodicity.map, date.quarter,
##     date.quarter.ends, date.semiannual, date.semiannual.ends,
##     date.week, date.week.ends, date.year, date.year.ends,
##     last.business.day, map.spx.expiration, next.business.day,
##     third.friday.month
## Loading required package: quantmod
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## 
## Attaching package: 'TTR'
## The following object is masked _by_ '.GlobalEnv':
## 
##     DVI
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## 
## Attaching package: 'SIT'
## The following objects are masked _by_ '.GlobalEnv':
## 
##     add, add.avg.factor, add.constraint.cdar, add.constraint.cvar,
##     add.constraint.gini, add.constraint.mad,
##     add.constraint.mad.downside, add.constraint.maxloss,
##     add.constraint.omega, add.constraints, add.StringBuffer,
##     add.variables, all.permutations, aritm2geom, aritm2geom4,
##     as.xts.list, asc, asset.paths, asset.paths.at.period.ends,
##     average.shrinkage, barplot.with.labels, bbb_control, beta.degree,
##     binary_branch_bound, bl.compute.eqret, bl.compute.optimal,
##     bl.compute.posterior, bl.compute.risk.aversion, br.rank,
##     bt.aaa.combo, bt.aaa.minrisk, bt.append.today, bt.apply,
##     bt.apply.ex, bt.apply.ex2, bt.apply.matrix, bt.apply.matrix.ex,
##     bt.apply.matrix.ex2, bt.apply.min.weight, bt.apply.round.weight,
##     bt.change.periodicity, bt.detail.summary, bt.end.dates, bt.exrem,
##     bt.exrem.time.exit, bt.make.cashflow.event.summary.table,
##     bt.make.trade.event.summary.table, bt.max.deviation.rebalancing,
##     bt.merge, bt.min.holding.period, bt.prep, bt.prep.matrix,
##     bt.prep.remove.symbols, bt.prep.remove.symbols.min.history,
##     bt.prep.trim, bt.price.stop, bt.rank, bt.run, bt.run.share,
##     bt.run.share.ex, bt.run.share.ex.allocate, bt.run.share.ex.invest,
##     bt.run.share.ex.test, bt.run.share.ex.test.cashflow,
##     bt.run.share.ex.test.tax, bt.run.share.fast,
##     bt.run.share.unadjusted.test, bt.run.share.unadjusted.test.data,
##     bt.run.trim.helper, bt.run.weight.fast, bt.simple, bt.start.dates,
##     bt.stop.strategy.plot, bt.summary, bt.time.price.stop,
##     bt.time.stop, bt.trade.summary, bt.trade.summary.helper,
##     bt.trade.summary.old, bt.trim, bt.ts.enter.state, bt.ts.price.stop,
##     bt.ts.time.price.stop, bt.ts.time.stop, bt.ts.trade.index,
##     bt.unadjusted.add.div.split, bundes.bank.data,
##     bundes.bank.data.gold, calendar.signal, calendar.strategy,
##     cap.weighted.mean, cboe.volatility.term.structure.SPX, check.args,
##     chr, clean.table, close, close.StringBuffer, cluster.group.FTCA,
##     cluster.group.hclust, cluster.group.kmeans.90,
##     cluster.group.kmeans.elbow, clusterApplyLB.log, col.add.alpha,
##     col.name2row, compute.annual.factor, compute.avg.drawdown,
##     compute.avgcor, compute.cagr, compute.calmar, compute.cdar,
##     compute.cor, compute.cvar, compute.drawdown, compute.drawdowns,
##     compute.DVR, compute.exposure, compute.max.deviation,
##     compute.max.drawdown, compute.nyears, compute.quantiles,
##     compute.R2, compute.raw.annual.factor, compute.risk,
##     compute.sharpe, compute.stats, compute.turnover, compute.var,
##     consecutive.changes, convert2expr, count, country.code, cov.2param,
##     cov.const.cor, cov.diag, cov.market, cov.sample, cov.shrink,
##     create.basic.constraints, create.cov.matrix, create.historical.ia,
##     create.ia, create.ia.averaged, create.ia.period, create.ia.subset,
##     create.leveraged, create.monthly.table, create.strategies,
##     createNonReactiveTextInput, createNonReactiveTextInputCustom,
##     cross, cross.dn, cross.dn.eq, cross.up, cross.up.eq,
##     custom.composite.diversification.indicator, custom.stop.fn,
##     custom.stop.fn.list, data.aqr, data.clean,
##     data.csi.security.master, data.ff, data.fomc,
##     data.ft.index.members, data.ft.search.ticker,
##     data.ishares.universe, data.yahoo.profile, date.fund.data,
##     dates2index, debug.load, debug.save, default.round.lot.control,
##     default.tax.control, delete.constraints, diagonal.shrinkage,
##     distribute.weights, dow.jones.components, download.helper, DV, DVI,
##     edgar.info, ef.portfolio, empty.group, engineering.returns.kpi,
##     env, env.del, env.rm, equal.risk.contribution.portfolio,
##     equal.weight.portfolio, ev.ratio, event.at, exp.sample.shrinkage,
##     expr.symbols, exrem, extend.data, extend.data.proxy, extend.GLD,
##     extract.table, extract.table.from.webpage, extract.token,
##     extract.VXX.CBOE, factor.avgcor, factor.model.shrinkage,
##     fast.na.omit, find.all.patterns.window, find.erc.portfolio,
##     find.erc.portfolio.simple, find.extrema,
##     find.maximum.distance.point, find.names, find.patterns,
##     find.tokens, flip.xts, fm.hist.dow.jones.components,
##     fred.fx.symbol, ftse100.components, fund.data, fx.sauder.data,
##     fxhistoricaldata.fx.symbol, geom2aritm, geom2aritm4, get.algo,
##     get.barcharts.quote, get.bigcharts.quote, get.CRB, get.extension,
##     get.fama.french.data, get.filename, get.FOMC.dates,
##     get.full.filename, get.fund.data, get.fund.data.index, get.G10,
##     get.group, get.risky.asset.index, get.url, getQuote.google,
##     getQuote.google.xml, getQuote.yahoo.info, getQuote.yahoo.today,
##     getSymbol.CBOE, getSymbol.intraday.google, getSymbols.extra,
##     getSymbols.fxhistoricaldata, getSymbols.intraday, getSymbols.PI,
##     getSymbols.sit, getSymbols.TB, google.search, group.seasonality,
##     hierarchical.risk.parity, hist.quotes.url, ia.build.hist, ifna,
##     ifna.prev, ifna.prevx, ifna.prevx.rev, ifnull, iif, iline,
##     index.xts, inv, inv1, inv2, inv3, inverse.variance.portfolio, join,
##     last.signals, last.trades, ledoit.wolf.shrinkage, len, list2matrix,
##     list2vars, lm.constraint, load.aqr.data, load.packages,
##     load.VXX.CBOE, log.fn, log.fn.msg, look.at.taxes, lookup.index,
##     lp.obj.portfolio, ls.f, ls.v, lst, make.data.proxy,
##     make.random.string, make.stock.xts, make.xts, map.min.risk.fns,
##     map.symbols, map2monthly, map2vector, mat, mat.3d, mat.slice.3d,
##     mat2num, max.div.portfolio, max.geometric.return.portfolio,
##     max.omega.portfolio, max.return.portfolio,
##     max.sharpe.nlp.portfolio, max.sharpe.portfolio,
##     max.sharpe.portfolio.axioma, max.sharpe.portfolio.helper,
##     max.shrinkage, meom.strategy, merge.constraints,
##     min.avgcor.portfolio, min.cdar, min.cdar.portfolio,
##     min.cor.insteadof.cov.portfolio, min.corr, min.corr.excel,
##     min.corr.excel.portfolio, min.corr.portfolio,
##     min.corr.special.case, min.corr2, min.corr2.portfolio, min.cvar,
##     min.cvar.portfolio, min.gini.portfolio, min.mad.downside,
##     min.mad.downside.portfolio, min.mad.portfolio,
##     min.maxloss.portfolio, min.portfolio, min.risk.downside,
##     min.risk.downside.portfolio, min.risk.portfolio, min.shrinkage,
##     min.te.portfolio.test, min.var.excel, min.var.excel.portfolio,
##     min.var.portfolio, min.var.portfolio.gmpl, min.var2,
##     min.var2.portfolio, min.var2111, mlag, mlast, momentum.averaged,
##     month.year.seasonality, nasdaq.100.components, new.constraints,
##     normal.transform, normalize.mkval, normalize.normal, ntop,
##     ntop.helper, ntop.keep, ols, ols.summary, optimize.portfolio,
##     optimize.portfolio.nlp, parse.expr, parse.number, parse.views,
##     pattern.db, percent.rank, percent.rankM,
##     performance.barchart.helper, plot.add.portfolios,
##     plot.bt.quantiles, plot.ef, plot.factors, plot.ia, plot.omega,
##     plot.patterns, plot.quantiles, plot.table, plot.transition.map,
##     plot.transitopn.map, plot.txt, plot12month.rolling.spread, plota,
##     plota.add.copyright, plota.colors, plota.colors.experimental,
##     plota.format, plota.grid, plota.layout, plota.legend, plota.lines,
##     plota.matplot, plota.recession, plota.scale.volume, plota.stacked,
##     plota.test, plota.text, plota.theme, plota.theme.blue.red,
##     plota.theme.gray.orange, plota.theme.green.orange, plota.volume,
##     plota.x.highlight, plota.y.highlight, plota2Y, plotbt,
##     plotbt.custom.report, plotbt.custom.report.part1,
##     plotbt.custom.report.part2, plotbt.custom.report.part3,
##     plotbt.holdings, plotbt.holdings.time, plotbt.monthly.table,
##     plotbt.strategy.sidebyside, plotbt.transition.map,
##     portfolio.allocation.custom.stats, portfolio.allocation.helper,
##     portfolio.allocation.helper.basic,
##     portfolio.allocation.helper.parallel, portfolio.avgcor,
##     portfolio.avgcor.real, portfolio.cdar, portfolio.cdar.real,
##     portfolio.concentration.gini.coefficient,
##     portfolio.concentration.herfindahl.index, portfolio.cvar,
##     portfolio.geometric.return, portfolio.gini.coefficient,
##     portfolio.mad, portfolio.mad.downside, portfolio.maxloss,
##     portfolio.omega, portfolio.return, portfolio.risk,
##     portfolio.risk.contribution, portfolio.risk.downside,
##     portfolio.turnover, portfolio.unrebalanced.return, portfolio.var,
##     portopt, portopt.omega, PricingZeroCouponBond, processTBill,
##     proxy.map, proxy.overlay.plot, proxy.prices, proxy.test,
##     quantumonline.info, randfixedsum, random.hist, random.hist.weight,
##     random.string, randsphere, read.file, read.xts,
##     reconstruct.VXX.CBOE, remove.tags, rep.col, rep.row, replace.token,
##     repmat, rev.map, Rglpk.create.constraints, Rglpk.read.model,
##     risk.parity.portfolio, risk.parity.portfolio.basic, roofing.filter,
##     roofing.stochastic.indicator, rotation.strategy, round.lot,
##     round.lot.basic, round.lot.basic.base, round.to, row.name2col,
##     rso.portfolio, run.count, runQuantile, sample.anchored.shrinkage,
##     sample.mix.shrinkage, sample.shrinkage, scale.one, sector.mean,
##     sector.spdr.components, set.risky.asset, setup.cluster,
##     shrink.const.cor, shrink.diag, shrink.single.index,
##     shrink.two.parameter, solve.LP.bounds, solve.QP.bounds,
##     sp100.components, sp500.components, spl, static.group,
##     static.weight.portfolio, strategy.load.historical.data,
##     strategy.performance.snapshoot, string, string.buffer,
##     string.StringBuffer, super.smoother.filter, tableColor,
##     target.return.portfolio, target.return.portfolio.helper,
##     target.risk.portfolio, target.risk.portfolio.helper,
##     target.vol.strategy, tax.cashflows, tax.summary, test.equality,
##     tic, time.seasonality, timing.strategy, tls, to.cash, to.nice,
##     to.percent, toc, trim, TSI, type.constraints, ulcer.index,
##     update.ia, us.ishares.components, variable.number.arguments,
##     vars2list, vec, verify.control,
##     visualize.system.parameter.optimization, wealthsimple.portfolio,
##     write.file, write.xts, xts2ts, XTSFunctions, zacks.info
## The following object is masked from 'package:TTR':
## 
##     DVI
## The following object is masked from 'package:base':
## 
##     close
library(quantmod)
library(quadprog)
library(lpSolve)
# Load historical data
tickers = spl('SPY,TLT')
data <- new.env()
getSymbols(tickers, src = 'yahoo', from = '1980-01-01', env = data, auto.assign = T)
## [1] "SPY" "TLT"
for(i in ls(data)) data[[i]] = adjustOHLC(data[[i]], use.Adjusted=T)
bt.prep(data, align='remove.na', dates='2005::')



# Setup
 
lookback.len = 60

prices = data$prices

models = list()


# Simple Momentum
 
momentum = prices / mlag(prices, lookback.len)
data$weight[] = NA
data$weight$SPY[] = momentum$SPY > momentum$TLT
data$weight$TLT[] = momentum$SPY <= momentum$TLT
models$Simple  = bt.run.share(data, clean.signal=T)
## Latest weights :
##            SPY TLT
## 2023-05-26 100   0
## 
## Performance summary :
##  CAGR    Best    Worst   
##  7.2 7.5 -6.7    
# Probabilistic Momentum
confidence.level = 60/100
ret = prices / mlag(prices) - 1 
 
ir = sqrt(lookback.len) * runMean(ret$SPY - ret$TLT, lookback.len) / runSD(ret$SPY - ret$TLT, lookback.len)
momentum.p = pt(ir, lookback.len - 1)
     
data$weight[] = NA
    data$weight$SPY[] = iif(cross.up(momentum.p, confidence.level), 1, iif(cross.dn(momentum.p, (1 - confidence.level)), 0,NA))
    data$weight$TLT[] = iif(cross.dn(momentum.p, (1 - confidence.level)), 1, iif(cross.up(momentum.p, confidence.level), 0,NA))
models$Probabilistic  = bt.run.share(data, clean.signal=T)
## Latest weights :
##            SPY TLT
## 2023-05-26 100   0
## 
## Performance summary :
##  CAGR    Best    Worst   
##  9.9 7.5 -6.7    
 # Probabilistic Momentum + SPY Leverage 
data$weight[] = NA
    data$weight$SPY[] = iif(cross.up(momentum.p, confidence.level), 1, iif(cross.up(momentum.p, (1 - confidence.level)), 0,NA))
    data$weight$TLT[] = iif(cross.dn(momentum.p, (1 - confidence.level)), 1, iif(cross.up(momentum.p, confidence.level), 0,NA))
models$Probabilistic.Leverage = bt.run.share(data, clean.signal=T)  
## Latest weights :
##            SPY TLT
## 2023-05-26 100   0
## 
## Performance summary :
##  CAGR    Best    Worst   
##  11.4    6.4 -12.7   
# Create Report
strategy.performance.snapshoot(models, T)

## NULL
# Visualize Signal
       
cols = spl('steelblue1,steelblue')
prices = scale.one(data$prices)
 
layout(1:3)
 
plota(prices$SPY, type='l', ylim=range(prices), plotX=F, col=cols[1], lwd=2)
plota.lines(prices$TLT, type='l', plotX=F, col=cols[2], lwd=2)
## Warning in plot.xy(xy.coords(x, y), type = type, ...): "plotX" is not a
## graphical parameter

# Visualize Signal
cols = spl('steelblue1,steelblue')
prices = scale.one(data$prices)
 
layout(1:3)
 
plota(prices$SPY, type='l', ylim=range(prices), plotX=F, col=cols[1], lwd=2)
plota.lines(prices$TLT, type='l', plotX=F, col=cols[2], lwd=2)
## Warning in plot.xy(xy.coords(x, y), type = type, ...): "plotX" is not a
## graphical parameter
    plota.legend('SPY,TLT',cols,as.list(prices))
 
highlight = models$Probabilistic$weight$SPY > 0
    plota.control$col.x.highlight = iif(highlight, cols[1], cols[2])
plota(models$Probabilistic$equity, type='l', plotX=F, x.highlight = highlight | T)
    plota.legend('Probabilistic,SPY,TLT',c('black',cols))
             
highlight = models$Simple$weight$SPY > 0
    plota.control$col.x.highlight = iif(highlight, cols[1], cols[2])
plota(models$Simple$equity, type='l', plotX=T, x.highlight = highlight | T)
    plota.legend('Simple,SPY,TLT',c('black',cols))