pyalbedo 0.0.1
Transform raw market data into indicators and trading signals—no decisions, no orders
Requires Python: >=3.10
Keywords: trading, signals, indicators, technical-analysis, rsi, macd, bollinger, ema, market-data

# PyAlbedo

Transform raw market data into indicators and trading signals—no decisions, no orders.

**PyAlbedo** is a minimal-dependency Python library that answers one question: *"What does the data suggest right now?"* It provides pure mathematical indicators (EMA, RSI, MACD, Bollinger Bands, ATR, etc.) and signal generators (crossover, mean reversion, breakout) that interpret those indicators and emit structured signals. It does **not** handle position sizing, order generation, persistence, or market data fetching—that stays in your strategy and execution layers.

## Installation

```bash
pip install pyalbedo
```

With optional dependencies:

```bash
pip install pyalbedo[dev]   # pytest, hypothesis, ruff, mypy
pip install pyalbedo[pandas] # DataFrame helpers (future)
```

## Quick example

```python
import numpy as np
from pyalbedo import MarketDataWindow, EMA, RSI
from pyalbedo.signals import MACrossover, RSIMeanReversion, SignalAggregator

# Build a window from arrays (e.g. from your data source)
close = np.random.rand(200) * 100 + 100
high = close + np.random.rand(200) * 2
low = close - np.random.rand(200) * 2
open_ = np.roll(close, 1)
open_[0] = close[0]
volume = np.random.rand(200) * 1e6

window = MarketDataWindow.from_arrays(
    symbol="AAPL",
    open_=open_, high=high, low=low, close=close,
    volume=volume,
)

# Indicators: pure transformations
ema_fast = EMA(period=12)
ema_slow = EMA(period=26)
fast = ema_fast.calculate(close)
slow = ema_slow.calculate(close)

rsi = RSI(period=14)
rsi_series = rsi.calculate(close)

# Signal generators: interpret and emit
ma_cross = MACrossover(fast_period=12, slow_period=26)
rsi_reversion = RSIMeanReversion(period=14, oversold=30, overbought=70)
aggregator = SignalAggregator([ma_cross, rsi_reversion])

bundle = aggregator.generate(window)
if bundle and bundle.signals:
    for s in bundle.signals:
        print(f"{s.source}: {s.direction} strength={s.strength:.2f}")
```

## Indicator groups

- **Moving averages**: SMA, EMA, WMA, DEMA, TEMA, Hull MA
- **Oscillators**: RSI, Stochastic (%K/%D), MACD, CCI, Williams %R, Ultimate Oscillator, ROC
- **Volatility**: ATR, Bollinger Bands, Keltner Channels
- **Volume**: OBV, VWAP, MFI, VWMA
- **Trend**: ADX (+DI/-DI), Aroon, Supertrend

## Signal types

- **Crossover**: MA crossover, MACD crossover, Stochastic crossover
- **Mean reversion**: RSI oversold/overbought, Bollinger bands, CCI
- **Breakout**: ATR-based breakout, Bollinger squeeze/expansion
- **Composite**: `SignalAggregator` runs multiple generators and returns a `SignalBundle`

## What's out of scope

| Concern | Why excluded |
|--------|--------------|
| Position sizing | Risk management; depends on portfolio state |
| Order generation | Execution; depends on broker |
| Signal filtering by position | Strategy logic, not signal logic |
| Persistence | Signals are ephemeral; persist in your layer |
| Market data fetching | This package receives data; it doesn't fetch it |

## Links

- [Repository](https://github.com/statfyi/pyalbedo)
- [Changelog](https://github.com/statfyi/pyalbedo/blob/main/CHANGELOG.md)