Backtest smarter.
Ship faster.

71 technical features, realistic execution modeling, and 27 chart types — one API call away. No infra to manage.

Get Started Live API Docs
$ pip install cobweb-py
71
Technical features
27
Chart types
3
Execution horizons
<20
Lines to backtest
📊

71 Technical Features

Returns, momentum, MACD, RSI, Bollinger, ATR, stochastic, volume, risk, beta, regime detection. Computed server-side, lazily evaluated.

Realistic Execution

Spread, slippage, market impact (sqrt model), participation caps, and multi-bar order slicing. Three horizon presets: intraday, swing, longterm.

🧪

Full Backtest Engine

Signal-to-trade conversion, cash/margin constraints, rebalance modes, and RL-ready reward series with turnover and drawdown penalties.

📈

27 Plot Types

Equity curves, drawdown, rolling Sharpe/Sortino, regime performance, trade analysis, volume diagnostics, correlation heatmaps, and more.

🐍

Python SDK

pip install cobweb-py[all] — accepts CSV, DataFrame, or JSON. Built-in Yahoo Finance helper, scoring, signal generation, and Plotly chart helpers.

🌐

REST API

Three endpoints: /features, /backtest, /plots. JSON in, JSON out. Works from any language.

14 lines to a full backtest

Grab data, compute features, generate signals, and backtest with realistic friction.

import cobweb_py as cw

# Grab SPY data
df = cw.from_yfinance("SPY", "2020-01-01", "2024-12-31")

# Connect (free, no key needed)
sim = cw.CobwebSim("https://web-production-83f3e.up.railway.app")

# Enrich to get SMA-50, then momentum: long when price > SMA-50
rows = sim.enrich_rows(df, feature_ids=[12])
signals = [1.0 if (r.get("sma_50") and r["Close"] > r["sma_50"]) else 0.0 for r in rows]
signals[:50] = [0.0] * 50

# Backtest with realistic friction
bt = sim.backtest(
    rows, signals=signals,
    config=cw.BacktestConfig(exec_horizon="swing", initial_cash=100_000),
)

cw.print_signal(bt)
cw.plots.save_equity_plot(bt, out_html="equity.html")