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 as a nested JSON object.
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 — Submit the request
The strategy is nested directly under the strategySnapshotJson field of the request body.
curl -X POST \
"https://backtest.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://backtest.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. By default, 1R = 1% of your position (the default stop-loss distance) — configurable per strategy viariskManagement. 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.