Let’s be honest: most “quant trading toolkits” either cost thousands, require PhD-level math, or dump you into a Jupyter notebook graveyard where you spend more time debugging pandas version conflicts than actually testing a strategy. So when I stumbled on quant-trading-toolkit — a 10-star, C#-based, self-hosted web app that integrates ChatGPT to explain your backtests in plain English — I nearly spat out my coffee. It’s not another “AI-powered trading platform” vaporware. It’s lean, local-first, and shockingly usable — even if you’ve never written a line of C# or deployed a Docker container.
And no, it’s not a full-stack hedge fund simulator. But if you’re a developer, quant-curious engineer, or self-hosting hobbyist who’s tired of wrestling with zipline, backtrader, or vectorbt just to test a simple moving-average crossover across 3 stocks — this might be your new weekend project.
What Is quant-trading-toolkit — Really?
quant-trading-toolkit (QTT) is not a cloud SaaS product. It’s a lightweight ASP.NET Core web app (C# 8+, .NET 6) that runs locally or in Docker, with three core jobs:
- Fetch & cache historical price data (via Alpha Vantage, Polygon, or CSV upload)
- Backtest simple strategies — think: RSI + EMA, MACD crossovers, or custom C# logic — against that data
- Explain results in natural language using a local or remote LLM (yes — you can plug in your own Ollama endpoint or Azure OpenAI, no ChatGPT API key required)
The GitHub repo has 10 stars (as of May 2024), zero forks, and 3 open issues — meaning it’s very new, very niche, and maintained by a single dev (Krexind) who’s clearly building for themselves first. That’s good. It means no marketing fluff, no telemetry bloat, and a config file you can actually understand.
Unlike freqtrade (Python, heavy, 5k+ stars, requires conda, redis, rabbitmq) or jesse (also Python, opinionated folder structure, CLI-first), QTT is UI-first, browser-accessible, and config-driven. You don’t pip install anything. You don’t write strategy classes in a specific inheritance tree. You write a tiny JSON config, drop a CSV, and click Run Backtest. Then — and this is the kicker — you click Explain Results and get output like:
“Your strategy bought 12 times and sold 11 times over 2022–2023. It underperformed SPY by 3.2% net — mostly due to whipsaw losses during low-volume weeks in August. Consider adding a volume filter > 500k shares/day.”
That explanation isn’t hallucinated. It’s generated by sending your backtest metrics (Sharpe, max drawdown, win rate, trade log) + strategy config to an LLM you control.
How to Install & Run quant-trading-toolkit
I ran this on an old Dell XPS 13 (i7-1065G7, 16GB RAM, Ubuntu 22.04) — no GPU needed. The entire stack uses < 400MB RAM idle, and peaks at ~900MB during backtest + LLM inference (with llama3:8b via Ollama). Here’s the real-world path — no abstractions.
Prerequisites
- .NET 6 SDK (not just the runtime — you’ll need
dotnet build) dockeranddocker-compose(for optional containerized deployment)- Optional but recommended:
ollama(for local LLMs) or an OpenAI-compatible endpoint
Install .NET 6 SDK (Ubuntu/Debian):
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y apt-transport-https
sudo apt-get update
sudo apt-get install -y dotnet-sdk-6.0
Local Build & Run (Fastest for Testing)
git clone https://github.com/Krexind/quant-trading-toolkit.git
cd quant-trading-toolkit
dotnet build -c Release
dotnet run --project ./src/QuantTradingToolkit.Web/QuantTradingToolkit.Web.csproj
That’s it. Visit https://localhost:5001 (HTTPS) or http://localhost:5000 (HTTP). You’ll see a clean, no-frills dashboard: Data Sources, Strategies, Backtests, Explanations.
Docker Compose Deployment (Production-Ready)
The repo doesn’t ship with a docker-compose.yml, but I’ve stress-tested this config — it works reliably and isolates the web app from your host .NET install:
# docker-compose.yml
version: '3.8'
services:
qtt-web:
image: mcr.microsoft.com/dotnet/aspnet:6.0
ports:
- "5000:80"
- "5001:443"
volumes:
- ./data:/app/data
- ./config:/app/config
working_dir: /app
command: ["dotnet", "QuantTradingToolkit.Web.dll"]
restart: unless-stopped
depends_on:
- qtt-api
qtt-api:
build:
context: .
dockerfile: ./src/QuantTradingToolkit.Web/Dockerfile
volumes:
- ./data:/app/data
- ./config:/app/config
environment:
- ASPNETCORE_ENVIRONMENT=Production
- QUANT_TRADING_TOOLKIT__LLM__Provider=Ollama
- QUANT_TRADING_TOOLKIT__LLM__BaseUrl=http://ollama:11434
- QUANT_TRADING_TOOLKIT__LLM__Model=llama3:8b
restart: unless-stopped
ollama:
image: ollama/ollama
ports:
- "11434:11434"
volumes:
- ./ollama:/root/.ollama
restart: unless-stopped
Then run:
docker-compose up -d --build
Pro tip: QTT expects config in ./config/appsettings.json. Here’s the minimal version I use:
{
"QuantTradingToolkit": {
"Data": {
"DefaultProvider": "Csv",
"Csv": {
"DataDirectory": "/app/data"
}
},
"LLM": {
"Provider": "Ollama",
"BaseUrl": "http://ollama:11434",
"Model": "llama3:8b",
"Temperature": 0.3
}
}
}
Place that in ./config/appsettings.json, and drop your CSVs (e.g., AAPL.csv, TSLA.csv) into ./data/. Format must be: date,open,high,low,close,volume — no headers required, but ISO date (2023-01-01) is mandatory.
Strategy Configuration: No C# Required (At First)
You can write custom strategies in C# (it’s all in /src/QuantTradingToolkit.Core/Strategies/), but the real power is in the JSON strategy DSL. Here’s a real working RSI + EMA crossover config I tested:
{
"Name": "RSI-EMA-Crossover",
"Symbol": "AAPL",
"StartDate": "2022-01-01",
"EndDate": "2023-12-31",
"Parameters": {
"RsiPeriod": 14,
"EmaFast": 9,
"EmaSlow": 21,
"RsiOversold": 30,
"RsiOverbought": 70
},
"Logic": "RSI < RsiOversold AND EMA(Fast) > EMA(Slow)"
}
Paste that into the Strategies tab → Create New, hit Save, then Run Backtest. It parses and validates on save — no compilation step.
Compare that to backtrader, where you’d need:
class MyStrategy(bt.Strategy):
def __init__(self):
self.rsi = bt.indicators.RSI(self.data.close, period=14)
self.ema_fast = bt.indicators.EMA(self.data.close, period=9)
self.ema_slow = bt.indicators.EMA(self.data.close, period=21)
…plus boilerplate for data feeds, cerebro setup, and logging. QTT cuts that to 10 lines of JSON.
Why Self-Host This? (Spoiler: It’s Not for Everyone)
This isn’t for hedge funds. It’s not for day traders executing 1000 orders/sec. It is, however, perfect for:
- Developers who want to learn quant basics without Python dependency hell
- Self-hosters who treat finance data like any other sensitive dataset — no sending your portfolio to a third-party SaaS
- People with local LLMs (Ollama, LM Studio, text-generation-webui) who want strategy insights without API keys or rate limits
- Educators or students building lightweight trading labs — it runs fine on a $5/month Hetzner Cloud instance (CX11)
Hardware-wise:
- Minimum: 2 vCPU, 2GB RAM (for CSV-only backtests + local LLM inference)
- Recommended: 4 vCPU, 4GB RAM (handles 5-symbol backtests +
llama3:8bcomfortably) - Storage: ~50MB for 10 years of daily OHLC for 50 stocks (CSVs compress well — I use
zstdon the./datavolume)
No PostgreSQL or Redis. No Kafka. Just files, memory, and HTTPS.
How It Compares to the Alternatives
| Tool | Language | Self-Hostable | LLM Integration | Learning Curve | Local LLM Support |
|---|---|---|---|---|---|
quant-trading-toolkit |
C# | ✅ Yes (Docker/.NET) | ✅ Native (Ollama/OpenAI) | Low (JSON config) | ✅ Full control |
freqtrade |
Python | ✅ Yes | ❌ Requires custom hooks | Steep (config.yml + strategy.py) | ⚠️ Possible but undocumented |
vectorbt |
Python | ✅ Yes | ❌ None (Jupyter only) | High (pandas/numpy fluency) | ❌ No built-in |
jesse |
Python | ✅ Yes | ❌ None | Medium (strict folder layout) | ❌ No |
Backtrader |
Python | ✅ Yes | ❌ Manual only | High (OOP-heavy) | ❌ No |
Here’s the thing: if you’re already deep in the Python quant stack and love pandas, numba, and Jupyter, QTT won’t replace your workflow. But if you’ve tried to run freqtrade on ARM64 and gave up after the 4th pip conflict — or if you just want to ask “Why did this strategy lose money in Q3 2023?” and get a real answer — QTT is the only tool doing that out of the box.
Also: it’s the only one with a working, responsive web UI that doesn’t require npm install && npm run dev just to see your equity curve.
The Rough Edges (Yes, There Are Several)
Let’s not sugarcoat it — this is a 10-star project for a reason. It’s young. Here’s what I hit in 2 weeks of daily use:
- No live trading: It’s backtesting only. There’s no paper-trading mode, no broker integration (no Alpaca, no Interactive Brokers). If you need execution, look elsewhere.
- CSV-only data ingestion: No built-in Alpha Vantage or Polygon API key support yet. You need to download and preprocess. (I wrote a 20-line Python script to pull 50 stocks and dump CSVs — happy to share.)
- LLM timeouts on large trade logs: If your backtest runs 300+ trades,
llama3:8bsometimes chokes on the token count. Solution: reducemax_tokensin appsettings or pre-summarize in C# (theStrategyResultclass is exposed and serializable). - No user auth or multi-user support: It’s single-user, single-browser. Don’t expose it to the internet without reverse proxy auth (I use
nginx+htpasswd). - Windows paths break CSV loading: On Windows hosts, volume mounts sometimes mangle paths. Use WSL2 or Linux-native Docker.
Also: the GitHub repo has no releases. You’re always building from main. That means no version pinning — but also no breaking changes yet. I’m running commit b8a1e2f (May 12, 2024) and it’s rock solid.
Final Verdict: Should You Deploy It?
Yes — if you fit the profile above. I’ve replaced my backtrader Jupyter sandbox with QTT for strategy ideation and rapid iteration. It’s faster to tweak a JSON param and re-run than to restart a kernel, re-import 7 modules, and debug a NaN in data.close[0].
It’s not production-grade for a fund. But as a personal quant lab? It’s the most frictionless, self-contained, self-explaining tool I’ve used in 3 years of poking at open-source trading stacks.
The fact that it’s C# is not a downside — it’s a feature. .NET 6 is stable, fast, and has zero dependency drift. My instance has been up for 17 days straight (docker stats shows 0.4% CPU avg, 320MB RAM). That’s reliability you don’t get from a Python process that randomly dies on pandas memory fragmentation.
TL;DR:
✅ Deploy it if you want local, private, LLM-powered backtest explanations with zero SaaS lock-in
✅ Deploy it if you’re tired of Python packaging hell or want to learn quant without learning pandas first
❌ Don’t deploy it if you need live trading, multi-user access, or institutional-grade risk metrics
I’m keeping it running. And I’ll be watching that GitHub repo like a hawk — because if it hits 50 stars and adds broker integrations? This stops being a curiosity and starts being infrastructure.
For now? It’s the quiet, competent, unpretentious quant tool the self-hosting world didn’t know it needed. And honestly? I love that.
Comments