Overall Statistics |
Total Trades 470 Average Win 1.50% Average Loss -4.49% Compounding Annual Return 5.938% Drawdown 39.400% Expectancy 0.131 Net Profit 252.789% Sharpe Ratio 0.387 Probabilistic Sharpe Ratio 0.025% Loss Rate 15% Win Rate 85% Profit-Loss Ratio 0.34 Alpha 0.012 Beta 0.622 Annual Standard Deviation 0.127 Annual Variance 0.016 Information Ratio -0.113 Tracking Error 0.099 Treynor Ratio 0.079 Total Fees $470.00 Estimated Strategy Capacity $26000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X |
#region imports from AlgorithmImports import * #endregion #################################################################### # Simple System that Trades the S&P 500 (SPY) # Inspired by https://relaxedtrader.com/spy-swing-trading-system/ # Logic / Decision tree: https://imgur.com/a/kYmsiLi #################################################################### class SimpleSpyClimber(QCAlgorithm): def Initialize(self): ## Initialize algo params self.ticker = "SPY" # Ticker symbol to trade self.SetStartDate(2001, 1, 1) # Backtest start date self.SetCash(10000) # Starting portfolio balance ## Subscrbe to the data feed for this ticker. ## We're subscribing to the Daily resolution, ## so each 'bar' (candlesrtick) represents one day. self.Equity = self.AddEquity(self.ticker, Resolution.Minute) ## Register our technical indicators w/the ticker so they are updated automatically self.MA_66 = self.SMA(self.ticker, 66, Resolution.Daily) # track moving average of past 66 days self.LOW_3 = self.MIN(self.ticker, 3, Resolution.Daily) # track min price of past 3 days self.HIGH_19 = self.MAX(self.ticker, 19, Resolution.Daily) # track max price of past 19 days # A handler that's called every time there is a new bar # (ie candlestick) of data. The 'dataSlice' holds all the data. # ============================================================== def OnData(self, dataSlice): ## Make sure we have data for this ticker before we check for our entry conditions if( dataSlice.ContainsKey(self.ticker)) and (dataSlice[self.ticker] is not None ): ## The price that the last bar closed at closePrice = dataSlice[self.ticker].Close ## If we're not hodling any positions, check for a signal if not self.Portfolio.Invested: ## If closing price > 66 day Moving average && is the lowest in past 3 days, take a position. if(closePrice > self.MA_66.Current.Value) and (closePrice < self.LOW_3.Current.Value): self.SetHoldings(self.ticker, 1) # allocate 100% of portfolio to ticker else: # If we're holding, and the day's close price is the highest of the last 19 days, then exit. if(closePrice > self.HIGH_19.Current.Value): self.Liquidate()