I Built My Own Algorithmic Trading Research Engine

…and What I Learned Doing It

I didn’t get into coding through a bootcamp or a CS degree. I got into it because I wanted to trade better.

Like many traders-turned-devs, I bounced between platforms looking for the right setup for backtesting and strategy research. Some tools were decent, but none gave me the freedom or flexibility I wanted — too many constraints, too little control, or just not built for scale.

Eventually, I hit a wall. So I took a sabbatical and built my own.


The Goal

This wasn’t supposed to be a product. It started as my personal research engine — something I could trust long-term. Fast, flexible, and powerful enough to explore serious ideas, not just moving average crossovers.

Two goals:

  • Build something I could use for years

  • Use it as a deep dive into Python

It quickly turned into something much bigger.

Under the Hood: The Engine

At the core is a custom event-driven backtesting engine, built from scratch.

  • Multi-portfolio, multi-broker support

  • Live and historical data feeds

  • Concurrent strategies across timeframes

  • Hot-pluggable components at runtime

The whole system simulates real-world conditions — not idealized ones. Everything is asynchronous, timestamped, and event-sequenced like a real data feed, even during historical playback.

To pull that off, I built my own internal systems:

  • Event bus and dispatcher

  • Time controller and sync manager

  • Signal router per strategy

Also — no libraries for TA. I wrote every indicator by hand. Not because I had to, but because I wanted to understand every moving part. That process taught me more than any tutorial ever could.

Architecture: From Callback Soup to Clean Pub/Sub

The first version? Callback hell. It worked, but every new feature was a nightmare.

Eventually, I rebuilt everything around a pub/sub, queue-based architecture. Each module — data feed, strategy, executor, logger, handler — is isolated, and all communication happens through events.

This made the engine:

  • Easier to test

  • Easier to extend

  • Easier to reason about

Now I can drop in a new strategy or switch data sources mid-run without touching the rest of the system. It’s clean, flexible, and fun to work on again.

From C# to Python (…and Beyond)

Coming from C# and .NET, Python felt strange — too implicit, too loose. But I get it now.

Python gives you velocity. I used it for everything — the engine core, API integrations, logging, data tools. When you're iterating fast, that matters more than strict typing.

That said, this won’t stay 100% Python forever. As the project grows, parts of it will need to run faster. Some core pieces may get rewritten in Rust or C++ — haven’t decided yet. But Python got me from zero to here, fast.

The Frontend: Still Barebones

The engine is API-first, so most testing happens through Postman collections and CLI scripts. I’ve wired up a basic Angular frontend for controlling runs and inspecting jobs, but that’s about it.

It’s not polished — intentionally. I’ve kept the focus on the backend, and the frontend will evolve naturally once I need more interactivity.

There is another project I’m working on that goes deeper into frontend UX — but that’s a story for another post.

Strategy Design: Antifragile by Default

I’m not chasing a “perfect” system. I’m building a research pipeline that explores a broad spectrum of strategy types:

  • Momentum

  • Trend following

  • Breakouts

  • Mean reversion

  • Volatility-based

  • Cross-asset signals

The goal isn’t optimization — it’s antifragility: resilience through diversity.

Any single strategy might fail under pressure. But 20 small, uncorrelated strategies? That’s robustness.

Most ideas won’t work. And that’s expected. The engine is designed to surface those failures early and filter out noise.

Each strategy that survives goes through:

  • Survivorship bias checks

  • Lookahead bias detection

  • Execution feasibility

  • Slippage modeling

  • Robustness under parameter shifts

And I’m baking these checks directly into the tooling. Not as optional steps — but as defaults.

Only the ideas that survive the gauntlet make it past simulation.

What’s Next?

The engine is about 90% done. It’s already functional, but two big features are still in the works:

  • Live broker integration

  • Full performance/statistics dashboard (partially done)

Right now, it’s on pause while I finish Pineblocks — a no-code tool to build TradingView scripts.

Once that ships, I’ll circle back and finish the last mile here. Whether this becomes a full product or stays a power tool for personal use — that’s still TBD.

C# gave me structure.
Python gave me velocity.
This project taught me how to balance both.