👋 Introduction

Hello fellow quants — I want to share a recent learning project I worked on that finally ran smoothly in backtest. A quick disclaimer: I’m a beginner, and my primary goal here was to learn QuantConnect and the LEAN framework, not to build a profitable trading system.

The project was inspired by a blog post from Quantitativo, who explored a gap-down reversal strategy. I used that concept as a jumping-off point to build my own version.


💡 Hypothesis

Stocks in an uptrend often revert after a sharp overnight gap down.

This strategy attempts to capture that short-term reversion by entering positions right after the open and closing them the same day.

 

🧠 Strategy

  • Universe Selection: S&P 500 stocks trading above their 100-day SMA.
  • Entry Rule: At market open, if a stock gaps down more than 1.2× its 14-day ATR relative to yesterday’s close, we go long.
  • Exit Rule: Liquidate all positions 15 minutes after the open.

 

I drew ideas from two QC Bootcamp 101 lessons but had to combine them to meet the needs of this intraday strategy:

  • Lesson 6 – Fading the Gap
    Had intraday data and volatility-based entry logic, but lacked a dynamic universe manager.
  • Lesson 7 – 200/50 EMA Momentum Universe
    Had universe filtering via momentum, but used daily resolution and no volatility measures.

 

📊 Backtest

You can check out my backtest here. While this strategy isn’t optimal (I imagine I overcomplicated the SMA universe selection and ATR update method) it served its purpose as a learning tool.

If you’re new to QuantConnect and working through:

  • Universe selection
  • Intraday timing logic
  • Indicator warm-ups and updates

…this code might serve as a helpful reference. It took time to get everything running correctly, but I learned a ton — and I’m glad to share it.


🔍 Key Challenges & Takeaways

  • Time handling: Understanding how scheduled events, data updates, and indicator values interact over time was critical.
  • Indicator updates: Indicators like ATR, which require TradeBar inputs, must be handled differently than those like SMA.
  • Universe selection: Managing a dynamic symbol universe (and cleaning up unused symbols/indicators) was trickier than expected. In the codes current form, backtesting is slow.

 

🚀 Final Thoughts

I’m just getting started, but I believe in sharing progress even before it's perfect. This strategy may not beat the market, but it helped me understand the platform, debug tricky issues, and build confidence.

If you're exploring something similar or want to exchange ideas, feel free to reach out — I’d love to compare notes.