Skip to main content

A backtestable signal engine for perpetual-futures strategies — DSL, indicators, and an honest backtester.

Project description

perpsignal

tests + backtest License: Apache 2.0 Python 3.10+

A backtestable signal engine for perpetual-futures strategies. Write a strategy as a compact expression (or a JSON signal definition), evaluate it against OHLCV data, and backtest it into honest metrics — Sharpe, return, drawdown, win rate — with fees, funding, stops/targets, and leverage modelled.

This is the open-source core extracted from Signalview, a non-custodial platform where backtested perps strategies are scored and traded by AI agents on Hyperliquid. The engine here has no wallet, key, custody, or live-trading code — it's a pure research/backtest library, safe to run anywhere.

⚠️ Research and backtesting only. Nothing here is financial advice, and a backtest is not a promise of future results. Perpetual-futures trading is high-risk.

Install

pip install perpsignal          # once published
# or, from source:
pip install git+https://github.com/mokshyaprotocol/signalview

Requires Python 3.10+, pandas, numpy, requests.

Quickstart

import pandas as pd
from perpsignal import evaluate, discretize, run, BacktestConfig, RiskConfig

# df needs columns: open, high, low, close, volume (a DatetimeIndex is ideal)
df = pd.read_parquet("BTCUSDT-1h.parquet")

cfg = BacktestConfig(symbol="BTCUSDT", interval="1h")  # holds the entry thresholds

# A score is any expression that evaluates to a Series (positive = long).
# This one is a mean-reversion fade: high when price is stretched below its
# 48-bar mean, low when stretched above.
score = evaluate("zscore(close, 48) * -1", df)

# Map the continuous score to a {-1, 0, +1} position via the config thresholds.
# run() expects a discrete position, not a raw score.
position = discretize(score, cfg)

result = run(
    df, position, cfg,
    RiskConfig(),            # leverage / take-profit / stop-loss (sane defaults)
    bars_per_year=24 * 365,  # hourly bars
)
print(result.metrics)   # {'sharpe': ..., 'total_return': ..., 'max_drawdown': ..., 'win_rate': ..., 'trades': ...}

The signal DSL

Expressions are built from market variables and functions.

Variables: close, high, low, open, volume, funding, oi (open interest), bar_index.

Functions:

Trend / momentum rsi(close, n), ema(close, n), sma(close, n), slope(close, n), adx(n), macd-style via ema diffs
Volatility atr(n), stdev(x, n), bb_width(close, n, k), bb_upper/bb_lower/bb_mid(close, n, k)
Normalization zscore(x, n), clip(x, lo, hi), sign(x), abs(x), log(x), sqrt(x), tanh(x)
Volume / flow vwap(n), session_vwap(), corr(a, b, n)
Windowing highest(x, n), lowest(x, n), prev(x, k)
Logic if(cond, a, b), min, max, comparisons (>, <, >=, ...), and/or

Expressions are parsed by a real tokenizer→parser→evaluator (perpsignal.dsl) and include an auto-repair pass (parse_with_repair) that fixes common mistakes and reports what it changed — handy when the author is an LLM.

Signals as data

A strategy can also be a JSON SignalDef (portable, diffable, PR-able):

from perpsignal import parse_signal
sig = parse_signal({
    "asset": "BTCUSDT", "timeframe": "1h",
    "expression": "rsi(close, 14) - 50",
    # ... weights, regime config, risk bounds
})

See examples/ for runnable scripts and a sample signal file.

Fetching data

perpsignal.data pulls public Binance / Hyperliquid OHLCV and caches to disk. An optional Upstash cache layer self-disables when its env vars are unset — you never need it to run locally.

Contributing

New indicators, factors, and strategies are very welcome — this engine exists to be extended. A new built-in is usually one function plus one test. See CONTRIBUTING.md. Every PR is backtested in CI so improvements are judged on objective metrics, not opinion — which also makes this a clean target for autonomous/AI-agent strategy search.

License

Apache License 2.0. © 2026 Signalview.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

perpsignal-0.1.0.tar.gz (70.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

perpsignal-0.1.0-py3-none-any.whl (69.6 kB view details)

Uploaded Python 3

File details

Details for the file perpsignal-0.1.0.tar.gz.

File metadata

  • Download URL: perpsignal-0.1.0.tar.gz
  • Upload date:
  • Size: 70.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for perpsignal-0.1.0.tar.gz
Algorithm Hash digest
SHA256 faa2bde935989030636a0937fe45ef771ba85b1db362920b85f4edd4f1d2759d
MD5 4d8533a9cafe3ec41a72ca33c51845f7
BLAKE2b-256 ef1f7b655a20af6641bdf3fa73c0bc831c92ac4dab065f380a52edda6d60ac25

See more details on using hashes here.

Provenance

The following attestation bundles were made for perpsignal-0.1.0.tar.gz:

Publisher: publish.yml on mokshyaprotocol/signalview

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file perpsignal-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: perpsignal-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 69.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for perpsignal-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7b15641d96c88ddcd2359fd6f519b3d36f29a721e45ec929c96eda0d66e1ab10
MD5 97c56734be542b898cfe5311c8ac0b0d
BLAKE2b-256 10fa6fad0403fa040eb8d19cdd5a6ae5981c5280b99e813832d6f7b9ba0dad27

See more details on using hashes here.

Provenance

The following attestation bundles were made for perpsignal-0.1.0-py3-none-any.whl:

Publisher: publish.yml on mokshyaprotocol/signalview

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page