Overall Statistics |
Total Trades 148 Average Win 2.66% Average Loss -2.20% Compounding Annual Return -50.376% Drawdown 28.000% Expectancy -0.104 Net Profit -18.673% Sharpe Ratio -0.792 Probabilistic Sharpe Ratio 10.190% Loss Rate 59% Win Rate 41% Profit-Loss Ratio 1.21 Alpha -0.325 Beta 0.052 Annual Standard Deviation 0.417 Annual Variance 0.174 Information Ratio -0.508 Tracking Error 0.457 Treynor Ratio -6.323 Total Fees $2079.35 Estimated Strategy Capacity $8500000.00 Lowest Capacity Asset TQQQ UK280CGTCB51 |
# region imports from AlgorithmImports import * import datetime as dt # endregion class TimedTrader(QCAlgorithm): def Initialize(self): self.SetStartDate(2022, 6, 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