Overall Statistics
Total Trades
3
Average Win
0%
Average Loss
-0.68%
Compounding Annual Return
-6.451%
Drawdown
1.300%
Expectancy
-1
Net Profit
-0.541%
Sharpe Ratio
-1.262
Probabilistic Sharpe Ratio
21.002%
Loss Rate
100%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-0.114
Beta
0.1
Annual Standard Deviation
0.036
Annual Variance
0.001
Information Ratio
-5.535
Tracking Error
0.132
Treynor Ratio
-0.456
Total Fees
$3.00
Estimated Strategy Capacity
$30000000.00
Lowest Capacity Asset
MSFT R735QTJ8XC9X
# notes
# I think rolling window is affecting the self.high function? this algo only carrys 2 bars of data so that is probably the reason.

# for charts. the charts lag to it might not be beneficial to actually use this information.
from System.Drawing import Color

class ParticleTachyonCompensator(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 12, 1)
        self.SetEndDate(2021, 12, 30)
        self.SetCash(100000)  # Set Strategy Cash
        
        # add stock with 1min bars
        equity = self.AddEquity("MSFT", Resolution.Minute)
        self.equity = equity.Symbol
        
        # rolling window for 5min bars (we only want to trade if the 5min bar closes above the breakout)
        self.rollingWindow = RollingWindow[TradeBar](2)
        
        # which high do we want to use?
        self.high = self.MAX(self.equity, 5 , Resolution.Daily, Field.High)
        
        # create consolidator
        self.Consolidate(self.equity, timedelta(minutes=5), self.FiveMinuteBarHandler)
    
    
        # order tickets
        self.entryTicket = None
        self.stoplossTicket = None
        self.profit1Ticket = None
        self.profit2Ticket = None
        
        #captital risk
        self.riskCaptial = self.Portfolio.TotalPortfolioValue * 0.05
        
        # charts
        #stockPlot = Chart("Trade Plot")
        #stockPlot.AddSeries(Series("Buy", SeriesType.Scatter, "$", Color.Green, ScatterMarkerSymbol.Triangle))
        #stockPlot.AddSeries(Series("Sell 1", SeriesType.Scatter, "$", Color.Green, ScatterMarkerSymbol.TriangleDown))
        #stockPlot.AddSeries(Series("Sell 2", SeriesType.Scatter, "$", Color.Green, ScatterMarkerSymbol.TriangleDown))
        #stockPlot.AddSeries(Series("Stop", SeriesType.Scatter, "$", Color.Red, ScatterMarkerSymbol.TriangleDown))
        #stockPlot.AddSeries(Series("Price", SeriesType.Line, "$", Color.White))
        #self.AddChart(stockPlot)
    
        
    def OnData(self, data):
        
        # see if the high is ready
        if not self.high.IsReady:
            return
        
        # see if rolling window (5 min bar) is complete
        if not self.rollingWindow.IsReady:
            return
        
        # we want to start trading after first bar is complete
        if not (self.Time.hour == 9 and self.Time.minute == 36):
            return
        
        # chart for current price of the stock
        #self.Plot('Trade Plot', 'Price', data.Bars["MSFT"].Close)
        
        # stop/limit parameters (to be optimized)
        sp = int(self.GetParameter("stop_percent"))
        pp1 = int(self.GetParameter("profit_percent1"))
        pp2 = int(self.GetParameter("profit_percent2"))
    
        if self.entryTicket == None:
            
            # next 5min candle closes above the breakout area
            if self.rollingWindow[0].Close >= self.high.Current.Value:
                
                # order entry
                self.entryTicket = self.MarketOrder("MSFT", 100)
                
                # Enter stop loss order
                self.stoplossTicket = self.StopMarketOrder("MSFT", -100, data["MSFT"].Close * (sp / 1000))
           
                # Enter limit order 1
                self.profit1Ticket = self.LimitOrder("MSFT", -50, data["MSFT"].Close * (pp1 / 1000))
          
                # Enter limit order 2
                self.profit2Ticket = self.LimitOrder("MSFT", -50, data["MSFT"].Close * (pp2 / 1000))
            
            # position sizing
            #self.quantity = int(self.riskCaptial / self.stopBuyPrice)
            
            
            
            
    def OnOrderEvent(self, orderevent):
       
        if orderevent.Status != OrderStatus.Filled:
            return
        
        # sales entry ticket tells us if we currently have a position.
        # references orders below to verfiy
        if self.entryTicket != None and self.entryTicket.OrderId == orderevent.OrderId:
            
            self.entryFillPrice = self.entryTicket.Get(AverageFillPrice)
        
        # tells us if the first profit order was triggered
        if self.profit1Ticket != None and self.profit1Ticket.OrderId == orderevent.OrderId:
            
            # plots first limit sell price
            #self.Plot('Trade Plot', 'Sell 1', orderevent.FillPrice)
            # updates stop loss quantity
            self.stoplossTicket.UpdateQuantity(-50)
            
            
        # tells us if the stop order was sent
        if self.stoplossTicket != None and self.stoplossTicket.OrderId == orderevent.OrderId:
            
            self.Log(f"{self.Time}")
            # plots stop loss fill price
            #self.Plot('Trade Plot', 'Stop', orderevent.FillPrice)
            # cancels limit profit orders
            self.profit1Ticket.Cancel()
            self.profit2Ticket.Cancel()
            # only one entry ticket, needs to be adjusted for trding multiple stocks
            self.entryTicket = None
        
        # tells us if second profit order was triggered
        if self.profit2Ticket != None and self.profit2Ticket.OrderId == orderevent.OrderId:
            
            # plots stop loss fill price
            #self.Plot('Trade Plot', 'Sell 2', orderevent.FillPrice)
            # cancels stop loss order (no more stocks left)
            self.stoplossTicket.Cancel()
            # only one entry ticket, needs to be adjusted for trding multiple stocks
            self.entryTicket = None
    
    # converting 1min to 5min bars
    def FiveMinuteBarHandler(self, bar):
        self.rollingWindow.Add(bar)