| Overall Statistics |
|
Total Trades 8047 Average Win 0.20% Average Loss -0.20% Compounding Annual Return -2.622% Drawdown 30.300% Expectancy -0.023 Net Profit -19.164% Sharpe Ratio -0.301 Loss Rate 51% Win Rate 49% Profit-Loss Ratio 1.00 Alpha -0.028 Beta 0.117 Annual Standard Deviation 0.066 Annual Variance 0.004 Information Ratio -0.498 Tracking Error 0.185 Treynor Ratio -0.169 Total Fees $14886.95 |
class ComblinedSeasonalityMarketSessionTrading(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2008, 1, 1) # Set Start Date
self.SetEndDate(2015, 12, 31) # Set End Date
self.SetCash(100000) # Set Strategy Cash
future = self.AddFuture(Futures.Indices.SP500EMini) # S&P E-mini future contracts
future.SetFilter(timedelta(0), timedelta(180)) # Filter according to Expiry date
# Set benchmark
benchmark = self.AddEquity("SPY")
self.SetBenchmark(benchmark.Symbol)
# Set season
# Bullish Season: Nov - May;
# Bearish Season: Jun - Oct
# self.bullSeason = {11, 12, 1, 2, 3, 4, 5} # Bullish Season
self.bearSeason = {6, 7, 8, 9, 10} # Bearish Season
# Overnight trading strategy
# Bullish Season: buy at 18:00, sell at 5:30; buy at 13:15, sell at 15:15
# Bearlish Season: buy at 18:00, sell at 5:30; buy at 13:15, sell at 14:00
# Night: 1800 - 530
# Afternoon: 1315 - 1400
# Close: 1400 - 1515
# Night session
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.At(18, 0), Action(self.Enter))
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.At(5, 30), Action(self.Exit))
# Afternoon session
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.At(13, 15), Action(self.Enter))
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.At(14, 0), Action(self.ExitException))
# Close session
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.At(14, 0), Action(self.EnterException))
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.At(15, 15), Action(self.Exit))
def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
Arguments:
data: Slice object keyed by symbol containing the stock data
'''
# self.Debug(f'Month: {self.Time.date().month}')
self.data = data
pass
def Enter(self):
if not self.Portfolio.Invested:
for chain in self.data.FutureChains:
contracts = list(filter(lambda x: x.Expiry < self.Time + timedelta(90), chain.Value))
# self.Debug(f'Num of Contracts {self.Time}: {len(contracts)}')
if len(contracts) == 0:
continue
front = sorted(contracts, key = lambda x: x.Expiry, reverse = False)[0]
# long
self.MarketOrder(front.Symbol, 1)
def Exit(self):
if self.Portfolio.Invested:
# short
self.Liquidate()
def EnterException(self):
isBear = self.Time.date().month in self.bearSeason
if (not self.Portfolio.Invested) and isBear:
for chain in self.data.FutureChains:
contracts = list(filter(lambda x: x.Expiry < self.Time + timedelta(90), chain.Value))
if len(contracts) == 0:
continue
front = sorted(contracts, key = lambda x: x.Expiry, reverse = False)[0]
# long
self.MarketOrder(front.Symbol, 1)
def ExitException(self):
isBear = self.Time.date().month in self.bearSeason
if self.Portfolio.Invested and isBear:
# short
self.Liquidate()