| 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