Overall Statistics
Total Trades
270
Average Win
0.03%
Average Loss
-0.05%
Compounding Annual Return
-9.180%
Drawdown
1.400%
Expectancy
-0.128
Net Profit
-0.841%
Sharpe Ratio
-2.436
Probabilistic Sharpe Ratio
13.459%
Loss Rate
49%
Win Rate
51%
Profit-Loss Ratio
0.71
Alpha
-0.147
Beta
0.119
Annual Standard Deviation
0.027
Annual Variance
0.001
Information Ratio
-8.853
Tracking Error
0.084
Treynor Ratio
-0.551
Total Fees
$561.46
Estimated Strategy Capacity
$48000000.00
Lowest Capacity Asset
EEM SNQLASP67O85
class DynamicOptimizedContainmentField(QCAlgorithm):
    
    def Initialize(self):
        
        self.stopMarketTicket = None
        self.stopMarketOrderFillTime = datetime.min
        self.highestPrice = 0
        self.SetStartDate(2021, 3, 26)  # Set Start Date\
        self.SetEndDate(2021, 4, 26)
        self.SetCash(1000000)  # Set Strategy Cash
        self.UniverseSettings.Resolution = Resolution.Minute
        self.AddUniverse(self.SelectCoarse)
        self.UniverseSettings.Leverage = 2
        self.AddEquity("SPY")
        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(13,30), self.ClosePositions)
        self.symbols = {}
        self.AddRiskManagement(TrailingStopRiskManagementModel(0.05))
        self.stopPrice = self.GetParameter("stop")
    
    def SelectCoarse(self, coarse):
        sortedCoarse = sorted(coarse, key=lambda c:c.DollarVolume, reverse=True)
        return [c.Symbol for c in sortedCoarse][:10]
    
    def OnSecuritiesChanged(self, changes):
        
        for security in changes.AddedSecurities:
            symbol = security.Symbol
            if symbol not in self.symbols:
                self.symbols[symbol] = SymbolData(self, symbol)
                
                
        for security in changes.RemovedSecurities:
            symbol = security.Symbol
            if symbol in self.symbols:
                symbolData = self.symbols.pop(symbol, None)
                self.SubscriptionManager.RemoveConsolidator(symbol, symbolData.consolidator)
                
    def OnData(self, data):
        
        for symbol, symbol_data in self.symbols.items():
            
            if symbol_data.openingBar is None: continue
        
            if not data.Bars.ContainsKey(symbol):
                continue
            
            if data.Bars[symbol].Close > symbol_data.openingBar.High and not self.Securities[symbol].Invested:
                quantity = self.CalculateOrderQuantity(symbol, 0.08) # orders 8% of portfolio
                self.MarketOrder(symbol, quantity) 
               
                continue
                
            
    
    def OnOrderEvent(self, orderEvent):
        if orderEvent.Status != OrderStatus.Filled:
            self.symbols[orderEvent.Symbol].openingBar = None
            return
       
                       
    def ClosePositions(self):
        for symbolData in self.symbols.values():
            symbolData.openingBar = None
        self.Liquidate() # liquidate entire portfolio
    
    
        
class SymbolData:
    
    def __init__(self, algorithm, symbol):
        
        self.algorithm = algorithm
        self.symbol = symbol
        self.consolidator = TradeBarConsolidator(timedelta(minutes = 30))
        self.consolidator.DataConsolidated += self.OnDataConsolidated
        self.openingBar = None

        algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
        
    def OnDataConsolidated(self, sender, bar):
        
        if bar.Time.hour == 10 and bar.Time.minute == 0:
            self.openingBar = bar