Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
2.182
Tracking Error
0.154
Treynor Ratio
0
Total Fees
$0.00
from System.Drawing import Color

class SMA_multi_timescale(QCAlgorithm):
    
    def Initialize(self):
        self.SetStartDate(2010, 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.AddEquity(self.EQY, Resolution.Daily)          # add a stock to the list of those we want to trade, and how often to pull data
        self.starting_price = None
        daily_period = 20
        weekly_period = 50
        monthly_period = 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.sma_daily = self.SMA(self.EQY, daily_period, Resolution.Daily) 
        #self.sma_daily = self.SMA(self.EQY, daily_period2, Resolution.Daily) 
        #self.sma_daily = self.SMA(self.EQY, daily_period3, Resolution.Daily) 
        
        self.sma_weekly = SimpleMovingAverage(weekly_period)
        self.sma_monthly = SimpleMovingAverage(monthly_period)
        
        # need to give the indicators data before running the algorithm
        self.SetWarmUp(monthly_period*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
        
        self.sma_weekly.Update(self.weeklyBar.Time, self.weeklyBar.Close)
        self.sma_monthly.Update(self.monthlyBar.Time, self.monthlyBar.Close)
        
        # # if the indicators aren't ready, don't do anything
        if (not self.sma_monthly.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_daily = self.sma_daily.Current.Value
        sma_weekly = self.sma_weekly.Current.Value
        sma_monthly = self.sma_monthly.Current.Value
        
        # Entry points
        # daily logic
        lowprice > sma20
        lowprice > sma50
        lowprice > sma200
        
        # Sanity check 
        # weekly logic
        lowprice > sma20
        lowprice > sma50
        lowprice > sma200
        
        # Sanity check 
        # monthly logic
        lowprice > sma20
        lowprice > sma50
        lowprice > sma200
        
        
        # Exit points
        # daily logic
        highprice < sma20
        highprice < sma50
        highprice < sma200
        
        # Sanity check 
        # weekly logic
        highprice < sma20
        highprice < sma50
        highprice < sma200
        
        # Sanity check 
        # monthly logic
        highprice < sma20
        highprice < sma50
        highprice < sma200
        
        
        # entry point logic
        # if monthly_entry:
        #     if weekly_entry:
        #         if daily_entry:
        #             # entry
        
        
        # exit point logic
        # if monthly_exit:
        #     if weekly_exit:
        #         if daily_exit:
        #             # exit
        
        # determine where the price is relative to the sma20
        upSMA = (daily_low_price > sma_daily) and (weekly_low_price > sma_weekly) and (monthly_low_price > sma_monthly)
        #upSMA = weekly_low_price > sma_weekly
        downSMA = (daily_high_price < sma_daily) and (weekly_high_price < sma_weekly) and (monthly_high_price < sma_monthly)
        #downSMA = weekly_high_price < sma_weekly
        
        
        if (upSMA):
            if not self.Portfolio[self.EQY].Invested:
                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)
        if (downSMA):
            if self.Portfolio[self.EQY].Invested:
                self.SetHoldings(self.EQY, 0)        # otherwise exit the position
                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","SMA",sma_daily)
        # 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)
        
        # plotting stuff
        self.Plot("Equity Weekly",self.EQY,self.Securities[self.EQY].Price)
        self.Plot("Equity Weekly","SMA",sma_weekly)
        self.SPY_weekly_candles.AddPoint(self.Time + timedelta(days=1), self.weeklyBar.Open)
        self.SPY_weekly_candles.AddPoint(self.Time + timedelta(days=2), self.weeklyBar.High)
        self.SPY_weekly_candles.AddPoint(self.Time + timedelta(days=3), self.weeklyBar.Low)
        self.SPY_weekly_candles.AddPoint(self.Time + timedelta(days=4), self.weeklyBar.Close)
        
        # # plotting stuff
        # self.Plot("Equity Monthly",self.EQY,self.Securities[self.EQY].Price)
        # self.Plot("Equity Monthly","SMA",sma_monthly)
        # self.SPY_monthly_candles.AddPoint(self.Time + timedelta(minutes=1), self.monthlyBar.Open)
        # self.SPY_monthly_candles.AddPoint(self.Time + timedelta(minutes=2), self.monthlyBar.High)
        # self.SPY_monthly_candles.AddPoint(self.Time + timedelta(minutes=3), self.monthlyBar.Low)
        # self.SPY_monthly_candles.AddPoint(self.Time + timedelta(minutes=4), self.monthlyBar.Close)
        

        
        self.Log(self.Securities[self.EQY].Price)
        
        
        
    def OnWeeklyBar(self, weeklyBar):
        
        # self.Log(weeklyBar)
        
        self.weeklyBar = weeklyBar
        
        
    def OnMonthlyBar(self, monthlyBar):
        
        # self.Log(weeklyBar)
        
        self.monthlyBar = monthlyBar