Skip to content
← Back to work

Autonomous Trading Agent

A personal experiment in whether an agent can be engineered to production standards instead of prototyped and abandoned.

Role

Sole engineer — personal project

Context

Personal research

Status

Research project

Verified by

274 tests · strict mypy + ruff

Paper trading only. This is a research project, not financial advice.

Results

274

Tests · pytest, strict mypy + ruff

10

Phases, 42 tracked tasks

Type-checked under strict mypy with ruff enforced throughout.

The problem

Most agent projects are demos. They work in the happy path, they are impressive for an afternoon, and they quietly stop running a week later because nothing about them was built to survive contact with reality.

I wanted to find out what changes if you hold an LLM-driven agent to the standards of production software: typed, tested, monitored, and safe to leave running when you are not watching. The trading domain was chosen because it is unforgiving about silent failure — a wedged process during market hours is unambiguous.

Constraints

  • It must never wedge silently. A stuck agent that looks alive is worse than one that has obviously crashed.
  • Credentials must never sit in plaintext.
  • It must respect market hours rather than assume they are always open.

How I built it

The API client is raw httpx. The vendor SDK was dropped early because it was sync-only, which does not survive contact with an async agent loop — and a dependency that constrains your architecture is not saving you any work.

Decisions run through Claude with extended thinking. Around that sits the machinery that makes it a system rather than a script: a dual-process heartbeat watchdog over SQLite so a wedged process is detected instead of assumed healthy, PBKDF2 + Fernet credential encryption, market-calendar gating, and structured JSON logging so a decision can be reconstructed after the fact.

It was built the way work gets built, not the way experiments get built: 274 tests, strict mypy and ruff, delivered across 10 phases and 42 tracked tasks.

What I’d do differently

I would define the evaluation harness for decision quality before building the execution layer. Making the machinery reliable was tractable; judging whether the decisions were any good needed a measurement design I had not set up first.

Stack

Python · httpx · Claude API · SQLite · asyncio · pytest · mypy · ruff