The Setup: What I'm Actually Running
Strategy: USDJPY momentum + seasonal model Experiment size: SGD 200 per signal Go-live: December 2024 January 2026 P&L: -$2.26 USD (2 trades: 1 win, 1 loss)Yes, January was slightly negative. That's real trading — not every month is green. The important part: the system executed exactly as designed, risk per trade stayed within limits, and I didn't blow up.
Why IB for a Systematic Strategy
I evaluated 4 brokers before going live on IB: Oanda, Saxo, FXCM, and Interactive Brokers. IB won on three criteria:
1. API quality: IB's TWS API, accessed via the Pythonib_insync library, is the gold standard for retail algo trading. It's not pretty — the official docs are from 2015 — but it works reliably.
2. Cost: IB charges approximately $2 per $100,000 notional on FX spot. Small-lot trades cost fractions of a cent in commission. On Saxo or OANDA, spreads would eat the edge on the same signal.
3. Custody: IB is an SIPC-member US broker, publicly traded (IBKR). For a strategy running 24/7 with automation, I want the broker to still be there when I wake up.
The Real Python Setup

My trading daemon connects to IB Gateway (not TWS — it's lighter, more stable for headless servers). The core connection:
ib = IB()
ib.connect('127.0.0.1', 4001, clientId=1)
# USDJPY contract
forex = Forex('USDJPY')
ib.qualifyContracts(forex)
# Market order for signals
order = MarketOrder('BUY', 50000) # 50k base
trade = ib.placeOrder(forex, order)
The daemon runs as a systemd service, checks signals every 60 seconds, and executes when conditions are met. Uptime since December: 99.2% (one restart for IB Gateway 2FA refresh).
The 2FA Problem (and My Workaround)
This is IB's biggest pain point for automated trading. Every time IB Gateway reconnects — after a restart, weekly maintenance, or timeout — you need to authenticate on your phone.
My workaround: I run a monitoring cron that Telegram-alerts me when the connection drops. I have 15 minutes before the strategy would miss a signal window. In practice, scheduled maintenance is weekly (Saturdays), and I've never missed a trade because of it.
Is this annoying? Yes. Is it a dealbreaker? No. It's the cost of using an institutional broker at retail prices.
Real Fee Comparison: USDJPY Trade
| Broker | Spread | Commission | Total on $10k notional |
|---|---|---|---|
| Interactive Brokers | 0.2-0.5 pips | ~$0.20 | ~$0.70 |
| OANDA | 0.8-1.2 pips | $0 | ~$1.00 |
| Saxo Bank | 0.7-1.0 pips | ~$0.30 | ~$1.30 |
| IG Group | 0.6-0.9 pips | $0 | ~$0.75 |
January 2026: Month-by-Month Reality
My strategy trades in February, June, and October (seasonal long months) and July (seasonal short, when momentum aligns). January was a 'monitor only' month — but I had two legacy positions close.
Both trades from the December entry:
- Trade 1: Long USDJPY @ 152.1 → exit @ 155.4 ✅ Win
- Trade 2: Long USDJPY @ 153.8 → exit @ 153.2 ❌ Loss (hit monthly stop)
Who IB Is Actually For
Use IB if:- You're running automated strategies via API (this is IB's primary advantage)
- You're trading FX, futures, or options with meaningful size
- You're comfortable with a technical setup and occasional manual authentication
- You want the lowest execution costs at retail level
- You want a clean mobile UI (IB's is genuinely bad)
- You want 24/7 automation with zero manual intervention (the 2FA requirement rules this out)
- You're trading mostly US stocks and don't need the API (many simpler brokers are better for that)