BACKEND & API ENGINEER
← All work

[ Python ] 4 of 6

Trading Suite

Self-hosted IDX market desk: FastAPI over a SQLite WAL cache, five UI routes.

./trading-suite run
39 passedBackend test suite
900+ tickersIDX universe in config
22 apps to 5UI routes after lean pass
~963Rows per IDX summary call
  • Python
  • FastAPI
  • Next.js
  • TypeScript
  • SQLite

[ 01 ] WHAT IT IS

In plain words

A self-hosted desk for the Indonesian stock market (IDX). It pulls quotes, history, foreign flow and broker activity from public feeds, caches them, and turns them into five screens: an overview, a charting page with foreign-flow bars, a streaming screener, a per-ticker profiler, and calculators.

It is for one person or a small team who wants their own copy of the market data rather than a subscription, and who is happy to run a backend and a front end on their own machine.

Nothing is stored in a company cloud: quotes live in a local SQLite WAL cache under backend/data/cache.db, and the only outbound calls are to the public data sources.

[ 02 ] ARCHITECTURE

How it is put together

  • backend/app/main.py wires FastAPI routers from backend/app/routers/ (market, screener, validator, intel, analysis, regime, backtest, portfolio, summary, alerts, sentiment); services live one level up in backend/app/*.py. The front end is Next.js 16 app-router routes in src/app/{overview,markets,screener,profiler,calculators}, with the nav generated from one source in src/lib/apps.ts.
  • Screener: backend/app/screener.py with backend/app/routers/screener.py streams results over SSE at GET /api/screener/scan/stream, and the suspended-ticker filter runs in backend/app/idx.py before the ThreadPool fan-out so excluded names are never fetched.
  • Bandarmology (Indonesian broker-flow analysis) is the strongest single feature: backend/app/validator.py holds BandarmologyAnalyzer (phase, intent radar, flow metrics), served by backend/app/routers/validator.py at GET /api/validator/{ticker} and rendered inside the profiler page at src/app/profiler/page.tsx.
  • FIFO portfolio P/L is a real engine - backend/app/_fifo.py holds FIFOEngine and JSON load/save, called only by backend/app/portfolio.py - but it is API-only: next.config.ts redirects /portfolio to /profiler, so there is no standalone portfolio screen.
  • Backtesting is backend/app/backtest.py (pattern_backtests) behind GET /api/analysis/backtest/{ticker} in backend/app/routers/analysis.py - likewise API-only, since /backtest redirects to /profiler.
  • Caching is the seam that makes it cheap: backend/app/cache.py plus backend/app/db.py give per-feed TTLs in a SQLite WAL file with stale-while-revalidate and _spawn_refresh dedupe; the front end mirrors it in src/lib/cache.ts (memory + sessionStorage).

[ 03 ] INSTALL

Set it up

cd backend
python -m venv .venv
.venv/bin/pip install -r requirements.txt
cp ../.env.example .env   # optional; runs empty
cd .. && npm install

[ 04 ] QUICKSTART

See it work

  1. Start both halves with the runner from the repo root: chmod +x ./trading-suite && ./trading-suite run (backend on :8000, front end on :3000).
  2. Open http://localhost:3000 - the launcher shows exactly five cards: Overview, Markets, Screener, Profiler, Calculators.
  3. Go to /screener: the scan streams in over SSE rather than waiting for one big payload.
  4. Open /profiler?ticker=BBCA - one screen showing quote, candles, beta, regime, the bandarmology phase, the intent radar, the broker panel and an entry plan.
  5. Check the backend directly at http://127.0.0.1:8000/api/health, and browse the auto-generated API at http://127.0.0.1:8000/docs.

[ 05 ] NUMBERS

What the repo states

Backend test suite

REPO STATES

39 passed

IDX universe in config

REPO STATES

900+ tickers

UI routes after lean pass

REPO STATES

22 apps to 5

Rows per IDX summary call

REPO STATES

~963

[ 06 ] TRADEOFFS

What it does not do

  1. AI-generated summaries are not a working feature any more: backend/app/ai.py is an explicit no-op stub ('AI section has been dismantled'), it returns None and nothing imports it, so every caller falls back to deterministic text - the README's OPENCODE_GO_API_KEY row is stale and was left out of the claims above.
  2. FIFO portfolio tracking and pattern backtesting are backend-only: next.config.ts hard-redirects /portfolio and /backtest to /profiler, so both show up as API endpoints rather than screens.
  3. Broker data is best-effort and partly credentialed: the Stockbit panel needs STOCKBIT_JWT_TOKEN (or user/password) and shows a degraded message without it.
  4. Accuracy is bounded by third-party sources - an IDX summary endpoint scraped with curl_cffi, yfinance .JK history, and TradingView - so the numbers are cached copies of someone else's feed, not an exchange-grade tick store.

[ 07 ] SOURCE

Read the code

The full implementation, tests and documentation live in the repository.