Overall Statistics |
Total Trades 21 Average Win 0.01% Average Loss -0.02% Compounding Annual Return -0.255% Drawdown 0.100% Expectancy -0.210 Net Profit -0.042% Sharpe Ratio -1.503 Probabilistic Sharpe Ratio 15.372% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 0.58 Alpha -0.002 Beta 0.001 Annual Standard Deviation 0.002 Annual Variance 0 Information Ratio 1.612 Tracking Error 0.246 Treynor Ratio -2.574 Total Fees $21.00 |
class HorizontalMultidimensionalThrustAssembly(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 11, 1) self.SetEndDate(2019, 1, 1) self.SetCash(50000) self.AddEquity("SPY", Resolution.Minute) # Measures the change in SPY prices between 2 minutes self.spyMomentum = self.MOMP("SPY", 2, Resolution.Minute) # Measures the standard deviation in SPY prices in 24 hours self.spySD = self.STD("SPY", 10080, Resolution.Minute) # Measures the mean SPY momentum in 24 hours self.spyMomentumMean = SimpleMovingAverage(10080) # Performs the operation to update the SPY momentum mean indicator by piping spyMomentum into it self.spyMomentum.Updated += self.OnSpyMomentum # For tracking stats self.longstopLossTicket = None self.shortstopLossTicket = None self.shorttakeProfitTicket = None self.longtakeProfitTicket = None self.noOfTrades = 0 self.noOfSL = 0 self.noOfTP = 0 self.daysInvested = {} 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 ''' if not self.spyMomentum.IsReady or not self.spySD.IsReady: return # Putting 1 percent of the portfolio in a trade self.percentageOfPortfolioPerTrade = 0.01 self.noOfSDForSL = 0.1 self.noOfSDForTP = 10 # Purchasing quantities self.price = self.Securities["SPY"].Close self.quantity = self.percentageOfPortfolioPerTrade * self.Portfolio.TotalPortfolioValue / self.price self.lotSize = self.Securities["SPY"].SymbolProperties.LotSize self.quantity = round(self.quantity/self.lotSize) * self.lotSize # Stop losses self.longStopLoss = self.Securities["SPY"].Close - 10*self.noOfSDForSL*self.spySD.Current.Value self.shortStopLoss = self.Securities["SPY"].Close + 10*self.noOfSDForSL*self.spySD.Current.Value # Take Profits self.longTakeProfit = self.Securities["SPY"].Close + self.noOfSDForTP*self.spySD.Current.Value self.shortTakeProfit = self.Securities["SPY"].Close - self.noOfSDForTP*self.spySD.Current.Value # The current change in price is greater than the mean change in price over 24 hours if not self.Portfolio.Invested: if self.spyMomentum.Current.Value > self.spyMomentumMean.Current.Value: self.MarketOrder("SPY", self.quantity) self.longstopLossTicket = self.StopMarketOrder("SPY", -self.quantity, self.longStopLoss) self.longtakeProfitTicket = self.LimitOrder("SPY", -self.quantity, self.longTakeProfit) self.noOfTrades += 1 elif self.spyMomentum.Current.Value < self.spyMomentumMean.Current.Value: self.MarketOrder("SPY", -self.quantity) self.shortstopLossTicket = self.StopMarketOrder("SPY", self.quantity, self.shortStopLoss) self.shorttakeProfitTicket = self.LimitOrder("SPY", self.quantity, self.shortTakeProfit) self.noOfTrades += 1 if self.noOfTrades > 0: self.Debug(f"Number of trades so far: {self.noOfTrades}\n\ Percentage of trades stopped out: {round(self.noOfSL/self.noOfTrades, 5)}\n\ Percent of trades profitted out: {round(self.noOfTP/self.noOfTrades, 5)}\n\n") def OnSpyMomentum(self, sender, updated): if self.spyMomentum.IsReady: self.spyMomentumMean.Update(self.Time, updated.Value) def OnEndOfDay(self): for symbol in self.Portfolio.Keys: holding = self.Portfolio[symbol] if not holding.Invested: continue if symbol not in self.daysInvested: self.daysInvested[symbol] = 1 else: self.daysInvested[symbol] += 1 if self.daysInvested[symbol] >= 5: self.Liquidate(symbol) def OnOrderEvent(self, orderEvent): if orderEvent.Status != OrderStatus.Filled: return #2. Check if we hit our stop loss (Compare the orderEvent.Id with the stopMarketTicket.OrderId) # It's important to first check if the ticket isn't null (i.e. making sure it has been submitted) if self.longstopLossTicket is not None and self.longstopLossTicket.OrderId == orderEvent.OrderId: self.noOfSL += 1 self.longtakeProfitTicket.Cancel() if self.shortstopLossTicket is not None and self.shortstopLossTicket.OrderId == orderEvent.OrderId: self.noOfSL += 1 self.shorttakeProfitTicket.Cancel() if self.shorttakeProfitTicket is not None and self.shorttakeProfitTicket.OrderId == orderEvent.OrderId: self.noOfTP += 1 self.shortstopLossTicket.Cancel() if self.longtakeProfitTicket is not None and self.longtakeProfitTicket.OrderId == orderEvent.OrderId: self.noOfTP += 1 self.longstopLossTicket.Cancel()