Overall Statistics
Total Trades
91
Average Win
0.14%
Average Loss
-0.04%
Compounding Annual Return
0.146%
Drawdown
0.500%
Expectancy
-0.052
Net Profit
0.146%
Sharpe Ratio
0.223
Probabilistic Sharpe Ratio
17.362%
Loss Rate
78%
Win Rate
22%
Profit-Loss Ratio
3.27
Alpha
0.001
Beta
0.01
Annual Standard Deviation
0.005
Annual Variance
0
Information Ratio
0.165
Tracking Error
0.14
Treynor Ratio
0.107
Total Fees
$91.00
Estimated Strategy Capacity
$10000000.00
Lowest Capacity Asset
KSS R735QTJ8XC9X
class MeasuredFluorescentPinkButterfly(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 1)
        self.SetCash(10000)  # Set Strategy Cash
        self.AddEquity("KSS", Resolution.Minute)
        
        dailyConsolidator = TradeBarConsolidator(TimeSpan.FromDays(1))
        dailyConsolidator.DataConsolidated += self.DailyConsolidator
        self.SubscriptionManager.AddConsolidator("KSS", dailyConsolidator)
                        
        self.entrySignalMessage = ""
        self.entryPrice = None
        self.highestPrice = None
        self.timeInTrade = None
        self.limitMarketTicket = None
        
        self.stopLoss = 0.99
        self.trailingStopLoss = 0.984
        #self.targetStop = 1.08
        
        # self.obv = OnBalanceVolume()
        # self.RegisterIndicator("KSS", self.obv, TimeSpan.FromDays(1))
        
        self.closeWindow = RollingWindow[float](3)
        self.openWindow = RollingWindow[float](3)
        self.highWindow = RollingWindow[float](3)
        # self.obvWindow = RollingWindow[float](3)
        
        self.SetWarmup(3)
    
    def DailyConsolidator(self, sender, bar):
        self.closeWindow.Add(self.Securities["KSS"].Close)
        self.highWindow.Add(self.Securities["KSS"].Close)
        # self.obvWindow.Add(self.obv.Current.Value)


    def OnData(self, data):
        if self.Time.hour == 9 and self.Time.minute == 31:
            self.openWindow.Add(self.Securities["KSS"].Open)
        
        if self.Time.hour <= 9 and self.Time.minute <= 32: return
        
        if self.EntrySignalFired():
            if not self.Portfolio.Invested:
                quantity = self.CalculateOrderQuantity("KSS", 0.025)
                self.marketTicket = self.MarketOrder("KSS", quantity, tag=self.entrySignalMessage)
                
        if self.Portfolio.Invested and ((self.entryPrice and self.highestPrice) != None):
            if not self.Transactions.GetOpenOrders("KSS"):
                self.Debug(f"order price = {self.entryPrice}")
                self.stopMarketTicket = self.StopMarketOrder("KSS", \
                                        -self.Portfolio["KSS"].Quantity, \
                                        (self.stopLoss * self.entryPrice))
                # self.limitMarketTicket = self.LimitOrder("KSS", \
                #                         -self.Portfolio["KSS"].Quantity, \
                #                         (self.targetStop * self.entryPrice))
                                        
            if self.Securities["KSS"].Close > self.highestPrice and ((self.Securities["KSS"].Close*self.trailingStopLoss) < (self.entryPrice*self.stopLoss)):
                self.highestPrice = self.Securities["KSS"].Close
                updateFields = UpdateOrderFields()
                updateFields.StopPrice = self.Securities["KSS"].Close * self.trailingStopLoss
                
        if not self.Portfolio["KSS"].Invested:
            # if not self.limitMarketTicket is None:
            #     self.limitMarketTicket.Cancel()
            self.entryPrice = None
            self.highestPrice = None
            
            
        if self.ExitSignalFired():
            if self.Portfolio["KSS"].Invested:
                self.Liquidate()
                self.entryPrice = None
                self.highestPrice = None
                
    def EntrySignalFired(self):
        # if not (self.closeWindow.IsReady and self.openWindow.IsReady and self.highWindow.IsReady and self.obvWindow): return
        if not (self.closeWindow.IsReady and self.openWindow.IsReady and self.highWindow.IsReady): return
    
        # obvList = list(self.obvWindow)
        # obvList.reverse()
        # obvMax = max(obvList[:-1])
        
        if self.highWindow[0] < self.highWindow[1] and \
            self.closeWindow[0] < self.openWindow[1] and \
            self.openWindow[0] < self.highWindow[0] and self.Securities["KSS"].Price > self.highWindow[0]:
                return True
        
        return False
        
    def ExitSignalFired(self):
        if (self.timeInTrade != None) and (self.Time - self.timeInTrade).days >= 8:
            return True
            
    def OnOrderEvent(self, orderEvent):
        order = self.Transactions.GetOrderById(orderEvent.OrderId)
        
        if order.Type == OrderType.Market and order.Status == OrderStatus.Filled:
            self.entryPrice = orderEvent.FillPrice
            self.highestPrice = orderEvent.FillPrice
            self.timeInTrade = self.Time
        
        # if order.Type == OrderType.StopMarket and order.Status == OrderStatus.Filled:
        #     self.limitMarketTicket.Cancel()
            
        if order.Type == OrderType.Limit and order.Status == OrderStatus.Filled:
            self.stopMarketTicket.Cancel()