| Overall Statistics |
|
Total Trades 110 Average Win 1.29% Average Loss -0.53% Compounding Annual Return 9.621% Drawdown 30.200% Expectancy 2.109 Net Profit 248.494% Sharpe Ratio 0.981 Probabilistic Sharpe Ratio 40.557% Loss Rate 9% Win Rate 91% Profit-Loss Ratio 2.43 Alpha 0.056 Beta 0.432 Annual Standard Deviation 0.104 Annual Variance 0.011 Information Ratio -0.046 Tracking Error 0.129 Treynor Ratio 0.237 Total Fees $281.00 |
def UpdateBenchmarkValue(self):
''' Simulate buy and hold the Benchmark '''
if self.initBenchmarkPrice == 0:
self.initBenchmarkCash = self.Portfolio.Cash
self.initBenchmarkPrice = self.Benchmark.Evaluate(self.Time)
self.benchmarkValue = self.initBenchmarkCash
else:
currentBenchmarkPrice = self.Benchmark.Evaluate(self.Time)
self.benchmarkValue = (currentBenchmarkPrice / self.initBenchmarkPrice) * self.initBenchmarkCash
def UpdatePlots(self):
# simulate buy and hold the benchmark and plot its daily value
UpdateBenchmarkValue(self)
self.Plot('Strategy Equity', self.benchmarkTicker, self.benchmarkValue)
# plot portfolio exposures
portfolioValue = self.Portfolio.TotalPortfolioValue
equityExposure = (self.Portfolio[self.equitySymbol].HoldingsValue / portfolioValue) * 100
safeExposure = (self.Portfolio[self.safeSymbol].HoldingsValue / portfolioValue) * 100
self.Plot('Portfolio Exposures', 'Equity Exposure', equityExposure)
self.Plot('Portfolio Exposures', 'Safe Exposure', safeExposure)from HelperFunctions import *
from System.Drawing import Color
import pandas as pd
class TrendFollowingSystemTemplateAlgorithm(QCAlgorithm):
''' Implementation of the Pacer Trendpilot Strategy '''
def Initialize(self):
''' Initialization at beginning of backtest '''
### USER-DEFINED INPUTS ---------------------------------------------------------------------------------------------------
self.SetStartDate(2007, 1, 1)
self.SetEndDate(2020, 7, 31)
self.SetCash(1000000)
# TICKERS ----------------------------------------------------------------------------------
self.equityTicker = 'SPY' # equity like asset
self.safeTicker = 'TLT' # cash/bond like asset
self.benchmarkTicker = 'SPY' # select a benchmark
# ALLOCATIONS ------------------------------------------------------------------
# allocations = [equityTicker allocation, safeTicker allocation]
self.allocations = [0.6, 0.4]
# rebalancing (options are monthly/quarterly)
self.rebalancingPeriod = 'quarterly'
### -----------------------------------------------------------------------------------------------------------------------
# add benchmark
self.SetBenchmark(self.benchmarkTicker)
# add data
self.equitySymbol = self.AddEquity(self.equityTicker, Resolution.Hour).Symbol
self.safeSymbol = self.AddEquity(self.safeTicker, Resolution.Hour).Symbol
self.initBenchmarkPrice = 0
self.previousPeriod = 0
# initialize plots
portfolioExposuresPlot = Chart('Portfolio Exposures')
portfolioExposuresPlot.AddSeries(Series('Equity Exposure', SeriesType.Line, '%', Color.Green))
portfolioExposuresPlot.AddSeries(Series('Safe Exposure', SeriesType.Line, '%', Color.Red))
self.AddChart(portfolioExposuresPlot)
def OnData(self, data):
''' Event triggering every time there is new data '''
if self.Time.hour != 10:
return
# update plots
UpdatePlots(self)
# rebalancing
if self.rebalancingPeriod == 'monthly':
currentPeriod = self.Time.month
elif self.rebalancingPeriod == 'quarterly':
currentPeriod = pd.Timestamp(self.Time.date()).quarter
else:
raise ValueError('self.rebalancingPeriod must be either monthly or quarterly')
if currentPeriod != self.previousPeriod:
if (data.ContainsKey(self.equitySymbol) and data.ContainsKey(self.safeSymbol)
and self.ActiveSecurities[self.equitySymbol].Price > 0
and self.ActiveSecurities[self.safeSymbol].Price > 0):
# set holdings
allocationEquity = self.allocations[0]
allocationSafe = self.allocations[1]
self.SetHoldings([PortfolioTarget(self.equitySymbol, allocationEquity),
PortfolioTarget(self.safeSymbol, allocationSafe)])
self.previousPeriod = currentPeriod