| Overall Statistics |
|
Total Orders 12638 Average Win 0.25% Average Loss -0.28% Compounding Annual Return 0.762% Drawdown 34.700% Expectancy 0.014 Start Equity 100000 End Equity 121218.61 Net Profit 21.219% Sharpe Ratio -0.283 Sortino Ratio -0.289 Probabilistic Sharpe Ratio 0.000% Loss Rate 47% Win Rate 53% Profit-Loss Ratio 0.90 Alpha -0.021 Beta 0.128 Annual Standard Deviation 0.056 Annual Variance 0.003 Information Ratio -0.38 Tracking Error 0.149 Treynor Ratio -0.125 Total Fees $0.00 Estimated Strategy Capacity $19000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X Portfolio Turnover 136.05% |
# https://quantpedia.com/strategies/lunch-effect-in-the-u-s-stock-market-indices/
#
# The investment universe for this strategy is centered on the SPDR S&P 500 ETF Trust (SPY), which represents the S&P 500 Index. This ETF is chosen due to its
# high liquidity and broader U.S. stock market representation. The strategy can also be applied to other trading vehicles, such as near-term futures on the S&P 500
# Index (e.g., S&P 500 E-mini Futures) or CFDs on SPY. (The selection of SPY is based on its ability to capture the overall market movements and its suitability for
# intraday and overnight trading strategies.)
# (You can get data for your backtesting needs from Yahoo Finance and/or Finram.)
# The strategy employs specific time-based trading rules derived from the research paper’s findings on the Lunch Effect and Overnight Anomaly. No additional technical
# indicators are used; the approach is purely time-based.
# Once again, rules overview:
# 1. At 11:00 AM ET, enter a short position on SPY.
# 2. At noon ET: reverse; hence, cover the short position and enter a long position on SPY.
# 3. At 2:00 PM ET, exit the extended position.
# This is an intraday strategy with no overnight holding and involves one (100 %) asset, so it is fully weighted in that proportion of total capital.
#
# QC implementation changes:
# - Only long position at 12:00 PM ET is held until 14:00 PM ET. Short position is not traded.
# - No trading fees are applied and mid price execution is enforced to test out strategy's theoretical performance.
# region imports
from AlgorithmImports import *
# endregion
class LunchEffectInTheUSStockMarketIndices(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2000, 1, 1)
self.set_cash(100_000)
self._traded_asset: Symbol = self.add_equity('SPY', Resolution.MINUTE).symbol
self.securities[self._traded_asset].set_fee_model(ConstantFeeModel(0))
self.securities[self._traded_asset].set_fill_model(MidPriceFillModel())
self._trading_hours: List[int] = [12, 14]
def on_data(self, slice: Slice) -> None:
if slice.contains_key(self._traded_asset) and slice[self._traded_asset]:
if self.time.hour == self._trading_hours[0]:
if not self.portfolio[self._traded_asset].invested:
self.set_holdings(self._traded_asset, 1)
if self.time.hour == self._trading_hours[1]:
if self.portfolio[self._traded_asset].invested:
self.liquidate()
class MidPriceFillModel(FillModel):
def market_fill(self, asset, order) -> OrderEvent:
mid_price: float = (asset.bid_price + asset.ask_price) / 2.
fill = OrderEvent(
orderId=order.Id, symbol=order.Symbol, utcTime=order.Time, status=OrderStatus.Filled,
direction=order.Direction,
fillPrice=mid_price, fillQuantity=order.Quantity, orderFee=OrderFee.Zero
)
return fill