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
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
import numpy as np

class JumpingSkyBlueHorse(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetEndDate(2020,1,1)
        self.SetCash(10000)  
        self.Settings.FreePortfolioValuePercentage = 0.3
        
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
        
        self.entrySignalMessage = ""
        self.exitSignalMessage = ""
        
        self.AddEquity("IBM", Resolution.Hour)
        
        
        self.SetWarmup(12)
        
        self.obv = OnBalanceVolume()
        self.RegisterIndicator("IBM", self.obv, Resolution.Hour)
        
        self.priceWindow = RollingWindow[float](12)
        self.obvWindow = RollingWindow[float](12)
        #self.momentum = Momentum(self.forex, Resolution.Daily,)
        
        # Price offset for stop order
        self.initialStopRisk = 0.98
        self.trailingStopRisk = 0.96
        self.target = 1.06

    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
        '''
        self.UpdateRollingWindows()
        
        #if not self.IsWarmingUp() and self.IndicatorsAreReady():
        if self.EntrySignalFired():
            if not self.Portfolio.Invested:
                self.SetHoldings("IBM", 0.02, tag=self.entrySignalMessage)
                self.stopMarketTicket = self.StopMarketOrder("IBM", -self.Portfolio["IBM"].Quantity, self.Portfolio["IBM"].AveragePrice*self.initialStopRisk)
                self.entrySignalMessage = ""
                #self.Debug(f"The lot quantity is {lotQuantity}")
                
        if self.Portfolio["IBM"].IsLong:
            # If no order exists, send stop-loss
            if not self.Transactions.GetOpenOrders("IBM"):
                self.stopMarketTicket = self.StopMarketOrder("IBM", -self.Portfolio["IBM"].Quantity, self.Portfolio["IBM"].AveragePrice*self.initialStopRisk)
                self.targetMarketTicket = self.LimitOrder("IBM", -self.Portfolio["IBM"].Quantity, self.Portfolio["IBM"].AveragePrice*self.target)
                
            
            if self.Securities["IBM"].Close > self.Portfolio["IBM"].AveragePrice and self.initialStopRisk*self.Portfolio["IBM"].AveragePrice < self.Securities["IBM"].Price*self.trailingStopRisk:
                updateFields = UpdateOrderFields()
                updateFields.StopPrice = self.Securities["IBM"].Price*self.trailingStopRisk
                if not self.stopMarketTicket != OrderStatus.Invalid:
                    self.stopMarketTicket.Update(updateFields)
                
                self.Debug(f"The stop price is {updateFields.StopPrice}")
                    
        if self.ExitSignalFired():
            if self.Portfolio["IBM"].Invested:
                self.Liquidate()
                self.stopMarketTicket.Cancel()
                self.targetMarketTicket.Cancel()
            
        

    def EntrySignalFired(self):
        # # for i in range(self.priceWindow[1:i-1:1]):
        # #     if (index+1 < len(self.priceWindow) and index-1>=0):
        # #         up = count(self.priceWindow[index] > self.priceWindow[index -1])
        # #         down = count(self.priceWindow[index] < self.priceWindow[index -1])
        
        if not self.priceWindow.IsReady and self.obvWindow.IsReady: return
        obvList = list(self.obvWindow)
        obvList.reverse()
        obvList = obvList[:-1]
        
        self.Debug(obvList[:-1])
        self.Debug(obvList[-2:])
        #obvMax = max(obvList)
        
        
        upCount = 0
        downCount = 0
        closeList = list(self.priceWindow)
        closeList.reverse()
        for index, elem in enumerate(closeList):
            if (index+1 < len(closeList) and index-1>=0):
                prev = closeList[index-1]
                current = closeList[index]
                
                if prev < current:
                    upCount += 1
                if prev > current:
                    downCount += 1
                
            # if upCount > downCount and (self.obvWindow[0] > obvMax):
            #     #self.Debug(upCount)
            #     return True
        
        
        return False
    
    def ExitSignalFired(self):
        # if self.Portfolio["IBM"].Invested:
        #     if self.lowWindow[0] < self.lowWindow[1]:
        #         return True
        pass

    
    def UpdateRollingWindows(self):
        self.priceWindow.Add(self.Securities["IBM"].Close)
        self.obvWindow.Add(self.obv.Current.Value)
    
    def IndicatorsAreReady():
        return self.obv.IsReady
    
    def PlotCharts(self):
        pass