tstrends.trend_labelling package

Submodules

tstrends.trend_labelling.base_labeller module

class tstrends.trend_labelling.base_labeller.BaseLabeller[source]

Bases: ABC

Abstract base class for trend labellers.

This class serves as a template for all trend labelling implementations. It provides common input validation functionality and defines the interface that all trend labellers must implement.

None

Example

To implement a new trend labeller, inherit from this class and implement the get_labels method:

class MyLabeller(BaseLabeller):
    def get_labels(self, time_series_list, return_labels_as_int=True):
        # Implementation here
        pass
abstractmethod get_labels(time_series_list: list[float], return_labels_as_int: Literal[True] = True) list[int][source]
abstractmethod get_labels(time_series_list: list[float], return_labels_as_int: Literal[False]) list[Labels]

Label trends in a time series of prices.

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

  • 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 trend labels, either as integers or Labels enum values.

Return type:

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

tstrends.trend_labelling.binary_CTL module

class tstrends.trend_labelling.binary_CTL.TrendState(current_high=0.0, current_low=0.0, curr_high_time=0, curr_low_time=0, current_direction=Labels.NEUTRAL, extreme_point_idx=0)[source]

Bases: object

Holds the state for trend labelling process.

Parameters:
  • current_high (float)

  • current_low (float)

  • curr_high_time (int)

  • curr_low_time (int)

  • current_direction (Labels)

  • extreme_point_idx (int)

current_high: float = 0.0
current_low: float = 0.0
curr_high_time: int = 0
curr_low_time: int = 0
current_direction: Labels = 0
extreme_point_idx: int = 0
set_upwards_trend(price, time_idx)[source]

Set the state for an upward trend.

Parameters:
  • price (float) – The current price value

  • time_idx (int) – The current time index

Return type:

None

set_downwards_trend(price, time_idx)[source]

Set the state for a downward trend.

Parameters:
  • price (float) – The current price value

  • time_idx (int) – The current time index

Return type:

None

__init__(current_high=0.0, current_low=0.0, curr_high_time=0, curr_low_time=0, current_direction=Labels.NEUTRAL, extreme_point_idx=0)
Parameters:
  • current_high (float)

  • current_low (float)

  • curr_high_time (int)

  • curr_low_time (int)

  • current_direction (Labels)

  • extreme_point_idx (int)

Return type:

None

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

Bases: BaseLabeller

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]]

tstrends.trend_labelling.label_scaling module

Label scaling utilities for trend labelling.

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

Bases: IntEnum

Standard label values for trend classification.

DOWN = -1
NEUTRAL = 0
UP = 1
tstrends.trend_labelling.label_scaling.scale_binary(labels)[source]

Scale binary labels from {0,1} to {-1,1}.

Parameters:

labels (NDArray[np.int_]) – Input labels (must contain only 0s and 1s)

Returns:

Scaled labels in {-1,1}

Return type:

NDArray[np.int_]

tstrends.trend_labelling.label_scaling.scale_ternary(labels)[source]

Scale ternary labels from {0,1,2} to {-1,0,1}.

Parameters:

labels (NDArray[np.int_]) – Input labels (must contain only 0s, 1s, and 2s)

Returns:

Scaled labels in {-1,0,1}

Return type:

NDArray[np.int_]

tstrends.trend_labelling.label_scaling.extract_label_values(labels)[source]

Convert a list of Labels enum to their integer values.

Parameters:

labels (list[Labels]) – List of Labels enum values.

Returns:

List of integer values corresponding to the Labels enum values.

Return type:

list[int]

tstrends.trend_labelling.oracle_labeller module

class tstrends.trend_labelling.oracle_labeller.BaseOracleTrendLabeller(transaction_cost)[source]

Bases: BaseLabeller

Base class for Oracle Trend Labellers.

This class implements the core functionality of the Oracle Trend Labelling algorithm, which uses dynamic programming to find optimal trend labels by maximizing returns while considering transaction costs.

The algorithm works in three main steps:
  1. Compute transition costs between states

  2. Forward pass to calculate cumulative returns

  3. Backward pass to determine optimal labels

Parameters:

transaction_cost (float)

transaction_cost

Cost coefficient for making a transaction between states.

Type:

float

Note

This is an abstract base class. Concrete implementations must provide the _scale_labels method to define how raw labels are scaled to the final output format.

__init__(transaction_cost)[source]

Initialize the base Oracle Trend Labeller.

Parameters:

transaction_cost (float) – Cost of making a transaction

Return type:

None

transaction_cost: float
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]

Run the full Oracle Trend Labeling Algorithm over a time series.

Parameters:
  • time_series_list (list[float]) – The price series.

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

Returns:

Optimal trend labels. If return_labels_as_int is True, returns scaled integers,

otherwise returns Labels enum values.

Return type:

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

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

Bases: BaseOracleTrendLabeller

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.oracle_labeller.OracleTernaryTrendLabeller(transaction_cost, neutral_reward_factor)[source]

Bases: BaseOracleTrendLabeller

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

tstrends.trend_labelling.ternary_CTL module

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

Bases: BaseLabeller

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]]

Module contents

class tstrends.trend_labelling.BaseLabeller[source]

Bases: ABC

Abstract base class for trend labellers.

This class serves as a template for all trend labelling implementations. It provides common input validation functionality and defines the interface that all trend labellers must implement.

None

Example

To implement a new trend labeller, inherit from this class and implement the get_labels method:

class MyLabeller(BaseLabeller):
    def get_labels(self, time_series_list, return_labels_as_int=True):
        # Implementation here
        pass
abstractmethod get_labels(time_series_list: list[float], return_labels_as_int: Literal[True] = True) list[int][source]
abstractmethod get_labels(time_series_list: list[float], return_labels_as_int: Literal[False]) list[Labels]

Label trends in a time series of prices.

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

  • 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 trend labels, either as integers or Labels enum values.

Return type:

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

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

Bases: BaseLabeller

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.OracleBinaryTrendLabeller(transaction_cost)[source]

Bases: BaseOracleTrendLabeller

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.TernaryCTL(marginal_change_thres, window_size)[source]

Bases: BaseLabeller

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]]

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

Bases: BaseOracleTrendLabeller

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
class tstrends.trend_labelling.Labels(value)[source]

Bases: IntEnum

Standard label values for trend classification.

DOWN = -1
NEUTRAL = 0
UP = 1