Coverage for src/ifunnel/models/lifecycle/glidePathCreator.py: 0%
19 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
3import plotly.express as px
6def generate_risk_profiles(n_periods: int, initial_risk: float, minimum_risk: float) -> (pd.DataFrame, px.line):
7 """Generate risk profiles for glide paths."""
9 df = pd.DataFrame(index=range(n_periods))
10 x_values = np.linspace(0, 1, n_periods)
12 df["Linear GP"] = np.linspace(initial_risk, minimum_risk, n_periods)
13 df["Concave GP"] = initial_risk - (initial_risk - minimum_risk) * (x_values**2)
14 df["Convex GP"] = initial_risk - (initial_risk - minimum_risk) * np.sqrt(x_values)
16 fig = px.line(
17 df,
18 labels={"value": "Risk", "index": "Period"},
19 title="Risk Budget Glide Paths",
20 ).update_traces(mode="lines")
21 fig.update_layout(
22 yaxis_title="Annual Standard Deviation",
23 xaxis_title="Period",
24 legend_title="Risk Budget Glide Paths",
25 height=900,
26 width=1500,
27 template="plotly_white",
28 )
30 # Update y-axis properties
31 fig.update_yaxes(
32 showgrid=True,
33 showline=True,
34 gridcolor="rgba(211, 211, 211, 0.5)",
35 tickformat=".0%",
36 title_font=dict(size=15),
37 range=[0, initial_risk * 1.1],
38 )
39 # Update x-axis properties, setting it to reverse
40 fig.update_xaxes(
41 showgrid=False,
42 showline=True,
43 title_font=dict(size=15),
44 gridcolor="rgba(211, 211, 211, 0.5)",
45 )
47 # Colors and line width
48 colors = [
49 "#99A4AE", # gray50
50 "#3b4956", # dark
51 "#b7ada5", # secondary
52 "#4099da", # blue
53 "#8ecdc8", # aqua
54 "#e85757", # coral
55 "#fdd779", # sun
56 "#644c76", # eggplant
57 "#D8D1CA", # warmGray50
58 # Additional colors if needed
59 ]
61 for i, trace in enumerate(fig.data):
62 trace.line.color = colors[i % len(colors)]
63 trace.line.width = 2.5
65 fig.layout.yaxis.tickformat = ",.1%"
67 # fig.show()
68 return df, fig