Overall Statistics |
Total Trades 950 Average Win 0.26% Average Loss -0.24% Compounding Annual Return 4.527% Drawdown 6.200% Expectancy 0.067 Net Profit 7.624% Sharpe Ratio 0.682 Probabilistic Sharpe Ratio 33.308% Loss Rate 48% Win Rate 52% Profit-Loss Ratio 1.06 Alpha 0.033 Beta 0.157 Annual Standard Deviation 0.07 Annual Variance 0.005 Information Ratio -0.32 Tracking Error 0.142 Treynor Ratio 0.306 Total Fees $951.47 Estimated Strategy Capacity $13000000.00 Lowest Capacity Asset TSLA UNU3P8Y3WFAD |
class BootCampTask(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 10, 2) self.SetEndDate(2019, 5, 30) self.SetCash(100000) self.SetSecurityInitializer(self.CustomSecurityInitializer) tickers = ['SPY','TSLA'] self.symbol_data_by_symbol = {} for ticker in tickers: openingBar = None symbol = self.AddEquity(ticker, Resolution.Minute).Symbol self.symbol_data_by_symbol[symbol] = SymbolData() self.Consolidate(symbol, timedelta(minutes=30), self.OnDataConsolidated) self.Schedule.On(self.DateRules.EveryDay(symbol), self.TimeRules.At(13,30), self.ClosePositions) #3. Create a scheduled event triggered at 13:30 calling the ClosePositions function self.stopPrice = self.GetParameter("stop") def CustomSecurityInitializer(self, security): security.SetDataNormalizationMode(DataNormalizationMode.Raw) def OnData(self, data): for symbol, symbol_data in self.symbol_data_by_symbol.items(): if symbol_data.openingBar is None: continue if not data.Bars.ContainsKey(symbol): continue if data.Bars[symbol].Close > symbol_data.openingBar.High and not self.Securities[symbol].Invested: quantity = self.CalculateOrderQuantity(symbol, 0.45) self.MarketOrder(symbol, quantity) # orders 45% of portfolio symbol_data.stopMarketTicket = self.StopMarketOrder(symbol, -self.Portfolio[symbol].Quantity, data.Bars[symbol].Close * 0.9) continue if self.Securities[symbol].Invested and data.Bars[symbol].Close > symbol_data.highestPrice: symbol_data.highestPrice = self.Securities[symbol].Close updateFields = UpdateOrderFields() updateFields.StopPrice = symbol_data.highestPrice * self.stopPrice symbol_data.stopMarketTicket.Update(updateFields) def OnOrderEvent(self, orderEvent): if orderEvent.Status != OrderStatus.Filled: self.symbol_data_by_symbol[orderEvent.Symbol].openingBar = None return if self.symbol_data_by_symbol[orderEvent.Symbol].stopMarketTicket is not None and self.symbol_data_by_symbol[orderEvent.Symbol].stopMarketTicket.OrderId == orderEvent.OrderId: self.symbol_data_by_symbol[orderEvent.Symbol].stopMarketOrderFillTime = self.Time def OnDataConsolidated(self, bar): self.Log(f"Bar at {self.Time} for {bar.Symbol}") if bar.Time.hour == 9 and bar.Time.minute == 30: self.symbol_data_by_symbol[bar.Symbol].openingBar = bar def ClosePositions(self): #2. Set self.openingBar to None, and liquidate TSLA for symbolData in self.symbol_data_by_symbol.values(): symbolData.openingBar = None self.Liquidate() # liquidate entire portfolio class SymbolData: def __init__(self): # Order ticket for our stop order, Datetime when stop order was last hit self.stopMarketTicket = None self.stopMarketOrderFillTime = datetime.min self.highestPrice = 0 self.openingBar = None