Brokerage risk platform
Keeping more than 1,000 trading accounts accurate while scheduled jobs, staff and clients act on them at the same moment.
- Role
- Core developer and team lead
- Status
- In production
- Stack
- PHP 8, Laravel, MySQL, Queues and scheduler, API and webhook integrations
The challenge
Trading data arrived from several external systems on different schedules, report tables grew every week, and money-moving operations could be triggered by jobs, staff and clients at the same time.
The solution
A Laravel platform with scheduled data pipelines, automated risk monitoring, and an operations layer where every money-moving action is safe to retry and limited in how many run at once.
My role
- Core developer across the data pipelines, partner billing, risk monitoring and client self-service
- Led 1 to 2 developers: task breakdown, estimates and code review
- More than four months on site for go-live, incident response and staff training
At a glance
- Trading accounts in production
- 1,000+
- Developers led
- 1 to 2
- On site through go‑live
- 4+ months
Challenges and solutions
Duplicate and conflicting operations
Challenge
A retry, a double click or two people acting on the same account could trigger the same money-moving operation twice.
Solution
Operations were made idempotent, so repeating one has no further effect, and the number that can run at once for an account is capped.
Trade-offThroughput is limited on purpose: where money moves, correctness comes before speed.
Illustrative Laravel pattern (simplified, not client code)php class ProcessOperation implements ShouldQueue, ShouldBeUnique { // The same operation is never queued twice. public function uniqueId(): string { return (string) $this->operation->id; } // One operation per account at a time. public function middleware(): array { return [(new WithoutOverlapping($this->operation->account_id))->releaseAfter(10)]; } }Reports slowing down as data grows
Challenge
Report tables gain rows every day, and reports had to stay quick without throwing history away.
Solution
The largest tables are partitioned by week, and a scheduled job adds the next partition automatically, so a report reads only the periods it needs.
Trade-offPartition maintenance becomes a scheduled job that must never be missed.
Spotting risk without manual review
Challenge
Unusual trading activity had to be caught early, across thousands of trades a day.
Solution
Automated rules cross-check activity against several independent signals and raise alerts for the operations team, instead of relying on someone noticing.
Self-service that stays secure
Challenge
Clients wanted balances and bills on their phones without installing another app.
Solution
A messaging bot verifies every request with signed payloads, asks for a PIN before sensitive actions, and delivers bills as PDFs.
Trade-offOne extra step for clients, so an open chat alone is never enough to change anything.
What was delivered
- Automated data pipelines from external trading systems
- Rule-based risk monitoring with alerts for the operations team
- Multi-level partner billing with permissions and audit logs
- Secure client self-service through a messaging bot
- Reporting that stays fast as data grows
How it fits together
A brokerage needed one back office for operations, risk and billing, fed by trading systems it does not control.
IngestScheduled jobs collect data from external trading systemsStoreSeveral MySQL databases, partitioned for scaleMonitorRules flag unusual activity for reviewActBilling, alerts and client self-service
Constraints
- External data sources with different formats and schedules
- Money-moving actions must never run twice
- Report tables grow every week
- Client-facing actions must be verified