← Jordi Lluis / Projects

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

Tools and what they did in this project
SkillWhere it was used
React and TypeScriptWorkspace controls, loading and error states, replay slider and timeframe compare.
Next.js candle APIValidates markets and closed candles before anything reaches the chart.
WebSocketsA separate live mid-price with heartbeat and reconnection. Not the replay source.
PostgreSQLLocal/CI persistence of closed candles and ingest runs. The public demo does not serve that database.
Docker and GitHub ActionsImage build, tests and a restart check that the stored rows survive.

Try it step by step

  1. Open the workspace. Bitcoin loads by default. The live mid-price changes automatically; the candle chart is a separate snapshot.
  2. Choose a timeframe or select a recorded market such as Gold. Recorded markets are labelled Historical recording.
  3. Move the Replay slider left, then advance a candle at a time. Later candles stay out of indicator calculations.
  4. Choose Compare timeframes to see which complete higher-timeframe candles were available at that point.
  5. Export the selected data prefix. Refresh reloads public candles; it does not turn an archive into a live feed.

What depends on what

Components, dependencies and responsibility
ComponentDepends onResponsibility
React workspaceCandle API and local analysis functionsSelection, chart controls and loading/error states.
Next.js candle APIFixed Hyperliquid HTTP endpointValidates supported markets and closed candles; shares concurrent requests and caches successful snapshots in process memory.
Live quote connectionHyperliquid public WebSocketA separate mid-price with receipt time, heartbeat and reconnection. No trading account.
Recorded replayBundled OHLC JSON and the replay cursorOnly the selected prefix reaches indicators and timeframe aggregation.
Chart renderingTradingView Lightweight ChartsCandles, overlays and chart interaction.
Python ingester (local/CI)Validated public candles or a recorded fixture, psycopg and PostgreSQLWrites 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.

Stored records, keys and responsibility
RecordDepends onResponsibility
candles tablePrimary key (symbol, interval, open_time)Prevents duplicate rows on repeated ingestion; stores OHLCV values and ingestion time.
ingest_runs tableEach ingestion attemptStores source, row counts, timing and errors separately from candle data.
Stored-candle API (local/CI)PostgreSQL through the pg client and DATABASE_URLReads saved candles into the existing chart. An empty store returns 404; an unavailable database returns 503.
Public demo storageRecording files and temporary process memoryNo user accounts and no hosted PostgreSQL on Vercel.

Implementation, step by step

  1. Define a candle format with timestamps and OHLC values.
  2. Reject malformed, conflicting and still-forming candles at the boundary.
  3. Calculate indicators from the selected prefix, then render the result in React.
  4. Keep the streaming mid-price separate from historical calculations.
  5. 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 start

Use 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.