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.
- pyalloq_features-0.1.5/PKG-INFO +40 -0
- pyalloq_features-0.1.5/README.md +25 -0
- pyalloq_features-0.1.5/pyproject.toml +26 -0
- pyalloq_features-0.1.5/src/pyalloq_features/__init__.py +0 -0
- pyalloq_features-0.1.5/src/pyalloq_features/core/__init__.py +0 -0
- pyalloq_features-0.1.5/src/pyalloq_features/core/base.py +17 -0
- pyalloq_features-0.1.5/src/pyalloq_features/core/exceptions.py +0 -0
- pyalloq_features-0.1.5/src/pyalloq_features/core/pipeline.py +18 -0
- pyalloq_features-0.1.5/src/pyalloq_features/py.typed +1 -0
- pyalloq_features-0.1.5/src/pyalloq_features/scalers/__init__.py +0 -0
- pyalloq_features-0.1.5/src/pyalloq_features/scalers/rolling.py +27 -0
- pyalloq_features-0.1.5/src/pyalloq_features/scalers/stationary.py +0 -0
- pyalloq_features-0.1.5/src/pyalloq_features/transformers/__init__.py +0 -0
- pyalloq_features-0.1.5/src/pyalloq_features/transformers/alternative.py +0 -0
- pyalloq_features-0.1.5/src/pyalloq_features/transformers/cross_sectional.py +20 -0
- pyalloq_features-0.1.5/src/pyalloq_features/transformers/mergers.py +0 -0
- pyalloq_features-0.1.5/src/pyalloq_features/transformers/technical.py +48 -0
|
@@ -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/"]
|
|
File without changes
|
|
File without changes
|
|
@@ -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
|
+
...
|
|
File without changes
|
|
@@ -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
|
|
File without changes
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -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
|
|
File without changes
|
|
@@ -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
|