Overall Statistics
Total Trades
125
Average Win
0.05%
Average Loss
-0.04%
Compounding Annual Return
-1.365%
Drawdown
1.500%
Expectancy
-0.636
Net Profit
-1.363%
Sharpe Ratio
-2.892
Probabilistic Sharpe Ratio
0.000%
Loss Rate
84%
Win Rate
16%
Profit-Loss Ratio
1.26
Alpha
-0.009
Beta
0.01
Annual Standard Deviation
0.003
Annual Variance
0
Information Ratio
0.179
Tracking Error
0.141
Treynor Ratio
-0.995
Total Fees
$125.00
Estimated Strategy Capacity
$14000000.00
Lowest Capacity Asset
IBM 2T
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("IBM", Resolution.Minute)
        
        dailyConsolidator = TradeBarConsolidator(TimeSpan.FromDays(1))
        dailyConsolidator.DataConsolidated += self.DailyConsolidator
        self.SubscriptionManager.AddConsolidator("IBM", dailyConsolidator)
                        
        self.entrySignalMessage = ""
        self.entryPrice = None
        self.highestPrice = None
        self.timeInTrade = None
        self.limitMarketTicket = None
        self.openPrice = None
        
        self.stopLoss = 0.99
        self.trailingStopLoss = 0.984
        self.targetStop = 1.08
        
        # self.obv = OnBalanceVolume()
        # self.RegisterIndicator("IBM", 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(8)
    
    def DailyConsolidator(self, sender, bar):
        self.closeWindow.Add(self.Securities["IBM"].Close)
        self.highWindow.Add(self.Securities["IBM"].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["IBM"].Open)
        
        if self.Time.hour <= 9 and self.Time.minute <= 32: return
        
        if self.EntrySignalFired():
            if not self.Portfolio.Invested:
                quantity = self.CalculateOrderQuantity("IBM", 0.025)
                self.marketTicket = self.MarketOrder("IBM", quantity, tag=self.entrySignalMessage)
                
        if self.Portfolio.Invested and ((self.entryPrice and self.highestPrice) != None):
            if not self.Transactions.GetOpenOrders("IBM"):
                self.Debug(f"order price = {self.entryPrice}")
                self.stopMarketTicket = self.StopMarketOrder("IBM", \
                                        -self.Portfolio["IBM"].Quantity, \
                                        (self.stopLoss * self.entryPrice))
                self.limitMarketTicket = self.LimitOrder("IBM", \
                                        -self.Portfolio["IBM"].Quantity, \
                                        (self.targetStop * self.entryPrice))
                                        
            # if self.Securities["IBM"].Close > self.highestPrice and ((self.Securities["IBM"].Close*self.trailingStopLoss) < (self.entryPrice*self.stopLoss)):
            #     self.highestPrice = self.Securities["IBM"].Close
            #     updateFields = UpdateOrderFields()
            #     updateFields.StopPrice = self.Securities["IBM"].Close * self.trailingStopLoss
                
        if not self.Portfolio["IBM"].Invested:
            if not self.limitMarketTicket is None:
                self.limitMarketTicket.Cancel()
            self.entryPrice = None
            self.highestPrice = None
            
            
        if self.ExitSignalFired():
            if self.Portfolio["IBM"].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): 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["IBM"].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()