I have this MACD Crossover strategy I've adapted so that, after each entry position, a stop loss is created and the price of which is subsequently updated so it acts as a trailing stop loss. I am having difficulty getting it to initialize and would appreciate any guidance as to what I may be doing incorrectly (error below). Also, how can I set this so that it will only run once every hour? Every x number of minutes? Thanks in advance!

  1. from AlgorithmImports import *
  2. class MACDTrendAlgorithm(QCAlgorithm):
  3. # establish project objects
  4. stopMarketTicket = None
  5. stopMarketOrderFillTime = datetime.min
  6. stopPrice = 0
  7. def Initialize(self):
  8. # initialize our algorithm with the basics
  9. self.SetStartDate(2018, 1, 1)
  10. self.SetEndDate(2021, 10, 22)
  11. self.SetCash(25000)
  12. tqqq = self.AddEquity("TQQQ", Resolution.Daily)
  13. tqqq.SetDataNormalizationMode(DataNormalizationMode.Raw)
  14. # define our macd parameters
  15. self.__macd = self.MACD("TQQQ", 6, 35, 6, MovingAverageType.Exponential, Resolution.Daily)
  16. self.__previous = datetime.min
  17. self.PlotIndicator("MACD", True, self.__macd, self.__macd.Signal)
  18. self.PlotIndicator("TQQQ", self.__macd.Fast, self.__macd.Slow)
  19. def OnData(self, data):
  20. # wait for our macd to fully initialize
  21. if not self.__macd.IsReady:
  22. return
  23. # define a small tolerance on our checks to avoid bouncing
  24. tolerance = 0.0025
  25. holdings = self.Portfolio["TQQQ"].Quantity
  26. signalDeltaPercent = (self.__macd.Current.Value - self.__macd.Signal.Current.Value)/self.__macd.Fast.Current.Value
  27. if holdings == 0:
  28. if signalDeltaPercent > tolerance:
  29. self.SetHoldings("TQQQ", 1.0)
  30. self.stopMarketTicket = self.StopMarketOrder("TQQQ", -self.Portfolio["TQQQ"].Quantity, 0.9 * self.Portfolio["TQQQ"].Price)
  31. if signalDeltaPercent < -tolerance:
  32. self.SetHoldings("TQQQ", -1.0)
  33. self.stopMarketTicket = self.StopMarketOrder("TQQQ", self.Portfolio["TQQQ"].Quantity, 0.9 * self.Portfolio["TQQQ"].Price)
  34. elif holdings != 0:
  35. if holdings < 0 and signalDeltaPercent > tolerance:
  36. self.Liquidate("TQQQ")
  37. self.SetHoldings("TQQQ", 1.0)
  38. self.stopMarketTicket = self.StopMarketOrder("TQQQ", -self.Portfolio["TQQQ"].Quantity, 0.9 * self.Portfolio["TQQQ"].Price)
  39. if holdings > 0 and signalDeltaPercent < -tolerance:
  40. self.Liquidate("TQQQ")
  41. self.SetHoldings("TQQQ", -1.0)
  42. self.stopMarketTicket = self.StopMarketOrder("TQQQ", self.Portfolio["TQQQ"].Quantity, 0.9 * self.Portfolio["TQQQ"].Price)
  43. if holdings >=0 and self.Securities["TQQQ"].Close > self.stopPrice:
  44. self.stopPrice = self.Securities["TQQQ"].Close
  45. updateFields = UpdateOrderFields()
  46. updateFields.StopPrice = self.stopPrice * 0.95
  47. self.stopMarketTicket.Update(updateFields)
  48. elif holdings <=0 and self.Securities["TQQQ"].Close < self.stopPrice:
  49. self.stopPrice = self.Securities["TQQQ"].Close
  50. updateFields = UpdateOrderFields()
  51. updateFields.StopPrice = self.stopPrice * 0.95
  52. self.stopMarketTicket.Update(updateFields)
  53. self.__previous = self.Time
+ Expand

Errors:

42 | 17:29:57:

Runtime Error: InvalidOperationException : Sequence contains no elements
at System.Linq.ThrowHelper.ThrowNoElementsException()
at System.Linq.Enumerable.Last[TSource](IEnumerable`1 source)
at QuantConnect.Orders.OrderTicket.Update(UpdateOrderFields fields) in /LeanCloud/CI.Builder/bin/Debug/src/QuantConnect/Lean/Common/Orders/OrderTicket.cs:line 279 
at OnData
self.stopMarketTicket.Update(updateFields)
===
at Python.Runtime.PyObject.Invoke(PyTuple args in main.py: line 66 (Open Stacktrace)

43 | 17:30:07:

Algorithm Id:(15bdaac636f5d7f605a7df768009cb99) completed in 10.63 seconds at 0k data points per second. Processing total of 328 data points.

44 | 17:30:07:

Backtest Handled Error: Unable to submit order with id -10 that has zero quantity.

 

 

Author

James Hawkins

October 2021