Overall Statistics
Total Trades
78
Average Win
10.84%
Average Loss
-4.52%
Compounding Annual Return
13.953%
Drawdown
33.800%
Expectancy
0.917
Net Profit
449.610%
Sharpe Ratio
0.728
Probabilistic Sharpe Ratio
10.687%
Loss Rate
44%
Win Rate
56%
Profit-Loss Ratio
2.40
Alpha
0.151
Beta
-0.191
Annual Standard Deviation
0.181
Annual Variance
0.033
Information Ratio
0.117
Tracking Error
0.285
Treynor Ratio
-0.69
Total Fees
$1010.04
# Dual Momentum v3

class DualMomentum(QCAlgorithm):

    def Initialize(self):
    
        self.SetStartDate(2008, 1, 1)  
        self.SetEndDate(2021, 1, 13)  
        self.InitCash = 100000
        self.SetCash(self.InitCash)  
        self.MKT = self.AddEquity("SPY", Resolution.Daily).Symbol
        self.mkt = []
        
        self.bond = self.AddEquity("TLT", Resolution.Minute).Symbol
        self.mom_period = 100        
        self.leverage = 1 
        self.SetWarmUp(self.mom_period)
        
        self.assets_mom = [SymbolData(self,symbolString, self.mom_period) for symbolString in ['QQQ', 'EFA', 'EEM']]
        self.bill_mom = SymbolData(self,"SHV", self.mom_period)
        
        
        self.Schedule.On(self.DateRules.MonthStart(self.MKT),self.TimeRules.AfterMarketOpen(self.MKT), 
            self.Rebalance)
        
            
    def Rebalance(self):
        self.assets_mom.sort(key = lambda x: x.Momentum.Current.Value, reverse = True)
        selected = self.assets_mom[0].Symbol
        if self.assets_mom[0].Momentum.Current.Value < self.bill_mom.Momentum.Current.Value:
            selected  = self.bond
        self.SetHoldings(selected, self.leverage, True)
        
        
    def OnEndOfDay(self): 
        
        mkt_price = self.Securities[self.MKT].Close
        self.mkt.append(mkt_price)
        mkt_perf = self.InitCash * self.mkt[-1] / self.mkt[0] 
        self.Plot('Strategy Equity', self.MKT, mkt_perf)     
        
        account_leverage = self.Portfolio.TotalHoldingsValue / self.Portfolio.TotalPortfolioValue
        
        self.Plot('Holdings', 'leverage', round(account_leverage, 2))
        self.Plot('Holdings', 'Target Leverage', self.leverage)    
        
        
class SymbolData:
    def __init__(self,algorithm, symbolString,lookBackPeriod):
        self.Symbol = algorithm.AddEquity(symbolString, Resolution.Daily).Symbol
        self.Momentum = algorithm.MOM(self.Symbol, lookBackPeriod, Resolution.Daily)