Pattern Forge
Replay without look-ahead: later candles stay out of the indicators. CI runs tests, Docker and a PostgreSQL restart. The public demo does not serve that database.
React · TypeScript · Next.js · WebSockets
The problem
When reviewing a market, it is easy to let later prices influence an earlier decision. I wanted to inspect what an indicator could actually have shown at a chosen point in time.
My contribution
I built the market controls, data validation, replay calculations, candle API and connection handling. TradingView Lightweight Charts renders the chart; I did not build that charting library.
Skills this work used
| Skill | Where it was used |
|---|---|
| React and TypeScript | Workspace controls, loading and error states, replay slider and timeframe compare. |
| Next.js candle API | Validates markets and closed candles before anything reaches the chart. |
| WebSockets | A separate live mid-price with heartbeat and reconnection. Not the replay source. |
| PostgreSQL | Local/CI persistence of closed candles and ingest runs. The public demo does not serve that database. |
| Docker and GitHub Actions | Image build, tests and a restart check that the stored rows survive. |
Try it step by step
- Open the workspace. Bitcoin loads by default. The live mid-price changes automatically; the candle chart is a separate snapshot.
- Choose a timeframe or select a recorded market such as Gold. Recorded markets are labelled Historical recording.
- Move the Replay slider left, then advance a candle at a time. Later candles stay out of indicator calculations.
- Choose Compare timeframes to see which complete higher-timeframe candles were available at that point.
- Export the selected data prefix. Refresh reloads public candles; it does not turn an archive into a live feed.
What depends on what
| Component | Depends on | Responsibility |
|---|---|---|
| React workspace | Candle API and local analysis functions | Selection, chart controls and loading/error states. |
| Next.js candle API | Fixed Hyperliquid HTTP endpoint | Validates supported markets and closed candles; shares concurrent requests and caches successful snapshots in process memory. |
| Live quote connection | Hyperliquid public WebSocket | A separate mid-price with receipt time, heartbeat and reconnection. No trading account. |
| Recorded replay | Bundled OHLC JSON and the replay cursor | Only the selected prefix reaches indicators and timeframe aggregation. |
| Chart rendering | TradingView Lightweight Charts | Candles, overlays and chart interaction. |
| Python ingester (local/CI) | Validated public candles or a recorded fixture, psycopg and PostgreSQL | Writes closed candles; records each attempt and its fetch/write timing. |
How the data was organised
Closed candles and ingest runs can be stored in PostgreSQL locally and in CI. The public demo uses recording files and process memory; it does not serve that database.
| Record | Depends on | Responsibility |
|---|---|---|
| candles table | Primary key (symbol, interval, open_time) | Prevents duplicate rows on repeated ingestion; stores OHLCV values and ingestion time. |
| ingest_runs table | Each ingestion attempt | Stores source, row counts, timing and errors separately from candle data. |
| Stored-candle API (local/CI) | PostgreSQL through the pg client and DATABASE_URL | Reads saved candles into the existing chart. An empty store returns 404; an unavailable database returns 503. |
| Public demo storage | Recording files and temporary process memory | No user accounts and no hosted PostgreSQL on Vercel. |
Implementation, step by step
- Define a candle format with timestamps and OHLC values.
- Reject malformed, conflicting and still-forming candles at the boundary.
- Calculate indicators from the selected prefix, then render the result in React.
- Keep the streaming mid-price separate from historical calculations.
- Test malformed inputs, partial upstream failures, replay causality and connection cleanup; build and run the Docker image in CI.
Run the public code locally
npm ci
npm test
npm run build
npm startUse the repository README for environment setup and supported versions.
Limits and unfinished work
The quote timestamp is local receipt time, not an exchange-latency benchmark. Public candles update on Refresh. The oil and other archive datasets are recordings. The repository also includes PostgreSQL persistence for local Docker and CI; the public Vercel demo does not serve that database. The README explains ingestion, duplicate handling and restart checks. This is a read-only analysis tool, not a trading terminal or a profitable strategy.