Overall Statistics
Total Trades
3
Average Win
17.08%
Average Loss
0%
Compounding Annual Return
9.560%
Drawdown
33.800%
Expectancy
0
Net Profit
321.050%
Sharpe Ratio
0.633
Probabilistic Sharpe Ratio
4.504%
Loss Rate
0%
Win Rate
100%
Profit-Loss Ratio
0
Alpha
0.095
Beta
-0.071
Annual Standard Deviation
0.14
Annual Variance
0.02
Information Ratio
0.008
Tracking Error
0.235
Treynor Ratio
-1.256
Total Fees
$3.00
from System.Drawing import Color

class SMA_multi_timescale(QCAlgorithm):
    
    def Initialize(self):
        self.SetStartDate(2005, 1, 1)                       # the starting date for our backtest
        #self.SetEndDate(2020, 6, 1)                        # the ending date for our backtest (if no date, then it will test up until today)
        self.start_value = 5000
        self.cash = self.start_value
        self.SetCash(self.cash)                                  # the starting amount of our portfolio
        self.EQY = "SPY"                                   # define the stock ticker
        self.EQY2 = "SH"
        self.AddEquity(self.EQY, Resolution.Daily)          # add a stock to the list of those we want to trade, and how often to pull data
        self.AddEquity(self.EQY2, Resolution.Daily)
        self.starting_price = None
        period0 = 10
        period1 = 20
        period2 = 50
        period3 = 20
    
        # all 3 time periods needs to have 3 indicators
        
    
        
        # create a consolidator for weekly data
        self.Consolidate(self.EQY, Calendar.Weekly, self.OnWeeklyBar)
        
        # create a consolidator for monthly data
        self.Consolidate(self.EQY, Calendar.Monthly, self.OnMonthlyBar)
        
        # set up an SMA20 indicator
        #var sma = SMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
        self.mom = self.MOM(self.EQY, period0)
        
        self.sma_daily0 = self.SMA(self.EQY, period0, Resolution.Daily) 
        self.sma_daily1 = self.SMA(self.EQY, period1, Resolution.Daily) 
        self.sma_daily2 = self.SMA(self.EQY, period2, Resolution.Daily) 
        self.sma_daily3 = self.SMA(self.EQY, period3, Resolution.Daily) 
        
        self.sma_weekly1 = SimpleMovingAverage(period1)
        self.sma_weekly2 = SimpleMovingAverage(period2)
        self.sma_weekly3 = SimpleMovingAverage(period3)
        
        self.sma_monthly1 = SimpleMovingAverage(period1)
        self.sma_monthly2 = SimpleMovingAverage(period2)
        self.sma_monthly3 = SimpleMovingAverage(period3)
        
        # need to give the indicators data before running the algorithm
        self.SetWarmUp(period3*7*31)
        
        #set up a chart to display our buy and sell dates
        self.stockPlot = Chart('Equity Daily')
        self.SPY_candles  = Series(self.EQY, SeriesType.Candle)
        self.stockPlot.AddSeries(self.SPY_candles)
        self.AddChart(self.stockPlot)
        
        # set up a chart to display our buy and sell dates
        self.stockPlot = Chart('Equity Weekly')
        self.SPY_weekly_candles  = Series(self.EQY, SeriesType.Candle)
        self.stockPlot.AddSeries(self.SPY_weekly_candles)
        self.stockPlot.AddSeries(Series('Buy', SeriesType.Scatter, '$', Color.Green, ScatterMarkerSymbol.Triangle))
        self.stockPlot.AddSeries(Series('Sell', SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.TriangleDown))
        self.AddChart(self.stockPlot)
        
        # set up a chart to display our buy and sell dates
        self.stockPlot = Chart('Equity Monthly')
        self.SPY_monthly_candles  = Series(self.EQY, SeriesType.Candle)
        self.stockPlot.AddSeries(self.SPY_monthly_candles)
        self.AddChart(self.stockPlot)
        
        
     # this is for plotting the relative change of each stock and our portfolio value   
    # def OnEndOfDay(self):
    #     current_portfolio = self.Portfolio.TotalPortfolioValue
    #     change_portfolio = (current_portfolio - self.start_value )/ self.start_value
    #     self.Plot("Percent Change","Portfolio Change", change_portfolio)
        
    #     # # if we haven't gotten the starting price, then get it
    #     if self.starting_price == None:
    #         self.starting_price = self.Securities[self.EQY].Price
        
    #     start_price = self.starting_price
    #     price = self.Securities[self.EQY].Price
    #     change_in_price = (price - start_price)/ start_price
    #     self.Plot("Percent Change", self.EQY + " Change", change_in_price)
   

    def OnData(self, data):         # this function is where trades happen. it executes based on the freqeuncy of data in the self.AddEquity function above
        
        if self.IsWarmingUp: return
        
        price = self.Securities[self.EQY].Price
        
        # # if the indicators aren't ready, don't do anything
        if (not self.sma_monthly3.IsReady): return
        
        daily_low_price  = self.Securities[self.EQY].Low
        daily_high_price = self.Securities[self.EQY].High
        
        weekly_low_price = self.weeklyBar.Low
        weekly_high_price = self.weeklyBar.High
        
        monthly_low_price = self.monthlyBar.Low
        monthly_high_price = self.monthlyBar.High
        
        # # extract the current value of each indicator
        sma_daily0 = self.sma_daily0.Current.Value
        sma_daily1 = self.sma_daily1.Current.Value
        sma_daily2 = self.sma_daily2.Current.Value
        sma_daily3 = self.sma_daily3.Current.Value
        
        sma_weekly1 = self.sma_weekly1.Current.Value
        sma_weekly2 = self.sma_weekly2.Current.Value
        sma_weekly3 = self.sma_weekly3.Current.Value
        
        sma_monthly1 = self.sma_monthly1.Current.Value
        sma_monthly2 = self.sma_monthly2.Current.Value
        sma_monthly3 = self.sma_monthly3.Current.Value
        
        mom_daily0 = self.mom.Current.Value
        
        # Entry points
        # daily logic
        up_mom = mom_daily0 > 0
        
        daily_entry0 = daily_low_price > sma_daily0
        daily_entry1 = daily_low_price > sma_daily1
        daily_entry2 = daily_low_price > sma_daily2
        daily_entry3 = daily_low_price > sma_daily3
        
        # Sanity check 
        # weekly logic
        weekly_entry1 = weekly_low_price > sma_weekly1
        weekly_entry2 = weekly_low_price > sma_weekly2
        weekly_entry3 = weekly_low_price > sma_weekly3
        
        # Sanity check 
        # monthly logic
        monthly_entry1 = monthly_low_price > sma_monthly1
        monthly_entry2 = monthly_low_price > sma_monthly2
        monthly_entry3 = monthly_low_price > sma_monthly3
        
        
        
        
        # Exit points
        # daily logic
        daily_exit1 = daily_high_price < sma_daily1
        daily_exit2 = daily_high_price < sma_daily2
        daily_exit3 = daily_high_price < sma_daily3
        
        # Sanity check 
        # weekly logic
        weekly_exit1 = weekly_high_price < sma_weekly1
        weekly_exit2 = weekly_high_price < sma_weekly2
        weekly_exit3 = weekly_high_price < sma_weekly3
        
        # Sanity check 
        # monthly logic
        monthly_exit1 = monthly_high_price < sma_monthly1
        monthly_exit2 = monthly_high_price < sma_monthly2
        monthly_exit3 = monthly_high_price < sma_monthly3
        
        
        
        # entry point logic
        if not self.Portfolio.Invested:
            if monthly_entry1: #and monthly_entry2 and monthly_entry3:
                if weekly_entry1: #and weekly_entry2 and weekly_entry3:
                    if daily_entry1: #and daily_entry2 and daily_entry3:
                        # entry
                        self.SetHoldings(self.EQY, 1)       # if the price is above the 20-day moving average, buy the stock
                        self.Plot("Equity Weekly", 'Buy', self.Securities[self.EQY].Price)
                
        
        # exit point logic
        if self.Portfolio.Invested:
            if monthly_exit1:
                if weekly_exit1:
                    if daily_exit1:
                        # exit
                        self.SetHoldings(self.EQY, 0)        # otherwise exit the position
                        self.Plot("Equity Weekly", 'Sell', self.Securities[self.EQY].Price)
         
         
        # # for going short                  
        # if self.Portfolio.Invested:
        #     if up_mom:              
        #         self.SetHoldings(self.EQY2, 0) 
        #         self.Plot("Equity Weekly", 'Buy', self.Securities[self.EQY].Price)
            
        # if not self.Portfolio.Invested:
        #     if monthly_exit1:
        #         self.SetHoldings(self.EQY2, 1)
        #         self.Plot("Equity Weekly", 'Sell', self.Securities[self.EQY].Price)
        
            
        # plotting stuff 
        # self.Plot("Equity Daily",self.EQY,self.Securities[self.EQY].Price)
        # self.Plot("Equity Daily","SMA1",sma_daily1)
        # self.Plot("Equity Daily","SMA2",sma_daily1)
        # self.Plot("Equity Daily","SMA3",sma_daily1)
        # self.SPY_candles.AddPoint(self.Time + timedelta(minutes=1), self.Securities[self.EQY].Open)
        # self.SPY_candles.AddPoint(self.Time + timedelta(minutes=2), self.Securities[self.EQY].High)
        # self.SPY_candles.AddPoint(self.Time + timedelta(minutes=3), self.Securities[self.EQY].Low)
        # self.SPY_candles.AddPoint(self.Time + timedelta(minutes=4), self.Securities[self.EQY].Close)
        

        
        #self.Log(self.Securities[self.EQY].Price)
        
        
        
    def OnWeeklyBar(self, weeklyBar):
        
        # self.Log(weeklyBar)
        
        self.weeklyBar = weeklyBar
        
        self.sma_weekly1.Update(self.weeklyBar.Time, self.weeklyBar.Close)
        sma_weekly1 = self.sma_weekly1.Current.Value
        
        self.sma_weekly2.Update(self.weeklyBar.Time, self.weeklyBar.Close)
        sma_weekly2 = self.sma_weekly2.Current.Value
        
        self.sma_weekly3.Update(self.weeklyBar.Time, self.weeklyBar.Close)
        sma_weekly3 = self.sma_weekly3.Current.Value
        
        # plotting stuff
        self.Plot("Equity Weekly","SMA1",sma_weekly1)
        self.Plot("Equity Weekly","Weekly High",self.weeklyBar.High)
        self.Plot("Equity Weekly","Weekly Low",self.weeklyBar.Low)
        #self.Plot("Equity Weekly","SMA2",sma_weekly2)
        #self.Plot("Equity Weekly","SMA3",sma_weekly3)
        #self.SPY_weekly_candles.AddPoint(self.Time, self.weeklyBar.Open)
        #self.SPY_weekly_candles.AddPoint(self.Time, self.weeklyBar.High)
        #self.SPY_weekly_candles.AddPoint(self.Time, self.weeklyBar.Low)
        #self.SPY_weekly_candles.AddPoint(self.Time, self.weeklyBar.Close)
        
        current_portfolio = self.Portfolio.TotalPortfolioValue
        change_portfolio = (current_portfolio - self.start_value )/ self.start_value
        self.Plot("Percent Change","Portfolio Change", change_portfolio)
        
        # # if we haven't gotten the starting price, then get it
        if self.IsWarmingUp: return
        
        if self.starting_price == None:
            self.starting_price = self.Securities[self.EQY].Price
        
        start_price = self.starting_price
        price = self.Securities[self.EQY].Price
        change_in_price = (price - start_price)/ start_price
        self.Plot("Percent Change", self.EQY + " Change", change_in_price)
        
        
        

    def OnMonthlyBar(self, monthlyBar):
        
        # self.Log(weeklyBar)
        
        self.monthlyBar = monthlyBar
        
        self.sma_monthly1.Update(self.monthlyBar.Time, self.monthlyBar.Close)
        sma_monthly1 = self.sma_monthly1.Current.Value
        
        self.sma_monthly2.Update(self.monthlyBar.Time, self.monthlyBar.Close)
        sma_monthly2 = self.sma_monthly2.Current.Value
        
        self.sma_monthly3.Update(self.monthlyBar.Time, self.monthlyBar.Close)
        sma_monthly3 = self.sma_monthly3.Current.Value
        
        # self.Plot("Equity Monthly","SMA1",sma_monthly1)
        # self.Plot("Equity Monthly","Monthly High",self.monthlyBar.High)
        # self.Plot("Equity Monthly","Monthly Low",self.monthlyBar.Low)
        #self.Plot("Equity Monthly","SMA2",sma_monthly2)
        #self.Plot("Equity Monthly","SMA3",sma_monthly3)
        #self.SPY_monthly_candles.AddPoint(self.Time, self.monthlyBar.Open)
        #self.SPY_monthly_candles.AddPoint(self.Time, self.monthlyBar.High)
        #self.SPY_monthly_candles.AddPoint(self.Time, self.monthlyBar.Low)
        #self.SPY_monthly_candles.AddPoint(self.Time, self.monthlyBar.Close)