Skip to main content

Hunter quant bot framework Python bindings

Project description

hunter-quant

Python bindings for the Hunter quant trading framework. Built with PyO3 + maturin for high-performance live trading, sandbox, and backtesting.

Installation

pip install hunter-quant

Development

cd bindings/python
uv sync --extra dev
uv run maturin develop
uv run pytest

Static stub synchronization can be checked without installing the extension:

uv run python bindings/python/scripts/check_pyi_sync.py

Release steps are documented in docs/release.md.

Examples

Runnable strategy examples live in examples/:

  • examples/sma_cross.py
  • examples/supertrend_risk.py

Install the extension into your active environment before running examples:

cd bindings/python
uv run maturin develop
uv run python examples/sma_cross.py

Quality Gates

cargo fmt -p python
cargo check -p python
cargo test -p python
uv run python bindings/python/scripts/check_pyi_sync.py

After maturin develop, run Python smoke tests:

cd bindings/python
uv run maturin develop
uv run pytest

Quick Start

import hunter
from hunter import Strategy


class MyStrategy(Strategy):
    def __init__(self):
        self.btc = self.candles(connector_id="hyperliquid_perp", symbol="BTC-USDC", timeframe="15m")
        self.broker = self.broker(connector_id="hyperliquid_perp", address = "", private_key = "", rate_limit = 1200 )

    def on_bar(self):
        close = self.btc.close
        fast = hunter.ta.sma(close, 7)
        slow = hunter.ta.sma(close, 25)

        if fast.cross_over(slow):
            self.broker.market_buy("BTC-USDC", 0.01)
        elif fast.cross_under(slow):
            self.broker.market_sell("BTC-USDC", 0.01)

Run Modes

  • "live" — real trading on live exchanges
  • "sandbox" — simulated trading on testnet
  • "backtest" — historical backtesting
hunter.run(MyStrategy(), mode="backtest")
hunter.run(MyStrategy(), mode="sandbox")
hunter.run(MyStrategy(), mode="live")

Feeds

CandleFeed

feed = self.candles(connector_id="hyperliquid_perp", symbol="BTC-USDC", timeframe="15m", warmup_period=200)

Properties/Methods:

  • dataframe — polars DataFrame
  • open, high, low, close, volume, start_time — shortcut to each column as Series

OrderBookFeed

feed = self.orderbook(connector_id="hyperliquid_perp", symbol="BTC-USDC")

Properties: best_bid, best_ask, mid_price, spread, spread_bps, microprice, microprice_offset_bps, bids, asks, top_of_book_imbalance

Methods: cumulative_bid_depth(levels), cumulative_ask_depth(levels), depth_imbalance(levels), depth_pressure(levels, decay)

TradeFeed

feed = self.trades(connector_id="hyperliquid_perp", symbol="BTC-USDC", warmup_period=100)
  • dataframe — polars DataFrame

Series API

series[0]        # latest value (rightmost)
len(series)

series.cross_over(other)
series.cross_under(other)
series.cross(other)
series.to_polars()

TA Module

import hunter

hunter.ta.sma(source, period=20)
hunter.ta.ema(source, period=20)
hunter.ta.rsi(source, period=14)
hunter.ta.bollinger_bands(source, period=20, dev_up=2.0, dev_down=2.0)
hunter.ta.macd(source, fast=12, slow=26, signal=9)
hunter.ta.atr(high, low, close, period=14)
hunter.ta.adx(high, low, close, period=14)
hunter.ta.stoch(high, low, close, k=14, k_slow=3, d=3)
hunter.ta.supertrend(high, low, close, period=10, multiplier=3.0)
hunter.ta.vwap(high, low, close, volume)
hunter.ta.cci(high, low, close, period=20)
hunter.ta.obv(close, volume)
hunter.ta.sar(high, low, acceleration=0.02, maximum=0.2)
hunter.ta.heikin_ashi(open, high, low, close)
hunter.ta.slope(source, n=5)

# Candlestick patterns
hunter.ta.cdl_doji(open, high, low, close, body_percent=0.1)
hunter.ta.cdl_dragonfly_doji(open, high, low, close, body_percent=1.0)
hunter.ta.cdl_gravestone_doji(open, high, low, close, body_percent=1.0)
hunter.ta.cdl_hammer(open, high, low, close, period=20, factor=1.5)
hunter.ta.cdl_inverted_hammer(open, high, low, close, period=20, factor=1.5)
hunter.ta.cdl_long_shadow(open, high, low, close, period=10, shadow_factor=1.5)
hunter.ta.cdl_marubozu(open, high, low, close, period=10, shadow_percent=0.1)

Broker

broker = self.broker(connector_id="hyperliquid_perp")

# Order shortcuts
broker.market_buy("BTC-USDC", 0.01)
broker.market_sell("BTC-USDC", 0.01)
broker.limit_buy("BTC-USDC", 0.01, price=50000)
broker.limit_sell("BTC-USDC", 0.01, price=55000)

# Conditional orders
broker.stop_market_buy("BTC-USDC", 0.01, trigger_price=51000)
broker.take_profit_market_sell("BTC-USDC", 0.01, trigger_price=60000)
broker.stop_limit_buy("BTC-USDC", 0.01, trigger_price=51000, limit_price=51200)
broker.take_profit_limit_sell("BTC-USDC", 0.01, trigger_price=60000, limit_price=59000)

# Batch orders
broker.place_orders([
    {"symbol": "BTC-USDC", "side": "buy", "quantity": 0.01, "order_type": "market"},
    {"symbol": "BTC-USDC", "side": "sell", "quantity": 0.01, "order_type": "limit", "price": 60000},
])

# Order management
broker.get_order(order_id)
broker.get_opened_orders("BTC-USDC")
broker.get_orders()
broker.get_order_by_client_id("my-client-id")
broker.cancel_order(order_id)
broker.cancel_orders([id1, id2])

# Positions
position = broker.get_position("BTC-USDC")
position.unrealized_pnl(current_price=55000)
position.unrealized_pnl_percentage(current_price=55000)
broker.get_positions()
broker.close_position("BTC-USDC")
broker.get_orders_in_position("BTC-USDC")

# Stop loss / take profit
broker.with_stop_loss("BTC-USDC", price=48000)
broker.with_take_profit("BTC-USDC", price=65000)
broker.stop_loss_price("BTC-USDC")
broker.take_profit_price("BTC-USDC")
broker.clear_stop_loss("BTC-USDC")
broker.clear_take_profit("BTC-USDC")

# Market info
market = broker.get_market("BTC-USDC")
market.align_price(50000.123)
market.align_quantity(0.012345)

# Status
broker.running_status()
broker.current_price("BTC-USDC")

Risk Rules

Before-order rules

from hunter import MaxNetPositionRule, StopLossPauseRule, OrderSizeRule

strategy.add_before_order_rule(
    MaxNetPositionRule(max_abs_position_size=1.5),
    StopLossPauseRule(stop_loss_pause_mins=60, max_loss_nums=3),
    OrderSizeRule(min_order_size=0.001, max_order_size=1.0),
)

After-order rules

from hunter import OrderTimeoutRule, MaxDrawdownRule

strategy.add_after_order_rule(
    OrderTimeoutRule(timeout_secs=300),
    MaxDrawdownRule(drawdown_limit=0.1, limit_type="amount"),
)

Notifier

from hunter import Notifier

strategy.add_notifier(Notifier.logger(level="info"))
strategy.add_notifier(Notifier.telegram(token="xxx", recipients=[123456789]))
strategy.add_notifier(Notifier.dingtalk(token="xxx", secret=None))
strategy.add_notifier(
    Notifier.email(
        username="u@example.com",
        password="xxx",
        server="smtp.example.com",
        from_="u@example.com",
        recipients=["alerts@example.com"],
    )
)

# Send notification within a strategy
self.notify("Subject", "Message body")

Callbacks

class MyStrategy(Strategy):
    def on_ready(self):              # strategy initialized
    def on_bar(self):                # new candle
    def on_orderbook(self):          # orderbook updated
    def on_trade(self):              # trade occurred
    def on_order_update(self, order):  # order status changed
    def on_stop(self):               # strategy stopped

Callbacks must be synchronous functions. async def callbacks are rejected at runtime.

Event Objects

# Bar
bar.feed, bar.symbol, bar.interval
bar.open, bar.high, bar.low, bar.close, bar.volume, bar.timestamp

# OrderBook
ob.symbol, ob.best_bid, ob.best_ask, ob.spread, ob.microprice

# Trade
trade.symbol, trade.price, trade.quantity, trade.side, trade.timestamp

# Fill
fill.fill_id, fill.order_id, fill.price, fill.quantity

# Order
order.id, order.symbol, order.side, order.order_type
order.quantity, order.executed_quantity, order.average_price
order.status, order.created_at, order.updated_at

# Position
position.symbol, position.side, position.quantity, position.average_price
position.unrealized_pnl(current_price)
position.unrealized_pnl_percentage(current_price)

Backtest Example

import hunter
from hunter import Strategy


class SupertrendCross(Strategy):
    def __init__(self):
        self.btc = self.candles(
            connector_id="hyperliquid_perp", symbol="BTC-USDC", timeframe="15m",
        )
        self.broker = self.broker(connector_id="hyperliquid_perp")
        self.with_trailing_stop(3600)

    def on_bar(self):
        st = hunter.ta.supertrend(self.btc.high, self.btc.low, self.btc.close, 10, 3.0)

        if st.trend.cross_over(st.line):
            self.broker.market_buy("BTC-USDC", 0.01)
        elif st.trend.cross_under(st.line):
            self.broker.market_sell("BTC-USDC", 0.01)


hunter.run(SupertrendCross(), mode="backtest")

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

hunter_quant-0.1.2-cp314-cp314-macosx_11_0_arm64.whl (8.9 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

hunter_quant-0.1.2-cp312-cp312-win_amd64.whl (9.2 MB view details)

Uploaded CPython 3.12Windows x86-64

hunter_quant-0.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.5 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

File details

Details for the file hunter_quant-0.1.2-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hunter_quant-0.1.2-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7a3b5b813b0708ce90319d215e951e144bde79ec8ecf377893753076af25f5fd
MD5 e597eef161ad7538420098b1303e378b
BLAKE2b-256 6bac5b565b6690e36b02da89050caa17bf95624258a7154a3902a9c585f02ff8

See more details on using hashes here.

File details

Details for the file hunter_quant-0.1.2-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for hunter_quant-0.1.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 c3f24737a8262b130bb42ab9ab5596149c37ff5173afc3b3c1331b875f74bc64
MD5 6dd73ee2ef1a7f2872d8e966117d810c
BLAKE2b-256 96f6b88a99faed061545ec1502532339866ce44c02d80c179f01bf537740e479

See more details on using hashes here.

File details

Details for the file hunter_quant-0.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for hunter_quant-0.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 547a124c6554a1a7da2f3252fc604d223e7dd367d759d0dac797532ab878ce3e
MD5 47ce224d3041c11f877e6ce00ff2b005
BLAKE2b-256 b35425a0a18d9a10cb2d7746ffeb0522d475290f8cfaf492a5d607bd5e8873e6

See more details on using hashes here.

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