Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Heuristic:HKUDS AI Trader Sortino Ratio Capping

From Leeroopedia



Knowledge Sources
Domains Metrics, Visualization
Last Updated 2026-02-09 14:00 GMT

Overview

Cap Sortino Ratio values to the range [-20, 20] and apply a minimum downside standard deviation threshold of 0.0001 to prevent extreme spikes in performance visualization charts.

Description

The Sortino Ratio measures risk-adjusted return using only downside deviation. In early trading periods or when an agent has few/no negative returns, the ratio can spike to extreme values (infinity or very large numbers), making charts unreadable. The AI-Trader system applies two stabilization techniques: (1) clipping the Sortino to [-20, 20] using np.clip(), and (2) enforcing a minimum downside standard deviation of 0.0001 to prevent division-by-near-zero. When there are no negative returns at all, a positive mean return is capped at 20.

Usage

Apply this heuristic in performance visualization and metrics reporting code. Any expanding-window Sortino calculation should use these caps. Without them, early-period charts will show vertical spikes that obscure meaningful trends.

The Insight (Rule of Thumb)

  • Action: Apply np.clip(sortino, -20, 20) after calculation. Set min_downside_std = 0.0001 as a floor.
  • Value: Cap = 20 (positive and negative). Minimum denominator = 0.0001.
  • Trade-off: Capping masks genuinely extreme performance in rare cases. A Sortino of 25 would display as 20. This is acceptable for visualization but raw metrics should preserve the true value.

Reasoning

In expanding-window calculations, early periods have very few data points. If the first few returns are all positive, downside deviation is zero, producing an infinite Sortino. Even with 1-2 negative returns, a tiny downside std (e.g., 0.00001) produces ratios in the thousands. The cap of 20 was chosen as a practical upper bound: real-world annual Sortino ratios above 5 are exceptional, so 20 provides ample headroom while preventing chart distortion.

Code Evidence

Sortino capping from tools/plot_metrics.py:86-98:

if len(negative_returns) > 0:
    downside_std = negative_returns.std()
    # Use a minimum threshold for downside std to avoid extreme spikes
    min_downside_std = 0.0001
    downside_std = max(downside_std, min_downside_std)

    sortino = (returns_so_far.mean() / downside_std) * np.sqrt(periods_per_year)
    # Cap to reasonable range
    sortino = np.clip(sortino, -20, 20)
else:
    # No negative returns yet
    mean_return = returns_so_far.mean()
    if mean_return > 0:
        sortino = 20  # Cap at upper limit
    else:
        sortino = 0

Sortino in final metrics from tools/calculate_metrics.py:227-232:

negative_returns = returns[returns < 0]
if len(negative_returns) > 0:
    downside_std = np.std(negative_returns)
    sortino = excess_return / downside_std * np.sqrt(periods_per_year) if downside_std > 0 else 0
else:
    sortino = float('inf') if np.mean(returns) > 0 else 0

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment