Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
1.96
Tracking Error
0.354
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset

class MuscularFluorescentPinkSardine(QCAlgorithm):

    def Initialize(self):
        self.UniverseSettings.Resolution = Resolution.Minute
        self.SetStartDate(2022, 4, 28)
        self.SetEndDate(2022, 5, 8)
        self.SetWarmUp(timedelta(days = 301))
        
        
        self.SetCash(100000)
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
        self.SetBenchmark("SPY")
        

        self.stopLossPercentLong = .997
        self.takeProfitPercentLong = 1.004
        
        
        self.timeCheck = False
        
        
        

        self.coarse_count = 10
        self.averages = { }

        # this add universe method accepts two parameters:
        # - coarse selection function: accepts an IEnumerable<CoarseFundamental> and returns an IEnumerable<Symbol>
        self.AddUniverse(self.CoarseSelectionFunction)
        
        self.symbolData = {}
        
        
        
        for ticker in self.ActiveSecurities:
            symbol = ticker.Symbol
            self.symbolData[symbol] = SymbolData(self, symbol)
            
        
        
           
        everyday = self.DateRules.EveryDay()
        self.Schedule.On(everyday, self.TimeRules.At(15, 55), self.Liquidate)
        self.Schedule.On(everyday, self.TimeRules.At(15, 30) , self.timeCheckNight)
        self.Schedule.On(everyday, self.TimeRules.At(9, 45), self.timeCheckMorning)
        
       
    def CoarseSelectionFunction(self, coarse):

        # We are going to use a dictionary to refer the object that will keep the moving averages
        for cf in coarse:
            if cf.Symbol not in self.averages:
                self.averages[cf.Symbol] = DataSymbol(cf.Symbol)

            # Updates the SymbolData object with current EOD price
            avg = self.averages[cf.Symbol]
            avg.update(cf.EndTime, cf.AdjustedPrice)

        # Filter the values of the dict: we only want up-trending securities
        values = list(filter(lambda x: x.is_uptrend, self.averages.values()))

        # Sorts the values of the dict: we want those with greater difference between the moving averages
        values.sort(key=lambda x: x.scale, reverse=True)

        for x in values[:self.coarse_count]:
            self.Log('symbol: ' + str(x.symbol.Value) + '  scale: ' + str(x.scale))

        # we need to return only the symbol objects
        return [ x.symbol for x in values[:self.coarse_count] ]

    
    def OnSecuritiesChanged(self, changes):
        
        for ticker in changes.AddedSecurities:
            symbol = ticker.Symbol
            if symbol not in self.symbolData:
                self.symbolData[symbol] = SymbolData(self, symbol)

            
    def timeCheckMorning(self):
        self.timeCheck = True
    
    def timeCheckNight(self):
        self.timeCheck = False
        
        
    
    def OnEndOfDay(self):
        
        for data in self.symbolData.values():
            data.longTrade = True
            data.shortTrade = True
          
        

    def OnData(self, slice):
        if not all([data.IsReady for data in self.symbolData.values()]):
            return
            
        for symbol, data in self.symbolData.items():
            price = self.Securities[symbol].Price
            data.tradeBuffer += 1
            
            
            if price  > (data.sma3high.Current.Value):
                if data.sma5 > data.sma60:
                    if data.longTrade:
                        if data.tradeBuffer > 60:
                            if self.timeCheck:
                                marketorderticket = self.SetHoldings(symbol, 0.05)
                                data.stopmarketorderticket = self.StopMarketOrder(symbol, -self.Portfolio[symbol].Quantity, price * self.stopLossPercentLong)
                                data.limitorderticket = self.LimitOrder(symbol, -self.Portfolio[symbol].Quantity, price * self.takeProfitPercentLong)
                                data.longTrade = False
                                
                            
            
    
    def OnSecuritiesChanged(self, changes):
        
        for ticker in changes.AddedSecurities:
            symbol = ticker.Symbol
            if symbol not in self.symbolData:
                self.symbolData[symbol] = SymbolData(self, symbol)
       
       
        
    def OnOrderEvent(self, orderEvent):
        
        data = self.symbolData.get(orderEvent.Symbol, None)
        if not data or orderEvent.Status != OrderStatus.Filled:
            return
        
        for symbol, data in self.symbolData.items():
            price = self.Securities[symbol].Price    
            
            if orderEvent.Status != OrderStatus.Filled:
                return
            
            
            if data.stopmarketorderticket != None and data.stopmarketorderticket.OrderId == orderEvent.OrderId:
                data.limitorderticket.Cancel()
                data.longTrade = True
                data.tradeBuffer = 0
                
            
            if data.limitorderticket != None and data.limitorderticket.OrderId == orderEvent.OrderId:
                data.stopmarketorderticket.Cancel()
                data.longTrade = True
                data.tradeBuffer = 0
                
            
           
    
        
        
class SymbolData:
    def __init__(self, algorithm, symbol):
        #algorithm.Securities[symbol].SetLeverage(2.0)
        
        
        
        oneDayConsolidator = TradeBarConsolidator(timedelta(minutes = 390))
        self.subscribe = algorithm.SubscriptionManager.AddConsolidator(symbol, oneDayConsolidator)
        
        self.sma3high = SimpleMovingAverage(3)
        self.sma3low = SimpleMovingAverage(3)
        self.Registersma3high = algorithm.RegisterIndicator(symbol, self.sma3high, oneDayConsolidator, Field.High)
        self.Registersma3low = algorithm.RegisterIndicator(symbol, self.sma3low, oneDayConsolidator, Field.Low)
        
        self.sma200day = SimpleMovingAverage(200)
        self.Registersma30day = algorithm.RegisterIndicator(symbol, self.sma200day, oneDayConsolidator)
        
        self.sma5 = algorithm.SMA(symbol, 5, Resolution.Minute, Field.Volume)
        self.sma60 = algorithm.SMA(symbol, 60, Resolution.Minute, Field.Volume)
        
       
        
        self.window10min = RollingWindow[TradeBar](10)
        self.tradeBuffer = 60
        self.longTrade = True
        
        
        self.stopmarketorderticket = None
        self.limitorderticket = None
        
        self.stopmarketorderticketshort = None
        self.limitorderticketshort = None
        
        
        
    @property 
    def IsReady(self):
         return all
         ([window10min.IsReady for window10 in self.window10min.values()])
         
         

    


class DataSymbol(object):
    def __init__(self, unisymbol):
        self.symbol = unisymbol
        self.tolerance = 1.01
        self.fast = ExponentialMovingAverage(3900)
        self.slow = ExponentialMovingAverage(117000)
        self.is_uptrend = False
        self.scale = 0

    def update(self, time, value):
        if self.fast.Update(time, value) and self.slow.Update(time, value):
            fast = self.fast.Current.Value
            slow = self.slow.Current.Value
            self.is_uptrend = fast > slow * self.tolerance

        if self.is_uptrend:
            self.scale = (fast - slow) / ((fast + slow) / 2.0)