CS Thesis · Full-Stack + ML
Edge
Multi-tier forex market scanner with macroeconomic scoring & GBDT signal layer

What it is
Edge (deployed as 8ConEdge) is my Computer Science thesis: a full-stack SaaS platform that ranks forex currency pairs by macroeconomic-indicator consensus and augments those signals with a Python GBDT model. Users sign in, browse a “Top Setups” leaderboard of pairs scored from −10 to +10, drill into a per-pair profile (score breakdown, OHLC chart, ML conviction reading), and — depending on their tier — export the analysis to PDF / DOCX / XLSX. Role- and tier-gated access, session security, payment-receipt uploads, and a four-service Docker production deploy behind Nginx. This project won Best Thesis 2026 (BSCS).
The Signal — How Pairs Are Ranked
For each currency pair the engine pulls nine macro indicators for both the base and quote currencies, scores each +1 / 0 / −1 by comparing actual vs. forecast, then aggregates with a fixed weight per indicator into a normalized totalScore in [−10, +10].
| Indicator | Weight | Scoring |
|---|---|---|
| Interest Rate | 3.0 | vs. forecast |
| Core Inflation | 2.5 | vs. forecast |
| Employment Change | 2.0 | beats / misses forecast |
| GDP Growth | 2.0 | beat / miss |
| COT (net change %) | 1.8 | positional bias |
| Unemployment Rate | 1.5 | inverse: lower = +1 |
| Manufacturing PMI | 1.2 | beat / miss |
| Services PMI | 1.2 | beat / miss |
| Retail Sales | 1.0 | beat / miss |
The ML Layer
A separate Python Flask service (port 5001) runs two pre-trained Gradient Boosted Decision Tree models on top of the rule-based scores: conviction_regressor.pkl outputs how strongly to trust the signal for a given regime, and regime_classifier.pkl labels the current market regime. The Node API proxies requests to this service so the React frontend talks to a single domain. Training data lives as synthetic_training_data.csv; train_gbdt.py regenerates the models.
System Architecture
Browser (React 19 + Vite + Tailwind + Framer Motion) │ ▼ Nginx reverse proxy (production) ─── or ─── Vite proxy (dev) │ ├──► Express Main API (Node, :3000) ── pool8con (users, profiles, assets) │ └─ pool8cons (payments, OTP, registrations) │ ├──► Express Enrollment (Node, :3001) ── signup · OTP · password reset │ │ │ └── nodemailer → SMTP │ └──► Python AI Server (Flask, :5001) ── GBDT (conviction + regime) · scaler dev: 4 services run concurrently (concurrently --names BACKEND,ENROLL,VITE,AI-GBDT) prod: docker-compose orchestrates all four behind Nginx + certbot TLS
Tech Stack
| Frontend | React 19 · Vite 6 · React Router 7 · TailwindCSS 4 · Framer Motion · Recharts · react-financial-charts (OHLC) · lucide-react |
| Main API | Express 5 · MySQL 2 (two pools) · express-session · helmet · express-rate-limit · express-validator · multer |
| Auth API | Express 5 (separate process) · bcrypt · JWT · nodemailer (OTP delivery) |
| ML Server | Python 3 · Flask · scikit-learn (GBDT) · joblib · pandas · numpy |
| Data | MySQL — two databases: 8con (accounts, assets) and 8cons (payments, OTP) |
| Document Export | jsPDF + jspdf-autotable · docx · exceljs (PDF / DOCX / XLSX) |
| Production | Docker + docker-compose · Nginx reverse proxy · certbot TLS · self-managed VPS |
Engineering Decisions
- ›Two-dimension access control. Users have a role (student / teacher / admin) and an orthogonal tier (basic / full, payment-gated). RoleRoute guards admin pages; tier guards dashboard features. useAccessControl hits sessionStorage first then verifies with the backend, so guard re-renders are instant after the first check.
- ›Session security beyond the basics. A 15-minute idle timer triggers a 2-minute warning modal then auto-logout, with a 4-minute heartbeat to /api/session/heartbeat keeping live sessions alive. Single-tab enforcement uses a BroadcastChannel + localStorage heartbeat so opening a second tab kicks the first — protects shared accounts in lab/classroom contexts.
- ›Two MySQL databases on purpose. pool8con serves user-facing data (accounts, assets); pool8cons serves payments, OTP records, and registrations. Splitting concerns across pools means a payments outage can't take down the dashboard.
- ›Multi-format export. Reports can be downloaded as PDF (jspdf-autotable), DOCX (docx), or XLSX (exceljs) so users can drop them straight into whatever workflow they're using.
- ›Production hardening from day 1. helmet (security headers), express-rate-limit (anti-bruteforce), express-validator (input validation), cors — all wired in from the initial commit instead of bolted on later.