Metadata-Version: 2.4
Name: alphalens-core
Version: 0.3.15
Summary: AlphaLens — an event-driven backtesting & walk-forward engine for systematic strategies
Author: AlphaLens LLC
License: Apache-2.0
Project-URL: Homepage, https://github.com/AlphaLens-LLC/alphalens-core
Project-URL: Repository, https://github.com/AlphaLens-LLC/alphalens-core
Keywords: backtesting,quant,trading,walk-forward,finance
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=2.0
Requires-Dist: numpy>=1.24
Provides-Extra: viz
Requires-Dist: matplotlib>=3.7; extra == "viz"
Requires-Dist: quantstats; extra == "viz"
Provides-Extra: polygon
Requires-Dist: polygon-api-client; extra == "polygon"
Provides-Extra: live
Requires-Dist: alpaca-py>=0.35; extra == "live"
Requires-Dist: polygon-api-client; extra == "live"
Provides-Extra: fast
Requires-Dist: pyarrow>=14; extra == "fast"
Provides-Extra: cloud
Requires-Dist: supabase>=2.0; extra == "cloud"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Dynamic: license-file

# alphalens-core

**An event-driven backtesting & walk-forward engine for systematic trading strategies.**

Write a strategy as a Python class, run a single forward pass over an in-memory
OHLCV feed, and get back an equity curve, a trade log, and a rich set of
performance statistics — plus walk-forward analysis, parameter sweeps, and an
HTML dashboard. `alphalens-core` is the open engine behind **AlphaLens**.

## Install

```bash
pip install alphalens-core              # core engine (pandas + numpy only)
pip install "alphalens-core[viz]"       # + matplotlib / quantstats dashboard & reports
pip install "alphalens-core[polygon]"   # + Polygon market-data fetching
pip install "alphalens-core[live]"      # + Alpaca execution and Polygon history
pip install "alphalens-core[fast]"      # + pyarrow parquet cache
```

## Quickstart

```python
from alphalens_core import Algorithm, Backtester

class GoldenCross(Algorithm):
    start = "2020-01-01"
    end = "2024-12-31"
    universe = ["SPY"]

    def initialize(self):
        self.set_warmup(50)

    def on_data(self, slice):
        hist = self.history("SPY", 50)["close"]
        if len(hist) < 50:
            return
        self.set_holdings("SPY", 1.0 if hist.tail(10).mean() > hist.mean() else 0.0)

result = Backtester().run(GoldenCross)
print(result.stats)     # Sharpe, Sortino, CAGR, max drawdown, win rate, …
result.dashboard        # inline HTML report in Jupyter, or opens in your browser
```

Live data needs a `POLYGON_API_KEY` (a `.env` / `.env.local` file is loaded
automatically). To run fully offline, inject your own `DataFeed`.

## Host on AlphaLens

AlphaLens can host the dashboard side of your `alphalens-core` workflow:
backtest sync, Strategy Center dashboards, hosted market data access, and live
deployment telemetry. Your strategy code and broker execution still run
locally in v1.

Install the extras used by the hosted workflow:

```bash
pip install "alphalens-core[live,cloud,fast]"
```

Create an API key in AlphaLens Settings, then connect locally:

```bash
alphalens connect --api-key alens_...
alphalens status
```

Run and sync a backtest:

```bash
alphalens run --strategy my_strategy:MyStrategy
```

For CI or one-off shells, `ALPHALENS_API_KEY=alens_... alphalens run ...` is
also supported. End users should not need internal Supabase commands.

Run a local Alpaca paper deployment and stream telemetry to Strategy Center:

```bash
alphalens live --strategy my_strategy:MyStrategy
```

Use the Python API when you want key injection from code:

```python
from alphalens_core import AlphaLensClient
from my_strategy import MyStrategy

al = AlphaLensClient(api_key="alens_...")
result = al.backtest(MyStrategy)
al.live(MyStrategy, broker="alpaca", paper=True).run()
```

Read the hosted workflow docs at
[alphalens.dev/docs/alphalens-core](https://alphalens.dev/docs/alphalens-core),
including the strategy authoring guide at
[alphalens.dev/docs/alphalens-core/build-a-strategy](https://alphalens.dev/docs/alphalens-core/build-a-strategy).

## Live / Alpaca Paper Trading

The live runner uses the same `Algorithm` class and history API as the
backtester. The simplest path is the built-in Alpaca + Polygon runner:

```bash
export POLYGON_API_KEY=...
export ALPACA_API_KEY=...
export ALPACA_SECRET_KEY=...

alphalens live --strategy my_strategy:MyStrategy
```

`alphalens live` defaults to Alpaca paper trading. Pass `--live` only when you
intend to route orders to the live Alpaca account. The command reads
`class.universe` and `class.resolution` by default; override them with
`--universe SPY,QQQ` or `--resolution 5minute`.

For custom broker/data transports, `LiveSession.from_cache` seeds a bounded
rolling history, then each completed `Slice` is appended before `on_data` runs:

```python
from alphalens_core import AlpacaBrokerage, LiveSession, NO_BAR
from my_data import next_completed_slice
from my_strategy import MyStrategy

broker = AlpacaBrokerage(paper=True)
session = LiveSession.from_cache(
    MyStrategy,
    brokerage=broker,
    next_bar_fn=next_completed_slice,  # Slice, NO_BAR while idle, None to stop
    history_bars=500,
    state_path=".alphalens/live/my_strategy.json",
)
session.run()
```

`from_cache` uses `UniverseCache` and Polygon by default; inject an existing
cache to use another `DataSource`. The runner:

- exposes seeded and appended bars through `history()`, `history_array()`, and
  `history_arrays()`;
- keeps history bounded and suppresses duplicate timestamps;
- rejects out-of-order bars and unreconciled broker orders;
- synchronizes Alpaca cash/positions and FIFO lots at startup;
- respects strategy resolution and warmup settings;
- checkpoints the last processed bar to avoid replay after restart.

Market-data transport is intentionally separate from execution. A callback
must emit completed, consolidated slices for the strategy universe. See
`PolygonCompletedBarPoller` for the built-in Polygon polling implementation.
Live membership changes are not yet supported: the session fails explicitly
for dynamic universes until removal orders can be reconciled with broker fills.

## Features

- **Event-driven lifecycle** — `initialize`, `on_data`, `on_order_event`,
  `on_securities_changed`, `on_end_of_day`, `on_warmup_finished`.
- **Realistic fills** — next-bar execution with pluggable slippage / fee / fill
  models, and a one-bar look-ahead guard so decisions on bar *t* can't peek at
  bar *t*'s close.
- **Walk-forward analysis** with per-fold parameter search.
- **Parameter sweeps** + PBO (probability of backtest overfitting).
- **Live execution** through Alpaca paper/live brokerage with buffered rolling
  history and restart-safe bar processing.
- **Reporting** — `result.stats`, an HTML `result.dashboard`, and quantstats
  reports.

## CLI

```bash
alphalens run --strategy mymod:MyStrategy
alphalens live --strategy mymod:MyStrategy
alphalens wfa --strategy mymod:MyStrategy --train 504 --test 63 --step 63
alphalens cache --info
```

## License

[Apache-2.0](LICENSE) © AlphaLens LLC
