Label Tuning

The label tuning module enhances trend labels (UP/NEUTRAL/DOWN) by adding information about the potential trend magnitude, making them more useful for training prediction models.

After raw magnitudes are computed, RemainingValueTuner can run an ordered list of postprocessors—filters, shifters, and smoothers—that all implement tstrends.label_tuning.base.BasePostprocessor (see the tstrends.label_tuning.base section in the package API).

RemainingValueTuner

class tstrends.label_tuning.RemainingValueTuner(postprocessors=None)[source]

Bases: BaseLabelTuner

A tuner that calculates the remaining value change in intervals of continuous labels.

For each point in the time series, it calculates the absolute value change from the current position to the end of the current trend interval.

Parameters:

postprocessors (list[BasePostprocessor] | None)

postprocessors

Steps applied in order after computing remaining values (e.g. Shifter, ForwardLookingFilter, smoothers). Pass time_series and labels into each step for filters; smoothers and shifters ignore context as documented on each class.

Type:

Optional[list[BasePostprocessor]], optional

__init__(postprocessors=None)[source]

Initialize the RemainingValueTuner.

Parameters:

postprocessors (list[BasePostprocessor] | None)

tune(time_series, labels, enforce_monotonicity=False, normalize_over_interval=False, **kwargs)[source]

Tune trend labels to provide information about remaining value change.

For each point in the time series, calculates how much the value will change until the end of the current trend interval. The sign of the result matches the original label.

Parameters:
  • time_series (list[float]) – The price series used for trend detection.

  • labels (list[int]) – The original trend labels (-1, 1) or (-1, 0, 1).

  • enforce_monotonicity (bool, optional) – If True, the labels in each interval will not reverse on uncaptured countertrends.

  • normalize_over_interval (bool, optional) – If True, the remaining value change will be normalized over the interval.

  • kwargs (Any)

Returns:

Tuned up labels with the list of postprocessors applied.

Return type:

list[float]

Forward-looking filter

class tstrends.label_tuning.ForwardLookingFilter(forward_window=None, forward_window_rel=None, smoothing_window=None, smoothing_window_rel=None, quantile=0.95)[source]

Bases: BaseFilter

Per-timestep weights from a normalized forward-looking efficiency metric.

For timestep t inside an interval (with horizon h):

\[e_t = \frac{|x_{t+h} - x_t|}{\sum_{k=1}^{h} |x_{t+k} - x_{t+k-1}| + \epsilon}\]

Weights are smoothed to avoid propagating time series noise into the labels and scaled by a high quantile (avoiding a max to add robustness) so that low-efficiency regions are downweighted but not zeroed.

Parameters:
__init__(forward_window=None, forward_window_rel=None, smoothing_window=None, smoothing_window_rel=None, quantile=0.95)[source]
Parameters:
  • forward_window (int | None) – Absolute horizon h for efficiency (net vs path length).

  • forward_window_rel (float | None) – Relative horizon as a fraction of each trend interval length (mutually exclusive with forward_window).

  • smoothing_window (int | None) – Length of the centered moving-average kernel on the filtering weights.

  • smoothing_window_rel (float | None) – Relative length of the centered moving-average kernel on the filtering weights, as a fraction of each trend interval length (mutually exclusive with smoothing_window).

  • quantile (float) – High quantile for robust normalization denominator.

Return type:

None

get_coefficients(time_series, labels)[source]

Compute per-timestep multiplicative coefficients.

Parameters:
  • time_series (list[float] | ndarray) – The price series used for efficiency (or other) metrics.

  • labels (list[int] | ndarray) – The trend labels (-1, 0, 1).

Returns:

One-dimensional array of coefficients, same length as inputs.

Return type:

ndarray

Shifter

class tstrends.label_tuning.Shifter(periods)[source]

Bases: BasePostprocessor

Shift tuned values forward (positive periods) or backward (negative).

Forward shift moves each value to a later index, padding the start with zeros. Backward shift moves values to earlier indices, padding the end with zeros.

Parameters:

periods (int)

periods

Number of steps to shift; must be non-zero. Sign sets direction.

__init__(periods)[source]
Parameters:

periods (int)

Return type:

None

process(values, time_series, labels)[source]

Transform values in the tuner pipeline.

Parameters:
  • values (list[float] | ndarray) – Tuned magnitudes aligned with time_series.

  • time_series (list[float] | ndarray) – The price series (unused by some subclasses).

  • labels (list[int] | ndarray) – The trend labels (-1, 0, 1); unused by some subclasses.

Returns:

Transformed values as a float array of the same length as values.

Return type:

ndarray

Smoothing

class tstrends.label_tuning.smoothing.SimpleMovingAverage(window_size=3, direction='left')[source]

Bases: BaseSmoother

Simple moving average smoother with equal weights.

This smoother applies equal weights to all values in the window, resulting in uniform smoothing. Each point in the window has the same influence on the result.

Examples

For a window size of 3: - With values [10, 20, 30], each value gets 1/3 weight (33.3%) - Result = (10 * 0.333) + (20 * 0.333) + (30 * 0.333) = 20

This approach produces gradual smoothing with consistent lag across all frequencies, making it good for removing noise but less responsive to recent changes.

Parameters:
__init__(window_size=3, direction='left')[source]

Initialize the smoother with a window size.

Parameters:
  • window_size (int) – Number of periods to include in the smoothing window.

  • direction (Union[str, Direction]) – Direction of smoothing, either “left” or “centered”. Can be provided as string or Direction enum.

Raises:
  • ValueError – If window_size < 2 or direction is invalid.

  • TypeError – If direction is not a string or Direction enum.

smooth(values)[source]

Apply smoothing to the input values.

Parameters:

values (list[float]) – The input values to smooth.

Returns:

The smoothed values, same length as input.

Return type:

np.ndarray

class tstrends.label_tuning.smoothing.LinearWeightedAverage(window_size=3, direction='left')[source]

Bases: BaseSmoother

Linear weighted moving average smoother.

This smoother applies linearly increasing weights to values in the window, giving more importance to recent values and less to older ones. This creates a more responsive smoothing that better preserves the shape of trends.

Examples

For a window size of 3 with left-sided smoothing: - With values [10, 20, 30], weights are distributed as:

  • Oldest value (10): 1/6 weight (16.7%)

  • Middle value (20): 2/6 weight (33.3%)

  • Recent value (30): 3/6 weight (50.0%)

  • Result = (10 * 0.167) + (20 * 0.333) + (30 * 0.5) = 23.33

Compared to SimpleMovingAverage, LinearWeightedAverage: - Responds more quickly to recent changes - Reduces lag in trend detection - Better preserves the shape of peaks and valleys - More effective for early trend detection

Parameters:
__init__(window_size=3, direction='left')[source]

Initialize the smoother with a window size.

Parameters:
  • window_size (int) – Number of periods to include in the smoothing window.

  • direction (Union[str, Direction]) – Direction of smoothing, either “left” or “centered”. Can be provided as string or Direction enum.

Raises:
  • ValueError – If window_size < 2 or direction is invalid.

  • TypeError – If direction is not a string or Direction enum.

smooth(values)[source]

Apply smoothing to the input values.

Parameters:

values (list[float]) – The input values to smooth.

Returns:

The smoothed values, same length as input.

Return type:

np.ndarray

Smoothing Direction

class tstrends.label_tuning.smoothing_direction.Direction(value)[source]

Bases: Enum

Direction of smoothing to apply.

The direction determines which values are included in the smoothing window relative to the current point being smoothed.

Values:
LEFT: Only uses past values (causal smoothing).

For point at time t, uses points [t-n+1, t-n+2, …, t].

CENTERED: Uses both past and future values (non-causal smoothing).

For point at time t, uses points [t-n/2, …, t, …, t+n/2].

Example

For a time series [10, 20, 30, 40, 50] with window_size=3: - LEFT smoothing for point at index 2 (value 30) uses [10, 20, 30] - CENTERED smoothing for point at index 2 (value 30) uses [20, 30, 40]

LEFT = 'left'
CENTERED = 'centered'