S&P 500 PREDICTION COMPETITION

A ~3-month live forward test

Build your own predictive model, freeze it, and let it forecast the S&P 500 every trading day. No backtest tricks: predictions are locked in before the outcome is known.

Prize Pool

Total Prize Pool: To be announced

Entry is free. Anyone can compete. Prizes go to the top verified finishers once their models pass the end-of-competition audit.

Objective

Forecast the S&P 500 on the daily timeframe for roughly three months, live. Each day your model outputs a position between -1 (fully short) and +1 (fully long) for the next trading session, and you are scored on the profit that position would have made.

This competition is built for beginner-to-intermediate data analysts working in R or Python. You can use any features and any data you can access, but your model has to stay exactly as it is once the competition starts.

How It Works

Forward test, not a backtest. Predictions are submitted before the outcome is known and scored after the close. Nobody can tune a model to results that have already happened.

Frozen models, enforced with commit-reveal

  1. Before day one, zip your model package: code, trained weights, feature pipeline, and a pinned requirements.txt (Python) or renv.lock (R). Compute its SHA-256 hash and submit only the hash. All hashes are published.
  2. During the competition, your model runs automatically every trading day through GitHub Actions. Nothing is submitted by hand.
  3. At the end, the top finishers (top 3-5) reveal their package. The organizer checks that the hash matches, then re-runs the model on the logged daily inputs to confirm it reproduces the submitted predictions.

Your model repository can be private, so your code stays secret until the reveal.

Automated Daily Submissions

You will not be submitting by hand for three months. A GitHub Actions workflow runs your model on a schedule and posts the result to the organizer's Google Form.

PieceWhat it does
.github/workflows/predict.ymlCron 37 21 * * 1-5 (UTC), which is after the 4 PM ET close year-round.
predict.pyBuilds features, runs model/model.pkl, clips the position to [-1, 1], appends inputs to logs/inputs.jsonl, and POSTs to the form.
logs/inputs.jsonlExactly what your model saw each day. Used for the audit replay.

What the form receives

  • Your private participant token
  • The as_of date
  • Your position
  • The SHA-256 of the logged input line

The form's server-side timestamp is the authoritative submission time. Git commit timestamps can be faked, so they are not used.

Secrets

Each participant gets a private token, stored as the repo secret PARTICIPANT_TOKEN. The form address is stored as FORM_URL. Any API keys your features need go in as repo secrets too.

cron: "37 21 * * 1-5"   # 21:37 UTC, Mon-Fri
# 5:37 PM ET in summer, 4:37 PM ET in winter: always after the close

Scoring

Daily P&L

Position × SPY return for the session. The cumulative sum of daily P&L is your equity curve.

No Leverage

Positions are capped at ±1. Anything outside that range is clipped.

Price Source

SPY adjusted prices from Yahoo, via yfinance (Python) or tidyquant (R).

Timing

  • A prediction made after the close on day T is scored on the next trading session, open-to-close.
  • Submission deadline: 9:00 AM ET on the session being predicted.
  • A missed day counts as position 0 (flat).
  • Holiday submissions map to the next trading session.

Primary ranking metric

To be announced. Under consideration: total return, a Sharpe-style risk-adjusted ratio, or excess return over buy-and-hold SPY. A buy-and-hold SPY benchmark line will be shown on the leaderboard regardless.

Rules

  • Frozen Model

    Your model cannot change during the competition. Its hash is on record, and changes will fail the audit.

  • Reproducibility

    Use a fixed random seed. Audit tolerance is about 0.01 on positions.

  • Rolling Retraining

    Policy to be announced. If it is allowed, the retraining logic must be part of the committed code.

  • Features Must Be Reachable From the Runner

    Your pipeline runs on a GitHub runner, so data must come from:

    • Internet APIs, with keys stored as repo secrets, or
    • Files committed to your repo.

    Local-only data would require a self-hosted runner.

  • System Dependencies

    Packages with system libraries (for example R sf / terra, or GDAL) need an apt-get install step in your workflow.

  • Large Files

    Files over 100 MB need Git LFS.

  • Free Entry

    No purchase or fee to enter.

Audit & Disqualification

  1. Top finishers reveal their zipped model package.
  2. The organizer computes its SHA-256 and checks it against the hash published before day one.
  3. The model is re-run on the daily input log. Reproduced positions must match the submitted ones within the tolerance.
Failed audit = disqualification. The prize passes to the next verified finisher.

Getting Started

A participant template is in the works so you only have to swap in your own feature pipeline and model.

  • Python template: link coming soon
  • R template: in development (will use r-lib/actions/setup-r with use-public-rspm: true, r-lib/actions/setup-renv, and Rscript predict.R)
  • Hashing instructions: coming soon

Leaderboard

The live leaderboard (equity curves plus a buy-and-hold SPY benchmark) will appear here once the competition starts. Format to be announced.

Enter the Competition