SortinoLoss

Defined in fynance.models.loss

class SortinoLoss(rf=0., period=252, eps=1e-8)[source]

Bases: BaseLoss

Negative Sortino ratio as a differentiable loss.

Minimizing this loss penalizes downside returns only, unlike SharpeLoss which penalizes both tails symmetrically.

Parameters:
rffloat, optional

Annualized risk-free rate. Default is 0.

periodint, optional

Number of periods per year. Default is 252.

epsfloat, optional

Relative numerical stabilizer scaling the downside-deviation floor (see Notes). Default is 1e-8.

See also

SharpeLoss, DirectionalAccuracyLoss

Notes

The loss is defined as:

\[\mathcal{L} = -\frac{\mu(r - rf_p)} {\sqrt{\mu(\text{ReLU}(-(r - rf_p))^2) + \varepsilon}}\]

where \(r\) is y_pred and \(rf_p = rf / period\). The denominator is a differentiable proxy for the downside deviation; its magnitude differs from the numpy sortino evaluation metric.

This is a training proxy — the value is not comparable to the numpy sortino evaluation metric.

The downside deviation is \(O(\text{returns})\), so a fixed absolute eps inside the square root is dimensionally wrong: on an all-gains batch (zero downside) the loss would explode (e.g. -100). The downside is therefore floored with a returns-scaled epsilon proportional to the excess-return magnitude, keeping the loss finite and bounded while preserving the sign convention.

Examples

>>> import torch
>>> from fynance.models.loss import SortinoLoss
>>> returns = torch.tensor([-0.01, 0.02, 0.01, -0.005, 0.03])
>>> loss_fn = SortinoLoss()
>>> loss = loss_fn(returns)
>>> loss.shape
torch.Size([])
forward(y_pred, y_true=None)[source]

Compute the negative Sortino ratio.

Parameters:
y_predtorch.Tensor

Predicted return series, shape (T,) or (T, M).

y_truetorch.Tensor, optional

Not used; accepted for API compatibility with PyTorch criterions.

Returns:
torch.Tensor

Scalar loss value (negative Sortino ratio proxy).

Raises:
TypeError

If y_pred is not a torch.Tensor.