Back to Projects

CS Thesis · Full-Stack + ML

Edge

Multi-tier forex market scanner with macroeconomic scoring & GBDT signal layer

Edge forex market scanner demo

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

IndicatorWeightScoring
Interest Rate3.0vs. forecast
Core Inflation2.5vs. forecast
Employment Change2.0beats / misses forecast
GDP Growth2.0beat / miss
COT (net change %)1.8positional bias
Unemployment Rate1.5inverse: lower = +1
Manufacturing PMI1.2beat / miss
Services PMI1.2beat / miss
Retail Sales1.0beat / 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

FrontendReact 19 · Vite 6 · React Router 7 · TailwindCSS 4 · Framer Motion · Recharts · react-financial-charts (OHLC) · lucide-react
Main APIExpress 5 · MySQL 2 (two pools) · express-session · helmet · express-rate-limit · express-validator · multer
Auth APIExpress 5 (separate process) · bcrypt · JWT · nodemailer (OTP delivery)
ML ServerPython 3 · Flask · scikit-learn (GBDT) · joblib · pandas · numpy
DataMySQL — two databases: 8con (accounts, assets) and 8cons (payments, OTP)
Document ExportjsPDF + jspdf-autotable · docx · exceljs (PDF / DOCX / XLSX)
ProductionDocker + 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.