| Overall Statistics |
|
Total Trades 95 Average Win 7.26% Average Loss -3.77% Compounding Annual Return 12.095% Drawdown 24.900% Expectancy 0.866 Net Profit 293.950% Sharpe Ratio 0.696 Probabilistic Sharpe Ratio 12.490% Loss Rate 36% Win Rate 64% Profit-Loss Ratio 1.92 Alpha 0.108 Beta -0.024 Annual Standard Deviation 0.151 Annual Variance 0.023 Information Ratio 0.082 Tracking Error 0.234 Treynor Ratio -4.405 Total Fees $2066.69 |
class DualMomentum(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2008, 1, 1) # Set Start Date
self.SetEndDate(2020, 1, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.us = self.AddEquity("SPY", Resolution.Daily).Symbol
self.worldExUS = self.AddEquity("VEU", Resolution.Daily).Symbol
self.tbill = self.AddEquity("SHV", Resolution.Daily).Symbol #SHY
self.agg = self.AddEquity("BND", Resolution.Daily).Symbol # AGG
self.leverage = 1.3
self.Schedule.On(self.DateRules.MonthStart("SPY"),self.TimeRules.AfterMarketOpen("SPY"), self.rebalance)
self.currentLong = self.us
self.returnWindowLength = 100
def Returns(self, symbol, period):
closingBars = self.History(symbol, TimeSpan.FromDays(period),Resolution.Daily).close
return (closingBars[-1] - closingBars[0])/closingBars[-1]
def rebalance(self):
if self.Returns(self.us,self.returnWindowLength) < self.Returns(self.tbill,self.returnWindowLength):
self.currentLong = self.agg
elif self.Returns(self.us,self.returnWindowLength) > self.Returns(self.worldExUS,self.returnWindowLength):
self.currentLong=self.us
else:
self.currentLong = self.worldExUS
stocksInvested = [x.Key for x in self.Portfolio if x.Value.Invested]
if not stocksInvested:
self.SetHoldings(self.currentLong, self.leverage)
elif self.currentLong != stocksInvested[0]:
self.SetHoldings(self.currentLong, self.leverage, True)
def OnData(self, data):
pass