I needed a TA library that did three things I couldn't find together:
- Indicators that aren't a stack of opinionated TA-Lib glue. Pure Python, deterministic, zero runtime deps.
- Composite signals my way, not LuxAlgo's. No copying. Different naming. Different weighting.
- MCP-native runtime so Claude / Cursor / Cline can query live signals without glue code.
So I built one. It's called Sigil (pip install sigil-ta), and I'm releasing v0.1.0 today.
What's in the box
8 core indicators — pure Python, no numpy required
| Indicator | Function |
|---|---|
| Simple Moving Average | sma(closes, period) |
| Exponential Moving Average | ema(closes, period) |
| Wilder RSI | rsi(closes, period=14) |
| MACD |
macd(closes, 12, 26, 9) — returns line, signal, histogram |
| Bollinger Bands |
bollinger_bands(closes, 20, 2.0) — upper/middle/lower |
| Wilder ATR | atr(series, 14) |
| Supertrend |
supertrend(series, 10, 3.0) — line + direction |
| Stochastic |
stochastic(series, 14, 3) — %K and %D |
All deterministic, all return list[float | None] aligned to input length, with None during the warm-up period. No silent NaN propagation, no magic resampling, no exotic dependencies.
2 composite signals — our naming, our weighting
reversion_score(series) → list of values in [-1, +1]
Combines RSI deviation from 50, Bollinger Band position, and ATR-normalized deviation from the 20-bar SMA. Score of +1 means strongly oversold (likely reversion up); -1 means strongly overbought.
momentum_composite(series) → list of values in [-1, +1]
RSI deviation, MACD histogram (volatility-normalized), and Supertrend direction. +1 means strong sustained uptrend; -1 means strong downtrend.
I tested both on 500 hours of BTCUSDT 1h data:
ReversionScore (long+short, 10bps fees):
24 trades, 66.7% WR, total_pnl_pct -2.84%, avg_bars_held 14.0
MomentumComposite (long-only, 10bps fees):
6 trades, 50.0% WR, total_pnl_pct +2.69%, avg_bars_held 35.5
Real numbers from a real test. Not impressive, not unimpressive — exactly what you should expect from generic TA on a 500-bar window. The point isn't that these signals print money; the point is that they're honestly measurable, you can tune them, and they live next to a backtest harness with realistic fees and no look-ahead.
1 unique signal — Polymarket Sentiment Divergence (PSD)
This is the one that doesn't exist in any other TA library, because it requires data only Polymarket has.
PSD measures divergence between an underlying asset's price action and the resolved sentiment of a related Polymarket prediction market.
Example: BTC trades on Binance. Polymarket has a contract "Will BTC be above $80,000 by month-end?" The Polymarket price is a sentiment time-series — when bettors think yes is more likely, the price rises; when they think no, it falls.
PSD scores +1 when:
- BTC price is dropping
- AND the Polymarket "yes" probability is rising
- = bullish divergence — sentiment thinks the dip is buying opportunity
PSD scores -1 when:
- BTC price is rising
- AND the Polymarket "yes" probability is falling
- = bearish divergence — sentiment doesn't believe the rally
When both move together, PSD is near zero (no signal).
Why this matters: pure-TA libraries (LuxAlgo, ta, pandas-ta, ta-lib) do not have access to prediction-market sentiment. PSD captures information that a chart-only signal cannot see. It's an integration play, not a math play — anyone can copy the formula, but they need a Polymarket data layer to use it. Sigil includes the Polymarket fetcher (fetch_polymarket_price_history(token_id)) so the integration is built in.
Backtest harness with realistic fees
from sigil.backtest import backtest_signal
result = backtest_signal(
series=ohlcv_series,
signal=reversion_scores,
entry_threshold=0.5,
exit_threshold=0.0,
fee_per_side_pct=0.001, # 10 bps each side
)
print(result.summary())
# Backtest: 24 trades, WR 66.7% (16/24), total_pnl_pct -2.84%, ...
Decisions on bar i, fills at bar i+1 open. No look-ahead. Default 10 bps per side fee (realistic for retail crypto).
Live data fetchers
from sigil.data import fetch_binance_ohlcv, fetch_polymarket_price_history
btc = fetch_binance_ohlcv("BTCUSDT", "1h", limit=500)
pm = fetch_polymarket_price_history(token_id="...", fidelity=60)
Both use only Python's stdlib for HTTP. Zero runtime dependencies in core. Network only when you call the fetcher.
The MCP angle: indicators as Claude tools
If you've used Claude Desktop, Cursor, or Cline, you know how MCP tools work — they appear in the LLM's tool catalog and get called natively in the conversation.
Sigil exposes 14 tools through FastMCP:
pip install sigil-ta[mcp]
sigil-mcp # stdio transport (Claude Desktop / Cursor / Cline)
sigil-mcp --transport http --port 8765 # HTTP transport
Add to claude_desktop_config.json:
{
"mcpServers": {
"sigil": { "command": "sigil-mcp" }
}
}
Then in Claude:
"Fetch the last 200 hours of BTCUSDT and compute the RSI and Bollinger Bands."
"Run a Supertrend backtest on ETHUSDT with default params."
"What's the MomentumComposite for SOLUSDT right now?"
The agent calls fetch_binance_ohlcv, then compute_rsi, then compute_bollinger_bands, and shows you the result. No glue code.
This is how I run my own analysis now. I haven't opened a TradingView tab in two weeks. Claude does the indicator queries directly, and when I want a chart, I ask it to render one with plotly.
Streamlit dashboard
pip install sigil-ta[dashboard]
sigil-dashboard
A simple chart-and-indicator UI for when you want to look at price visually rather than asking the agent. Pick a symbol, an interval, an indicator, see the output live. Backtest panel underneath for the composite signals.
It's not a TradingView competitor — it's a 200-line proof that the same indicators work in a UI when you want one.
Design choices
Pure stdlib core. No numpy, pandas, scipy required for indicators. Every implementation is plain Python doing arithmetic. This means:
- Installs in milliseconds. No compilation.
- Runs on cold-start serverless.
- Never breaks because of a third-party version bump.
pandas, streamlit, plotly, mcp, fastmcp are optional extras (pip install sigil-ta[mcp], pip install sigil-ta[dashboard]).
Indicators return list[float | None] aligned to input length. This is unfashionable. Most libraries return numpy arrays with NaN warmup or pandas Series with index alignment. I find lists with explicit None more debuggable — when something's wrong, you can see exactly which bars are warmup and which are data.
Test coverage is the contract. 47 tests at v0.1, including:
- Constant-input behavior for every indicator
- Monotone-up RSI = 100, monotone-down = 0
- Stochastic at top of range = 100, at bottom = 0
- Bollinger Bands widen with volatility
- ATR converges on constant range
- Supertrend direction flips on trend reversal
- Backtest harness handles long-only, short-allowed, fee accounting
- All MCP tools register correctly
git clone https://github.com/LuciferForge/sigil
cd sigil
pip install -e ".[dev,mcp]"
pytest tests/ -v
# 47 passed in 3.18s
What's next
v0.1 ships today with the core indicators + composite signals + PSD + backtest + MCP + dashboard. Roadmap:
- v0.2 — More indicators: ADX, Ichimoku, OBV, VWAP, Heikin-Ashi
- v0.3 — Walk-forward backtest with parameter sweeps
- v0.4 — Multi-timeframe signal fusion (15m + 1h + 4h alignment in one decision)
- v0.5 — Live signal alerting (Discord / Telegram / Slack)
- v0.6 — Public ground-truth ledger at signals.protodex.io
If there's an indicator you'd use and don't see, open an issue — happy to prioritize.
Why ship this open source
I run a Polymarket trading bot (308 trades, 80.2% WR, all data public). I needed a TA library to ask "should I add an RSI filter to the entry signal?" and didn't want to wrap an existing library that has 50+ dependencies and 5,000 lines of pandas magic.
So I built the simplest thing that worked. Then I made it MCP-native because that's how I do all my analysis now. Then I added PSD because that's the part that's actually mine.
Open-sourcing it isn't charity. The TA logic isn't the moat — the moat is the integration with Polymarket data, and that data layer is also what I sell access to via api.protodex.io. If you want indicators on stocks or crypto, Sigil works fine standalone; if you want PSD on prediction markets, you need the Polymarket data, and that's where the funnel is.
But honestly, even if there were no funnel — building a TA library this clean was satisfying enough that the time would have been worth it for me alone.
Resources
- Repo: github.com/LuciferForge/sigil
-
PyPI: pypi.org/project/sigil-ta (
pip install sigil-ta) -
MCP-only install:
pip install sigil-ta[mcp] -
Dashboard install:
pip install sigil-ta[dashboard] -
Tests:
git clone && pip install -e ".[dev,mcp]" && pytest
If you ship a project on top of Sigil, send me the link.
LuciferForge runs a public-audited Polymarket trading bot, protodex.io (5,800+ MCP servers indexed), and the free Polymarket data API.
Top comments (0)