Developing a Trading Strategy Platform: A Guide with gRPC, Buf, and Python
Creating a Trading Backtesting System Using gRPC, Python, and Multi-Language Support

Introduction
Modern quantitative trading platforms rarely live in a single language or runtime. Performance-critical components may be written in Go, data science logic in Python, and APIs consumed by dashboards, notebooks, or web clients.
To support scalability, language-agnostic services, and clean contracts, this article walks through building a polyglot microservice-based strategy backtesting system using:
gRPC – high-performance service communication
gRPC-Gateway – REST access for dashboards & clients
Buf – protobuf linting, breaking-change detection & generation
Uber FX – dependency injection for Go services
Python – strategy logic & backtesting engine
Nx Workspace – monorepo orchestration for multi-language systems
By the end, you’ll have a cleanly designed system that:
Defines strategies once
Backtest them at scale
Exposes results via gRPC & REST
Is ready for extension into live trading or research tooling
System Architecture Overview
Core Services
| Service | Language | Responsibility |
| Strategy Service | Python | Strategy definition & signal generation |
| Backtest Service | Python | Historical simulation & PnL computation |
| Market Data Service | Go | OHLCV & order book access |
| Result Service | Go | Aggregation & storage of backtest outputs |
| API Gateway | Go | REST exposure via gRPC-Gateway |
High-Level Flow
User submits a strategy definition
Strategy service validates logic
Backtest service runs simulations
Results are stored & aggregated
Clients query results via REST or gRPC
Why This Stack?
gRPC
Language-agnostic
Strongly typed contracts
Streaming support (ideal for market data)
Buf
Single source of truth for protobufs
Prevents accidental breaking changes
Clean code generation across Go & Python
Uber FX
Explicit dependency graph
Easy service composition
Production-ready lifecycle management
Nx Workspace
Monorepo with dependency graphs
One command to build/test everything
Language-agnostic orchestration
Hands-On: Step-by-Step Implementation
1. Nx Workspace Setup
Initialize Workspace
npx create-nx-workspace@latest backtesting-platform
cd backtesting-platform
Choose:
- Template: Empty Starter Template
then create your services
mkdir apps
cd apps
mkdir api-gateway market-data-service result-service strategy-service backtest-service
Next, we create the packages.
cd packages
mkdir proto shared
Your Final Folder Structure
apps/
api-gateway/
market-data-service/
result-service/
strategy-service/
backtest-service/
packages/
proto/
shared/
Nx now manages builds, caching, and dependency graphs across Go & Python.
2. Buf Initialization
Install Buf (https://buf.build/docs/cli/installation/)
npm install @bufbuild/buf
Initialize Buf Workspace
cd packages/proto
npx buf mod init
touch buf.gen.yaml
buf.yaml
version: v1
lint:
use:
- DEFAULT
breaking:
use:
- FILE
3. gRPC Contract Definition
Create the proto files in the proto folder, with the contents below
strategy.proto
syntax = "proto3";
package strategy;
service StrategyService {
rpc RegisterStrategy(RegisterStrategyRequest)
returns (RegisterStrategyResponse);
}
message RegisterStrategyRequest {
string name = 1;
string language = 2;
string source_code = 3;
}
message RegisterStrategyResponse {
string strategy_id = 1;
}
backtest.proto
syntax = "proto3";
package backtest;
service BacktestService {
rpc RunBacktest(RunBacktestRequest)
returns (RunBacktestResponse);
}
message RunBacktestRequest {
string strategy_id = 1;
string symbol = 2;
string start_date = 3;
string end_date = 4;
}
message RunBacktestResponse {
string backtest_id = 1;
}
4. Code Generation with Buf
In the buf.gen.yaml file, add the content below
version: v2
managed:
enabled: true
override:
- file_option: go_package_prefix
value: github.com/bufbuild/buf-examples/gen
plugins:
- remote: buf.build/protocolbuffers/go
out: ../gen
opt: paths=source_relative
- remote: buf.build/connectrpc/gosimple
out: ../gen
opt:
- paths=source_relative
- remote: buf.build/protocolbuffers/python
out: ../gen
- remote: buf.build/connectrpc/python
out: ../gen
- remote: buf.build/grpc-ecosystem/gateway
out: ../gen
opt:
- paths=source_relative
inputs:
- directory: .
Generate code for python and Golang:
npx buf generate
This will create a gen sub-folder in the packages folder, with generated python and Golang code.
5. Python Strategy Service
FastAPI + gRPC
class StrategyService(strategy_pb2_grpc.StrategyServiceServicer):
def RegisterStrategy(self, request, context):
strategy_id = str(uuid.uuid4())
save_strategy(strategy_id, request.source_code)
return strategy_pb2.RegisterStrategyResponse(
strategy_id=strategy_id
)
This service:
Accepts user strategies
Stores code safely
Returns a versioned strategy ID
6. Python Backtesting Engine
def run_backtest(strategy_fn, data):
positions = []
for candle in data:
signal = strategy_fn(candle)
positions.append(signal)
return compute_pnl(positions, data)
Key ideas:
Deterministic replay
Time-aligned execution
Reproducible results
7. Go Market Data Service (Uber FX)
func NewMarketDataService() *MarketDataService {
return &MarketDataService{}
}
func main() {
app := fx.New(
fx.Provide(NewMarketDataService),
fx.Invoke(RegisterGRPC),
)
app.Run()
}
FX ensures:
Explicit dependency wiring
Clean startup/shutdown
Testable services
8. gRPC-Gateway for REST Access
import "google/api/annotations.proto";
rpc RunBacktest(RunBacktestRequest)
returns (RunBacktestResponse) {
option (google.api.http) = {
post: "/v1/backtests/run"
body: "*"
};
}
Now clients can:
Use REST for dashboards
Use gRPC for internal services
9. Viewing Backtest Results
Expose endpoints like:
GET /v1/backtests/{id}/metrics
Returned metrics:
Total PnL
Sharpe Ratio
Max Drawdown
Win rate
Perfect for:
Streamlit dashboards
Research notebooks
Web UIs
10. Nx Task Orchestration
nx run-many --target=serve --all
Nx ensures:
Correct startup order
Cached builds
Parallel execution
Final Thoughts
This architecture gives you:
Strong contracts
Language freedom
Scalable experimentation
Production-grade structure
It’s suitable for:
Quant research platforms
Trading infrastructure
Large-scale simulation engines
From here, we can add:
Distributed backtesting
Strategy versioning
Live trading adapter
and much more feature
For the full code you can check the github repo linked below:
https://github.com/litmus-zhang/personal-playground/tree/main/quant/backtesting-platform




