Skip to content

Backtest

midas.backtest

Backtest engine — replays historical data through strategies.

write_backtest_csv(result, path)

Write backtest results to a CSV file.

Source code in src/midas/backtest.py
def write_backtest_csv(result: BacktestResult, path: Path) -> None:
    """Write backtest results to a CSV file."""
    with open(path, "w", newline="") as f:
        writer = csv.writer(f)

        writer.writerow(["=== TRADE LOG ==="])
        writer.writerow([
            "Date", "Ticker", "Direction", "Shares", "Price",
            "Strategy", "Holding Period",
        ])
        for t in result.trades:
            writer.writerow([
                t.date.isoformat(),
                t.ticker,
                t.direction.value,
                t.shares,
                f"{t.price:.2f}",
                t.strategy_name,
                t.holding_period.value if t.holding_period else "",
            ])

        writer.writerow([])
        writer.writerow(["=== SUMMARY ==="])
        writer.writerow(["Metric", "Value"])
        sv = result.starting_value
        total_return = (result.final_value - sv) / sv if sv > 0 else 0
        bh_return = (result.buy_and_hold_value - sv) / sv if sv > 0 else 0
        writer.writerow(["Starting Value", f"${sv:.2f}"])
        writer.writerow(["Final Value", f"${result.final_value:.2f}"])
        writer.writerow(["Total Return", f"{total_return:.2%}"])
        writer.writerow(["Buy & Hold Value", f"${result.buy_and_hold_value:.2f}"])
        writer.writerow(["Buy & Hold Return", f"{bh_return:.2%}"])
        writer.writerow(["Total Trades", len(result.trades)])

        if result.split_date:
            writer.writerow([])
            writer.writerow(["=== OUT-OF-SAMPLE SPLIT ==="])
            writer.writerow(["Split Date", result.split_date.isoformat()])
            writer.writerow(["Train Return", f"{result.train_return:.2%}"])
            writer.writerow(["Train B&H Return", f"{result.train_bh_return:.2%}"])
            writer.writerow(["Train Trades", len(result.train_trades)])
            writer.writerow(["Test Return", f"{result.test_return:.2%}"])
            writer.writerow(["Test B&H Return", f"{result.test_bh_return:.2%}"])
            writer.writerow(["Test Trades", len(result.test_trades)])