"""Test del contenitore portafoglio estensibile.""" import sys from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(PROJECT_ROOT)) import numpy as np import pandas as pd import pytest from src.portfolio.portfolio import Sleeve, StrategyPortfolio, to_daily, metrics def _const_sleeve(name, weight, val, n=400): idx = pd.date_range("2020-01-01", periods=n, freq="1D", tz="UTC") return Sleeve(name, weight, lambda: pd.Series(val, index=idx)) def test_single_sleeve_equals_itself(): s = _const_sleeve("A", 1.0, 0.001) pf = StrategyPortfolio([s]) combo = pf.combined_daily() assert np.allclose(combo.values, s.daily().values) assert pf.weights() == {"A": 1.0} def test_weights_normalize(): pf = StrategyPortfolio([_const_sleeve("A", 3.0, 0.001), _const_sleeve("B", 1.0, 0.002)]) w = pf.weights() assert abs(sum(w.values()) - 1.0) < 1e-12 assert abs(w["A"] - 0.75) < 1e-12 and abs(w["B"] - 0.25) < 1e-12 def test_equal_weight_combine(): a, b = _const_sleeve("A", 1.0, 0.001), _const_sleeve("B", 1.0, 0.003) pf = StrategyPortfolio([a, b]) combo = pf.combined_daily() assert np.allclose(combo.values, 0.5 * 0.001 + 0.5 * 0.003) # 0.002 def test_to_daily_compounds_intraday(): # due barre da +1% nello stesso giorno -> +2.01% giornaliero idx = pd.to_datetime(["2020-01-01T00:00", "2020-01-01T12:00"], utc=True) d = to_daily(pd.Series([0.01, 0.01], index=idx)) assert len(d) == 1 and abs(d.iloc[0] - (1.01 * 1.01 - 1)) < 1e-12 def test_metrics_basic(): idx = pd.date_range("2020-01-01", periods=730, freq="1D", tz="UTC") m = metrics(pd.Series(0.0005, index=idx)) # ritorno costante positivo assert m["ret"] > 0 and m["maxdd"] == 0.0 and m["n"] == 730 def test_empty_portfolio_raises(): with pytest.raises(ValueError): StrategyPortfolio([])