Overall Statistics
Total Trades
130
Average Win
1.43%
Average Loss
-0.61%
Compounding Annual Return
21.427%
Drawdown
13.400%
Expectancy
1.409
Net Profit
79.132%
Sharpe Ratio
1.505
Probabilistic Sharpe Ratio
75.778%
Loss Rate
28%
Win Rate
72%
Profit-Loss Ratio
2.35
Alpha
0.187
Beta
-0.041
Annual Standard Deviation
0.12
Annual Variance
0.014
Information Ratio
0.177
Tracking Error
0.246
Treynor Ratio
-4.399
Total Fees
$320.25
Estimated Strategy Capacity
$71000000.00
Lowest Capacity Asset
BND TRO5ZARLX6JP
class CrawlingYellowGreenJackal(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 1)
        self.SetEndDate(2021, 1, 1)
        self.SetCash(100000)
        self.spy = self.AddEquity("QQQ", Resolution.Daily).Symbol
        self.bnd = self.AddEquity("BND", Resolution.Daily).Symbol
        
        length = self.GetParameter("sma_length")
        length = 30 if length is None else int(length)
        self.sma = self.SMA(self.spy, length, Resolution.Daily)

        self.rebalanceTime = datetime.min
        self.uptrend = True

    def OnData(self, data):
        if not self.sma.IsReady:
            return
        if data.Bars.ContainsKey("QQQ") and data.Bars.ContainsKey("BND"):
            if data.Bars[self.spy].Price >= self.sma.Current.Value:
                # Either rebalance or rice has crossed above SMA
                if self.Time >= self.rebalanceTime or not self.uptrend:
                    self.SetHoldings(self.spy, 0.8)
                    self.SetHoldings(self.bnd, 0.2)
                    self.uptrend = True
                    self.rebalanceTime = self.Time + timedelta(30)
            # Either rebalance or price has crossed below SMA
            elif self.Time >= self.rebalanceTime or self.uptrend:
                self.SetHoldings(self.spy, 0.2)
                self.SetHoldings(self.bnd, 0.8)
                self.uptrend = False
                self.rebalanceTime = self.Time + timedelta(30)
            
            self.Plot("Benchmark", "SMA", self.sma.Current.Value)