| Overall Statistics |
|
Total Trades 13 Average Win 7.65% Average Loss -5.16% Compounding Annual Return 4.297% Drawdown 21.100% Expectancy -0.173 Net Profit 23.883% Sharpe Ratio 0.409 Probabilistic Sharpe Ratio 6.933% Loss Rate 67% Win Rate 33% Profit-Loss Ratio 1.48 Alpha 0.041 Beta -0.012 Annual Standard Deviation 0.099 Annual Variance 0.01 Information Ratio 0.078 Tracking Error 0.236 Treynor Ratio -3.255 Total Fees $13.00 |
from System.Drawing import Color
class SMA_trading(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2005, 1, 1) # the starting date for our backtest
self.SetEndDate(2010, 2, 1) # the ending date for our backtest (if no date, then it will test up until today)
self.start_value = 5000 # define the amount of starting cash
self.SetCash(self.start_value) # initialize our wallet
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
self.spy_portfolio = None
self.period = 20
# create a consolidator for weekly data
self.Consolidate(self.EQY, Calendar.Weekly, self.OnWeeklyBar)
# set up an SMA20 indicator
#var sma = SMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
self.sma = SimpleMovingAverage(self.period)
# need to give the indicators data before running the algorithm
self.SetWarmUp(timedelta(self.period * 7))
# set up a chart to display our buy and sell dates
self.stockPlot = Chart('Equity')
self.SPY_candles = Series(self.EQY, SeriesType.Candle)
self.stockPlot.AddSeries(self.SPY_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)
# 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)
# price = self.Securities[self.EQY].Price
# change_in_price = (price - start_price)/ start_price
# self.Plot("Strategy Equity", self.EQY + " Change", change_in_price * self.start_value)
def OnWeeklyBar(self, weeklyBar):
# self.Log(weeklyBar)
self.currentBar = weeklyBar
self.sma.Update(weeklyBar.Time, weeklyBar.Close)
# # if the indicators aren't ready, don't do anything
if (not self.sma.IsReady): return
low_price = self.currentBar.Low
high_price = self.currentBar.High
# # extract the current value of each indicator
sma = self.sma.Current.Value
# # determine where the price is relative to the sma20
upSMA = low_price > sma
downSMA = high_price < sma
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", 'Buy', self.Securities[self.EQY].Price)
elif (downSMA):
if self.Portfolio[self.EQY].Invested:
self.SetHoldings(self.EQY, 0) # otherwise exit the position
self.Plot("Equity", 'Sell', self.Securities[self.EQY].Price)
# plotting stuff
self.SPY_candles.AddPoint(self.Time + timedelta(minutes=1), weeklyBar.Open)
self.SPY_candles.AddPoint(self.Time + timedelta(minutes=2), weeklyBar.High)
self.SPY_candles.AddPoint(self.Time + timedelta(minutes=3), weeklyBar.Low)
self.SPY_candles.AddPoint(self.Time + timedelta(minutes=4), weeklyBar.Close)
#self.Plot("Equity",self.EQY + " HIGH", weeklyBar.High)
#self.Plot("Equity",self.EQY + " LOW", weeklyBar.Low)
#self.Plot("Equity",self.EQY, weeklyBar.High)
#self.Plot("Equity",self.EQY, weeklyBar.Low)
#self.Plot("Equity",self.EQY, weeklyBar.Close)
#self.Plot("Equity",self.EQY+' Price',self.Securities[self.EQY].Close)
self.Plot("Equity","SMA", sma)
def OnOrderEvent(self, orderEvent):
if orderEvent.Status != OrderStatus.Filled:
return
self.Log(f"Order Executed! Open Time: {self.currentBar.Time}, Close Time: {self.currentBar.EndTime} -- Bar: {self.currentBar}, SMA: {self.sma.Current.Value}")