Overall Statistics |
Total Trades 2850 Average Win 0.71% Average Loss -0.69% Compounding Annual Return -28.870% Drawdown 86.000% Expectancy -0.189 Net Profit -85.710% Sharpe Ratio -1.396 Probabilistic Sharpe Ratio 0.000% Loss Rate 60% Win Rate 40% Profit-Loss Ratio 1.03 Alpha -0.205 Beta 0.04 Annual Standard Deviation 0.144 Annual Variance 0.021 Information Ratio -1.398 Tracking Error 0.212 Treynor Ratio -5.024 Total Fees $47001.64 Estimated Strategy Capacity $1900000.00 Lowest Capacity Asset TQQQ UK280CGTCB51 |
# region imports from AlgorithmImports import * import datetime as dt # endregion class TimedTrader(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 1, 1) # Set Start Date self.SetEndDate(2022, 9, 17) self.SetCash(100000) # Set Strategy Cash self.ticker = self.GetParameter('Ticker') self.symbol = self.AddEquity(self.ticker, Resolution.Minute).Symbol OpenTime = self.GetParameter('OpenTime') # Format: 'HH:MM' OpenTime = dt.datetime.strptime(OpenTime,'%H:%M').time() CloseTime = self.GetParameter('CloseTime') # Format: 'HH:MM' CloseTime = dt.datetime.strptime(CloseTime,'%H:%M').time() self.GreaterThanOpen = self.GetParameter('GreaterThanOpen') # Long, Short, Ignore self.GreaterThanClose = self.GetParameter('GreaterThanClose') # Long, Short, Ignore self.resolution = self.GetParameter('Resolution') # Minute, Second self.close = 0 self.open = 0 if self.resolution == 'Minute': self.symbol = self.AddEquity(self.ticker, Resolution.Minute).Symbol else: self.symbol = self.AddEquity(self.ticker, Resolution.Second).Symbol self.Schedule.On(self.DateRules.EveryDay(self.symbol),self.TimeRules.At(OpenTime.hour,OpenTime.minute),self.CheckInitiation) self.Schedule.On(self.DateRules.EveryDay(self.symbol),self.TimeRules.At(CloseTime.hour,CloseTime.minute),self.Close) self.Schedule.On(self.DateRules.EveryDay(self.symbol),self.TimeRules.AfterMarketOpen(self.symbol,1),self.RecordOpen) self.Schedule.On(self.DateRules.EveryDay(self.symbol),self.TimeRules.BeforeMarketClose(self.symbol,1),self.RecordClose) def CheckInitiation(self): if (self.open == 0) or (self.close==0): return current_price = self.SliceToPrice() open_trigger = self.GetOpenTrigger(current_price) close_trigger = self.GetCloseTrigger(current_price) signal = open_trigger + close_trigger quantity = max(-1, min(1, signal)) self.SetHoldings(self.symbol,quantity,tag=f'O:{round(self.open,2)}|C:{round(self.close,2)}|P:{round(current_price,2)}') def Close(self): self.Liquidate() def RecordOpen(self): self.open = self.SliceToPrice() def RecordClose(self): self.close = self.SliceToPrice() def GetOpenTrigger(self, price): if self.GreaterThanOpen == 'Long': if price > self.open: return 1 else: return -1 elif self.GreaterThanOpen == 'Short': if price < self.open: return 1 else: return -1 else: return 0 def GetCloseTrigger(self, price): if self.GreaterThanClose == 'Long': if price > self.close: return 1 else: return -1 elif self.GreaterThanClose == 'Short': if price < self.close: return 1 else: return -1 else: return 0 def SliceToPrice(self): slice = self.CurrentSlice if slice.ContainsKey(self.symbol): if slice[self.symbol] is not None: return self.CurrentSlice[self.symbol].Price return 0