Trend Labelling

This module provides tools for labelling trends in time series data.

Continuous Trend Labellers

class tstrends.trend_labelling.BinaryCTL(omega)[source]

Binary Continuous Trend Labeller.

This class implements a binary trend labelling algorithm based on the paper by Wu, D., Wang, X., Su, J., Tang, B., & Wu, S. “A Labeling Method for Financial Time Series Prediction Based on Trends”.

The algorithm identifies two distinct states in price movements:
  • Upward trends (label: Labels.UP or 1)

  • Downward trends (label: Labels.DOWN or -1)

Example

>>> labeller = BinaryCTL(omega=0.1)
>>> prices = [1.0, 1.15, 1.2, 1.0]
>>> labels = labeller.get_labels(prices)
>>> print(labels)  # [-1, 1, 1, -1]

Note

The omega parameter determines how significant a price movement must be to be considered a trend change. Higher values result in fewer trend changes being identified.

Parameters:

omega (float)

__init__(omega)[source]

Initialize the continuous trend labeller.

Parameters:

omega (float) – The proportion threshold parameter of the trend definition.

Return type:

None

get_labels(time_series_list: list[float], return_labels_as_int: Literal[True] = True) list[int][source]
get_labels(time_series_list: list[float], return_labels_as_int: Literal[False]) list[Labels]

Auto-labels a price time series based on the provided algorithm.

Parameters:
  • time_series_list (list[float]) – The original time series data X = [x1, x2, …, xN]

  • return_labels_as_int (bool, optional) – If True, returns integer labels (-1, 1), if False returns Labels enum values. Defaults to True.

Returns:

The label vector Y. If return_labels_as_int is True, returns integers (-1, 1), otherwise returns Labels enum values (Labels.DOWN, Labels.UP).

Return type:

Union[list[int], list[Labels]]

class tstrends.trend_labelling.TernaryCTL(marginal_change_thres, window_size)[source]

Ternary Continuous Trend Labeller.

This class implements an adaptation of the Continuous Trend Labeller (CTL) algorithm to a three-state labelling approach. A somewhat not so different approach is proposed in the second pass of the labelling algorithm outlined in the paper by Dezhkam et al. “A Bayesian-based classification framework for financial time series trend prediction.”

The algorithm identifies three distinct states in price movements:
  • Upward trends (label: Labels.UP or 1)

  • Neutral trends (label: Labels.NEUTRAL or 0)

  • Downward trends (label: Labels.DOWN or -1)

Example

>>> labeller = TernaryCTL(marginal_change_thres=0.1, window_size=3)
>>> prices = [1.0, 1.15, 1.2, 1.18, 1.0]
>>> labels = labeller.get_labels(prices)
>>> print(labels)  # [-1, 1, 1, 0, -1]

Note

The window_size parameter helps prevent the algorithm from getting stuck in prolonged sideways movements by forcing a state transition to NEUTRAL after the window is exceeded. It can artificially cut ongoing trends short, so it must be set carefully.

Parameters:
  • marginal_change_thres (float)

  • window_size (int)

__init__(marginal_change_thres, window_size)[source]

Initialize the ternary trend labeller.

Parameters:
  • marginal_change_thres (float) – The threshold for significant price movements as a percentage.

  • window_size (int) – The maximum window to look for trend confirmation before resetting state.

Return type:

None

get_labels(time_series_list: list[float], return_labels_as_int: Literal[True] = True) list[int][source]
get_labels(time_series_list: list[float], return_labels_as_int: Literal[False]) list[Labels]

Labels trends in a time series of closing prices using a ternary classification approach.

The method identifies three distinct states in price movements:
  • Upward trends (label: Labels.UP)

  • Downward trends (label: Labels.DOWN)

  • No-action (label: Labels.NEUTRAL)

The algorithm uses two key parameters:
  • marginal_change_thres: Defines the threshold for significant price movements as a percentage

  • window_size: Maximum window to look for trend confirmation before resetting state

The labeling process works by tracking the current state and transitioning between states when price movements exceed thresholds, while using the window_size parameter to avoid getting stuck in prolonged sideways movements.

Parameters:
  • time_series_list (list[float]) – List of closing prices.

  • return_labels_as_int (bool, optional) – If True, returns integer labels (-1, 0, 1), if False returns Labels enum values. Defaults to True.

Returns:

List of labels. If return_labels_as_int is True, returns integers (-1, 0, 1), otherwise returns Labels enum values.

Return type:

Union[list[int], list[Labels]]

Oracle Labellers

class tstrends.trend_labelling.OracleBinaryTrendLabeller(transaction_cost)[source]

Oracle Binary Trend Labeller.

This class implements a binary version of the Oracle Trend Labelling algorithm, adapted from the paper by T. Kovačević, A. Merćep, S. Begušić and Z. Kostanjčar, “Optimal Trend Labeling in Financial Time Series”.

The algorithm identifies two distinct states:
  • Upward trends (label: Labels.UP or 1)

  • Downward trends (label: Labels.DOWN or -1)

Parameters:

transaction_cost (float)

transaction_cost

Inherited from BaseOracleTrendLabeller.

Type:

float

Example

>>> labeller = OracleBinaryTrendLabeller(transaction_cost=0.001)
>>> prices = [1.0, 1.15, 1.2, 1.0]
>>> labels = labeller.get_labels(prices)
>>> print(labels)  # [-1, 1, 1, -1]

Note

The transaction cost parameter influences how readily the algorithm switches between trends. Higher costs result in more stable trend assignments.

__init__(transaction_cost)[source]

Initialize the binary trend labeller.

Parameters:

transaction_cost (float)

Return type:

None

class tstrends.trend_labelling.OracleTernaryTrendLabeller(transaction_cost, neutral_reward_factor)[source]

Oracle Ternary Trend Labeller.

This class implements an adaptation of the Oracle Trend Labelling algorithm to a three-state setting with dynamic programming. This consists is two main ideas, managing the general behaviour through the neutral state: 1. Transitions between downtrend and uptrend must go through the neutral state. 2. The reward for staying in the neutral state is calculated differently than

the reward for staying in a downtrend or uptrend.

The algorithm identifies three states:
  • Upward trends (label: Labels.UP or 1)

  • Neutral trends (label: Labels.NEUTRAL or 0)

  • Downward trends (label: Labels.DOWN or -1)

Parameters:
  • transaction_cost (float)

  • neutral_reward_factor (float)

transaction_cost

Inherited from BaseOracleTrendLabeller.

Type:

float

neutral_reward_factor

Coefficient for tuning the reward for staying in the neutral state.

Type:

float

Lower values ease the switch into downtrends and uptrends.

Example

>>> labeller = OracleTernaryTrendLabeller(transaction_cost=0.001, neutral_reward_factor=0.5)
>>> prices = [1.0, 1.15, 1.2, 1.18, 1.0]
>>> labels = labeller.get_labels(prices)
>>> print(labels)  # [-1, 1, 1, 0, -1]

Note

The neutral_reward_factor parameter influences how the algorithm weights price changes in the neutral state. The neutral_reward_factor is usually best set lower than 1.0, tuned up together with the transaction_cost.

__init__(transaction_cost, neutral_reward_factor)[source]

Initialize the ternary trend labeller.

Parameters:
  • transaction_cost (float) – Cost coefficient for switching between trends.

  • neutral_reward_factor (float) – Trend coefficient for weighting price changes.

Return type:

None

neutral_reward_factor: float

Enums

class tstrends.trend_labelling.Labels(value)[source]

Standard label values for trend classification.

DOWN = -1
NEUTRAL = 0
UP = 1