Getting Started
Get your API key, make your first request, and receive your first backtest result in minutes.
Prerequisites
To use the EmidLabs Backtesting API you need:
- An EmidLabs account — create one at the Console.
- An API key generated from the Console.
- Any HTTP client — curl, fetch, Python requests, or any language SDK.
#Authentication
All API requests must include your API key in the x-api-key header. There are no other authentication methods.
x-api-key: em_YOUR_API_KEYGenerating an API key
Open the Console
Go to API Keys
Create a key
Set an expiry (optional)
#Your First Backtest
A backtest is submitted as a POST request. The body includes the asset pair, date range, and a strategy definition serialized as a JSON string.
Step 1 — Define the strategy
The strategy is a JSON object that describes what the engine should look for. Here is a simple EMA crossover with RSI confirmation:
{
"configuration": {
"timeframe": "1H"
},
"inputs": {
"emaFast": "ema(close, 9)",
"emaSlow": "ema(close, 21)",
"rsiValue": "rsi(close, 14)"
},
"conditions": {
"trendUp": "emaFast > emaSlow",
"rsiHealthy": "rsiValue > 40 AND rsiValue < 65"
},
"score": {
"trendUp": 20,
"rsiHealthy": 30
},
"decision": {
"entry": "score >= 40"
}
}Step 2 — Serialize and submit
The strategy must be serialized into a JSON string and passed as thestrategySnapshotJson field of the request body.
curl -X POST \
"https://api.emidlabs.com/api/public/v1/backtest" \
-H "Content-Type: application/json" \
-H "x-api-key: em_YOUR_API_KEY" \
-d '{
"assetPair": "BTC-USDC",
"initialDate": "2023-01-01",
"finalDate": "2023-12-31",
"strategySnapshotJson": "{"configuration":{"timeframe":"1H"},"inputs":{"emaFast":"ema(close, 9)","emaSlow":"ema(close, 21)","rsiValue":"rsi(close, 14)"},"conditions":{"trendUp":"emaFast > emaSlow","rsiHealthy":"rsiValue > 40 AND rsiValue < 65"},"score":{"trendUp":20,"rsiHealthy":30},"decision":{"entry":"score >= 40"}}"
}'status: "Running". Execution typically completes within 200–500ms for most date ranges.Step 3 — Fetch the results
Use the returned id to fetch results via a GET request. Add includeTrades=true to receive individual trade details.
curl -X GET \
"https://api.emidlabs.com/api/public/v1/backtest/YOUR_BACKTEST_ID?includeTrades=true" \
-H "x-api-key: em_YOUR_API_KEY"#Reading Results
When status is Completed, theresult object contains all performance metrics.
Key metrics
tradesTotal number of trades executed.winRatePercentage of winning trades (0–1).expectancyRAverage expected R per trade. Positive is profitable.pnlRTotal profit/loss in R-units across all trades.profitFactorGross profit divided by gross loss. >1 is profitable.maxDrawdownPctLargest peak-to-trough drawdown as a percentage.conditionsDistributionPctHow often each condition was true per candle.scoreDistributionPctDistribution of total score values across all candles.R-units explained
All profit/loss values are in R-units, not currency amounts. 1R = 1% of your position (the risk per trade under the fixed risk model). A result of +10R means the strategy would have returned 10× the risked amount per trade, in aggregate.
This makes results comparable across strategies and assets regardless of position size, and forces focus on the statistical edge rather than dollar amounts.