The research question
Can another person reconstruct the evidence behind our result? Before an agent can learn from an experiment, we need to know exactly what that experiment used. A screenshot of a rising chart cannot answer that question. A small dataset, a clear schema, and a repeatable script are a better beginning.
This edition creates a local lab with synthetic prices. These values are invented teaching data, not observations of a real asset. We will make no network requests, connect no brokerage account, and install no third-party packages. By the end, you will have a CSV file and a small machine-readable description of the experiment.
Time: approximately 25 minutes. You need: Python 3.12 or later, a terminal, and a text editor. The examples in this series use the standard library. Python 3.12 is a reproducible baseline, not a requirement to replace a newer supported installation.
Step 1 — Make a separate workspace
Create a folder named agentic-research-lab using your file manager, then open a terminal in that folder. On macOS or Linux, run:
python3 --version
python3 -m venv .venv
.venv/bin/python --version
On Windows, use:
py -3 --version
py -3 -m venv .venv
.venv\Scripts\python.exe --version
The environment keeps this project's interpreter and any future packages separate. We use the environment's interpreter directly, so activating it or changing a PowerShell execution policy is unnecessary. Run the rest of the examples with that same interpreter.
Step 2 — Define what one row means
Each row below is one artificial observation at a fixed minute. observed_at is an ISO timestamp with a UTC offset, asset identifies an invented instrument, mid_price is a quoted mid-price rather than an executable fill, and source states where the row came from.
That distinction between quote and fill matters. A mid-price does not prove that an order of a given size could execute there. Later editions will introduce a deliberately simplified cost model rather than quietly calling these quotes trade receipts.
Step 3 — Generate and audit the fixture
Save the following complete script as lab_02.py. It intentionally writes only synthetic_quotes.csv and lab_manifest.json in the folder where you run it. Re-running replaces those two exercise outputs.
import csv
import json
from datetime import datetime, timedelta, timezone
from pathlib import Path
start = datetime(2026, 1, 1, tzinfo=timezone.utc)
prices = [100, 101, 99, 103, 102, 105]
rows = [
{
"observed_at": (start + timedelta(minutes=i)).isoformat(),
"asset": "SYNTHETIC_DEMO",
"mid_price": f"{price:.2f}",
"source": "invented_fixture_v1",
}
for i, price in enumerate(prices)
]
path = Path("synthetic_quotes.csv")
with path.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=list(rows[0]))
writer.writeheader()
writer.writerows(rows)
with path.open(newline="", encoding="utf-8") as handle:
loaded = list(csv.DictReader(handle))
assert len(loaded) == 6
assert all(float(row["mid_price"]) > 0 for row in loaded)
times = [datetime.fromisoformat(row["observed_at"]) for row in loaded]
assert all((b - a).total_seconds() == 60 for a, b in zip(times, times[1:]))
manifest = {
"experiment": "fixture-audit-v1",
"mode": "synthetic_only",
"rows": len(loaded),
"first_observation": loaded[0]["observed_at"],
"last_observation": loaded[-1]["observed_at"],
}
Path("lab_manifest.json").write_text(
json.dumps(manifest, indent=2) + "\n", encoding="utf-8"
)
print("rows=6 cadence_seconds=60 positive_prices=True")
print("mode=synthetic_only")
print("wrote synthetic_quotes.csv and lab_manifest.json")
Run .venv/bin/python lab_02.py on macOS/Linux or .venv\Scripts\python.exe lab_02.py on Windows. Expected terminal output:
rows=6 cadence_seconds=60 positive_prices=True
mode=synthetic_only
wrote synthetic_quotes.csv and lab_manifest.json
Open both generated files. Confirm that their contents agree with the script before moving on. Keep the script and these outputs together.
Step 4 — Try a controlled failure
Change one price to 0 and rerun. The positive-price assertion should fail. Restore the value. This is an intentional failed check, not an instruction to remove validation until the script becomes green. Record the failed run in a short note: what changed, which check caught it, and why the original data contract rejected it.
Troubleshooting
If python3 or py is not found, install Python from the official Python website and reopen the terminal. If .venv is missing, rerun the creation command from the project folder. If a file appears in an unexpected place, check your terminal's current directory. If your editor inserts smart quotes into code, switch to a plain-text code editor. Do not paste the Markdown fence markers into the .py file.
What this establishes—and what it does not
We established the identity, format, and spacing of six invented observations. We did not establish market coverage, executable prices, predictive value, or a profitable strategy. Even valid real data can be incomplete, delayed, or selected in a biased way. A schema check is the first evidence layer, not the final one.
Completion check: You can explain what each field means, regenerate the files, and demonstrate one failing validation check.
Next edition: Price changes are not profits: build a cost-aware paper ledger.
Primary references
- Python's virtual-environment tutorial explains isolated environments and platform-specific commands.
- Python CSV documentation documents dictionary-based reading and writing, including
newline="". - Python JSON documentation documents the manifest serialization used here.