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
uv add hunter-quant
For projects that do not use uv:
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.pyexamples/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 DataFrameopen,high,low,close,volume,start_time— shortcut to each column asSeries
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hunter_quant-0.1.3-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: hunter_quant-0.1.3-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 8.9 MB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0939b1bd130b830866237271ff9bba181e8bb263829f574ddff58775ca9357d
|
|
| MD5 |
81d5a07de63ceda39805c5e534317df5
|
|
| BLAKE2b-256 |
7477395a3015690e038040d6864bd313d01790016a2df9a30fed938fcef847f3
|
File details
Details for the file hunter_quant-0.1.3-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: hunter_quant-0.1.3-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 9.2 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02cc91e68aeb8c4845f8e46442c63c771b8587bec0667bce08d6eb271f88916e
|
|
| MD5 |
e53685003c6b9ce6b4f1795d88220a5a
|
|
| BLAKE2b-256 |
7502b18b91062b70774f335d57837912f83f5aa4bb4a32305f260bc3ad5c2744
|
File details
Details for the file hunter_quant-0.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: hunter_quant-0.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 12.5 MB
- Tags: CPython 3.9, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fd77e142e39e9534a82f7a0490db6ac7d9cac6a8f2c17172f8084ce08f79118
|
|
| MD5 |
757b1ae7c1516b46e36a097c8ba3a3d9
|
|
| BLAKE2b-256 |
bd6c7441e5050dee328be63912f540b84a880394ad5c42d74344fe414adb64f2
|