# EcoFinLearn teaching dataset

Version 1.0.0 (16 October 2026). Author: Sitraka Forler. Documentation page: https://ecofinlearning.com/data

The three tables behind the SQL lessons of EcoFinLearn, exactly as the in-browser SQL sandbox loads them. Every learner, every browser and every timezone gets the same rows.

| File | Rows | What it is | Real or synthetic |
|---|---|---|---|
| `equity_prices.csv` | 2,600 | Daily open, high, low, close and volume for AAPL, MSFT, JPM, GS and SPY, 2022-01-03 to 2023-12-29 | **Synthetic** |
| `trade_ledger.csv` | 200 | Fills booked by four desks, 2022-01-10 to 2023-08-30 | **Synthetic** |
| `macro_indicators.csv` | 42 | US CPI inflation (25 monthly releases) and the Federal Reserve's policy rate (17 FOMC decisions) | **Real**, with sources |

Files are UTF-8 CSV (RFC 4180), comma-separated, one header row, LF line endings. Dates are ISO 8601 (`YYYY-MM-DD`; months `YYYY-MM`). Numbers are written the shortest way that round-trips (`7` for 7.0, `0.5` for 0.50).

## Synthetic versus real

**The prices and the trades are synthetic.** The ticker symbols are real, but the numbers are not market data: they come from a seeded random walk and must not be used as, or compared with, historical prices. They exist so that queries have something realistic in shape to work on. The generator is deterministic (mulberry32 PRNG, seeds 20261016 and 424242, integer and plain floating-point arithmetic only, calendar computed in UTC), so the files can be cited and reproduced bit for bit.

**The macro figures are real.** Each value and each date was read from the official publication, listed below, and checked on 16 October 2026.

## Data dictionary

### equity_prices.csv (synthetic)

| Column | Type | Unit | Meaning |
|---|---|---|---|
| `ticker` | text | | AAPL, MSFT, JPM, GS or SPY (labels only) |
| `trade_date` | date | | A weekday (Monday to Friday) from 2022-01-03 to 2023-12-29. Exchange holidays are not removed: 520 days per ticker |
| `open_price` | decimal | USD, 2 dp | Opening price |
| `high_price` | decimal | USD, 2 dp | Session high, never below open or close |
| `low_price` | decimal | USD, 2 dp | Session low, never above open or close |
| `close_price` | decimal | USD, 2 dp | Closing price; each day's walk starts from the previous close |
| `volume` | integer | shares | Between 1,000,000 and 9,999,999 |

Generator: close = previous close × (1 + d), with d uniform on [-0.0096, 0.0104), so a slight upward drift; open within ±0.25% of the previous close; high and low up to 1% beyond the open/close range. Starting levels: AAPL 150, MSFT 290, JPM 130, GS 340, SPY 420.

### trade_ledger.csv (synthetic)

| Column | Type | Unit | Meaning |
|---|---|---|---|
| `trade_id` | integer | | 1 to 200 |
| `ticker` | text | | Round-robin over AAPL, MSFT, JPM, GS, SPY |
| `trade_date` | date | | Every third calendar day from 2022-01-10, so some fills fall on a weekend and have no matching `equity_prices` row (the join lessons use this) |
| `side` | text | | `SELL` for every third trade, otherwise `BUY` |
| `quantity` | integer | shares | 100 to 999 |
| `price` | decimal | USD, 2 dp | Fill price, uniform on [100, 500); not tied to the `equity_prices` level |
| `desk` | text | | Equities-US, Equities-EU, Macro or Quant, round-robin |

### macro_indicators.csv (real)

| Column | Type | Unit | Meaning |
|---|---|---|---|
| `indicator_name` | text | | `CPI_YoY` or `FedFunds` |
| `ref_period` | month | | The month the figure refers to (`YYYY-MM`) |
| `release_date` | date | | The day the figure became public |
| `value` | decimal | percent | The published figure |
| `prior_value` | decimal | percent | The previous figure of the same series |

`CPI_YoY`: US Consumer Price Index for All Urban Consumers (CPI-U), all items, U.S. city average, not seasonally adjusted, percent change over the 12 months ending in `ref_period`, as stated in the headline of the BLS news release. `release_date` is the date of that release (published at 8:30 a.m. Eastern Time). References December 2021 to December 2023. The not seasonally adjusted index is not revised, so the first published figure is still the official one.

`FedFunds`: upper bound of the target range for the federal funds rate set at each scheduled FOMC meeting, holds included. `release_date` is the date of the FOMC statement (2:00 p.m. Eastern Time); the new range takes effect the next day. `ref_period` is the month of the meeting. Meetings from 15 December 2021 to 13 December 2023.

For a monthly statistic such as CPI, `release_date` is always after the end of `ref_period`: June 2022 CPI (9.1%) was published on 13 July 2022. A backtest must join on `release_date <= trade_date`, never on `ref_period`; the "Point-in-Time Macro Join" lesson teaches why.

## Sources

- US Bureau of Labor Statistics, Consumer Price Index news releases, archive: https://www.bls.gov/bls/news-release/cpi.htm. Each release is at `https://www.bls.gov/news.release/archives/cpi_MMDDYYYY.htm`, where MMDDYYYY is the `release_date` (for example `cpi_07132022.htm`). The November 2021 figure used as the first `prior_value` (6.8) is from `cpi_12102021.htm`.
- Federal Reserve Bank of St. Louis, FRED series CPIAUCNS (index levels, used as a cross-check): https://fred.stlouisfed.org/series/CPIAUCNS
- Board of Governors of the Federal Reserve System, FOMC meeting calendars and statements: https://www.federalreserve.gov/monetarypolicy/fomccalendars.htm
- Federal Reserve Bank of St. Louis, FRED series DFEDTARU (federal funds target range, upper limit): https://fred.stlouisfed.org/series/DFEDTARU

## Licence

- `macro_indicators.csv`: the figures are works of the US federal government (Bureau of Labor Statistics, Board of Governors of the Federal Reserve System) and are in the public domain in the United States. Please cite the original publishers.
- `equity_prices.csv`, `trade_ledger.csv` and this documentation: Creative Commons Attribution 4.0 International (CC BY 4.0), https://creativecommons.org/licenses/by/4.0/. Credit "Sitraka Forler, EcoFinLearn" with a link to https://ecofinlearning.com/data.

## How to cite

Forler, S. M. (2026). EcoFinLearn teaching dataset: synthetic equity prices and trades with point-in-time US macro releases (Version 1.0.0) [Data set]. EcoFinLearn. https://ecofinlearning.com/data

```bibtex
@misc{forler_ecofinlearn_teaching_data_2026,
  author       = {Forler, Sitraka M.},
  title        = {{EcoFinLearn teaching dataset: synthetic equity prices and trades with point-in-time US macro releases}},
  year         = {2026},
  version      = {1.0.0},
  publisher    = {EcoFinLearn},
  howpublished = {\url{https://ecofinlearning.com/data}},
  note         = {Data set. Macro figures from the US Bureau of Labor Statistics and the Federal Reserve Board; prices and trades are synthetic}
}
```

No DOI has been registered for this dataset. Cite the version number and the URL above.

## Reproducing the files

The files are generated from `lib/teaching-data.ts` in the EcoFinLearn source code by `npm run gen:data`; a test fails if the published files and the generator ever disagree. In SQL, the sandbox schema is:

```sql
CREATE TABLE equity_prices (id INTEGER PRIMARY KEY AUTOINCREMENT, ticker TEXT NOT NULL, trade_date TEXT NOT NULL,
  open_price REAL, high_price REAL, low_price REAL, close_price REAL NOT NULL, volume INTEGER);
CREATE TABLE macro_indicators (id INTEGER PRIMARY KEY AUTOINCREMENT, indicator_name TEXT NOT NULL,
  ref_period TEXT NOT NULL, release_date TEXT NOT NULL, value REAL, prior_value REAL);
CREATE TABLE trade_ledger (trade_id INTEGER PRIMARY KEY, ticker TEXT NOT NULL, trade_date TEXT NOT NULL,
  side TEXT CHECK(side IN ('BUY','SELL')), quantity INTEGER, price REAL, desk TEXT);
```

In pandas:

```python
import pandas as pd
base = "https://ecofinlearning.com/data/ecofinlearn-teaching-data/"
prices = pd.read_csv(base + "equity_prices.csv", parse_dates=["trade_date"])
macro  = pd.read_csv(base + "macro_indicators.csv", parse_dates=["release_date"])
```
