Scoring¶
The scoring module wraps skfolio ratio measures and custom scoring functions into callables compatible with sklearn cross-validation and hyperparameter tuning. It provides a consistent interface for evaluating portfolio performance during model selection.
Overview¶
When using GridSearchCV or RandomizedSearchCV with portfolio optimizers, you need a scoring function that evaluates the quality of each portfolio. The scoring module maps ratio measure names to sklearn-compatible scorer callables via the frozen-config + factory pattern.
ScorerConfig¶
from optimizer.scoring import ScorerConfig
config = ScorerConfig(
ratio_measure=RatioMeasureType.SHARPE_RATIO,
greater_is_better=None, # auto-detected from measure
)
| Field | Type | Default | Description |
|---|---|---|---|
ratio_measure |
RatioMeasureType or None |
SHARPE_RATIO |
Built-in ratio measure; None for custom scorer |
greater_is_better |
bool or None |
None |
Whether higher scores are better; auto-detected when None |
Presets¶
| Preset | Ratio Measure | Use Case |
|---|---|---|
ScorerConfig.for_sharpe() |
Sharpe Ratio | General-purpose risk-adjusted return |
ScorerConfig.for_sortino() |
Sortino Ratio | Downside-risk-focused evaluation |
ScorerConfig.for_calmar() |
Calmar Ratio | Drawdown-focused evaluation |
ScorerConfig.for_cvar_ratio() |
CVaR Ratio | Tail-risk-focused evaluation |
ScorerConfig.for_information_ratio() |
Information Ratio | Active return vs benchmark |
ScorerConfig.for_custom() |
None |
Custom callable passed to factory |
Available Ratio Measures¶
All 19 ratio measures available in RatioMeasureType:
| Measure | Description |
|---|---|
SHARPE_RATIO |
Excess return / standard deviation |
ANNUALIZED_SHARPE_RATIO |
Annualized Sharpe ratio |
SORTINO_RATIO |
Excess return / downside deviation |
ANNUALIZED_SORTINO_RATIO |
Annualized Sortino ratio |
MEAN_ABSOLUTE_DEVIATION_RATIO |
Return / mean absolute deviation |
FIRST_LOWER_PARTIAL_MOMENT_RATIO |
Return / first lower partial moment |
VALUE_AT_RISK_RATIO |
Return / VaR |
CVAR_RATIO |
Return / CVaR |
ENTROPIC_RISK_MEASURE_RATIO |
Return / entropic risk |
EVAR_RATIO |
Return / EVaR |
WORST_REALIZATION_RATIO |
Return / worst realization |
DRAWDOWN_AT_RISK_RATIO |
Return / drawdown-at-risk |
CDAR_RATIO |
Return / CDaR |
CALMAR_RATIO |
Return / max drawdown |
AVERAGE_DRAWDOWN_RATIO |
Return / average drawdown |
EDAR_RATIO |
Return / EDaR |
ULCER_INDEX_RATIO |
Return / ulcer index |
GINI_MEAN_DIFFERENCE_RATIO |
Return / Gini mean difference |
INFORMATION_RATIO |
Active return / tracking error (custom) |
Building Scorers¶
from optimizer.scoring import ScorerConfig, build_scorer
# Built-in ratio measure
scorer = build_scorer(ScorerConfig.for_sharpe())
# Information ratio (requires benchmark)
scorer = build_scorer(
ScorerConfig.for_information_ratio(),
benchmark_returns=benchmark_returns,
)
# Custom scoring function
def my_scorer(portfolio):
return portfolio.annualized_mean / portfolio.max_drawdown
scorer = build_scorer(ScorerConfig.for_custom(), custom_func=my_scorer)
Code Examples¶
Using with hyperparameter tuning¶
from optimizer.scoring import ScorerConfig
from optimizer.tuning import GridSearchConfig
# Grid search scored by Sortino ratio
tuning_config = GridSearchConfig(
scorer_config=ScorerConfig.for_sortino(),
n_jobs=-1,
)
Using with cross-validation¶
from optimizer.scoring import ScorerConfig, build_scorer
from optimizer.validation import WalkForwardConfig, run_cross_val
scorer = build_scorer(ScorerConfig.for_calmar())
# scorer is a callable compatible with sklearn CV
Gotchas and Tips¶
Information Ratio requires benchmark
The INFORMATION_RATIO is not a native skfolio ratio measure — it is implemented as a custom scorer (active return / tracking error). You must pass benchmark_returns to build_scorer().
Scorer sign convention
All built-in ratio measures follow the sklearn convention where greater_is_better=True. The scorer returns positive values for good portfolios and the search maximizes the score.
Default scorer
When no ScorerConfig is provided to tuning, the default is Sharpe ratio — a reasonable choice for most equity portfolio strategies.
Quick Reference¶
| Task | Code |
|---|---|
| Sharpe scorer | build_scorer(ScorerConfig.for_sharpe()) |
| Sortino scorer | build_scorer(ScorerConfig.for_sortino()) |
| Calmar scorer | build_scorer(ScorerConfig.for_calmar()) |
| CVaR ratio scorer | build_scorer(ScorerConfig.for_cvar_ratio()) |
| Information ratio | build_scorer(ScorerConfig.for_information_ratio(), benchmark_returns=bm) |
| Custom scorer | build_scorer(ScorerConfig.for_custom(), custom_func=fn) |