| 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