尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Local trading simulation: synthetic market data, authenticated orders, simulated fills and persistent state, with a React dashboard
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗TradeOps is a local trading simulation 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.
Open the live demo → — choose Try the isolated demo; synthetic data, no real-money execution.
Implemented workflow: seeded synthetic feeds → Redis streams and PostgreSQL → authenticated order submission → simulated fills → persisted orders/cash/positions. The React UI polls REST endpoints; a WebSocket gateway and portfolio/risk service remain planned. This is an educational local stack, with no real-money execution.
Legacy-route limits: concurrent submissions for one account may overwrite balance updates. Execution publication occurs before the database transaction commits, so Redis and PostgreSQL can disagree after a failure. There is no transactional outbox or exactly-once guarantee. Do not use this demo to establish production consistency.
make install
The install target does three things:
git config core.hooksPath .githooks)
and ensures they are executable../venv.requirements.txt.Once installed, run tests with:
venv/bin/pytest
To build the docker stack and run the smoke suite locally, execute:
make smoke
Run the market data agent with Redis and Postgres:
docker compose up --build market_data
Useful commands:
docker compose exec redis redis-cli monitordocker compose exec postgres psql -U postgres -d marketdatamake 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 smoke
Stream names can be customised via the REDIS_TICK_STREAM,
REDIS_ORDER_BOOK_STREAM and REDIS_DEALER_QUOTE_STREAM environment variables.
Custom hooks live in .githooks. Enable them once per clone:
git config core.hooksPath .githooks
Hook responsibilities:
pre-commit – runs pytest -m "not e2e" and (when the frontend is
present) npm run build. Set SKIP_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 chars
verb must be one of: add/remove/refactor/change/revert/admin/fix. 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/:
release / release/** pushes or manual dispatch. It
requires an exact version tag, builds the image, and publishes only when registry
credentials are configured. Unit and compose checks belong to CI.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, fix.
Remember to keep explanations thorough—describe the behaviour change, the reason behind it, and notable testing decisions.
An asynchronous trading agent 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:
http://localhost:8080http://localhost:8081http://localhost:8082make stack-up # or: docker compose up --build market_data trading_agent auth_service
Install frontend dependencies and launch the dev server:
cd frontend
npm install
npm run dev
Vite serves the UI on http://localhost:5173 (configurable via
VITE_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:5173 and use the sign-in form. Registration is wired
through the auth agent; newly created users receive starting balances defined
by AUTH_STARTING_BALANCE. A demo account ([email protected] / demo) is
seeded automatically for quick testing.
Select an instrument in Market pulse (or in the order form), choose a side and quantity, then submit a simulated market or limit order. Order activity shows the last ten server submission receipts, including actual filled quantity, status and average fill price. It clears on refresh/logout and does not poll historical or working orders. Portfolio/risk views remain planned. Identity comes from the authenticated session; there is no editable user ID in the order form.
npm run build runs receipt unit tests and TypeScript checks before Vite. An
optional browser integration check uses mocked APIs to exercise instrument
selection, partial fills and logout reset; it requires Playwright and a running
Vite server configured with the same-origin /api/market, /api/trading and
empty auth bases:
node tests/dashboard.browser.cjs # run from frontend/
The frontend logging helper (src/lib/logging.ts) writes JSON entries with the
fields of logging.schema.json; the app shell, login view and auth context use it.
The built-in equity/futures GBM feeds use annual synthetic drift/volatility
(5%/20% and 1%/18%), converted to the simulator's seconds convention with a
365-day calendar year. They advance by their configured 0.5/0.25-second feed
steps. This prevents annual-sized shocks on each subsecond quote. Simulation
time advances per generated tick; scheduling delays do not imply exact elapsed
wall-clock time. Custom MARKET_DATA_INSTRUMENTS configurations and scenario
drift shifts keep the existing per-second drift and per-square-root-second
volatility convention; rate-feed parameters are also unchanged. These are
educational processes, not calibrated market forecasts or guaranteed price bounds.
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. The
frontend helper serializes the same field set (timestamp, level, component,
event, message, optional correlation identifiers, and a context object).
uvicorn trading.app:create_default_app --factory --reload
Configuration 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 stackCommon 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 integration
End-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 e2e
The frontend also ships with npm run build for CI verification.
release branch (or release/* branches).x.y.z or x.y.z+flag format (for example 1.2.0 or 1.2.0+hotfix).
tags are enforced by CI.The auth service prepares the shared users, accounts, positions and orders
schema before accepting logins. Preparation is idempotent: restarting the stack
keeps existing orders. The full-stack CI test submits an authenticated order,
repeats schema preparation and verifies that the order remains in PostgreSQL.
The market-data tables are initialized separately by docker/init/.
The prepared native manifest supports sudo homelab project deploy tradeops
alongside the existing Docker development workflow; homelab is the author's
private server tooling and is not part of this repository. A frozen uv.lock and
explicit setuptools package discovery support production-only wheel installs.
The service entry point is .venv/bin/python deploy/homelab_run.py: it starts
the existing auth, market-data and trading workers, binds them to loopback and
fails the whole service if any worker exits. Its /health response is ready
only after all three workers respond and each synthetic instrument has a tick.
Partial startup and termination are covered by lifecycle regression tests.
Caddy serves the static frontend and forwards /api/market/*,
/api/trading/* and /auth/* to their existing APIs. Build with
VITE_MARKET_DATA_BASE_URL=/api/market,
VITE_TRADING_BASE_URL=/api/trading and an empty VITE_AUTH_BASE_URL to keep
browser requests on the public origin. PostgreSQL/Redis connection settings
come from the service environment. Production uses Secure/HttpOnly cookies and
matching AUTH_SESSION_COOKIE_NAME/TRADING_SESSION_COOKIE_NAME values.
The guided demo uses guest-owned synthetic accounts, not real funds. Its new snapshot route has scoped PostgreSQL locking, durable accounting receipts and idempotent retries. The existing host retention job also removes only expired guest evidence older than 24 hours. These changes do not establish a general distributed event-delivery guarantee. See demo limits and migration. Local verification does not prove the currently deployed version has these features.