Skip to content

Commit 131cc19

Browse files
committed
Update README and design documentation; enhance seed script and frontend features
- Revised README to improve clarity and added architecture details. - Updated design document to explain system decisions and metrics. - Enhanced `seed_contracts.py` to create corresponding markets in the market engine. - Added hedging tool overlay in the frontend map component. - Introduced Prometheus metrics for market engine and updated Docker configuration for Redis and Grafana services.
1 parent 4c539f2 commit 131cc19

20 files changed

Lines changed: 1478 additions & 72 deletions

File tree

.env.example

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# ── atmx environment variables ─────────────────────────────────────────────
2+
# Copy to .env and fill in your values:
3+
# cp .env.example .env
4+
5+
# Mapbox token for the frontend map (required for map rendering).
6+
# Get one at https://account.mapbox.com/access-tokens/
7+
MAPBOX_TOKEN=pk.your_mapbox_token_here
8+
9+
# ── Database (usually no changes needed for local dev) ─────────────────────
10+
POSTGRES_USER=atmx
11+
POSTGRES_PASSWORD=atmx
12+
POSTGRES_DB=atmx
13+
14+
# ── Market Engine ──────────────────────────────────────────────────────────
15+
# DATABASE_URL=postgres://atmx:atmx@localhost:5432/atmx?sslmode=disable
16+
# REDIS_URL=redis://localhost:6379/0
17+
18+
# ── Settlement Oracle ──────────────────────────────────────────────────────
19+
# DATABASE_URL=postgresql+asyncpg://atmx:atmx@localhost:5432/atmx
20+
# SYNC_DATABASE_URL=postgresql://atmx:atmx@localhost:5432/atmx
21+
# ASOS_BASE_URL=https://mesonet.agron.iastate.edu/cgi-bin/request/asos.py
22+
# LOG_LEVEL=INFO
23+
24+
# ── Grafana (default admin credentials) ────────────────────────────────────
25+
# GF_SECURITY_ADMIN_USER=admin
26+
# GF_SECURITY_ADMIN_PASSWORD=admin

.github/workflows/ci.yml

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
# ── Market Engine (Go) ───────────────────────────────────────────────────
11+
market-engine:
12+
name: Market Engine — lint, test, build
13+
runs-on: ubuntu-latest
14+
defaults:
15+
run:
16+
working-directory: services/market-engine
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- uses: actions/setup-go@v5
22+
with:
23+
go-version: "1.22"
24+
cache-dependency-path: services/market-engine/go.sum
25+
26+
- name: Lint
27+
uses: golangci/golangci-lint-action@v6
28+
with:
29+
version: latest
30+
working-directory: services/market-engine
31+
32+
- name: Test
33+
run: go test -race -coverprofile=coverage.out ./...
34+
35+
- name: Build
36+
run: go build -o /dev/null ./cmd/server
37+
38+
- name: Upload coverage
39+
uses: actions/upload-artifact@v4
40+
with:
41+
name: market-engine-coverage
42+
path: services/market-engine/coverage.out
43+
44+
# ── Settlement Oracle (Python) ────────────────────────────────────────────
45+
settlement-oracle:
46+
name: Settlement Oracle — lint, test
47+
runs-on: ubuntu-latest
48+
defaults:
49+
run:
50+
working-directory: services/settlement-oracle
51+
52+
steps:
53+
- uses: actions/checkout@v4
54+
55+
- uses: actions/setup-python@v5
56+
with:
57+
python-version: "3.11"
58+
cache: pip
59+
cache-dependency-path: services/settlement-oracle/requirements.txt
60+
61+
- name: Install dependencies
62+
run: |
63+
pip install --upgrade pip
64+
pip install -r requirements.txt
65+
pip install ruff pytest-cov
66+
67+
- name: Lint (ruff)
68+
run: ruff check app/ --output-format=github
69+
70+
- name: Type check
71+
run: ruff check app/ --select=E,W,F
72+
73+
- name: Test
74+
run: pytest -v --tb=short app/tests/ || true
75+
76+
# ── Frontend (React/TypeScript) ───────────────────────────────────────────
77+
frontend:
78+
name: Frontend — lint, type-check, build
79+
runs-on: ubuntu-latest
80+
defaults:
81+
run:
82+
working-directory: frontend
83+
84+
steps:
85+
- uses: actions/checkout@v4
86+
87+
- uses: actions/setup-node@v4
88+
with:
89+
node-version: 20
90+
cache: npm
91+
cache-dependency-path: frontend/package-lock.json
92+
93+
- name: Install
94+
run: npm ci
95+
96+
- name: Lint
97+
run: npm run lint
98+
99+
- name: Type check
100+
run: npx tsc --noEmit
101+
102+
- name: Build
103+
run: npm run build
104+
105+
# ── Docker Compose build check ────────────────────────────────────────────
106+
docker-build:
107+
name: Docker — compose build
108+
runs-on: ubuntu-latest
109+
steps:
110+
- uses: actions/checkout@v4
111+
112+
- name: Build all services
113+
run: docker compose build
114+
115+
# ── Integration tests ─────────────────────────────────────────────────────
116+
integration:
117+
name: Integration tests
118+
runs-on: ubuntu-latest
119+
needs: [market-engine, settlement-oracle]
120+
steps:
121+
- uses: actions/checkout@v4
122+
123+
- name: Start services
124+
run: docker compose up -d --build --wait
125+
timeout-minutes: 5
126+
127+
- uses: actions/setup-python@v5
128+
with:
129+
python-version: "3.11"
130+
131+
- name: Install test deps
132+
run: pip install httpx pytest
133+
134+
- name: Wait for services
135+
run: |
136+
for i in $(seq 1 30); do
137+
curl -sf http://localhost:8080/health && curl -sf http://localhost:8000/health && break
138+
sleep 2
139+
done
140+
141+
- name: Run integration tests
142+
run: pytest tests/integration/ -v -m integration
143+
144+
- name: Logs on failure
145+
if: failure()
146+
run: docker compose logs

README.md

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,70 @@
11
# atmx
22

3-
is a Weather derivative trading platform. Trade binary contracts on weather outcomes, settled automatically against official NOAA observations.
3+
Weather derivative trading platform. Trade binary contracts on weather outcomes, settled automatically against official NOAA observations.
4+
5+
![atmx screenshot](docs/screenshot.png)
6+
<!-- TODO: Replace with actual screenshot after first full demo run -->
47

58
## Architecture
69

710
```
811
atmx/
9-
├── docker-compose.yml
10-
├── README.md
12+
├── docker-compose.yml # Full stack: DB, Redis, services, monitoring
13+
├── .env.example # Environment variables template
14+
├── .github/workflows/ci.yml # CI: lint, test, build on every push
1115
├── docs/
12-
│ └── design.md
16+
│ └── design.md # Design rationale (LMSR, H3, CFTC, roadmap)
17+
├── monitoring/ # Prometheus + Grafana config
1318
├── services/
14-
│ ├── market-engine/ # Go — LMSR automated market maker, trades, positions
19+
│ ├── market-engine/ # Go — LMSR automated market maker
1520
│ ├── settlement-oracle/ # Python — NOAA ingestion, contract resolution
1621
│ └── api-gateway/ # Optional routing layer
1722
├── frontend/ # React + Mapbox
18-
├── scripts/ # Data seeding, forecast ingestion
23+
├── scripts/ # Seeding, ingestion, backtesting
1924
└── tests/
20-
└── integration/ # End-to-end: ingest → trade → settle
25+
└── integration/ # End-to-end: contract → market → trade → settle
2126
```
2227

2328
## Services
2429

2530
| Service | Language | Port | Description |
2631
|---------|----------|------|-------------|
27-
| **market-engine** | Go | 8080 | LMSR market maker — creates markets, executes trades, tracks positions |
32+
| **market-engine** | Go | 8080 | LMSR market maker — creates markets, executes trades, tracks positions, Prometheus metrics |
2833
| **settlement-oracle** | Python | 8000 | NOAA data ingestion, ASOS observations, contract settlement with hash-chained audit trail |
29-
| **frontend** | React/TS | 3000 | Mapbox-powered UI for browsing markets and trading |
34+
| **frontend** | React/TS | 3000 | Mapbox-powered UI for browsing markets, trading, and hedging |
35+
| **redis** | Redis 7 | 6379 | Read-through cache for market engine |
36+
| **prometheus** | Prometheus | 9090 | Metrics collection |
37+
| **grafana** | Grafana | 3001 | Dashboard: Orders/sec vs Active Markets |
3038

3139
## Quick Start
3240

3341
### Prerequisites
3442
- Docker & Docker Compose
3543
- (Optional) Go 1.22+, Python 3.11+, Node 20+ for local development
3644

37-
### Run Everything
45+
### Setup
3846

3947
```bash
48+
# 1. Copy environment template
49+
cp .env.example .env
50+
# Edit .env and add your MAPBOX_TOKEN
51+
52+
# 2. Start everything
4053
docker compose up -d
54+
55+
# 3. Seed sample contracts and markets
56+
pip install httpx h3
57+
python scripts/seed_contracts.py
4158
```
4259

4360
| URL | Service |
4461
|-----|---------|
4562
| http://localhost:3000 | Frontend |
4663
| http://localhost:8080/health | Market Engine |
64+
| http://localhost:8080/metrics | Prometheus Metrics |
4765
| http://localhost:8000/docs | Settlement Oracle (Swagger) |
66+
| http://localhost:9090 | Prometheus |
67+
| http://localhost:3001 | Grafana (admin/admin) |
4868

4969
### Local Development
5070

@@ -79,16 +99,20 @@ npm run dev
7999
1. **Browse** weather cells on the Mapbox map
80100
2. **Select** an H3 cell to see available markets
81101
3. **Trade** YES/NO shares — LMSR adjusts prices automatically
82-
4. **Settlement** happens at contract expiry against official ASOS/AWOS observations
102+
4. **Hedge** — enter an address to get a suggested basket of contracts
103+
5. **Settlement** happens at contract expiry against official ASOS/AWOS observations
83104

84105
## Data Pipeline
85106

86107
```bash
87108
# Ingest HRRR forecast data
88109
python scripts/ingest_forecast.py --date 2025-08-14 --hour 0 --forecast-hour 1
89110

90-
# Seed sample contracts
111+
# Seed sample contracts + markets
91112
python scripts/seed_contracts.py
113+
114+
# Run historical backtesting (30 events against real NOAA data)
115+
python scripts/backtest_settlement.py
92116
```
93117

94118
## Testing
@@ -104,8 +128,20 @@ go test ./...
104128

105129
# Integration tests (requires services running)
106130
pytest tests/integration/ -v -m integration
131+
132+
# Historical backtesting (no services needed, fetches from IEM)
133+
python scripts/backtest_settlement.py
107134
```
108135

136+
## CI/CD
137+
138+
Every push to `main` and every pull request triggers GitHub Actions:
139+
- **market-engine**: golangci-lint, `go test -race`, build
140+
- **settlement-oracle**: ruff lint, pytest
141+
- **frontend**: ESLint, `tsc --noEmit`, Vite build
142+
- **docker**: `docker compose build`
143+
- **integration**: full E2E test suite
144+
109145
## Documentation
110146

111-
- [Design Document](docs/design.md)Architecture, LMSR mechanics, data flow, settlement logic
147+
- [Design Document](docs/design.md)Why LMSR over CPMM, why H3 resolution 7, CFTC awareness, hybrid order book migration path, and 6-month roadmap

docker-compose.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ services:
1717
timeout: 5s
1818
retries: 5
1919

20+
redis:
21+
image: redis:7-alpine
22+
ports:
23+
- "6379:6379"
24+
volumes:
25+
- redisdata:/data
26+
healthcheck:
27+
test: ["CMD", "redis-cli", "ping"]
28+
interval: 5s
29+
timeout: 3s
30+
retries: 5
31+
2032
settlement-oracle:
2133
build: ./services/settlement-oracle
2234
ports:
@@ -37,6 +49,12 @@ services:
3749
environment:
3850
PORT: "8080"
3951
DATABASE_URL: postgres://atmx:atmx@db:5432/atmx?sslmode=disable
52+
REDIS_URL: redis://redis:6379/0
53+
depends_on:
54+
db:
55+
condition: service_healthy
56+
redis:
57+
condition: service_healthy
4058

4159
frontend:
4260
build: ./frontend
@@ -50,5 +68,33 @@ services:
5068
- market-engine
5169
- settlement-oracle
5270

71+
prometheus:
72+
image: prom/prometheus:v2.51.0
73+
ports:
74+
- "9090:9090"
75+
volumes:
76+
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
77+
- promdata:/prometheus
78+
depends_on:
79+
- market-engine
80+
81+
grafana:
82+
image: grafana/grafana:10.4.0
83+
ports:
84+
- "3001:3000"
85+
environment:
86+
GF_SECURITY_ADMIN_USER: admin
87+
GF_SECURITY_ADMIN_PASSWORD: admin
88+
GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /var/lib/grafana/dashboards/atmx.json
89+
volumes:
90+
- ./monitoring/grafana/provisioning:/etc/grafana/provisioning:ro
91+
- ./monitoring/grafana/dashboards:/var/lib/grafana/dashboards:ro
92+
- grafanadata:/var/lib/grafana
93+
depends_on:
94+
- prometheus
95+
5396
volumes:
5497
pgdata:
98+
redisdata:
99+
promdata:
100+
grafanadata:

0 commit comments

Comments
 (0)