TradeOps is a multi-agent trading operations platform with synthetic market data, order execution, authentication, persistent state, and a live React dashboard. It generates prices, order books, and dealer quotes, publishes them to Redis streams, and persists canonical state in Postgres.
make installThe install target does three things:
- Configures git to use the repo’s custom hooks (
git config core.hooksPath .githooks) and ensures they are executable. - Creates (or reuses) a local virtual environment in
./venv. - Installs Python dependencies from
requirements.txt.
Once installed, run tests with:
venv/bin/pytestTo build the docker stack and run the smoke suite locally, execute:
make smokeRun the entire stack (Redis, Postgres, market data agent) with Docker Compose:
docker compose up --build market_dataUseful commands:
- Inspect Redis stream traffic:
docker compose exec redis redis-cli monitor - Inspect Postgres tables:
docker compose exec postgres psql -U postgres -d marketdata
make smoke compiles the docker images, launches Redis/Postgres/market data,
runs pytest -k smoke, and tears the stack down automatically. To execute the
smoke suite manually:
export MARKET_DATA_SMOKE=1
export MARKET_DATA_REDIS_URL=redis://localhost:6379/0
export MARKET_DATA_POSTGRES_DSN=postgresql://postgres:postgres@localhost:5432/marketdata
pytest -k smokeStream names can be customised via the MARKET_DATA_*_STREAM environment
variables.
Custom hooks live in .githooks. Enable them once per clone:
git config core.hooksPath .githooksHook responsibilities:
-
pre-commit – runs
pytest -m "not e2e"and (when the frontend is present)npm run build. SetSKIP_TEST_COMMIT=1 git commit ...to bypass in emergencies (the hook warns when checks are skipped). -
commit-msg – enforces the standard commit message format:
verb: concise title thorough explanation covering design choices, wrapped at 80 charsverbmust be one of: add/remove/refactor/change/revert/admin. The detail section must start after a blank line, contain at least one non-empty line, and total at least 12 words. Every line (subject and body) must be ≤80 chars. -
post-commit – prints a short summary of the most recent commit and reminds you to push.
GitHub Actions workflows reside in .github/workflows/:
- ci.yml – runs on pushes and pull requests. It checks out the repo,
installs dependencies, executes the unit/integration suite, and then invokes
scripts/run_smoke.shto validate the docker-compose stack end-to-end. - cd.yml – runs on pushes to
main. In addition to the CI steps, it builds the Docker image to ensure the container artefact is healthy.
The management FastAPI application (market_data/management_api.py) exposes
runtime diagnostics for the agent:
GET /health– last emitted tick per instrument and current liquidity regime.GET /metrics– configured tick cadence/tick size plus registered scenario presets.
Mount this app alongside the streaming service when you need operational visibility or integration with external monitoring.
verb: title
Detailed explanation with multiple sentences explaining the change,
covering design trade-offs, and future considerations. Wrap each line at
80 characters to retain readability in terminals and tooling.
Allowed verbs: add, remove, refactor, change, revert, admin.
Remember to keep explanations thorough—describe the behaviour change, the reason behind it, and notable testing decisions.
An asynchronous trading agent now lives under trading/. It accepts authenticated
order requests, matches them against the latest simulated order book, persists
cash/position state, and publishes executions onto the configured Redis stream.
A lightweight React single-page app lives in frontend/. It polls the market
data management API for the latest ticks and submits demo orders to the trading
agent. Both backends expose CORS-friendly endpoints by default so the UI can run
locally via Vite.
-
Start the docker stack so Redis, Postgres, market data, the trading agent, and the auth service are running. The services expose:
- Market data management API –
http://localhost:8080 - Trading agent REST API –
http://localhost:8081 - Auth service –
http://localhost:8082
make stack-up # or: docker compose up --build market_data trading_agent auth_service - Market data management API –
-
Install frontend dependencies and launch the dev server:
cd frontend npm install npm run devVite serves the UI on
http://localhost:5173(configurable viaVITE_DEV_PORT). The page displays live market snapshots and an order form. -
To customise service endpoints, set the following environment variables before running the dev server:
export VITE_MARKET_DATA_BASE_URL="http://localhost:8080" export VITE_TRADING_BASE_URL="http://localhost:8081" export VITE_AUTH_BASE_URL="http://localhost:8082"
-
Hit
http://localhost:5173and use the sign-in form. Registration is wired through the auth agent; newly created users receive starting balances defined byAUTH_STARTING_BALANCE. A demo account (demo@example.com/demo) is seeded automatically for quick testing.
All UI interactions emit JSON logs that match logging.schema.json, keeping the
schema consistent with backend services.
All services emit JSON logs that follow logging.schema.json. The helper in
common/logging.py wires Python's logging subsystem to this schema, ensuring
messages stay human-readable while remaining easy to ingest elsewhere. Frontend
code should serialize the same field set (timestamp, level, component,
event, message, optional correlation identifiers, and a context object)
when we instrument SPA interactions.
uvicorn trading.app:create_default_app --factory --reloadConfiguration is sourced from the same environment variables used across the
stack (TRADING_REDIS_URL, TRADING_POSTGRES_DSN, TRADING_MARKETDATA_STREAM,
TRADING_EXECUTION_STREAM, TRADING_ORDER_STREAM). The bootstrap wiring opens
an asyncpg pool and a Redis client on startup; ensure the services from the
docker-compose stack are available before launching the API.
We organise tests by scope using Pytest markers:
unit– fast, isolated tests (default marker for many modules)integration– exercises multiple layers (database/redis/service wiring)e2e– full stack verification requiring the docker compose stack
Common commands:
# Run unit + integration tests locally
venv/bin/pytest -m "not e2e"
# Run only unit tests
venv/bin/pytest -m unit
# Run integration tests
venv/bin/pytest -m integrationEnd-to-end tests are gated behind an environment flag so they only run when the stack is available (typically CI):
RUN_E2E_TESTS=1 \
E2E_MARKET_URL=http://localhost:8080 \
E2E_TRADING_URL=http://localhost:8081 \
E2E_AUTH_URL=http://localhost:8082 \
venv/bin/pytest -m e2eThe frontend also ships with npm run build for CI verification.
- Release work happens on the
releasebranch (orrelease/*branches). - Each release commit must be tagged with the application version in the
x.y.zorx.y.z+flagformat (for example1.2.0or1.2.0+hotfix). tags are enforced by CI. - The CD workflow builds and publishes the Docker image using the release tag as the image version.