Skip to main content

edenalpha

Write trading strategies in Python. Run them against the EdenAlpha engine — the same engine, fills, charges, and risk controls behind every EdenAlpha backtest, paper deployment, and live deployment. Two ways to backtest: hosted, where your file runs on EdenAlpha compute, and local sessions, where your code stays on your machine and drives the engine bar by bar. Deployment happens in the web app.

# my_strategy.py
from edenalpha import strategy, Feature

@strategy(features=[Feature(name="rsi", period=14)])
def decide(ctx):
    if ctx.position.is_open and ctx.features["rsi_14"] > 55:
        return "EXIT"
    if not ctx.position.is_open and ctx.features["rsi_14"] < 30:
        return "BUY"
    return "HOLD"
pip install edenalpha
edenalpha login                       # paste an API key from Settings -> API keys
edenalpha backtest my_strategy.py \
    --symbol RELIANCE --timeframe 15m \
    --start 2026-06-01 --end 2026-07-01

Beta. The SDK is in open beta and enabled per account: sign up at edenalpha.in, then request SDK access to have API-key creation turned on in Settings. Hosted backtests and local sessions both work today; paper deployment from the SDK is not exposed yet (deploy from the web app). Python backtests inside the web app need no grant. The decide contract is stable — code written against 0.2.x keeps working.

How it works

Your function is the agent; EdenAlpha is the world. On every bar close the engine hands you a Ctx — the bar, your declared indicators (computed server-side, identical to the web rule builder), your position, your cash, and the available bar history — and you answer BUY, SELL (opens a short), EXIT, or HOLD. Hosted backtests expose the full run through the current bar; paper deployments expose a rolling window from deployment time. Fills, charges, sizing, stop-losses, and square-off stay in the engine, so a backtest here is directly comparable to every other EdenAlpha run. The same strategy contract powers paper deployments in the EdenAlpha web app (currently operator-gated).

The contract does not change with where your code runs: one decide function works hosted, driven locally through run_local, or stepped by hand in your own loop.

  • Sizing is server-owned. You return direction; quantity comes from the run's sizing configuration. A strategy that can't over-size in a backtest can't over-size live.
  • Broker-agnostic. Nothing in this contract names a broker; execution routing happens server-side behind your deployment settings.
  • Typed everywhere. Ctx, Bar, Position, Decision are Pydantic models with full annotations (py.typed shipped) — your IDE's autocomplete is the API reference.
  • Unit-testable. @strategy returns a callable: build a fake Ctx and assert on the returned Decision in plain pytest, no network involved.

Shared-pool portfolio strategies

The web app also supports hosted Python portfolio backtests and paper deployments over up to 50 symbols. One agent sees the latest state of the whole universe while EdenAlpha keeps ownership of slots, quantities, fills, charges, risk, and square-off:

from edenalpha import Feature, Order, portfolio_strategy

@portfolio_strategy(
    features=[Feature(name="rsi", period=14, alias="rsi_14")],
    lookback_bars=50,
)
def decide(pf):
    orders = []
    for view in pf.holdings():
        if view.actionable_this_step and view.features["rsi_14"] > 55:
            orders.append(Order(symbol=view.symbol, action="EXIT"))

    for view in pf.symbols.values():
        rsi = view.features.get("rsi_14")
        if view.actionable_this_step and not view.position.is_open and rsi is not None and rsi < 30:
            orders.append(Order(
                symbol=view.symbol,
                action="BUY",
                score=30 - rsi,
                reason="oversold",
            ))
    return orders

Higher score proposals are admitted first. With unequal configured slot weights, higher scores also receive the larger available slots. A remote run_local_portfolio and multi-symbol step-session are not available yet; create and run portfolio strategies from EdenAlpha's web interface.

Python API

import edenalpha

client = edenalpha.Client()          # auth: EDENALPHA_API_KEY or `edenalpha login`
outcome = client.backtest(
    "my_strategy.py",
    symbol="RELIANCE", timeframe="15m",
    start="2026-06-01", end="2026-07-01",
)
print(outcome.summary.net_return_pct)
for trade in outcome.trades:
    print(trade["entry_time"], trade["net_pnl"])

Errors are typed (AuthenticationError, ScopeError, InsufficientCreditsError, RateLimitError, StrategyError, TransportError, EngineError) and retriable statuses (429/5xx) are retried with backoff automatically.

Hosted execution

client.backtest(...) runs your file on EdenAlpha compute next to the data (requires the backtest:hosted scope). Hosted strategies are single self-contained files with an import allowlist (numpy, pandas, and the computation-flavored stdlib). Inside hosted compute, auth is ambient — the runner injects the session; your code never handles keys.

Local sessions — your code stays on your machine

A session inverts the loop: instead of uploading your file, you drive the engine one bar at a time over HTTPS. The engine still owns fills, charges, sizing, and risk — you only answer with a direction. Requires the session:backtest scope.

The simplest form takes the same @strategy file as client.backtest:

outcome = client.run_local(
    "my_strategy.py",
    symbol="RELIANCE", timeframe="15m",
    start="2026-06-01", end="2026-07-01",
)
print(outcome.summary.net_pnl)

decide() runs on your computer, so local imports, private models, and anything else you would rather not upload stay put. No import allowlist applies to code that never leaves your machine.

For research loops — walk-forward, notebooks, policy inference — drive the session yourself:

from edenalpha import Feature

with client.session(symbol="RELIANCE", timeframe="15m",
                    start="2026-06-01", end="2026-07-01",
                    features=[Feature(name="rsi", period=14)]) as sess:
    t = sess.start()
    while not t.done:
        rsi = t.ctx.features["rsi_14"]
        t = sess.step("BUY" if rsi is not None and rsi < 30 else "HOLD")
    print(sess.result().summary.net_pnl)

Each step() returns a Transition:

  • t.ctx — the next decidable bar. ctx.history is rebuilt locally from incremental updates, so a long run never retransmits its past.
  • t.ack — what happened to the action you just submitted. Exactly one action is accepted per bar sequence number, so a runaway loop cannot fire twice for the same bar.
  • t.events — what the engine did, as typed events: FilledEvent, OrderPendingEvent, EntrySkippedEvent, ActionIgnoredEvent. "Accepted" is never dressed up as "filled" — with the default next_open fill policy the fill arrives on the following transition.
  • t.done — the run is over and sess.result() holds the full outcome.

A session costs the same one backtest credit as any other run, and completed sessions are saved to your Runs page alongside web and hosted backtests. Use the context manager (or call sess.close()) so an abandoned session releases its server-side slot promptly.

Declared features

Any indicator from the EdenAlpha catalog (the same one behind the web rule builder — Strategies → Reference lists all ~57):

Feature(name="rsi", period=14)                      # ctx.features["rsi_14"]
Feature(name="vwap")                                # ctx.features["vwap"]
Feature(name="sma", period=50, alias="slow_ma")     # ctx.features["slow_ma"]
Feature(name="macd", params={"fast": 12, "slow": 26, "signal": 9},
        outputs={"line": "macd", "signal": "macd_sig", "histogram": "macd_hist"})

Raw OHLCV (open, high, low, close, volume) is always present in ctx.features. Prefer declared features over hand-rolled ones — they're computed by the exact code that will feed your strategy in paper/live, so train/serve skew can't happen.

Requirements & license

Python 3.10+. MIT licensed — the SDK is open; the EdenAlpha engine and platform are a separate, server-side service.

Metadata

Release files for edenalpha 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for edenalpha 0.3.0
File Size Uploaded Provenance Actions
edenalpha-0.3.0.tar.gz 21.5 kB With provenance Details for edenalpha-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for edenalpha 0.3.0
File Interpreter ABI Platform Actions
edenalpha-0.3.0-py3-none-any.whl Python 3 none any Details for edenalpha-0.3.0-py3-none-any.whl

Total release size: 48.1 kB

Release files / edenalpha-0.3.0.tar.gz

Download URL edenalpha-0.3.0.tar.gz
Size 21.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4990b12a9acbcca9b491a92b6a551b0d846f3dc5c5b9051d88ae173318d5ae00
BLAKE2b-256 checksum
How to use checksums
efd0982106338bf44d7458cd437cb84b5ea2b2e9cdf22b94e5f7f84c4644fc68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.

Transparency log

Release files / edenalpha-0.3.0-py3-none-any.whl

Download URL edenalpha-0.3.0-py3-none-any.whl
Size 26.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2a46e2f001be56707156366639ddc518a60147aaadc0f2fcb122669ad42ce47c
BLAKE2b-256 checksum
How to use checksums
d272e06ddb29aa3bd37cf4c3faa6fcfc64e498e8e372ee6e8aff06982fc14fc3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.

Transparency log

Security for edenalpha 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for edenalpha-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page