Overall Statistics
Total Trades
1755
Average Win
0.35%
Average Loss
-0.15%
Compounding Annual Return
-6.973%
Drawdown
17.800%
Expectancy
-0.048
Net Profit
-7.004%
Sharpe Ratio
-0.344
Probabilistic Sharpe Ratio
8.900%
Loss Rate
72%
Win Rate
28%
Profit-Loss Ratio
2.38
Alpha
0
Beta
0
Annual Standard Deviation
0.166
Annual Variance
0.027
Information Ratio
-0.344
Tracking Error
0.166
Treynor Ratio
0
Total Fees
$1985.91
class SymbolData:
    #Trading Parameters
    tradewithquantity, longquantity, shortquantity = False, 100, -100 # Trade in terms of number of contracts
    tradewithequity, longequity, shortequity = True, 0.4, -0.4 # Trade in terms of percentage of strategy equity


    #Declare vars
    symbol = None
    TrendList = []
    bsignal = None
    ssignal = None
    sellmarketorder = None
    buymarketorder = None
    liquidationplaced = None
    
    def __init__(self, algorithm, symbol):
        self.symbol = symbol
        self.Fast = algorithm.SMA(symbol, 10, Resolution.Hour)
        self.Slow = algorithm.SMA(symbol, 20, Resolution.Hour)
        self.window = RollingWindow[TradeBar](10) # Max bars needed for pivothigh and pivotlow methods

        

class OptimizedVentralRegulators(QCAlgorithm):

    # Set parameters
    # Backtest Portfolio Parameters
    cash = 100000
    startyyyy, startm, startd = 2020, 1, 5
    endyyyy, endm, endd = 2021, 1, 5
    symbolList = ["AAPL", "GOOG"]
    symbolDict = {}

    def Initialize(self):
        
        # self.SetBenchmark(self.secticker)
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
        self.SetStartDate(self.startyyyy, self.startm, self.startd)   # Set Start Date
        self.SetEndDate(self.endyyyy, self.endm, self.endd)     # Set End Date
        self.SetCash(self.cash)            # Set Strategy Cash
        self.lookback = 30 # Set number of days to look back
        self.Transactions.MarketOrderFillTimeout = timedelta(seconds=30)

        for symbol in self.symbolList:
            self.AddEquity(symbol, Resolution.Hour) # Set security
            self.symbolDict[symbol] = SymbolData(self, symbol) # Pass symboldata object to symbolDict
            self.Securities[symbol].SetDataNormalizationMode(DataNormalizationMode.Raw)
    
    def LongOrder(self, symboldata): 
        if symboldata.tradewithquantity and not symboldata.tradewithequity:
            symboldata.buymarketorder = self.MarketOrder(symboldata.symbol, symboldata.longquantity, False, "Long")
        if symboldata.tradewithequity and not symboldata.tradewithquantity:
            self.SetHoldings(symboldata.symbol, symboldata.longequity, True, "Long Equity Order")

    def ShortOrder(self, symboldata): 
        if symboldata.tradewithquantity and not symboldata.tradewithequity:
            symboldata.sellmarketorder = self.MarketOrder(symboldata.symbol, symboldata.shortquantity, False,"Short")
        if symboldata.tradewithequity and not symboldata.tradewithquantity:
            self.SetHoldings(symboldata.symbol, symboldata.shortequity, True, "Short Equity Order")
        
    

    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
            Arguments:
                data: Slice object keyed by symbol containing the stock data
        '''
        
        for symboldata in self.symbolDict.values(): # looping through symboldata objects
            symbol = symboldata.symbol
            sec = self.Securities[symbol]
            close = sec.Close
            high = sec.High
            low = sec.Low
            if data.Bars.ContainsKey(symbol):
                currentbar = data.Bars[symbol]
                symboldata.window.Add(currentbar)
            if not symboldata.window.IsReady: # Ends onData method if rolling windowsnot ready
                return
            
            # Get fast and slow
            fast = symboldata.Fast.Current.Value
            slow = symboldata.Slow.Current.Value
            
            Trend = 0
            
            # Set Trend values
            if fast > slow:
                Trend = 1
            elif fast < slow:
                Trend = -1
                
            symboldata.TrendList.append(Trend)
            
            # Long and short crirteria
            if len(symboldata.TrendList) > 2:
                if Trend == 1 and symboldata.TrendList[-2] == -1:
                    symboldata.bsignal = True
                    self.Liquidate(symbol, "Liquidated Buy Signal")
                    symboldata.liquidationplaced = True
                if Trend == -1 and symboldata.TrendList[-2] == 1:
                    symboldata.ssignal = True
                    self.Liquidate(symbol, "Liquidated Sell Signal")
                    symboldata.liquidationplaced = True
            
            # Place trades when signals are true
            if symboldata.bsignal:
                self.LongOrder(symboldata)
    
            if symboldata.ssignal:
                self.ShortOrder(symboldata)
            
            self.Debug(f" {self.Time} s:{symbol} T:{Trend} bs:{symboldata.bsignal} ss:{symboldata.ssignal} LP: {symboldata.liquidationplaced}")

            # Recycle signals
            symboldata.bsignal = False
            symboldata.ssignal = False
            symboldata.liquidationplaced = False