Files
sanguo_vnpy_v2/tests/backtest/test_result_store.py

128 lines
4.1 KiB
Python

"""Tests for sanguo_backtest.result_store module."""
import pytest
import pandas as pd
from datetime import datetime
from sanguo_backtest.result_store import (
BacktestResult,
save_result,
load_result,
list_results
)
def test_save_and_load_result(temp_db_path):
"""Test saving and loading a backtest result without parquet files."""
# Create a result without equity_curve and trades (file_dir=None by default)
result = BacktestResult(
task_id="test_task_001",
type="cta",
status="completed",
strategy="DualThrustStrategy",
symbol="IF2401",
params={"window": 20, "entry_threshold": 0.5},
start="2024-01-01",
end="2024-03-31",
statistics={
"total_return": 0.15,
"sharpe_ratio": 1.2,
"max_drawdown": -0.08,
"win_rate": 0.55
}
)
# Save the result
result_id = save_result(result, temp_db_path)
assert result_id > 0
assert isinstance(result_id, int)
# Load the result
loaded_result = load_result(result_id, temp_db_path)
# Verify all fields match
assert loaded_result.task_id == result.task_id
assert loaded_result.type == result.type
assert loaded_result.status == result.status
assert loaded_result.strategy == result.strategy
assert loaded_result.symbol == result.symbol
assert loaded_result.params == result.params
assert loaded_result.start == result.start
assert loaded_result.end == result.end
assert loaded_result.statistics == result.statistics
assert loaded_result.equity_curve is None
assert loaded_result.trades is None
assert loaded_result.error_msg is None
def test_list_results_filter(temp_db_path):
"""Test listing results with type filter."""
# Create multiple results of different types
cta_result = BacktestResult(
task_id="cta_task_001",
type="cta",
status="completed",
strategy="DualThrustStrategy",
symbol="IF2401",
params={"window": 20},
start="2024-01-01",
end="2024-03-31",
statistics={"total_return": 0.15}
)
factor_result = BacktestResult(
task_id="factor_task_001",
type="factor",
status="completed",
strategy="Alpha158Strategy",
symbol="000001.SZ",
params={"factors": ["alpha001", "alpha002"]},
start="2024-01-01",
end="2024-03-31",
statistics={"total_return": 0.20}
)
# Save both results
cta_id = save_result(cta_result, temp_db_path)
factor_id = save_result(factor_result, temp_db_path)
# List all results
all_results = list_results(db_path=temp_db_path)
assert len(all_results) == 2
# List only CTA results
cta_results = list_results(type_filter="cta", db_path=temp_db_path)
assert len(cta_results) == 1
assert cta_results[0].type == "cta"
assert cta_results[0].task_id == "cta_task_001"
# List only factor results
factor_results = list_results(type_filter="factor", db_path=temp_db_path)
assert len(factor_results) == 1
assert factor_results[0].type == "factor"
assert factor_results[0].task_id == "factor_task_001"
def test_failed_result_stores_error_msg(temp_db_path):
"""Test that failed results store error messages."""
# Create a failed result with error message
failed_result = BacktestResult(
task_id="failed_task_001",
type="cta",
status="failed",
strategy="DualThrustStrategy",
symbol="IF2401",
params={"window": 20},
start="2024-01-01",
end="2024-03-31",
statistics={}, # Empty statistics for failed result
error_msg="Data loading failed: insufficient historical data"
)
# Save the failed result
result_id = save_result(failed_result, temp_db_path)
# Load and verify error message is preserved
loaded_result = load_result(result_id, temp_db_path)
assert loaded_result.status == "failed"
assert loaded_result.error_msg == "Data loading failed: insufficient historical data"
assert loaded_result.statistics == {}