# Metiqo — Devpost Project Story

Inspiration

The global metals market moves trillions of dollars a year, and a lot of the actual buying and selling still happens over WhatsApp and phone calls, with prices tracked in spreadsheets that get updated by hand. I spent time watching how small and mid-size metal traders actually operate day to day — checking price sites manually, logging conversations wherever they could, matching buyers to sellers mostly from memory and gut feel. There was no forecasting, no anomaly detection, nothing structural helping them make better decisions faster. That gap seemed worth building for. Metiqo is my attempt at giving that workflow real engineering instead of another spreadsheet.

What It Does

Metiqo is a full-stack metal trading intelligence platform. It tracks live LME prices daily for five metals — Copper, Aluminium, Nickel, Zinc, and Lead — and runs ten custom ML models: five Prophet models generating 7-day price forecasts, and five Isolation Forest models flagging anomalous price moves in near real time. RSI and MACD indicators turn those signals into automated BUY, HOLD, or SELL badges on each metal.

Beyond forecasting, Metiqo derives over 40 ISRI scrap grades from live base metal prices using industry-standard spreads, runs a marketplace that auto-matches buy and sell intents within 2% price tolerance, and includes a full CRM with contact management, deal tracking, and follow-up reminders. It handles CSV import/export, sends price alerts by email, and supports magic link login, Google OAuth, and TOTP two-factor authentication. All of it runs on free-tier infrastructure — Supabase, Render, Vercel, Brevo, GitHub Actions — for $0/month.

How We Built It

Frontend: React 18 with Vite, Recharts for the price and forecast charts, and custom CSS with a dark/light theme toggle.

Backend: FastAPI (Python 3.11) with Uvicorn, handling auth, persistence, model loading, and business logic. All endpoints require a JWT Bearer token from Supabase.

ML Pipeline: Ten models — 5 Prophet, 5 Isolation Forest, one pair per metal — retraining weekly via GitHub Actions, which pulls the latest 35 days of price history and commits updated pickle files back to the repo. In backtesting, 7-day forecast MAE runs roughly 2.5% for stable metals like Copper and up to 5% for volatile ones like Nickel. The anomaly models catch an estimated 80–85% of significant price moves while keeping false positives under 15%. Neither model replaces the trader's judgment — the forecast shows direction, the anomaly flag says "look here," and the decision stays with the person.

Derived Pricing (ISRI Grades): Over 40 scrap grades (Barley, Birch, Zorba, etc.) computed from live LME base prices via industry-standard spread multipliers, organized into searchable, collapsible sections.

Marketplace & Deal Matching: Users post buy or sell intents (metal, quantity, price per tonne). The backend auto-matches opposite intents within 2% price tolerance; accepting a match creates a deal record with no manual entry.

CRM: Contact CRUD, deal tracking grouped by contact, conversation logging with follow-up reminders, and a grouped inbox showing conversation count, last activity, and recent notes per contact.

Alerts & Data Tools: Price threshold alerts per metal with daily 9 AM email notifications via Brevo. CSV export for contacts, deals, metals, grades, and price history; bulk CSV import with template and preview.

Security: Email/password, magic link, and Google OAuth login, plus TOTP 2FA with QR code setup and session management to view or revoke active devices.

Database & Infra: Supabase (PostgreSQL, Row Level Security, Auth) for the data layer; Render and Vercel for backend/frontend deploys, both auto-deploying from GitHub on push. Total infrastructure cost: $0/month.

Challenges We Ran Into

Silent data corruption breaking forecasts. The hardest bug wasn't in the model code — it was duplicate price rows entering the database when the scraper ran more than once on the same day. Prophet doesn't error on bad data; it just quietly produces bad forecasts, which made this far harder to catch than a crash would have been. Fixed with a unique constraint on (metal, record_date) and an upsert-based scraper, plus a one-time cleanup pass on the existing history.

Anomaly model failing on a missing column. The Isolation Forest pipeline assumed a created_at column existed on the conversations table; it didn't, and the model failed without a clear error. Lesson: validate schema assumptions before any column access, especially with data from more than one source.

Smaller but real deploy friction. Escaped slashes in JSX breaking a production build, the frontend serving stale cached responses for hours after a backend deploy, mobile CSS overflow that only showed up on real devices, and a python-multipart dependency that existed locally but wasn't in requirements.txt until a Render deploy caught it.

Accomplishments That We're Proud Of

  • Ten ML models — five forecasting, five anomaly detection — that retrain themselves weekly with zero manual intervention.
  • Caught a data-integrity bug that most engineers would have mistaken for a model problem, because Prophet doesn't crash — it just quietly produces bad output.
  • A full trading platform — forecasting, anomaly detection, CRM, marketplace matching, alerts, 2FA — built and shipped solo, running on $0/month infrastructure.
  • Row Level Security policies that push real per-user access control into the database layer instead of scattering it through backend code.
  • 40+ ISRI scrap grades derived from live prices, extending the platform's relevance from base metal traders to the scrap trading side of the industry too. ## What We Learned

The most important lesson came from a bug, not a design choice: ML debugging starts with the data, not the model. I spent longer than I'd like to admit tuning Prophet hyperparameters before checking the raw training data. The root cause was duplicate price rows from a scraper running twice on the same day — Prophet treated two identical prices on the same date as separate days, effectively duplicating a one-day gap and hallucinating a trend to fit it. No amount of model tuning would have caught that.

Beyond that: Supabase RLS enforces per-user isolation at the database level, which meant less custom backend middleware, but getting the policies right took real iteration on cross-table joins. Brevo's free tier handles alert emails fine, but landing in the inbox instead of spam depends entirely on correct SPF/DKIM configuration on the sending domain. And the metals.dev API schema shifted slightly between calls in undocumented ways, so defensive validation before touching any column became non-negotiable.

What's Next for Metiqo

  • More metals — expanding beyond the current five LME metals to Tin, Cobalt, and Lithium.
  • Portfolio tracking — letting users log real holdings and see live P&L against current prices.
  • WhatsApp alerts — reaching traders through the channel they already use daily, rather than just email.
  • Mobile app — a React Native wrapper for traders who spend most of their day on the yard or in meetings, not at a desk.
  • Regional language support — Hindi and Gujarati localisation to reach a wider base of Indian metal traders. The core platform is live and functional today. These are the steps that would take it from a working tool to something traders reach for daily.

Built With

Share this project:

Updates