Skip to content

Backtesting Guide

Igor Sazonov edited this page Jul 21, 2026 · 1 revision

Once you have a valid strategy_version_id (either directly from a prompt or after materializing a schema), you can run a backtest against historical market data.

Backtests on the CoinQuant platform run asynchronously. You submit a backtest request, and the engine processes it in the background. The SDK provides both automated polling helpers and manual methods for handling this process [1].

One-Call Automated Backtesting

The simplest way to run a backtest is using the createBacktestAndWait() method. This method submits the backtest, automatically polls the API until the run reaches a terminal state, and returns the complete results, including CSV exports [1].

$versionId = 'your_strategy_version_id';

// Submit and poll. 
// Parameters: strategyVersionId, timeoutSeconds (default 900), pollIntervalSeconds (default 5)
$outcome = $client->createBacktestAndWait($versionId, 900, 5);

echo "Final Status: {$outcome['detail']['status']}\n";

if ($outcome['results'] !== null) {
    $metrics = $outcome['results']['metrics'];
    
    echo "Total Return: {$metrics['Total Return']}%\n";
    echo "Sharpe Ratio: {$metrics['Sharpe Ratio']}\n";
    echo "Max Drawdown: {$metrics['Max Drawdown']}%\n";
    
    // Raw CSV data is also available
    $summaryCsv = $outcome['summary_csv'];
    $tradesCsv = $outcome['trades_csv'];
    
    file_put_contents('trades.csv', $tradesCsv);
}

Terminal States

The polling loop will exit when the backtest status becomes one of the following:

  • completed: The backtest finished successfully.
  • failed: The backtest failed due to logic or data errors.
  • cancelled: The backtest was manually cancelled.
  • error: An internal system error occurred.
  • timeout: The backtest exceeded the allowed execution time.

Manual Backtesting Loop

If you prefer to manage the polling loop yourself (for example, using a task scheduler or queue system in Laravel), you can use the underlying methods directly [1].

1. Create the Backtest

Submit the strategy version to the engine. This returns a backtest_id.

$backtest = $client->createBacktest($versionId);
$backtestId = $backtest['backtest_id'];

2. Poll for Status

Periodically check the status of the backtest.

$detail = $client->getBacktest($backtestId);

if ($detail['status'] === 'completed') {
    // Proceed to fetch results
} elseif ($detail['status'] === 'running' || $detail['status'] === 'pending') {
    // Try again later
}

Note: If you attempt to fetch results while a backtest is still running, the API will return a 409 Conflict error.

3. Fetch Results and Exports

Once completed, retrieve the metrics and CSV exports.

// Get JSON metrics
$results = $client->getBacktestResults($backtestId);

// Get CSV exports (returns raw CSV string data)
$summaryCsv = $client->getBacktestSummaryCsv($backtestId);
$tradesCsv = $client->getBacktestTradesCsv($backtestId);

Comparing Backtests

You can compare the metrics of multiple completed backtests using the compareBacktests method:

$comparison = $client->compareBacktests([
    'backtest_id_1',
    'backtest_id_2',
    'backtest_id_3'
]);

print_r($comparison);

Duplicating Backtests

To rerun an exact backtest configuration, use the duplicate method:

$newBacktest = $client->duplicateBacktest('existing_backtest_id');

References

[1] CoinQuant PHP SDK README

Clone this wiki locally