DirectionalAccuracyLoss

Defined in fynance.models.loss

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

Bases: BaseLoss

Negative directional accuracy as a differentiable surrogate loss.

The true directional accuracy (fraction of correctly predicted signs) is non-differentiable. This loss replaces the hard sign comparison with a sigmoid surrogate, making it suitable for gradient-based optimization.

Parameters:
rffloat, optional

Not used; inherited from BaseLoss for API consistency.

periodint, optional

Not used; inherited from BaseLoss for API consistency.

epsfloat, optional

Not used; inherited from BaseLoss for API consistency.

temperaturefloat, optional

Sigmoid sharpness. Higher values push the surrogate closer to the hard sign indicator. Default is 1.0.

See also

SharpeLoss, SortinoLoss

Notes

The surrogate loss is:

\[\mathcal{L} = -\frac{1}{T} \sum_{t=1}^{T} \sigma(\hat{y}_t \cdot y_t \cdot T_{emp})\]

where \(\sigma\) is the logistic sigmoid, \(T_{emp}\) is the temperature parameter controlling sharpness, and a higher temperature produces a harder approximation closer to the true 0/1 accuracy.

This is a training proxy — the value is not comparable to the numpy directional_accuracy metric, which returns a hard 0/1 fraction.

Examples

>>> import torch
>>> from fynance.models.loss import DirectionalAccuracyLoss
>>> y_true = torch.tensor([1., -1., 1., -1., 1.])
>>> y_pred = torch.tensor([0.5, -0.3, 0.1, -0.8, 0.2])
>>> loss_fn = DirectionalAccuracyLoss()
>>> loss = loss_fn(y_pred, y_true)
>>> loss.shape
torch.Size([])
>>> loss.item() < 0   # all directions correct → loss close to -1
True
forward(y_pred, y_true)[source]

Compute the negative directional accuracy surrogate.

Parameters:
y_predtorch.Tensor

Predicted values, shape (T,) or (T, M).

y_truetorch.Tensor

True values, same shape as y_pred.

Returns:
torch.Tensor

Scalar loss (negative sigmoid-based directional accuracy).

Raises:
TypeError

If y_pred or y_true is not a torch.Tensor.