| 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