DEV Community

Shashank
Shashank

Posted on

I Built a Multi-Broker Trading Platform — Here’s What Actually Broke (and How I Fixed It)

Most trading tools lock you into a single broker.

I didn’t like that.

So I started building a platform where you can connect multiple brokers and manage your trades from one place—positions, orders, execution logic, everything.

Sounds straightforward… until it isn’t.

This is not a “how to build a trading app” guide.

This is what actually went wrong while building one—and how I dealt with it.


💡 The Idea

The goal was simple:

  • Connect multiple brokers (like IBKR, FYERS, ZERODHA etc.)
  • Provide a unified interface for:

    • Positions
    • Orderbook
    • Order placement / cancellation / modification
  • Add automation:

    • Auto-sell based on target/stop-loss
  • Handle real-time data using WebSockets

Basically: one platform to control everything without juggling multiple apps.


Architecture (High-Level)

Backend:

  • FastAPI
  • WebSockets for real-time updates
  • Broker-specific modules (client, orders, portfolio)

Frontend:

  • React

Core idea:
Each broker has its own implementation, but the platform exposes a common interface.

So internally:

  • Different logic
  • Externally: same API

Challenge 1: Every Broker is… Different

This was the first reality check.

Even though brokers provide similar features:

  • Authentication flows differ
  • Order formats differ
  • Response structures differ
  • WebSocket behavior differs

What I did

Created a broker abstraction layer:

  • client.py → authentication
  • orders.py → order placement, cancel, modify
  • portfolio.py → positions, holdings

Each broker implements the same structure.

So instead of:

if broker == "xyz":
Enter fullscreen mode Exit fullscreen mode

I just do:

broker.place_order(...)
Enter fullscreen mode Exit fullscreen mode

Clean. Scalable. Less headache later.


Challenge 2: Real-Time Execution Isn’t “Real-Time”

For features like:

  • Stop-loss
  • Target-based selling

You need live price updates.

Initially, I used WebSockets directly within the main application.

What broke?

  • Random disconnects
  • Delayed ticks
  • Missed execution windows

And in trading, delay = money lost.

What I changed

I shifted this responsibility to an independent service.

Instead of handling execution inside the main app, I built a separate service that:

  • Continuously monitors live prices
  • Runs independently of the main backend
  • Triggers sell execution when conditions are met

Why this worked better

  • Isolation: Failures in price monitoring don’t affect the main system
  • Reliability: Dedicated process for handling real-time logic
  • Scalability: Easier to optimize and scale independently

Also learned:

Don’t blindly trust WebSocket streams. Always have a fallback.


Challenge 3: Order State Lies (Sometimes)

You place an order.

Broker says: “Placed.”

But actual state?

  • Pending
  • Partially filled
  • Rejected later

Problem

Your system thinks:

“Done.”

Reality:

“Not even close.”

Solution

  • Continuously sync order status
  • Treat broker as source of truth
  • Build logic for:

    • partial fills
    • retries
    • cancellations

Challenge 4: Automation is Harder Than It Sounds

“Auto-sell when target hits” sounds easy.

It’s not.

Issues faced:

  • Price spikes triggering false execution
  • Multiple triggers firing at once
  • Race conditions

Fixes:

  • Locking execution per position
  • Adding thresholds (buffer zones)
  • Validating before placing sell orders

What’s Next

  • Add more brokers
  • Improve execution latency
  • Build better analytics around trades
  • Scale infrastructure

Final Thoughts

Building this wasn’t just about coding.

It was about:

  • handling uncertainty
  • designing for failure
  • and thinking beyond “happy paths”

If you're building anything involving real-time systems or external APIs:

Expect things to break. Design anyway.


If you’ve worked on something similar or are building in this space, I’d love to hear your experience.

Top comments (0)