pyalloq-features 0.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.3
2
+ Name: pyalloq-features
3
+ Version: 0.1.5
4
+ Summary: Feature Transformations and pipelines for pyalloq.
5
+ Author: Siddeshkanth
6
+ Author-email: Siddeshkanth <pyalloq-info@alloq-alpha.com>
7
+ Requires-Dist: numpy>=1.24
8
+ Requires-Dist: pandas>=2.0
9
+ Requires-Dist: scikit-learn>=1.3.0
10
+ Requires-Dist: scipy>=1.10.0
11
+ Requires-Dist: ta-lib>=0.4.28
12
+ Requires-Dist: pyalloq-core>=0.1.0
13
+ Requires-Python: >=3.11
14
+ Description-Content-Type: text/markdown
15
+
16
+ # pyalloq-features
17
+
18
+ `pyalloq-features` provides feature engineering transformers, TA-Lib indicator integration, scaling utilities, and feature pipeline orchestration for **PyAlloq**.
19
+
20
+ ## Key Modules
21
+
22
+ - **`BaseFeatureTransformer`**: Abstract base class for all feature transformation modules operating on `MarketData`.
23
+ - **`TechnicalIndicator`**: Applies TA-Lib technical indicators (e.g., `SMA`, `RSI`, `MACD`, `ATR`, `BBANDS`) across asset columns of a 2D DataFrame and appends resulting features to `MarketData.features`.
24
+ - **`FeaturePipeline`**: Sequential feature pipeline builder for chaining feature transformers.
25
+ - **`scalers`**: Cross-sectional and time-series feature normalization and standardization utilities.
26
+
27
+ ## Quick Example
28
+
29
+ ```python
30
+ from pyalloq_features.transformers.technical import TechnicalIndicator
31
+ from pyalloq_features.core.pipeline import FeaturePipeline
32
+
33
+ # Define feature engineering pipeline
34
+ pipeline = FeaturePipeline()
35
+ pipeline.add(TechnicalIndicator(indicator="RSI", timeperiod=14))
36
+ pipeline.add(TechnicalIndicator(indicator="SMA", timeperiod=50))
37
+
38
+ # Apply transformations directly to MarketData
39
+ # updated_data = pipeline.run(market_data)
40
+ ```
@@ -0,0 +1,25 @@
1
+ # pyalloq-features
2
+
3
+ `pyalloq-features` provides feature engineering transformers, TA-Lib indicator integration, scaling utilities, and feature pipeline orchestration for **PyAlloq**.
4
+
5
+ ## Key Modules
6
+
7
+ - **`BaseFeatureTransformer`**: Abstract base class for all feature transformation modules operating on `MarketData`.
8
+ - **`TechnicalIndicator`**: Applies TA-Lib technical indicators (e.g., `SMA`, `RSI`, `MACD`, `ATR`, `BBANDS`) across asset columns of a 2D DataFrame and appends resulting features to `MarketData.features`.
9
+ - **`FeaturePipeline`**: Sequential feature pipeline builder for chaining feature transformers.
10
+ - **`scalers`**: Cross-sectional and time-series feature normalization and standardization utilities.
11
+
12
+ ## Quick Example
13
+
14
+ ```python
15
+ from pyalloq_features.transformers.technical import TechnicalIndicator
16
+ from pyalloq_features.core.pipeline import FeaturePipeline
17
+
18
+ # Define feature engineering pipeline
19
+ pipeline = FeaturePipeline()
20
+ pipeline.add(TechnicalIndicator(indicator="RSI", timeperiod=14))
21
+ pipeline.add(TechnicalIndicator(indicator="SMA", timeperiod=50))
22
+
23
+ # Apply transformations directly to MarketData
24
+ # updated_data = pipeline.run(market_data)
25
+ ```
@@ -0,0 +1,26 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.10.9,<0.11.0"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "pyalloq-features"
7
+ version = "0.1.5"
8
+ description = "Feature Transformations and pipelines for pyalloq."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ authors = [{ name = "Siddeshkanth", email = "pyalloq-info@alloq-alpha.com" }]
12
+
13
+ dependencies = [
14
+ "numpy>=1.24",
15
+ "pandas>=2.0",
16
+ "scikit-learn>=1.3.0",
17
+ "scipy>=1.10.0",
18
+ "TA-Lib>=0.4.28",
19
+ "pyalloq-core>=0.1.0"
20
+ ]
21
+
22
+ [dependency-groups]
23
+ dev = ["pytest>=8", "ruff>=0.6", "mypy>=1.11"]
24
+
25
+ [tool.setuptools.packages.find]
26
+ where = ["src/"]
@@ -0,0 +1,17 @@
1
+ from abc import ABC, abstractmethod
2
+ from pyalloq_core.data import MarketData
3
+
4
+
5
+ class BaseFeatureTransformer(ABC):
6
+ """
7
+ Abstract interface for all feature engineering modules.
8
+ Operates directly on the MarketData dataclass.
9
+ """
10
+
11
+ def fit(self, data: MarketData) -> "BaseFeatureTransformer":
12
+ return self
13
+
14
+ @abstractmethod
15
+ def transform(self, data: MarketData) -> MarketData:
16
+ """Applies transformation and strictly appends new columns."""
17
+ ...
@@ -0,0 +1,18 @@
1
+ from .base import BaseFeatureTransformer
2
+ from pyalloq_core.data import MarketData
3
+
4
+
5
+ class FeaturePipeline:
6
+ def __init__(self):
7
+ self.steps = []
8
+
9
+ def add(self, transformer: BaseFeatureTransformer) -> "FeaturePipeline":
10
+ self.steps.append(transformer)
11
+ return self
12
+
13
+ def run(self, data: MarketData) -> MarketData:
14
+ current_data = data
15
+ for step in self.steps:
16
+ current_data = step.transform(current_data)
17
+
18
+ return current_data
@@ -0,0 +1 @@
1
+ # Marker file for PEP 561
@@ -0,0 +1,27 @@
1
+ from pyalloq_features.core.base import BaseFeatureTransformer
2
+ from pyalloq_core.data import MarketData
3
+
4
+
5
+ class RollingZScoreScaler(BaseFeatureTransformer):
6
+ """Point-in-Time Z-Score normalization utilizing backward-looking statistics."""
7
+
8
+ def __init__(self, target_feature: str, window: int = 252) -> None:
9
+ self.target_feature = target_feature
10
+ self.window = window
11
+ self.out_col = f"{target_feature}_zscore_{window}"
12
+
13
+ def transform(self, data: MarketData) -> MarketData:
14
+ df_feature = data.features[self.target_feature]
15
+
16
+ rolling_view = df_feature.rolling(
17
+ window=self.window, min_periods=self.window // 2
18
+ )
19
+ rolling_mean = rolling_view.mean()
20
+ rolling_std = rolling_view.std()
21
+
22
+ epsilon = 1e-8
23
+ data.features[self.out_col] = (df_feature - rolling_mean) / (
24
+ rolling_std + epsilon
25
+ )
26
+
27
+ return data
@@ -0,0 +1,20 @@
1
+ from pyalloq_features.core.base import BaseFeatureTransformer
2
+ from pyalloq_core.data import MarketData
3
+
4
+
5
+ class CrossSectionalRank(BaseFeatureTransformer):
6
+ """
7
+ Ranks a feature cross-sectionality across all available assets at timestamp T.
8
+ """
9
+
10
+ def __init__(self, target_feature: str) -> None:
11
+ self.target_feature = target_feature
12
+ self.out_col = f"{target_feature}_cs_rank"
13
+
14
+ def transform(self, data: MarketData) -> MarketData:
15
+ df_features = data.features[self.target_feature]
16
+
17
+ cs_rank = df_features.rank(axis=1, pct=True)
18
+ data.features[self.out_col] = cs_rank
19
+
20
+ return data
@@ -0,0 +1,48 @@
1
+ import talib
2
+ from pyalloq_features.core.base import BaseFeatureTransformer
3
+ from pyalloq_core.data import MarketData
4
+ import pandas as pd
5
+ import numpy as np
6
+
7
+
8
+ class TechnicalIndicator(BaseFeatureTransformer):
9
+ """
10
+ Applies TA-Lib functions across the asset columns of a 2D DataFrame.
11
+ """
12
+
13
+ def __init__(
14
+ self,
15
+ indicator: str,
16
+ source: str = "prices",
17
+ **kwargs,
18
+ ) -> None:
19
+ self.indicator_name = indicator.upper()
20
+ self.source = source # prices or a key in data.features
21
+ self.kwargs = kwargs
22
+ self._func = getattr(talib, self.indicator_name)
23
+
24
+ params_str = "_".join([str(v) for v in self.kwargs.values()])
25
+ self.out_col = (
26
+ f"{self.indicator_name}_{params_str}" if params_str else self.indicator_name
27
+ )
28
+
29
+ def transform(self, data: MarketData) -> MarketData:
30
+ if self.source == "prices":
31
+ df_source = data.prices
32
+ else:
33
+ df_source = data.features[self.source]
34
+
35
+ df_out = pd.DataFrame(
36
+ index=df_source.index, columns=df_source.columns, dtype=np.float64
37
+ )
38
+
39
+ for ticker in df_source.columns:
40
+ asset_series = df_source[ticker].to_numpy()
41
+ try:
42
+ df_out[ticker] = self._func(asset_series, **self.kwargs)
43
+ except Exception:
44
+ pass
45
+
46
+ data.features[self.out_col] = df_out
47
+
48
+ return data