Why I Built My Own Backtester - and Why You Might (or Might Not) Want To
Tired of forcing strategies into rigid frameworks? I built my own backtester in Go after outgrowing Python tools. This post covers the pros and cons, indicator accuracy, large-scale testing, and whether building your own is worth it.
Backtesting is the foundation of systematic trading - it’s how we validate ideas before putting real money at risk. Most traders either use platforms like TradingView or select a Python framework, such as Backtrader or Zipline.
I used the popular Python backtesters, starting with PyAlgoTrade and then others. However, over time, I encountered limitations. As my strategies became more complex, I found myself customizing or hacking around these engines so much that maintaining them became harder than just writing my own. I was bending the framework more than building a strategic logic.
Eventually, it made more sense to build my backtester in Go.
Not because existing tools are useless. But because I hit the same wall many traders eventually do: my strategies were getting too specific, too weird, too custom to fit neatly inside someone else’s framework.
Here’s why I made that choice, what I gained (and lost), and what you should consider before going down this path yourself.
🔧 Why Write Your Own Backtest Engine?
1. Customization Without Constraints
Every backtesting framework has its quirks. You eventually end up working around their assumptions - how orders are matched, how timeframes are handled, how positions are closed. With a custom engine, you define your own rules. No bending your strategy to fit someone else’s logic.
2. Indicator Matching: A Hidden Landmine
I’ve encountered multiple cases where some indicator values from common libraries (like TA-Lib or pandas-ta
) don’t match TradingView. Sometimes it’s a smoothing method, other times it’s an off-by-one issue. For example, Keltner Channels were off because of a slightly different method of computation. Subtle discrepancies like these can cause confusion and frustration.
I now write most indicators myself, matching TradingView’s behavior candle for candle. Yes, it takes more effort - but it gives me confidence that my backtest results are aligned with what I see on charts.
3. Testing Niche or Complex Logic
Do you have a strategy that depends on full moon dates? Volatility compression across instruments? Post-news-event entry conditions? Good luck forcing that into most frameworks. Custom logic becomes way easier when you have your backtester. And you are flexible; you are not making it for the public, you are not creating a framework to fit everything perfectly. You are making it for yourself.
⚙️ Why I Chose Go (Not Python)
While I use Python frequently for modeling, I chose Go for my backtester.
Now, I must say - this is not a critique of Python. Python is excellent for many use cases, and I continue to use it extensively for analysis and reporting. But when it comes to building a fast, stable, and scalable backtesting engine, Go offered better tooling for my specific scenarios. And it fit well with
💡 Compile-Time Type Checking = Fewer Bugs
One underrated reason I stick with Go: compile-time type checking.
Go catches entire classes of bugs during compilation that Python might silently let through unless you have robust unit tests in place. In a backtester, where small errors can lead to completely false conclusions, I prefer my bugs to be caught before execution.
🚀 Performance
Go is fast enough to chew through millions of candles and complex optimization loops without blinking. For large backtests and sweeping parameter searches, Python starts to lag. Go doesn’t. There are workarounds with Python, but the purpose is to write backtests and not get sucked into programming aspects.
🧳 Portable, Cloud-Ready
This part is more relevant if you're tech-savvy or handling large-scale backtests. Feel free to skip it if you’re not running batch jobs or deploying to cloud machines.
Go compiles into a single executable targeted for any platform - Windows, Linux, Mac, etc. That means I can run my backtester on a remote cloud machine with zero installation hassle. No Python environments, no containers, no dependency hell. For large parameter sweeps or overnight optimization workloads, this setup scales easily and is incredibly stable.
Of course, most traders who attempt algorithmic backtesting will never need this level of deployment. But for those who do - it’s a game-changer.
🧠 Productivity Balance
Sure, C++ or Rust are faster. But they're also slower to write, harder to debug, and easier to mess up. I wanted a language that balanced performance with developer speed. Go hit that sweet spot.
Pros and Cons of Writing Your Own Backtester
✅ Pros
- Total Control - No framework constraints. You can model anything.
- Performance - Go (or similar compiled languages) offer speed for large-scale testing.
- Exact Matching - You can write indicators to perfectly match TradingView or your charting platform.
- Debuggability - Every assumption is yours. No hidden logic to trip over.
- Portable Infrastructure - Compiled code runs easily on any cloud setup.
⚠️ Cons
- You Own the Bugs - Frameworks are battle-tested. Your custom engine is not.
- It’s More Work - You’ll spend time building basic stuff others have already solved.
- You Need Technical Skills - This isn’t beginner-friendly.
- Writing Indicators Is Tedious - You may need to reimplement many technical indicators from scratch, especially if you want chart-matching precision.
- No Built-In Visualizations - You’ll need to integrate plotting or build reports yourself.
- Reinventing the Wheel - Common features like portfolio management, slippage modeling, or performance metrics are non-trivial to implement well. Frameworks have already solved these.
🤔 What About GUI-Based Tools?
If a drag-and-drop backtester works for you, use it. Trading is hard enough. If a visual tool gives you the edge, don’t fix what isn’t broken.
But if you’ve hit a wall with customization, or you find yourself checking the same trades manually again and again, it might be time to explore code-driven backtesting.
🧠 Want to Go Deeper?
If you're not a developer, you don’t have to build your engine. However, learning even basic coding can save a significant amount of time and money while you work towards finding or improving your edge.
📚 Related Post:
The Backtester’s Edge: Discover how code and even AI tools like ChatGPT - can speed up your strategy testing and help you validate ideas faster
🏁 Final Thoughts
I built my backtester because I needed something I could trust - something flexible, fast, and fully transparent.
If you’re just getting started, stick with existing tools. But if your strategies are getting too complex, or you’re tired of guessing why your results don’t match reality, building your own might be the most liberating step you can take.
It’s not for everyone. But it might just be for you.