System Architecture
Overview
TradeEntry is a full-stack web application built with a decoupled frontend/backend architecture.
┌───────────────────────────────────────────┐
│ Browser (User) │
│ React 18 + TypeScript │
│ Vite + Tailwind + ShadCN │
└──────────────────┬────────────────────────┘
│ HTTP / REST
┌──────────────────▼────────────────────────┐
│ FastAPI (Python 3.11+) │
│ Uvicorn ASGI server │
│ SQLAlchemy (async) │
│ Pydantic v2 models │
└──────────────────┬────────────────────────┘
│ psycopg2 / asyncpg
┌──────────────────▼────────────────────────┐
│ PostgreSQL 14+ │
│ NSE EOD tables (EQ + FO) │
│ Trade journal tables │
└───────────────────────────────────────────┘
Core Components
Frontend (/frontend)
| Component | Technology |
|---|---|
| Framework | React 18 + TypeScript |
| Build Tool | Vite |
| UI Library | ShadCN / Radix UI + Tailwind CSS |
| State | React Hooks (useState, useCallback, useRef) |
| HTTP Client | Axios (src/services/api.js) |
| Charting | Lightweight Charts |
Backend (/backend)
| Component | Technology |
|---|---|
| Framework | FastAPI |
| ASGI Server | Uvicorn |
| ORM | SQLAlchemy (async) + psycopg2 (sync tasks) |
| Task Queue | FastAPI BackgroundTasks |
| Data Processing | pandas, numpy |
| NSE Data | Custom nseeod package |
Data Pipeline (/backend/nseeod)
The nseeod package handles all NSE data ingestion:
NSE Website
│
▼
BhavProcessor.run_update()
├── NseEodEqUpdater.update() → scr_nseeq_eod table
├── NseEodFoUpdater.update() → scr_nsefo_eod table
└── bhav.generateamiformat() → .txt AMI export files
Key Design Decisions
- Background Tasks over Celery — Simple
BackgroundTasksused for bhav downloads to avoid Redis/Celery infrastructure complexity. - File-based Status (stats.json) — Progress and logs written to
stats.jsonfor polling by the frontend, since WebSocket was not required. - Separate AMI Path — AmiBroker export files stored separately from CSV/bhav copies to allow independent cleanup.
- Direct psycopg2 for Bulk Queries — Used alongside SQLAlchemy async for time-series queries that benefit from raw cursor performance.
Security Notes
- All AMI filenames validated with
re.compile(r"^\d{8}\.txt$")before serving. - Path traversal prevented via
os.path.basename()normalization. - No authentication implemented yet (planned for v2.0).
See Deployment Notes for production setup.