chart.amow.com — FastAPI + Vue3 app
Find a file
Chris Amow 8e50d5cbc2 Add implementation plan for /ES multi-timeframe confluence chart
Planning-only commit: no application code yet.

The plan specifies a realtime /ES chart that derives moving averages and
trendlines across multiple timeframes, projects them onto one chart in a
shared (time, price) plane, and alerts when levels from different
timeframes converge.

Key findings that shaped it, all verified against source rather than
assumed:

- Schwab streams realtime futures fine (CHART_FUTURES, LEVEL_ONE_FUTURES)
  but provides no futures price *history* at all. An account does not
  change this; it is an API-surface limit.
- Yahoo's chart endpoint needs no key and has exactly what Schwab lacks:
  ~730d of hourly ES=F (~750 sessions), enough to warm a 200DMA from
  startup. So it serves as both the no-keys dev source and the history
  seeder, behind one MarketDataSource protocol.
- Yahoo anchors daily bars to midnight ET while the CME session runs
  18:00-17:00 ET, so daily bars are built from hourly using our own
  session rules instead.
- Lightweight Charts v5 replaced addCandlestickSeries() with
  addSeries(CandlestickSeries, ...); most tutorials online are v4.

Build order defers judgment-heavy work: moving averages first (fully
deterministic), then confluence scoring, then hand-drawn trendlines.
Automatic trendline detection comes last, tuned against the hand-drawn
lines as ground truth.

Includes a real trimmed Yahoo response as a test fixture; it contains a
null in the OHLC arrays, which is the parsing case that needs handling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 20:31:40 -05:00
docs Add implementation plan for /ES multi-timeframe confluence chart 2026-08-09 20:31:40 -05:00
static Scaffold FastAPI + Vue3 placeholder app with local docker compose stack 2026-08-09 23:34:01 +00:00
tests/fixtures Add implementation plan for /ES multi-timeframe confluence chart 2026-08-09 20:31:40 -05:00
.gitignore Scaffold FastAPI + Vue3 placeholder app with local docker compose stack 2026-08-09 23:34:01 +00:00
docker-compose.yml Make local compose host port overridable; record Coolify UUID in README 2026-08-09 23:38:33 +00:00
Dockerfile.dev Scaffold FastAPI + Vue3 placeholder app with local docker compose stack 2026-08-09 23:34:01 +00:00
main.py test 2026-08-09 20:02:03 -05:00
Procfile Scaffold FastAPI + Vue3 placeholder app with local docker compose stack 2026-08-09 23:34:01 +00:00
README.md Add implementation plan for /ES multi-timeframe confluence chart 2026-08-09 20:31:40 -05:00
requirements.txt Scaffold FastAPI + Vue3 placeholder app with local docker compose stack 2026-08-09 23:34:01 +00:00

chart

FastAPI backend + Vue 3 (from CDN, no build step) served at https://chart.amow.com.

Currently a placeholder: the frontend calls /api/hello and prints the JSON.

Where this is going: a realtime /ES chart that derives trendlines and moving averages across many timeframes and alerts when they converge. The full spec lives in docs/IMPLEMENTATION_PLAN.md — read it before writing code; it records decisions and verified API facts that are expensive to rediscover.

Local development

docker compose up --build

Then open http://localhost:8000. Override the host port with PORT=8010 docker compose up if 8000 is busy — on the VPS itself it always is, that's the Coolify UI. The source tree is bind-mounted and uvicorn runs with --reload, so edits to main.py or static/ take effect without a rebuild. Rebuild only when requirements.txt changes.

Without Docker:

python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload

Layout

Path Purpose
main.py FastAPI app — JSON under /api, serves the SPA at /
static/ index.html, app.js, style.css — Vue 3 loaded from unpkg
requirements.txt Python deps
Procfile Start command; nixpacks needs this or the deploy has nothing to run
Dockerfile.dev, docker-compose.yml Local dev only — production does not use them

Deployment

Push to main → Forgejo webhook → Coolify rebuilds with nixpacks → live in roughly 25 seconds.

git push

Two things to know before changing the deploy config:

  • The Coolify domain is registered as https://chart.amow.com:8000. The port suffix is how Coolify decides the Traefik target port; drop it and every request 502s while the container looks perfectly healthy. It does not appear in the public URL.
  • Ignore a 502 in the first minute after a deploy — that's the rolling container swap, and it clears on its own.

Manual redeploy:

curl -X POST -H "Authorization: Bearer $(cat ~/.coolify-token)" \
  "http://127.0.0.1:8000/api/v1/deploy?uuid=dgvch0xqv8uvjfor7dl8bwl9&force=true"