Final Year Research Project · CSE-25-26J-445 Sri Lanka Institute of Information Technology — Faculty of Computing · 2025/26
⚙️ Backend · |
🖥️ Frontend · |
| Nx applications | Trained models | REST endpoints | Test files | Docker containers | Annual reports in ETL |
The Colombo Stock Exchange has ~280 listed companies and almost no analytical tooling built for it. The data exists — filings, quarterly reports, financial news — but three properties break off-the-shelf models: Sri Lankan annual reports have no consistent layout, only a minority publish machine-extractable reports across a decade, and market-moving news mixes English with Sinhala and Tamil transliterations and local company nicknames.
Our position: a prediction an investor cannot interrogate is not usable. Every model here ships with its reasoning exposed — SHAP attributions, printed decision trees with real fusion weights, KaTeX feature derivations, retrieved historical precedents. Explainability is the deliverable, not a feature.
Live market dashboard — ASPI · S&P SL20 · sector performance · gainers and losers · CSE news pulled live from cse.lk
More screenshots — SHAP ratios · dividend features · AI narrative · Swagger · light mode · mobile
![]() AI-extracted financial ratios |
![]() Per-feature dividend contributions |
![]() LLM narrative over the prediction |
![]() Multi-company dividend comparison |
![]() Full light/dark parity |
![]() Mobile-first responsive |
Four members, four independently trained and evaluated models, one shared platform.
| Component | Method | Key result | |
|---|---|---|---|
| 🩺 | Financial Distress | SVR projecting next-quarter Altman Z-Score from 9 ratios, explained with a SHAP KernelExplainer. Ratios extracted by sending raw PDFs to Gemini's File API rather than parsing them. |
Safe / Grey / Distress with per-feature signed attribution |
| 📈 | Open Price Forecast | Equal-weight ensemble of LightGBM + XGBoost + CatBoost over 28 engineered technical features, 60-day lookback, log-returns clamped at ±0.15 | T+5 open-price path with SHAP feature importance |
| 💰 | Dividend Cut | Elastic-net Logistic Regression on 14 features engineered from 8 balance-sheet fields; temporal split at 2021, minority class weighted 3× | 82.1 % accuracy · AUC 0.697 · threshold 0.822 · n=140 |
| 📰 | News Market-Impact | Two-stage XGBoost cascade over 3072-d embeddings, fused with a financial lexicon, grounded by FAISS retrieval; a spaCy + RapidFuzz company gate runs before any paid inference | Impact flag + direction + 4-step decision tree + historical precedents |
📐 Model specifications
| Risk | Open Price | Dividend | Sentiment | |
|---|---|---|---|---|
| Algorithm | SVR | LightGBM + XGBoost + CatBoost | Logistic Regression | XGBoost ×2 + lexicon |
| Preprocessing | StandardScaler | 28-feature engineering | 14-feature engineering | text-embedding-3-large (3072-d) |
| Target | Next-quarter Z-Score | T+5 open price | P(dividend cut) | Impact + direction |
| Key hyperparameters | — | equal-weight ensemble | C=0.05, l1_ratio=0.2, saga, class_weight {0:1, 1:3}, max_iter=20000 |
Stage 1 threshold 0.30; fusion 0.6/0.4 when lex_conf ≥ 0.60, else 0.7/0.3 |
| Validation | — | held-out test set | temporal split, train cutoff 2021 | held-out + lexicon cross-check |
| Explainability | SHAP KernelExplainer, k-means background (k=10) | SHAP feature importance | KaTeX feature derivations + LLM narrative | printed decision tree + FAISS precedents |
| Serving | Flask · :5001 |
FastAPI · :5002 |
FastAPI · :8001 |
FastAPI · :8002 |
Why these choices: CSE liquidity is thin and volatility regime-dependent, so three price models disagree and average. Only ~19 companies publish extractable reports across 2012–2025, so the dividend model has 140 samples — at the default 0.5 threshold it cried wolf, hence 0.822. The lexicon is precise but brittle and the embedding model general but opaque, so the lexicon leads only when confident (≥ 0.60).
Four research tracks share one ingestion layer, one auth boundary, and one API contract — the separation that let them be developed in parallel.
graph TB
subgraph FE["Frontend · Next.js 16 + React 19"]
direction LR
UI1["Market<br/>Dashboard"]
UI2["Risk<br/>Analysis"]
UI3["Price<br/>Prediction"]
UI4["Dividend<br/>Prediction"]
UI5["News<br/>Sentiment"]
end
GW["<b>API Gateway</b> · NestJS · :3400<br/>JWT · RBAC · Subscription tiers · OpenAPI 3"]
subgraph MESH["gRPC Service Mesh · NestJS"]
direction LR
M1["Auth<br/>OTP · OAuth"]
M2["User<br/>Profiles"]
M3["Community<br/>Social"]
M4["Logs<br/>Audit"]
end
subgraph ML["ML Inference · Python"]
direction LR
R1["<b>Risk</b><br/>SVR + SHAP"]
R2["<b>Open Price</b><br/>3-model ensemble"]
R3["<b>Dividend</b><br/>Elastic-net"]
R4["<b>Sentiment</b><br/>2-stage + FAISS"]
end
subgraph ORCH["Orchestration"]
direction LR
O1["Financial Health<br/>6-stage SSE pipeline"]
O2["Payment<br/>PayHere"]
end
subgraph ASYNC["Async"]
K["Kafka"]
E["Email<br/>consumer"]
end
subgraph DATA["Data"]
direction LR
D1[("MongoDB")]
D2[("Redis")]
D3[("FAISS<br/>244 MB")]
D4[("PostgreSQL")]
end
subgraph ETL["Ingestion"]
direction LR
I1["Dividend ETL<br/>~240 annual reports<br/>YAML-pinned extraction"]
I2["News Scraper<br/>ft.lk RSS<br/>SHA-256 dedup"]
I3["cse.lk API<br/>live market data"]
end
FE -->|"REST + SSE"| GW
GW --> MESH
GW --> ML
GW --> ORCH
MESH -.-> K --> E
O2 -.-> K
O1 --> R1
MESH --> D1
ML --> D1
R3 --> D2
R4 --> D3
R2 --> D4
I1 --> D1
I2 --> D3
I3 --> FE
I3 --> O1
classDef fe fill:#7c3aed,stroke:#4c1d95,color:#fff
classDef gw fill:#a855f7,stroke:#6b21a8,stroke-width:3px,color:#fff
classDef mesh fill:#10b981,stroke:#065f46,color:#fff
classDef ml fill:#0ea5e9,stroke:#075985,color:#fff
classDef orch fill:#14b8a6,stroke:#115e59,color:#fff
classDef async fill:#f59e0b,stroke:#92400e,color:#fff
classDef data fill:#475569,stroke:#0f172a,color:#fff
classDef etl fill:#ec4899,stroke:#9d174d,color:#fff
class UI1,UI2,UI3,UI4,UI5 fe
class GW gw
class M1,M2,M3,M4 mesh
class R1,R2,R3,R4 ml
class O1,O2 orch
class K,E async
class D1,D2,D3,D4 data
class I1,I2,I3 etl
Four transports, deliberately. gRPC for the internal NestJS mesh (protobuf contracts make refactors safe) · HTTP/JSON at the Python boundary (an ML service shouldn't need a gRPC toolchain to be testable with curl) · Kafka for email (sign-up must never fail because SMTP is down) · SSE for long-running analysis (a 40-second wait becomes visible progress, with no WebSocket infrastructure).
# Backend — full stack including all ML services
git clone https://github.com/Research-SLIIT/Final-Year-Research_CSE-25-26J-445-Backend.git
cd Final-Year-Research_CSE-25-26J-445-Backend && git checkout dev-deploy
cp .env.example .env # fill in your values
docker compose --profile ml up -d # 14 containers
# Frontend
git clone https://github.com/Research-SLIIT/Final-Year-Research_CSE-25-26J-445-Frontend.git
cd Final-Year-Research_CSE-25-26J-445-Frontend && git checkout dev
pnpm install && pnpm dev # → http://localhost:3000Web app http://localhost:3000 · Swagger UI http://localhost:3400/api/v1
Tip
Allocate ≈ 11–12 GB of RAM to Docker before the first --profile ml run — the ML profile loads XGBoost boosters, a 3-model ensemble and a 244 MB FAISS index simultaneously; below that the Python containers are OOM-killed at startup and report unhealthy with no obvious error.
The stack starts without any LLM API keys. The dividend and sentiment services fall back to clearly labelled demo modes (every substituted stage marked demo_mode, so a demo result can never be mistaken for a real one) and every non-LLM path works fully.
Full setup, environment reference and troubleshooting live in each repository's README.
CSE-25-26J-445 · SLIIT Faculty of Computing · 2025/26
| Research Component | Backend | Frontend |
|---|---|---|
| 🩺 Financial Risk & Explainability | Risk-prediction-ml · financial-health-service |
/risk · Z-Score gauge · SHAP breakdown |
| 📈 Open Price Forecasting | open-price-prediction-ml |
/predict · forecast + delta charts |
| 💰 Dividend Cut Prediction | Dividend-prediction-ml · Dividend-ETL |
/dividend · feature cards · KaTeX |
| 📰 News Sentiment & Market Impact | sentiment-backend |
/news · AI terminal · decision tree |
| 🏗 Platform & Infrastructure | api-gateway · auth · user · community · email · payment · logs |
AppShell · auth store · /admin · /pricing |
Supervised by the SLIIT Faculty of Computing.
Released under the MIT License. Built for academic research — nothing here constitutes financial advice; the models are research artifacts trained on limited data, and their limitations are documented in each repository.
Sri Lanka Institute of Information Technology · Faculty of Computing · Final Year Research Project 2025/26
Colombo Stock Exchange · Explainable Machine Learning · Event-Driven Microservices
















