feat(portfolio): portfolios.yml + load_active_portfolio (override operativi)
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
# Config LIVE del paper trader a portafoglio. Seleziona UN portafoglio attivo
|
||||
# (definito in scripts/portfolios/_defs.py) e ne fa l'override dei parametri operativi.
|
||||
active: PORT06 # default raccomandato: master + shape
|
||||
overrides:
|
||||
total_capital: 1000
|
||||
weighting: cap # equal | cap | inverse_vol | cluster_rp | manual
|
||||
caps: {PAIRS: 0.33}
|
||||
leverage: 2 # sobrio per il live reale
|
||||
rebalance: 1D
|
||||
poll_seconds: 60
|
||||
@@ -77,3 +77,18 @@ class Portfolio:
|
||||
risk = {sid: float(rc[k] / pv * 100) if pv > 0 else 0.0
|
||||
for k, sid in enumerate(self.sleeve_ids)}
|
||||
return PortfolioResult(self.code, w, full, oos, yearly_returns(port_dr), risk)
|
||||
|
||||
|
||||
def load_active_portfolio(config_path) -> "Portfolio":
|
||||
"""Carica il portafoglio attivo da portfolios.yml applicando gli override."""
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
from scripts.portfolios._defs import PORTFOLIOS
|
||||
|
||||
cfg = yaml.safe_load(Path(config_path).read_text())
|
||||
p = PORTFOLIOS[cfg["active"]]
|
||||
ov = cfg.get("overrides", {})
|
||||
for k in ("total_capital", "weighting", "caps", "leverage", "rebalance", "vol_lookback"):
|
||||
if k in ov and ov[k] is not None:
|
||||
setattr(p, k, ov[k])
|
||||
return p
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
from src.portfolio.base import load_active_portfolio
|
||||
|
||||
|
||||
def test_load_active_applies_overrides(tmp_path):
|
||||
cfg = tmp_path / "portfolios.yml"
|
||||
cfg.write_text("active: PORT06\noverrides:\n leverage: 2\n total_capital: 500\n")
|
||||
p = load_active_portfolio(cfg)
|
||||
assert p.code == "PORT06"
|
||||
assert p.leverage == 2.0
|
||||
assert p.total_capital == 500
|
||||
Reference in New Issue
Block a user