summaryrefslogtreecommitdiff
path: root/services/backtester/tests/test_reporter.py
blob: 5199b68705725d438180a2acf8c3f58396273a8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""Tests for the report formatter."""

import json
from datetime import timedelta
from decimal import Decimal

from backtester.engine import BacktestResult
from backtester.metrics import DetailedMetrics
from backtester.reporter import export_csv, export_json, format_report


def _make_result(with_detailed: bool = False) -> BacktestResult:
    detailed = None
    if with_detailed:
        detailed = DetailedMetrics(
            total_return=0.15,
            total_trades=10,
            winning_trades=6,
            losing_trades=4,
            win_rate=60.0,
            profit_factor=2.5,
            sharpe_ratio=1.5,
            sortino_ratio=2.0,
            calmar_ratio=3.0,
            max_drawdown=0.05,
            max_drawdown_duration=timedelta(hours=5),
            monthly_returns={"2025-01": 500.0, "2025-02": 1000.0},
            avg_win=250.0,
            avg_loss=125.0,
            largest_win=600.0,
            largest_loss=-300.0,
        )
    return BacktestResult(
        strategy_name="sma_crossover",
        symbol="AAPL",
        total_trades=10,
        initial_balance=Decimal("10000"),
        final_balance=Decimal("11500"),
        profit=Decimal("1500"),
        profit_pct=Decimal("15"),
        trades=[],
        detailed=detailed,
    )


def test_format_report_contains_key_metrics():
    result = _make_result(with_detailed=False)
    report = format_report(result)

    assert "sma_crossover" in report
    assert "AAPL" in report
    assert "10000" in report
    assert "11500" in report
    assert "1500" in report
    assert "15" in report


def test_format_report_with_detailed_metrics():
    result = _make_result(with_detailed=True)
    report = format_report(result)

    assert "Sharpe Ratio" in report
    assert "Sortino Ratio" in report
    assert "Max Drawdown" in report
    assert "Profit Factor" in report


def test_format_report_monthly_returns():
    result = _make_result(with_detailed=True)
    report = format_report(result)

    assert "Monthly Returns" in report
    assert "2025-01" in report
    assert "2025-02" in report


def test_export_csv():
    result = _make_result(with_detailed=True)
    csv_output = export_csv(result)

    assert "Metric,Value" in csv_output
    assert "sma_crossover" in csv_output
    assert "Sharpe Ratio" in csv_output


def test_export_json():
    result = _make_result(with_detailed=True)
    json_output = export_json(result)

    data = json.loads(json_output)
    assert data["strategy_name"] == "sma_crossover"
    assert data["symbol"] == "AAPL"
    assert "detailed" in data
    assert data["detailed"]["sharpe_ratio"] == 1.5
    assert data["detailed"]["monthly_returns"]["2025-01"] == 500.0