Overall Statistics
Total Trades
63
Average Win
3.04%
Average Loss
-1.06%
Compounding Annual Return
61.241%
Drawdown
7.400%
Expectancy
0.249
Net Profit
8.117%
Sharpe Ratio
1.948
Probabilistic Sharpe Ratio
61.628%
Loss Rate
68%
Win Rate
32%
Profit-Loss Ratio
2.87
Alpha
0.429
Beta
0.172
Annual Standard Deviation
0.22
Annual Variance
0.049
Information Ratio
1.524
Tracking Error
0.279
Treynor Ratio
2.491
Total Fees
$97.67
Estimated Strategy Capacity
$30000000.00
Lowest Capacity Asset
QQQ RIWIV7K5Z9LX
# Fractal

# -------------------------------------------------------
STOCK = 'QQQ'; PERIOD = 3; X = 30; SL = -0.01; TP = 0.03;
# -------------------------------------------------------

class BillWilliamsFractal(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2022, 3, 6)
        self.SetEndDate(2022, 5, 4) 
        self.stock = self.AddEquity(STOCK, Resolution.Minute).Symbol
        self.rollingWindow = RollingWindow[TradeBar](PERIOD)
        self.Consolidate(self.stock, Resolution.Daily, self.CustomBarHandler)
        self.signal = 0
        self.wait = X
        self.Schedule.On(self.DateRules.EveryDay(self.stock), self.TimeRules.Every(TimeSpan.FromMinutes(1)), 
            self.TradeOut)
            
            
    def CustomBarHandler(self, bar):
        self.rollingWindow.Add(bar)        
                

    def OnData(self, data):
        if not self.rollingWindow.IsReady: return
        if not (self.IsMarketOpen(self.stock)): return
        self.wait += 1
        if not self.wait > X: return
    
        H = np.flipud(np.array([self.rollingWindow[i].High for i in range(PERIOD)]))
        L = np.flipud(np.array([self.rollingWindow[i].Low for i in range(PERIOD)]))
        
        dnFractal = (H[-1] < H[-2] < H[-3])
        upFractal = (L[-1] > L[-2] > L[-3])

        self.signal = -1 if (dnFractal and not upFractal) else 1 
        
        if not self.Portfolio[self.stock].Invested:
            self.SetHoldings(self.stock, self.signal)  
            

    def TradeOut(self):
        if self.Portfolio[self.stock].Invested:
            pnl = self.Securities[self.stock].Holdings.UnrealizedProfitPercent

            if pnl < SL:
                self.Liquidate(self.stock, "Stop Loss")
                self.wait = 0 
                
            elif pnl > TP:
                self.Liquidate(self.stock, "Take Profit")
                self.wait = 0 
        
        
    def OnEndOfDay(self, symbol): 
        self.Plot("Indicator", "signal", self.signal)
        self.Plot("Indicator", "zero", 0)