Overall Statistics
Total Trades
236
Average Win
1.16%
Average Loss
-2.95%
Compounding Annual Return
9.492%
Drawdown
20.200%
Expectancy
0.240
Net Profit
126.259%
Sharpe Ratio
0.653
Probabilistic Sharpe Ratio
9.433%
Loss Rate
11%
Win Rate
89%
Profit-Loss Ratio
0.39
Alpha
0.004
Beta
0.769
Annual Standard Deviation
0.109
Annual Variance
0.012
Information Ratio
-0.275
Tracking Error
0.059
Treynor Ratio
0.092
Total Fees
$236.00
Estimated Strategy Capacity
$63000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
#region imports
from AlgorithmImports import *
#endregion

class SimpleSpyClimber(QCAlgorithm):


    # Entry Point for the algo.     
    # ===========================
    def Initialize(self):
        ## Initialize algo params
        self.ticker = "SPY"             # Ticker symbol to trade
        self.SetStartDate(2010, 1, 1)   # Backtest start date
        self.SetEndDate(2019, 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()