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]. ```php $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`. ```php $backtest = $client->createBacktest($versionId); $backtestId = $backtest['backtest_id']; ``` ### 2. Poll for Status Periodically check the status of the backtest. ```php $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. ```php // 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: ```php $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: ```php $newBacktest = $client->duplicateBacktest('existing_backtest_id'); ``` --- ### References [1] [CoinQuant PHP SDK README](https://github.com/tigusigalpa/coinquant-php/blob/main/README.md)