Skip to main content

Quant Pulse

Quant Pulse is a lightweight Python library for generating market signals on demand. It supports various targets (asset classes, markets, etc.) and signal operations through a modular architecture that allows for easy extension and customization.

Current Version: 0.2.1 (alpha)

Core Principles

  • Scoped to financial domain, whether decentralized or centralized.

  • Remain fully open source to promote transparency and wider adoption.

Design Goals

  • Offer automatic trading systems raw or processed data to support decisions-making, embedded directly in-process.

  • Prototype composite signals from raw ones using Jupyter Notebook or similar environments.

Non-Goals

  • Not designed for high‑frequency trading (HFT) or other fast trading systems.

  • Direct interaction with markets is explicitly out of scope.

  • Not a server or service — no network interface is provided; embed it in your own process.

Further Notes

  • The codebase is still stabilizing, and contributions via pull request are not open yet. Key interfaces are subject to refinement; feel free to experiment with modules, but keep in mind that breaking changes may occur.

  • Note: custom signal handlers and services (extending the internal SignalHandler/Service base types) cannot yet be plugged in from an external project — the config-driven loader only resolves modules inside this package's own namespace. External extensibility (e.g. entry-point/plugin registration) is a coming-soon update.

Installation

pip install quant-pulse

Requires Python 3.10+. TA-Lib must be installed on the system before pip install (the Python package wraps the native library).

Modules

Path:

src/quant_pulse
├── handlers   # signal handlers
├── services   # core services
└── _core      # framework internals (abstractions, registries, config)

Handlers:

  • RSISignal: RSI indicator signal handler
  • MASignal: MA indicator signal handler (supports sma, ema, wma)
  • ATRSignal: ATR indicator signal handler
  • DMISignal: DMI indicator signal handler (combines ADX, DI+, DI-)
  • PriceStructSignal: Price structure signal handler
  • TrendDirectSignal: Trend direction signal handler
  • MntmQualitySignal: Momentum Quality signal handler
  • MACDSignal: MACD indicator signal handler
  • SupertrendSignal: Supertrend signal handler (composes ATRSignal)

Services:

  • CacheManager: factory-pattern based caching to create scoped caches
  • ExchangeClient: abstract base type for exchange implementations
  • BinanceClient: provides access to OHLCV data from Binance CEX
  • HyperliquidClient: provides access to OHLCV data from Hyperliquid DEX
  • OHLCVFetcher: abstracts OHLCV data fetching and provides caching

Usage

from quant_pulse import Context, ConfigBuilder

cfg = (
    ConfigBuilder()
    .hyperliquid_client('hl_client')
    .cache_manager()
    .ohlcv('hl_ohlcv', using=['hl_client', 'cache_manager'])
    .signal('rsi_hyperliquid', 'rsi_signal', ohlcv_service='hl_ohlcv')
    .build()
)

with Context.from_dict(cfg) as ctx:
    sig = ctx.get_signal_handler('rsi_hyperliquid')
    out = sig.compute_signal(
        target='BTC',
        signal_op='compute_rsi',
        request={'period': 14, 'timeframe': '1h'}
    )

    if out.errors:
        print('errors:', out.errors)
    else:
        print(f"latest_rsi: {out.result['latest_rsi']}")
        print(f"regime: {out.result['regime']}")

out.result is a plain Python object (dict/list/etc.) — no serialization step, nothing to decode.

ConfigBuilder also has typed shortcuts for other bundled exchange clients (binance_spot_client, binance_mf_client) and a raw .service() escape hatch for anything custom — see builder.py.

A runnable version of the first example is at samples/rsi_sample.py. For the simplest possible no-network usage, see samples/hello_world.py.

Configuration

A Context is built from a config dict with two sections: signals (profiles bound to a handler) and services (infrastructure a handler can depend on).

signals:
  - rsi_hyperliquid:
      _binding: rsi_signal
      ohlcv_service: ohlcv_hyperliquid

  - atr_hyperliquid:
      _binding: atr_signal
      ohlcv_service: ohlcv_hyperliquid

  - supertrend_hyperliquid:
      _binding: supertrend_signal
      ohlcv_service: ohlcv_hyperliquid
      atr_signal: atr_hyperliquid

  - macd_hyperliquid:
      _binding: macd_signal
      ma_signal: ma_hyperliquid
      fast_period: 12
      slow_period: 26
      signal_period: 9

services:
  - cache_manager:
      _service: cache
      _binding: CacheManager
      max_items: 10000
      max_bytes: 104857600

  - hyperliquid_client:
      _service: exchange/hyperliquid_client
      _binding: HyperliquidClient
      _api_url: https://api.hyperliquid.xyz
      timeout_sec: 10.0
      max_retries: 1
      retry_delay: 0

  - ohlcv_hyperliquid:
      _service: exchange/data_providers
      _binding: OHLCVFetcher
      _using:
        - hyperliquid_client
        - cache_manager
      ttl_1m: 60
      ttl_5m: 300
      ttl_1h: 3600
      ttl_1d: 86400
      ttl_default: closest # Auto-select nearest TTL

Handlers can invoke other signals as sub-components (e.g. SupertrendSignal calls its configured atr_signal profile), and declare reusable exchange/data integrations as service dependencies — wired via config, no code changes needed to add profiles or tune parameters.

Signal Sample

def _compute_signal_impl(self, target: str, signal_op: str, request: Optional[dict]) -> Outcome:
    """
    Compute RSI signal
    """
    try:
        period = int(request['period'])
        timeframe = request['timeframe']

        ohlcv_fetcher = self._ctx.get_service(self._ohlcv_service_name)
        if not ohlcv_fetcher or not hasattr(ohlcv_fetcher, 'retrieve_ohlcv'):
            return self._error(f"OHLCV service '{self._ohlcv_service_name}' not found or invalid")

        limit = period + 100
        candles = ohlcv_fetcher.retrieve_ohlcv(symbol=self._symbol, timeframe=timeframe, limit=limit)
        if not candles or len(candles) < period:
            return self._error(f"Insufficient candle data: need {period}, got {len(candles) if candles else 0}")

        close_prices = np.array([candle.close for candle in candles])
        rsi_values = talib.RSI(close_prices, timeperiod=period)
        rsi_list = rsi_values[~np.isnan(rsi_values)].round(2).tolist()

        latest_rsi = next((float(v) for v in reversed(rsi_values) if not np.isnan(v)), None)
        if latest_rsi is None:
            return self._error('Failed to compute RSI: all values are NaN')

        regime = 'overbought' if latest_rsi >= 70 else 'oversold' if latest_rsi <= 30 else 'neutral'

        return Outcome(
            result={'symbol': self._symbol, 'rsi': rsi_list, 'latest_rsi': round(latest_rsi, 2), 'regime': regime},
            computation=self.get_metadata()['name']
        )
    except Exception as e:
        self.logger.error(f"Error computing RSI: {e}", exc_info=True)
        return self._error(str(e))

License

MIT — see LICENSE.

Metadata

Release files for quant-pulse 0.2.1

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

Source distribution (sdist)

Source distribution for quant-pulse 0.2.1
File Size Uploaded
quant_pulse-0.2.1.tar.gz 88.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for quant-pulse 0.2.1
File Interpreter ABI Platform
quant_pulse-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 172.1 kB

Release files / quant_pulse-0.2.1.tar.gz

Download URL quant_pulse-0.2.1.tar.gz
Size 88.6 kB
Tags Source
SHA-256 checksum
How to use checksums
aff578ec7386dc7bec21a8835418fc654d9e0cd60d7531c473ae1fba73d44eb2
BLAKE2b-256 checksum
How to use checksums
20860c9693968861022940f5a324e6dc0e6e897d422ca2b9249590803c7d84bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release files / quant_pulse-0.2.1-py3-none-any.whl

Download URL quant_pulse-0.2.1-py3-none-any.whl
Size 83.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
670be5f999aa84b46b17aec441c0713d54b4633fce1c69a3591ffee22195fde3
BLAKE2b-256 checksum
How to use checksums
adec52252a662b781d3dc4046afd28a815686573b00111fd818a397a13ae0c8e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release history Release notifications | RSS feed

0.3.9

2 release files

0.3.2

2 release files

0.2.9

2 release files

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.5

2 release files

0.1.0

2 release files

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