Coverage for src/ifunnel/models/MVOtargets.py: 100%
30 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-12 09:14 +0000
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-12 09:14 +0000
1import numpy as np
2import pandas as pd
3from loguru import logger
5from .ScenarioGeneration import MomentGenerator
8# FUNCTION RUNNING THE OPTIMIZATION
9# ----------------------------------------------------------------------
10def portfolio_risk_target(covariance: np.array) -> float:
11 # Fixed equal weight x
12 n = covariance.shape[0]
13 x = np.ones(n) / n
15 # Volatility
16 portfolio_vty = np.sqrt(x @ covariance @ x)
18 return portfolio_vty
21# ----------------------------------------------------------------------
22# Mathematical Optimization: TARGETS GENERATION
23# ----------------------------------------------------------------------
24def get_mvo_targets(
25 test_date: str, benchmark: list, budget: int, data: pd.DataFrame
26) -> tuple[pd.DataFrame, pd.DataFrame]:
27 logger.info(f"🎯 Generating Volatility targets for {benchmark}")
29 # Define Benchmark
30 tickers = benchmark
31 # Get weekly return of our benchmark
32 whole_dataset_benchmark = data[tickers].copy()
34 # Get weekly data just for testing period
35 test_dataset_benchmark = whole_dataset_benchmark[whole_dataset_benchmark.index >= test_date]
37 # Number of weeks for testing
38 weeks_n = len(test_dataset_benchmark.index)
40 # Get parameters
41 sigma_lst, _ = MomentGenerator.generate_sigma_mu_for_test_periods(whole_dataset_benchmark, weeks_n)
43 # Compute the optimal portfolio outperforming zero percentage return
44 # ----------------------------------------------------------------------
45 p_points = len(sigma_lst) # number of periods
47 # COMPUTE MVO TARGETS
48 list_targets = []
49 for p in range(p_points):
50 # Get parameters for a given period p
51 sigma = sigma_lst[p]
53 # Compute volatility targets
54 vty_target = portfolio_risk_target(sigma)
56 # save the result
57 list_targets.append(vty_target)
59 # Generate new column so that dtype is set right.
60 targets = pd.DataFrame(columns=["Vty_Target"], data=list_targets)
62 # COMPUTE PORTFOLIO VALUE
63 list_portfolio_values = []
64 for w in test_dataset_benchmark.index:
65 budget_next = sum((budget / len(tickers)) * (1 + test_dataset_benchmark.loc[w, :]))
66 list_portfolio_values.append(budget_next)
67 budget = budget_next
69 # Generate dataframe so that dtype is set right.
70 portfolio_value = pd.DataFrame(
71 columns=["Benchmark_Value"],
72 index=test_dataset_benchmark.index,
73 data=list_portfolio_values,
74 )
76 return targets, portfolio_value