MENA Trade
AI trading-signals SaaS with courses, tiered subscriptions and an EN + Darija RTL UI


At a glance
- Platform
- Responsive web app (desktop and mobile browser)
- Timeline
- Jun 2025 to Feb 2026
- Role
- Lead full-stack engineer
- Commits
- 189 of 196 written by me
- Languages
- English and Moroccan Darija (RTL)
- Signal assets
- EURUSD, XAUUSD, NASDAQ 100, S&P 500
Overview
MENA Trade is a trading-education and signals platform for Moroccan and MENA retail traders. It combines AI-generated trading signals for EURUSD, gold, the NASDAQ 100 and the S&P 500 with an AI trading coach, market analysis, an economic calendar, a trading journal and courses, sold as Free, Advanced and Ultra tiers. I was the lead full-stack engineer and built the Next.js app, the admin panel, the payment flows and the AWS signal worker.
The challenge
The product had to produce trading signals on a schedule, not only when a user asked for one, and it had to deliver them to each user within that user's tier quota. Calls to Claude and Gemini and to the market-data APIs cost money per request, so a signal was only worth generating when the market was open and the setup was strong. The app also had to work in English and Moroccan Darija with a right-to-left layout. It needed payment options that suit a Moroccan audience (bank transfer and USDT) alongside Stripe. The web app is hosted on Netlify, whose serverless function timeouts rule out long-running jobs such as multi-timeframe analysis followed by a Claude call.
My role
Between June 2025 and February 2026 I wrote nearly all of the code (189 of 196 commits). I built the Next.js 15 App Router application: about 180 API route handlers across auth, signals, AI coach, forex/equity analysis, news, calendar, learning, notes, subscriptions and referrals, plus 40 Mongoose models. I also wrote the custom JWT/session auth with TOTP two-factor login, the role-based admin panel (users, subscriptions, payment requests, affiliate withdrawals, support, analytics) and the next-intl EN/Darija translations. On the signal side, I built the confluence-scoring signal engine and the Dockerised worker, and wrote the AWS setup scripts for ECS Fargate and EventBridge. The web-push and email broadcaster, Stripe checkout and webhooks, bank-transfer and USDT payment verification, and the affiliate commission system were mine as well.
Architecture
Clients
Web app
Next.js 15, React 19, Tailwind CSS, Radix UI, GSAP
Dashboard, signals, AI coach, analysis, calendar, notes and courses, with the document direction switched to RTL when the Darija locale is active.
Admin panel
Next.js App Router
Role-gated screens for users, subscriptions, payment requests and proofs, affiliates and withdrawals, support tickets and analytics.
Edge/Delivery
Hosting and middleware
Netlify, Next.js middleware
Next.js deployed on Netlify, with middleware that protects dashboard routes and serves an admin-controlled maintenance mode.
Services
API routes
Next.js route handlers, Zod
About 180 handlers covering auth, signals, AI coach, market data, news, learning, notes, subscriptions and referrals.
Signal worker
Node.js, Docker, AWS ECS Fargate
Standalone container that checks which markets are open, generates signals, and confirms the new signals are persisted in the database before it broadcasts them.
Scheduler
AWS EventBridge
Four cron rules start the worker every 30 minutes: three cover forex and gold from Sunday 22:00 to Friday 22:00 UTC, and one covers US indices during US trading hours on weekdays.
Confluence engine
TypeScript
Scores daily, 4H and 1H technical indicators and market structure out of 100, adds capped kill-zone and clean-news bonuses, and rejects any setup below 70.
Data
Primary database and cache
MongoDB, Mongoose
Users, signals, subscriptions, payments, referrals and notification logs, plus a MongoDB-backed cache with per-key TTLs.
File storage
AWS S3 (presigned URLs)
Course media, note attachments and bank-transfer payment proofs, uploaded directly from the browser.
Third-party
AI providers
Anthropic Claude, Google Gemini
Claude writes signals, coaching and analysis; Gemini is used for market sentiment and news filtering.
Market data
Yahoo Finance, Alpha Vantage, Twelve Data
Multi-timeframe OHLCV data, with a per-asset symbol map for each provider and a fallback to another provider when one fails.
Payments
Stripe, BNB Smart Chain RPC
Stripe checkout, webhooks and admin refunds and cancellations, plus on-chain USDT verification against several public RPC endpoints and a manual bank-transfer flow.
Notifications
Web Push (VAPID), Resend
Browser push and bilingual email templates for signals, with expired push subscriptions deactivated automatically.
Key decisions
- 01
Move signal generation off Netlify onto Fargate
A signal run fetches data for three timeframes, scores it and then calls Claude with web search, which ran into Netlify function timeouts and 504 errors I had to fix. I packaged the generator and broadcaster as a separate Docker worker that EventBridge starts on ECS Fargate. The trade-off is a second deploy target (container image builds) in return for no request timeout and pay-per-run compute.
- 02
Only run while the market is open
The EventBridge rules follow each asset class's trading hours, and the worker checks market hours again before it generates anything, so no AI or market-data calls are made while markets are closed. The cost of this is keeping the schedule logic correct in two places.
- 03
Deterministic score first, LLM second
A rule-based confluence engine scores each setup out of 100: daily bias 25, 4H confirmation 25, 1H entry 20, indicators 15 and structure 15. Kill-zone and clean-news bonuses apply only above a base score of 65 and are capped at 10 points, so they cannot push a weak setup into a higher tier. Setups below 70 are rejected before any model is called; setups scoring 80 or more are written by Claude Sonnet 4 and the rest by Claude Haiku, so the more expensive model is used only on the strongest signals.
- 04
Custom auth instead of a hosted provider
I built JWT and session-cookie auth with TOTP two-factor login and backup codes, three roles (user, admin, super_admin) and a maintenance-mode switch in middleware. This kept user, subscription-tier and role data in one MongoDB model. The cost is owning session handling and 2FA code that a hosted auth provider would otherwise supply.
- 05
Layered rate limits and a persistent cache
Per-service limits (for example Yahoo 1 request per 60 seconds, Claude 30 and Gemini 40 per 60 seconds) protect the upstream APIs. The AI coach chat adds per-user burst, per-minute and per-hour limits by tier, on top of daily tier quotas (5, 10 or 20 AI coach messages a day). A TTL cache stored in MongoDB keeps working across serverless cold starts, unlike an in-memory cache.
- 06
Local payment rails alongside Stripe
Many target users do not pay by card, so I added bank transfer with reference codes and S3-uploaded proof for admin review. I also added USDT verification that reads the blockchain directly through a list of public BNB Smart Chain RPC endpoints, with fallback, instead of a keyed explorer API.
Results
- Shipped a bilingual (English and Darija, RTL) trading platform with signals, an AI coach, forex and equity analysis, an economic calendar, a trading journal with attachments, and courses.
- Moved scheduled signal generation off Netlify onto pay-per-run Fargate, removing the 504 timeouts.
- Delivered signals by web push, capped at each tier's daily quota (1, 2 or 5 push notifications a day), and by bilingual email on the paid tiers.
- Made the Free, Advanced and Ultra tiers payable by Stripe, bank transfer or on-chain USDT, all managed from the admin panel.
- Built an affiliate program that tracks referrals and credits commission when a referred user upgrades, with admin-approved withdrawals.
Stack
- Frontend
- Next.js 15 (App Router)React 19TypeScriptTailwind CSSRadix UIGSAPFramer Motionnext-intlreact-hook-formZodTradingView widgetsRechartslightweight-charts
- Backend
- Next.js route handlersMongoDBMongooseJWT + session cookiesspeakeasy (TOTP 2FA)web-pushResendNodemailer
- AI
- Anthropic Claude (Sonnet 4, Haiku 3.5)Google Gemini
- Infrastructure
- NetlifyDockerAWS ECS FargateAWS ECRAWS EventBridgeAWS S3AWS Secrets Manager
- Payments
- Stripe Checkout and webhooksUSDT on BNB Smart Chain (public RPC)Bank transfer with proof upload
