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)