| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- import importlib.util
- import sys
- from pathlib import Path
- import pytest
- def load_module():
- path = Path(__file__).resolve().parents[1] / "scripts" / "search_cross_symbol_high_frequency_portfolios.py"
- spec = importlib.util.spec_from_file_location("search_cross_symbol_high_frequency_portfolios", path)
- assert spec is not None
- module = importlib.util.module_from_spec(spec)
- assert spec.loader is not None
- sys.modules[spec.name] = module
- spec.loader.exec_module(module)
- return module
- def test_add_cost_columns_records_net_metrics():
- module = load_module()
- row = {
- "total_return": 0.12,
- "annualized_return": 0.04,
- "max_drawdown": 0.20,
- "calmar": 0.20,
- }
- module.add_cost_columns(row, "maker_taker", 0.0021)
- assert row["cost_model"] == "maker_taker"
- assert row["roundtrip_cost_on_margin"] == pytest.approx(0.0021)
- assert row["net_total_return"] == pytest.approx(0.12)
- assert row["net_annualized_return"] == pytest.approx(0.04)
- assert row["net_max_drawdown"] == pytest.approx(0.20)
- assert row["net_calmar"] == pytest.approx(0.20)
- def test_risk_qualified_keeps_recent_horizons_per_cost_model():
- module = load_module()
- pandas = pytest.importorskip("pandas")
- rows = []
- for cost_model, ret_1y in (("maker_taker", 0.11), ("taker_taker", 0.07)):
- for horizon, total_return in (("full", 0.30), ("3y", 0.20), ("1y", ret_1y), ("6m", 0.08), ("3m", 0.06)):
- rows.append(
- {
- "cost_model": cost_model,
- "portfolio": "test-portfolio",
- "horizon": horizon,
- "total_return": total_return,
- "annualized_return": 0.05,
- "max_drawdown": 0.10,
- "calmar": 0.50,
- "trades_per_month": 20.0,
- }
- )
- qualified = module.risk_qualified(pandas.DataFrame(rows)).sort_values("cost_model").reset_index(drop=True)
- assert qualified["cost_model"].tolist() == ["maker_taker", "taker_taker"]
- assert qualified.loc[0, "ret_1y"] == pytest.approx(0.11)
- assert qualified.loc[1, "ret_1y"] == pytest.approx(0.07)
- def test_robust_survivors_requires_positive_all_horizons_and_calmar():
- module = load_module()
- pandas = pytest.importorskip("pandas")
- rows = []
- for portfolio, ret_3m in (("survivor", 0.04), ("reject", -0.01)):
- for horizon, total_return in (("full", 0.30), ("3y", 0.20), ("1y", 0.10), ("6m", 0.08), ("3m", ret_3m)):
- rows.append(
- {
- "cost_model": "maker_taker",
- "portfolio": portfolio,
- "horizon": horizon,
- "total_return": total_return,
- "annualized_return": 0.05,
- "max_drawdown": 0.10,
- "calmar": 0.50,
- "trades_per_month": 20.0,
- }
- )
- survivors = module.robust_survivors(pandas.DataFrame(rows))
- assert survivors["portfolio"].tolist() == ["survivor"]
|