MangroveAI Python SDK
Python SDK for the MangroveAI trading strategy platform.
Install
pip install mangroveai
The package imports as
mangrove_ai(e.g.from mangrove_ai import MangroveAI). The legacyimport mangroveaipath also still works for backwards compatibility.
Setup
- Create an account at mangrovedeveloper.ai
- Navigate to Settings > API Keys
- Generate a new API key
- Set it as an environment variable:
macOS / Linux (bash/zsh):
export MANGROVE_API_KEY=prod_your_key_here
Windows (PowerShell):
$env:MANGROVE_API_KEY = "prod_your_key_here"
Windows (cmd.exe):
set MANGROVE_API_KEY=prod_your_key_here
Or use a .env file
The SDK can load a .env file automatically if you install the optional
python-dotenv extra:
pip install "mangroveai[dotenv]"
Then create a .env file in your project root:
MANGROVE_API_KEY=prod_your_key_here
MangroveAI() will pick it up with no further code. Real environment variables
always take precedence over .env values, so a .env file never overrides a key
you've already exported. Disable autoloading with MangroveAI(load_dotenv=False).
If python-dotenv isn't installed, the SDK reads os.environ only (a .env
file is ignored).
Quickstart
from mangrove_ai import MangroveAI
client = MangroveAI() # reads MANGROVE_API_KEY from environment
# List trading signals
signals = client.signals.list(limit=10)
for s in signals.items:
print(f"{s.name} ({s.category}, {s.signal_type})")
# Get market data
btc = client.crypto_assets.get_market_data("BTC")
print(f"BTC: ${btc.data['current_price']:,.2f}")
# Create a strategy
from mangrove_ai.models import CreateStrategyRequest
strategy = client.strategies.create(CreateStrategyRequest(
name="RSI Momentum",
asset="BTC",
entry=[{"name": "rsi_oversold", "signal_type": "TRIGGER",
"timeframe": "1d", "params": {"window": 14, "threshold": 30}}],
))
# Run a backtest (blocks until done; async-backed since v1.14, so long
# lookbacks work -- it submits to the async surface and polls internally)
import json
from mangrove_ai.models import BacktestRequest
result = client.backtesting.run(BacktestRequest(
asset="BTC",
interval="1d",
strategy_json=json.dumps({"name": "test", "asset": "BTC",
"entry": [{"name": "rsi_oversold", "signal_type": "TRIGGER",
"timeframe": "1d", "params": {"window": 14, "threshold": 30}}],
"exit": []}),
lookback_months=3,
initial_balance=10000,
min_balance_threshold=0.1, min_trade_amount=25,
max_open_positions=3, max_trades_per_day=10,
max_risk_per_trade=0.02, max_units_per_trade=1000000,
max_trade_amount=10000000, volatility_window=24,
target_volatility=0.1,
# Optional: per-timeframe cooldown configuration (preferred over legacy flat fields).
# Keys are the primary timeframe; each value carries max_hold_time_hours,
# short_loss_limit, long_loss_limit, short_window_bars, and long_window_bars.
cooldown_config={
"1d": {
"max_hold_time_hours": 10,
"short_loss_limit": 4,
"long_loss_limit": 6,
"short_window_bars": 20,
"long_window_bars": 60,
}
},
))
print(f"Trades: {result.trade_count}, Sharpe: {result.metrics.get('sharpe_ratio')}")
Services
Layer 1: MangroveAI Core API
| Service | Access | Methods | Description |
|---|---|---|---|
client.auth |
auth.* |
5 | Login, refresh, API key management |
client.strategies |
strategies.* |
9 | Strategy CRUD, status, execution state, verify_strategy (pre-backtest conformance check) |
client.backtesting |
backtesting.* |
8 | Sync/async/bulk backtesting, get_benchmark (buy-and-hold over a window) |
client.market_data |
market_data.* |
2 | get_market_regime (direction over 90/180/365d + volatility), classify_market_segment (one named stretch in sweep-catalog labels) |
client.config |
config.* |
3 | Trading/execution defaults, get_execution_config_schema (each parameter's default, effect, bounds, status) |
client.oracle |
oracle.* |
28 | SIEVE scoring, parameter sweeps/experiments, corpus data queries, backtests, simulation, leaderboard |
client.signals |
signals.* |
8 | Signal discovery, evaluation, validation, query_signal_behavior (measured selectivity / firing rate by parameter setting) |
client.crypto_assets |
crypto_assets.* |
10 | Assets, approved universe, per-asset exchanges, OHLCV, market data |
client.execution |
execution.* |
8 | Accounts, positions, trades, evaluation |
client.on_chain |
on_chain.* |
11 | Smart-money flows, DEX/perp trades, token holders, whale activity (Nansen + WhaleAlert) |
client.defi |
defi.* |
8 | TVL/chain/stablecoins (any plan); token unlocks, perp funding, treasuries, ETF flows, lending rates (DeFiLlama Pro -- requires Pro/Startup/Enterprise, capped at 1,000 calls/account/month) |
client.social |
social.* |
3 | Topic sentiment, mentions, user influence (X / Twitter) |
client.docs |
docs.* |
2 | Documentation listing and content |
Layer 2: Knowledge Base API
| Service | Access | Methods | Description |
|---|---|---|---|
client.kb.documents |
kb.documents.* |
3 | Document listing, content, sections |
client.kb.search |
kb.search.* |
1 | Full-text search with BM25 ranking |
client.kb.tags |
kb.tags.* |
2 | Tag listing and filtering |
client.kb.glossary |
kb.glossary.* |
3 | Glossary terms and backlinks |
client.kb.signals |
kb.signals.* |
2 | Signal metadata from KB |
client.kb.indicators |
kb.indicators.* |
2 | Indicator metadata from KB |
client.kb.compute |
kb.compute.* |
2 | x402 paid signal/indicator computation |
On-chain capability surface
client.on_chain covers Mangrove's Nansen Pro plan plus WhaleAlert (Developer tier, 30-day history):
| Method | Source | What it returns |
|---|---|---|
get_onchain_series(symbol, metrics, date_from, date_to, interval, provider) |
Nansen (WhaleAlert fallback) | Per-bar metric time series (SmartMoneyNetflow, SmartMoneyHoldings, ExchangeNetflow, WhaleNetInflow, HolderConcentration) — one column per metric |
get_smart_money_sentiment(symbol) |
Nansen | Single-token accumulation/distribution score |
screen_smart_money(chains, timeframe) |
Nansen | Tokens with high smart-money activity |
get_smart_money_historical_holdings(chains, date_range, filters, order_by) |
Nansen | Date-stamped holdings snapshots |
get_smart_money_dex_trades(chains, filters, order_by) |
Nansen | Live DEX trades by smart-money wallets |
get_smart_money_perp_trades(filters, order_by) |
Nansen (Hyperliquid) | Perpetual-futures trades by smart-money wallets |
get_token_holders(symbol) |
Nansen | Holder distribution + concentration |
get_token_dex_trades(symbol, chain, date_range, filters, order_by) |
Nansen | Single-token DEX trades across all participants |
get_token_flows(symbol, chain, date_range, label, filters, order_by) |
Nansen | Per-wallet-category hourly flow rows (label scopes to smart_money/exchange/whale/…; excludes stablecoins) |
get_whale_transactions(symbol, min_value, hours_back) |
WhaleAlert | Recent large-value on-chain transactions |
get_exchange_flows(symbol, hours_back) |
WhaleAlert | Aggregated exchange inflows/outflows |
get_whale_activity(symbol, hours_back) |
WhaleAlert | High-level whale activity summary |
On-chain time series → signals. get_onchain_series returns a per-bar series for any window — the
same call serves a live trailing window (e.g. last 10 days, ending now) or a long historical range.
Build a DataFrame with pd.DataFrame(resp.series).set_index("timestamp") and feed it to a
mangrove-kb on-chain signal. End-to-end walkthrough:
examples/onchain_signals_demo.py.
filters and order_by pass through directly to the upstream Nansen API — restrict by
include_smart_money_labels, set value_usd min/max bounds, sort by any field. See
examples/on_chain_nansen.py for raw-method snippets.
Oracle — SIEVE + sweep
client.oracle.* is Mangrove's strategy-research engine. Two headline tools:
- SIEVE scores up to 99 strategy ideas in one call and tells you which are worth
testing — a binary go/no-go (
p_tradesvsp_no_trades) plus a 4-class outcome head (losing/no_trades/wash/winning). Most ideas never trade meaningfully; SIEVE finds the ones that do before you spend compute backtesting them. - Sweep fans a parameter search into one managed experiment of many backtests and ranks the results.
Score ideas with SIEVE
from mangrove_ai import MangroveAI
from mangrove_ai.models.oracle import SieveScoreRequest, StrategyInput, SignalSpec
client = MangroveAI() # reads MANGROVE_API_KEY
resp = client.oracle.sieve_score(SieveScoreRequest(strategies=[
StrategyInput(
asset="BTC",
entry=[SignalSpec(name="ema_crossover", signal_type="TRIGGER", timeframe="1h")],
exit=[SignalSpec(name="rsi", signal_type="FILTER", timeframe="1h")],
),
# ...up to 99 strategies per request
]))
print(f"scored {resp.count} | model {resp.model_version}")
for p in resp.predictions:
print(f" go/no-go: {p.binary}") # {'p_no_trades': .., 'p_trades': ..}
# SIEVE is a go/no-go gate (will it trade?), not a performance prediction:
# backtest the strategies it expects to trade. `four_class` is retired (None).
Run a parameter sweep (experiment lifecycle)
A sweep is a draft experiment you validate, then launch; it fans out into backtests
asynchronously. Poll get_experiment / list_results to track it.
# Pick a dataset + execution defaults from the API, then build a config
ds = client.oracle.list_datasets()[0]
exec_config = client.oracle.exec_config_defaults()
config = {
"name": "ema-sweep-demo",
"kind": "single",
"search_mode": "random",
"seed": 42,
"n_random": 50, # number of random strategies to draw
"datasets": [ds],
"random_signals": {
"n_entry_triggers": 1, "min_entry_filters": 0, "max_entry_filters": 2,
"min_exit_triggers": 0, "max_exit_triggers": 1,
"min_exit_filters": 0, "max_exit_filters": 1,
"n_param_draws": 3, "allowed_categories": None,
},
"execution_config": exec_config,
}
created = client.oracle.create_experiment(config) # -> status "draft"
val = client.oracle.validate_experiment(created.experiment_id)
print(f"valid={val.valid} total_runs={val.total_runs} errors={val.errors}")
if val.valid: # must pass before launch
client.oracle.launch_experiment(created.experiment_id) # fans out asynchronously
status = client.oracle.get_experiment(created.experiment_id)
print(f"status={status['status']} completed={status.get('completed_runs')}")
# client.oracle.pause_experiment(id) / delete_experiment(id) to stop or clean up
results = client.oracle.list_results(experiment_id=created.experiment_id, limit=20)
Other client.oracle.* methods
- Backtests:
backtest,backtest_async+backtest_poll,backtest_bulk - Corpus query:
data_query(curated BigQuery proxy over the results corpus) - Simulation:
simulate_run,simulate_generate,simulate_presets,simulate_history - Results & catalogs:
list_results,list_datasets,list_signals,list_templates,exec_config_defaults - Leaderboard & live:
leaderboard,list_deployed_strategies,get_deployed_strategy_state,get_deployed_strategy_events
Full reference: SIEVE pre-filter guide, SIEVE end-to-end, and the Experiments API reference.
Environment Detection
The SDK auto-detects the environment from your API key prefix:
| Prefix | Environment | API Base URL |
|---|---|---|
prod_ |
Production | https://api.mangrovedeveloper.ai/api/v1 |
dev_ |
Development | https://devapi.mangrove.trade/api/v1 |
Override with explicit parameters:
client = MangroveAI(api_key="...", base_url="http://localhost:5001/api/v1")
Error Handling
from mangrove_ai import MangroveAI, NotFoundError, RateLimitError, APIError
client = MangroveAI()
try:
strategy = client.strategies.get("nonexistent-id")
except NotFoundError as e:
print(f"Not found: {e.message} (correlation_id={e.correlation_id})")
except RateLimitError as e:
print(f"Rate limited, retry after {e.retry_after}s")
except APIError as e:
print(f"[{e.status_code}] {e.code}: {e.message}")
Pagination
Paginated endpoints return PaginatedResponse[T]:
# Single page
page = client.strategies.list(skip=0, limit=10)
print(f"Showing {len(page.items)} of {page.total}")
# Auto-paginate all items
for strategy in client.strategies.list_iter():
print(strategy.name)
Examples
See the examples/ directory for working scripts.
Development
git clone https://github.com/MangroveTechnologies/mangrove-ai-sdk.git
cd mangrove-ai-sdk
pip install -e ".[dev]"
pytest tests/ --ignore=tests/integration # unit tests
MANGROVE_API_KEY=... pytest tests/integration/ -m integration # live tests
Metadata
Release files for mangroveai 1.21.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mangroveai-1.21.0.tar.gz | 128.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mangroveai-1.21.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 214.2 kB
Release files / mangroveai-1.21.0.tar.gz
| Download URL | mangroveai-1.21.0.tar.gz |
|---|---|
| Size | 128.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9d3bc9e0358acfdf222c3412005933c8e046a151eba78dbe7cceb9f053573c8c
|
|
BLAKE2b-256 checksum How to use checksums |
863f6d1694dabe88a6c04f3e029409918e698af1400900ce8325a27fba1e8696
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / mangroveai-1.21.0-py3-none-any.whl
| Download URL | mangroveai-1.21.0-py3-none-any.whl |
|---|---|
| Size | 86.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
340c86889b83eea00234319a776000ec789bfbe63456fe6ee0fab342cc1c36c3
|
|
BLAKE2b-256 checksum How to use checksums |
b2ce71ad75a4500ee91129930fb498ff16105874afd137a813705b7d0a850fbf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|