Overall Statistics
Total Trades
60
Average Win
0.21%
Average Loss
-0.17%
Compounding Annual Return
8.762%
Drawdown
1.400%
Expectancy
0.344
Net Profit
1.763%
Sharpe Ratio
2.313
Probabilistic Sharpe Ratio
77.778%
Loss Rate
40%
Win Rate
60%
Profit-Loss Ratio
1.24
Alpha
0.056
Beta
0.053
Annual Standard Deviation
0.026
Annual Variance
0.001
Information Ratio
-0.232
Tracking Error
0.137
Treynor Ratio
1.153
Total Fees
$60.00
Estimated Strategy Capacity
$830000.00
Lowest Capacity Asset
TAN V44Y4YYPI2XX
Portfolio Turnover
19.57%
 #region imports
from AlgorithmImports import *
#endregion
class NadionResistanceShield(QCAlgorithm):



#class DataConsolidationAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2023, 1, 1)  # Set Start Date
        #self.SetEndDate(2023, 1, 1)
        self.SetCash(50000)  # Set Strategy Cash
        self.tickers =  ["SPY", "NUE", "MSFT", "AMZN", "GOOG", "NVDA", "TAN"]

        self.symbolDataBySymbol = {}
        self.trade = True
        self.vwaps = {}
        self.stds = {}
        

        # Before the open
   
        
        
        for symbol in self.tickers:
            self.AddEquity(symbol, Resolution.Minute)
            self.Debug(f"Registering {symbol}")
            
            '''For the below 3 EMA's, you can convert them to 4H bars using the colidator method'''
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily, Field.Close)
            
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            #sma7 = self.SMA(symbol, 7, Resolution.Minute, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema7 = self.EMA(symbol, 7, Resolution.Hour, Field.Close)
            #ema7 = self.EMA(symbol, 7, Resolution.Minute, Field.Close)
            ema9 = self.EMA(symbol, 9, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr_up = self.WILR(symbol, 10, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)

            self.vwaps[symbol] = self.VWAP(symbol, 14, Resolution.Daily)
            self.stds[symbol] = self.STD(symbol, 14, Resolution.Daily)
        

            
            '''Consolidator method'''
            smaConsolidate = ExponentialMovingAverage(20, MovingAverageType.Simple)
            # create the 4 hour data consolidator
            fourHourConsolidator = TradeBarConsolidator(timedelta(hours=4))
            self.SubscriptionManager.AddConsolidator(symbol, fourHourConsolidator)
            # register the 4 hour consolidated bar data to automatically update the indicator
            self.RegisterIndicator(symbol, smaConsolidate, fourHourConsolidator)
            

            
            symbolData = SymbolData(symbol, ema10, sma200, sma20, sma50, sma7, ema20, ema7, ema9, rsi, wilr, smaConsolidate)
            self.symbolDataBySymbol[symbol] = symbolData
        self.SetWarmUp(30, Resolution.Daily)

        self.spy = self.AddEquity("SPY", Resolution.Daily)
                 
        self.Schedule.On(self.DateRules.EveryDay("SPY"),
                 self.TimeRules.AfterMarketOpen("SPY"),
                 self.tradeStart)
                 
        self.Schedule.On(self.DateRules.EveryDay("SPY"),
                 self.TimeRules.BeforeMarketClose("SPY"),
                 self.tradeEnd)

        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(10, 0), self.Trade)
        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.AfterMarketOpen(10, 0), self.SellSignals)
        #self.Schedule.On(self.DateRules.EveryDay("SPY"),self.TimeRules.Every(timedelta(minutes=10)),self.sellSignals)
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(12, 0), self.Exit)

        #self.AddRiskManagement(TrailingStopRiskManagementModel(0.03))
        self.SetWarmUp(timedelta(days=50))
        
    def tradeStart(self):
        self.trade = True

    def tradeEnd(self):
        self.trade = False
        
    def Trade(self):
        if self.trade == False:
            return
        for symbol in self.tickers:
            # Get the daily data for the symbol
            history = self.History([symbol], 1, Resolution.Daily)
            if not history.empty:
                daily_data = history.loc[symbol]

                # Get the open and close prices for the previous day
                previous_open = daily_data["open"].iloc[0]
                previous_close = daily_data["close"].iloc[0]

                # Get the current price
                current_price = self.Securities[symbol].Price

                # Calculate the price gap and percentage change
                price_gap = current_price - previous_close
                percentage_change = price_gap / previous_close

                # Check if the price has gapped up by more than 1%
                if percentage_change > 0.02:
                    self.Log("{} gap up detected: {}%".format(symbol, percentage_change * 100))

                     # Enter a long position
                    self.SetHoldings(symbol, .25)
    
    def buySignals(self):
        if self.trade == False:
            return
        
        for symbol, symbolData in self.symbolDataBySymbol.items():
            if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.ema7.Current.Value) and (symbolData.sma20.Current.Value > symbolData.sma50.Current.Value):
                self.SetHoldings(symbol, .1, False, "Buy Signal")
     
                    
            
#    def sellSignals(self):
#        if self.trade == False:
#            return
#        for symbol, symbolData in self.symbolDataBySymbol.items():
#            if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close < symbolData.ema7.Current.Value):
#                self.Liquidate(symbol, "Sell Signal")


    def Exit(self):
        for symbol in self.tickers:
            # Exit the position
            self.Liquidate(symbol)

    def OnData(self, data):
        if self.IsWarmingUp:# or not all(std.IsReady for std in self.stds.values()):
            return

        for symbol in self.tickers:
            price = self.Securities[symbol].Price
            vwap = self.vwaps[symbol].Current.Value
            std = self.stds[symbol].Current.Value
            ub1 = vwap + std 
            ub2 = vwap + 2*std
            lb1 = vwap - std 
            lb2 = vwap - 2*std 

            self.Plot(symbol, 'price', price)
            self.Plot(symbol, 'vwap', vwap)
            self.Plot(symbol, 'ub2', ub2)
            self.Plot(symbol, 'ub1', ub1)
            self.Plot(symbol, 'lb1', lb1)
            self.Plot(symbol, 'lb2', lb2)

class SymbolData:
    def __init__(self, symbol, ema10, sma200, sma20, sma50, sma7, ema20, ema7, ema9, rsi, wilr, smaConsolidate):
        self.Symbol = symbol
        self.ema10 = ema10
        self.sma200 = sma200
        self.sma20 = sma20
        self.sma50 = sma50
        self.sma7 = sma7
        self.ema20 = ema20
        self.ema7 = ema7
        self.ema9 = ema9
        self.rsi = rsi
        self.wilr = wilr
        #self.emaConsolidate = emaConsolidate
        self.smaConsolidate = smaConsolidate





 #region imports
from AlgorithmImports import *
#endregion
class NadionResistanceShield(QCAlgorithm):



#class DataConsolidationAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2023, 1, 1)  # Set Start Date
        #self.SetEndDate(2023, 1, 1)
        self.SetCash(50000)  # Set Strategy Cash
        self.tickers =  ["SPY", "NUE", "MSFT", "AMZN", "GOOG", "NVDA", "TAN"]

        self.symbolDataBySymbol = {}
        self.trade = True
        self.vwaps = {}
        self.stds = {}
        

        # Before the open
   
        
        
        for symbol in self.tickers:
            self.AddEquity(symbol, Resolution.Minute)
            self.Debug(f"Registering {symbol}")
            
            '''For the below 3 EMA's, you can convert them to 4H bars using the colidator method'''
            macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily, Field.Close)
            
            ema10 = self.EMA(symbol, 10, Resolution.Hour, Field.Close)
            sma200 = self.SMA(symbol, 200, Resolution.Daily, Field.Close)
            sma20 = self.SMA(symbol, 20, Resolution.Daily, Field.Close)
            sma50 = self.SMA(symbol, 50, Resolution.Daily, Field.Close)
            sma7 = self.SMA(symbol, 7, Resolution.Hour, Field.Close)
            #sma7 = self.SMA(symbol, 7, Resolution.Minute, Field.Close)
            ema20 = self.EMA(symbol, 20, Resolution.Hour, Field.Close)
            ema7 = self.EMA(symbol, 7, Resolution.Hour, Field.Close)
            #ema7 = self.EMA(symbol, 7, Resolution.Minute, Field.Close)
            ema9 = self.EMA(symbol, 9, Resolution.Hour, Field.Close)
            rsi = self.RSI(symbol, 14, Resolution.Daily)
            wilr_up = self.WILR(symbol, 10, Resolution.Daily)
            wilr = self.WILR(symbol, 14, Resolution.Daily)

            self.vwaps[symbol] = self.VWAP(symbol, 14, Resolution.Daily)
            self.stds[symbol] = self.STD(symbol, 14, Resolution.Daily)

        

            
            '''Consolidator method'''
            smaConsolidate = ExponentialMovingAverage(20, MovingAverageType.Simple)
            # create the 4 hour data consolidator
            fourHourConsolidator = TradeBarConsolidator(timedelta(hours=4))
            self.SubscriptionManager.AddConsolidator(symbol, fourHourConsolidator)
            # register the 4 hour consolidated bar data to automatically update the indicator
            self.RegisterIndicator(symbol, smaConsolidate, fourHourConsolidator)
            

            
            symbolData = SymbolData(symbol, ema10, sma200, sma20, sma50, sma7, ema20, ema7, ema9, rsi, wilr, smaConsolidate)
            self.symbolDataBySymbol[symbol] = symbolData
        self.SetWarmUp(30, Resolution.Daily)

        self.spy = self.AddEquity("SPY", Resolution.Daily)
                 
        self.Schedule.On(self.DateRules.EveryDay("SPY"),
                 self.TimeRules.AfterMarketOpen("SPY"),
                 self.tradeStart)
                 
        self.Schedule.On(self.DateRules.EveryDay("SPY"),
                 self.TimeRules.BeforeMarketClose("SPY"),
                 self.tradeEnd)

        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(10, 0), self.Trade)
        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.AfterMarketOpen(10, 0), self.SellSignals)
        self.Schedule.On(self.DateRules.EveryDay("SPY"),self.TimeRules.Every(timedelta(minutes=10)),self.sellSignals)
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(12, 0), self.Exit)

        #self.AddRiskManagement(TrailingStopRiskManagementModel(0.03))
        self.SetWarmUp(timedelta(days=50))
        
    def tradeStart(self):
        self.trade = True

    def tradeEnd(self):
        self.trade = False
        
    def Trade(self):
        if self.trade == False:
            return
        for symbol in self.tickers:
            # Get the daily data for the symbol
            history = self.History([symbol], 1, Resolution.Daily)
            if not history.empty:
                daily_data = history.loc[symbol]

                # Get the open and close prices for the previous day
                previous_open = daily_data["open"].iloc[0]
                previous_close = daily_data["close"].iloc[0]

                # Get the current price
                current_price = self.Securities[symbol].Price

                # Calculate the price gap and percentage change
                price_gap = current_price - previous_close
                percentage_change = price_gap / previous_close

                # Check if the price has gapped up by more than 1%
                if percentage_change > 0.02:
                    self.Log("{} gap up detected: {}%".format(symbol, percentage_change * 100))

                     # Enter a long position
                    self.SetHoldings(symbol, .25)
    
    def buySignals(self):
        if self.trade == False:
            return
        
        for symbol, symbolData in self.symbolDataBySymbol.items():
            if not self.Portfolio[symbol].Invested and (self.Securities[symbol].Close > symbolData.ema7.Current.Value) and (symbolData.sma20.Current.Value > symbolData.sma50.Current.Value):
                self.SetHoldings(symbol, .1, False, "Buy Signal")
     
                    
            
#    def sellSignals(self):
#        if self.trade == False:
#            return
#        for symbol, symbolData in self.symbolDataBySymbol.items():
#            if self.Portfolio[symbol].Invested and (self.Securities[symbol].Close < symbolData.ema7.Current.Value):
#                self.Liquidate(symbol, "Sell Signal")

    def sellSignals(self):
        if self.trade == False:
            return
        invested_symbols = [x.Key for x in self.Portfolio if x.Value.Invested]
        for symbol in invested_symbols:
            if self.vwaps[symbol].Current.Value < self.Securities[symbol].Price and self.Securities[symbol].Price > (2 * self.stds[symbol].Current.Value):
                self.Log("{} sell signal detected.".format(symbol))
                self.Liquidate(symbol)
            else:
                self.Debug("{} has a VWAP of {} and current price is {}.".format(symbol, self.vwaps[symbol].Current.Value, self.Securities[symbol].Price))


    def Exit(self):
        for symbol in self.tickers:
            # Exit the position
            self.Liquidate(symbol)

    def OnData(self, data):
        if self.IsWarmingUp or not all(std.IsReady for std in self.stds.values()):
            return

        for symbol in self.tickers:
            price = self.Securities[symbol].Price
            vwap = self.vwaps[symbol].Current.Value
            std = self.stds[symbol].Current.Value
            ub1 = vwap + std 
            ub2 = vwap + 2*std
            lb1 = vwap - std 
            lb2 = vwap - 2*std 

            self.Plot(symbol, 'price', price)
            self.Plot(symbol, 'vwap', vwap)
            self.Plot(symbol, 'ub2', ub2)
            self.Plot(symbol, 'ub1', ub1)
            self.Plot(symbol, 'lb1', lb1)
            self.Plot(symbol, 'lb2', lb2)


class SymbolData:
    def __init__(self, symbol, ema10, sma200, sma20, sma50, sma7, ema20, ema7, ema9, rsi, wilr, smaConsolidate):
        self.Symbol = symbol
        self.ema10 = ema10
        self.sma200 = sma200
        self.sma20 = sma20
        self.sma50 = sma50
        self.sma7 = sma7
        self.ema20 = ema20
        self.ema7 = ema7
        self.ema9 = ema9
        self.rsi = rsi
        self.wilr = wilr
        #self.emaConsolidate = emaConsolidate
        self.smaConsolidate = smaConsolidate