Skip to content

Commit e5891c9

Browse files
committed
chore: format codebase with black and fix lint warnings
1 parent 42256fc commit e5891c9

File tree

6 files changed

+37
-9
lines changed

6 files changed

+37
-9
lines changed

.coverage

0 Bytes
Binary file not shown.
499 Bytes
Binary file not shown.

src/quant_research_starter/metrics/risk.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ def _calculate_risk_metrics(self) -> Dict[str, float]:
4646
vol = float(self.returns.std(ddof=1) * np.sqrt(252))
4747
downside_returns = self.returns[self.returns < 0]
4848
downside_vol = (
49-
float(downside_returns.std(ddof=1) * np.sqrt(252)) if len(downside_returns) > 0 else 0.0
49+
float(downside_returns.std(ddof=1) * np.sqrt(252))
50+
if len(downside_returns) > 0
51+
else 0.0
5052
)
5153

5254
max_drawdown, drawdown_duration = self._calculate_drawdown()
@@ -57,7 +59,9 @@ def _calculate_risk_metrics(self) -> Dict[str, float]:
5759
"max_drawdown": max_drawdown,
5860
"drawdown_duration": drawdown_duration,
5961
"var_95": float(self.returns.quantile(0.05)),
60-
"cvar_95": float(self.returns[self.returns <= self.returns.quantile(0.05)].mean()),
62+
"cvar_95": float(
63+
self.returns[self.returns <= self.returns.quantile(0.05)].mean()
64+
),
6165
}
6266

6367
def _calculate_ratio_metrics(self) -> Dict[str, float]:
@@ -91,7 +95,9 @@ def _calculate_benchmark_metrics(self) -> Dict[str, float]:
9195
return {}
9296

9397
# Ensure identical index after dropna
94-
strategy_returns, benchmark_returns = strategy_returns.align(benchmark_returns, join="inner")
98+
strategy_returns, benchmark_returns = strategy_returns.align(
99+
benchmark_returns, join="inner"
100+
)
95101

96102
x = benchmark_returns.values.astype(float)
97103
y = strategy_returns.values.astype(float)
@@ -114,10 +120,18 @@ def _calculate_benchmark_metrics(self) -> Dict[str, float]:
114120

115121
# Tracking error (annualized std of active returns)
116122
active_returns = (strategy_returns - benchmark_returns).dropna()
117-
tracking_error = float(active_returns.std(ddof=1) * np.sqrt(252)) if len(active_returns) > 1 else 0.0
123+
tracking_error = (
124+
float(active_returns.std(ddof=1) * np.sqrt(252))
125+
if len(active_returns) > 1
126+
else 0.0
127+
)
118128

119129
# Information ratio
120-
info_ratio = float((strategy_cagr - benchmark_cagr) / tracking_error) if tracking_error > 0 else 0.0
130+
info_ratio = (
131+
float((strategy_cagr - benchmark_cagr) / tracking_error)
132+
if tracking_error > 0
133+
else 0.0
134+
)
121135

122136
return {
123137
"alpha": alpha,
@@ -144,7 +158,11 @@ def _calculate_cagr_from_returns(self, returns: pd.Series) -> float:
144158
def _calculate_downside_vol(self) -> float:
145159
"""Calculate downside volatility (for Sortino ratio)."""
146160
downside_returns = self.returns[self.returns < 0]
147-
return float(downside_returns.std(ddof=1) * np.sqrt(252)) if len(downside_returns) > 0 else 0.0
161+
return (
162+
float(downside_returns.std(ddof=1) * np.sqrt(252))
163+
if len(downside_returns) > 0
164+
else 0.0
165+
)
148166

149167
def _calculate_drawdown(self) -> Tuple[float, int]:
150168
"""Calculate maximum drawdown and duration."""
@@ -168,8 +186,14 @@ def _calculate_drawdown(self) -> Tuple[float, int]:
168186
try:
169187
prior_max_mask = running_max[running_max.index <= max_dd_period]
170188
drawdown_start_val = prior_max_mask.max()
171-
start_candidates = prior_max_mask[prior_max_mask == drawdown_start_val].index
172-
drawdown_start = start_candidates[-1] if len(start_candidates) > 0 else running_max.index[0]
189+
start_candidates = prior_max_mask[
190+
prior_max_mask == drawdown_start_val
191+
].index
192+
drawdown_start = (
193+
start_candidates[-1]
194+
if len(start_candidates) > 0
195+
else running_max.index[0]
196+
)
173197
drawdown_duration = int((max_dd_period - drawdown_start).days)
174198
except Exception:
175199
drawdown_duration = 0
0 Bytes
Binary file not shown.
4 Bytes
Binary file not shown.

tests/test_metrics.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ def test_benchmark_metrics(self, sample_returns, benchmark_returns):
123123
# compute Spearman correlation between series (fallback to ensure relation is meaningful)
124124
strategy = sample_returns.loc[benchmark_returns.index].dropna()
125125
bench = benchmark_returns.loc[strategy.index].dropna()
126-
if len(strategy) > 10 and np.all(np.isfinite(strategy)) and np.all(np.isfinite(bench)):
126+
if (
127+
len(strategy) > 10
128+
and np.all(np.isfinite(strategy))
129+
and np.all(np.isfinite(bench))
130+
):
127131
spearman = strategy.corr(bench, method="spearman")
128132
# if the two series are meaningfully correlated (|spearman| > 0.2), expect beta in a reasonable range
129133
if abs(spearman) > 0.2:

0 commit comments

Comments
 (0)