Creating a Strategy

This guide walks you through creating a trading strategy from scratch using the MangroveAI API. By the end, you will have a saved strategy ready for backtesting.

Prerequisites

Before you begin, make sure you have:
  • An authentication token. All API calls require a Bearer token. See the Authentication guide for how to obtain one.
  • A basic understanding of signals. You should know the difference between TRIGGER and FILTER signals. If not, read Understanding Signals first.
Set up your token as an environment variable for use throughout this guide:
export TOKEN="your-jwt-token-here"

Step 1: Browse available signals

Start by exploring what signals are available. The signals endpoint returns every active signal with its metadata, parameters, and valid ranges.
Signals are organised into six categories — Momentum, Trend, Volume, Volatility, Patterns, and On-Chain. Before building, skim Signals Overview → Scope & limitations to confirm your idea is expressible: the library is OHLCV/indicator-based, so session / time-of-day filters (London open, etc.) and ICT / Smart Money Concepts (Fair Value Gap, Order Block, Breaker Block) are not currently available as built-in signals.
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.mangrovedeveloper.ai/api/v1/signals?limit=100" | python3 -m json.tool
You can also search for signals by name or keyword:
curl -s -X POST "https://api.mangrovedeveloper.ai/api/v1/signals/search" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "macd", "search_type": "name"}'
Not sure which signals to use? Describe your trading idea in plain English using the semantic match endpoint:
curl -X POST "https://api.mangrovedeveloper.ai/api/v1/signals/match" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"user_description": "I want to buy when momentum is turning bullish", "num_results": 5}'
The system will suggest matching TRIGGER and FILTER signals.

Step 2: Choose your entry signals

A strategy entry requires exactly 1 TRIGGER and 1 FILTER. For this walkthrough, we will build a trend-following strategy for ETH:
  • TRIGGER: macd_bullish_cross — enters when the MACD line crosses above the signal line
  • FILTER: is_above_sma — confirms the price is above the 50-period Simple Moving Average
First, inspect each signal to understand its parameters:
# Check the TRIGGER signal
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.mangrovedeveloper.ai/api/v1/signals/macd_bullish_cross" | python3 -m json.tool

# Check the FILTER signal
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.mangrovedeveloper.ai/api/v1/signals/is_above_sma" | python3 -m json.tool
The macd_bullish_cross signal requires three parameters:
  • window_fast (int, range 1-100) — fast EMA period
  • window_slow (int, range 1-200) — slow EMA period
  • window_sign (int, range 1-100) — signal line period
The is_above_sma signal requires one parameter:
  • window (int, range 1-1000) — SMA period
We will use standard values: MACD(12, 26, 9) and SMA(50).

Step 3: Choose exit signals (optional)

Exit signals follow the same pattern: 1 TRIGGER with an optional FILTER. For this strategy, we will add an explicit exit:
  • Exit TRIGGER: macd_bearish_cross — exits when the MACD line crosses below the signal line
If you skip exit signals (pass an empty exit array), the strategy will rely entirely on the built-in stop-loss, take-profit, and time-based exit rules from the execution_config.

Step 4: Create the strategy

Now assemble everything into a POST /api/v1/strategies request. The canonical format uses top-level entry and exit arrays.
curl -s -X POST "https://api.mangrovedeveloper.ai/api/v1/strategies" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ETH MACD Trend Strategy",
    "asset": "ETH",
    "entry": [
      {
        "name": "macd_bullish_cross",
        "signal_type": "TRIGGER",
        "timeframe": "1h",
        "params": {
          "window_fast": 12,
          "window_slow": 26,
          "window_sign": 9
        }
      },
      {
        "name": "is_above_sma",
        "signal_type": "FILTER",
        "timeframe": "1h",
        "params": {
          "window": 50
        }
      }
    ],
    "exit": [
      {
        "name": "macd_bearish_cross",
        "signal_type": "TRIGGER",
        "timeframe": "1h",
        "params": {
          "window_fast": 12,
          "window_slow": 26,
          "window_sign": 9
        }
      }
    ],
    "reward_factor": 2.0
  }' | python3 -m json.tool
A successful response returns the full strategy object including auto-populated execution_config and execution_state:
{
  "success": true,
  "strategy": {
    "id": "a3f1b2c4-5678-4def-9abc-1234567890ab",
    "name": "ETH MACD Trend Strategy",
    "asset": "ETH",
    "status": "inactive",
    "rules": {
      "name": "eth_macd_trend_strategy",
      "asset": "ETH",
      "entry": [
        {
          "name": "macd_bullish_cross",
          "signal_type": "TRIGGER",
          "timeframe": "1h",
          "params": {"window_fast": 12, "window_slow": 26, "window_sign": 9}
        },
        {
          "name": "is_above_sma",
          "signal_type": "FILTER",
          "timeframe": "1h",
          "params": {"window": 50}
        }
      ],
      "exit": [
        {
          "name": "macd_bearish_cross",
          "signal_type": "TRIGGER",
          "timeframe": "1h",
          "params": {"window_fast": 12, "window_slow": 26, "window_sign": 9}
        }
      ],
      "reward_factor": 2.0
    },
    "execution_config": {
      "max_risk_per_trade": 0.01,
      "reward_factor": 2,
      "stop_loss_calculation": "dynamic_atr",
      "atr_period": 14,
      "atr_volatility_factor": 2.0,
      "cooldown_bars": 24,
      "max_open_positions": 10,
      "max_hold_bars": 50
    },
    "execution_state": {
      "cash_balance": 10000.0,
      "account_value": 10000.0,
      "total_trades": 0,
      "num_open_positions": 0
    },
    "created_at": "2026-02-22T10:30:00Z"
  }
}
You did not provide execution_config or execution_state in the request. The API automatically populates both with defaults from trading_defaults.json. You can override any field by including it in your request — a partial execution_config you send is merged over the defaults, so omitting a field keeps its default rather than dropping it. See the Risk Management guide for details on every field.

Sizing version (position_size_calc)

Every strategy is created with a position_size_calc value — "v2" by default (the canonical value from trading_defaults.json). It is pinned at creation and immutable thereafter. The v2 position-sizing engine reads a set of execution_config fields with no built-in fallback:
atr_short_weight, atr_long_weight, min_balance_threshold, min_trade_amount,
max_open_positions, max_trades_per_day, volatility_window, target_volatility,
volatility_mode, enable_volatility_adjustment, max_hold_bars,
exit_on_loss_after_bars, exit_on_profit_after_bars, profit_threshold_pct
You do not need to set these yourself: because a provided execution_config is merged over the canon defaults (and an omitted one is filled entirely from canon), every created strategy carries the full v2 field set, and POST /api/v1/execution/evaluate/{id} works out of the box. To pin a strategy to the older v1 sizing math instead, pass "position_size_calc": "v1" in the create request. See the Risk Management guide for what each field does.

Step 5: Verify the strategy

Retrieve your newly created strategy to confirm everything was saved correctly:
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.mangrovedeveloper.ai/api/v1/strategies/a3f1b2c4-5678-4def-9abc-1234567890ab" \
  | python3 -m json.tool
You should see:
  • Status: inactive (the default for new strategies)
  • Entry signals: macd_bullish_cross (TRIGGER) + is_above_sma (FILTER)
  • Exit signals: macd_bearish_cross (TRIGGER)
Strategy visibility is scoped to your developer account. GET /api/v1/strategies returns only the strategies created through the developer API under the same authenticated user_id and organization. A strategy created under a different account or organization — or through a separate Mangrove product surface — will not appear in your list and total may read 0. To manage a strategy through this API (list it, evaluate it, back-test it by strategy_id), create it through this API.

Common validation errors

If your request is rejected, check for these common issues:
ErrorCauseFix
Missing required fields: name, assetMissing top-level fieldsInclude both name and asset in the request body
Multiple TRIGGERs in entryEntry has 2+ signals with signal_type: "TRIGGER"Keep exactly 1 TRIGGER and 1 FILTER for entry
Multiple FILTERs in entryEntry has 2+ signals with signal_type: "FILTER"Keep exactly 1 TRIGGER and 1 FILTER for entry
Signal 'xyz' not foundInvalid signal nameCheck the name against GET /api/v1/signals

What to do next

Your strategy is created and ready to test. Continue with: