Skip to main content

Pre-Trade API

The Pre-Trade API provides comprehensive analysis before order execution, answering two key questions:
  1. Can we trade? - Validation (balance, limits, symbol, market status)
  2. What will it cost? - Analytics (fees, slippage, impact, liquidity)

Key Features

  • Balance validation: Check sufficient funds in quote (buy) or base (sell) currency
  • Daily limit enforcement: Prevent exceeding configured trading limits
  • Symbol validation: Verify trading pair exists and is tradeable
  • Order size checks: Validate against exchange min/max constraints
  • Liquidity analysis: Order size vs depth, ADV, time-to-fill estimates
  • Cost estimation: Fees + slippage + market impact with confidence scoring
  • Scenario analysis: Size sensitivity and taker vs maker comparison
  • Trader summary: Human-readable output with warnings

POST /oems/pretrade/analyze

Perform comprehensive pre-trade analysis including validation, liquidity metrics, cost estimation, and optional scenario analysis.

Request Body (JSON)

  • symbol (string, required): Trading pair in CCXT format (e.g., “BTC/USDT”)
  • side (string, required): Order side: “buy” or “sell”
  • quantity (number, required): Order quantity in base currency (e.g., 0.5 for 0.5 BTC)
  • exchange_account_ids (array, required): List of exchange account IDs to check (e.g., [“gateio-001”, “binance-sandbox-001”])
  • order_type (string, optional): Order type: “market”, “limit”, or “algo”. Default: “market”
  • limit_price (number, optional): Limit price for limit orders (required if order_type is “limit”)
  • urgency (string, optional): Order urgency: “low”, “normal”, or “high”. Affects scenario analysis. Default: “normal”
  • include_scenarios (boolean, optional): Whether to include size sensitivity and taker/maker scenario analysis. Default: false

Request Example

curl -X POST http://localhost:8082/oems/pretrade/analyze \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "BTC/USDT",
    "side": "buy",
    "quantity": 0.5,
    "exchange_account_ids": ["gateio-001"],
    "order_type": "market",
    "urgency": "normal",
    "include_scenarios": true
  }'

Response Example (Validation Passed)

{
  "isError": false,
  "statusCode": 200,
  "data": {
    "request_id": "pt-uuid-here",
    "timestamp": "2025-01-15T10:30:00Z",
    "symbol": "BTC/USDT",
    "side": "buy",
    "quantity": 0.5,
    "can_execute": true,

    "validation": {
      "passed": true,
      "checks": [
        {"name": "balance", "passed": true, "message": "Sufficient balance: 50000.00 USDT available"},
        {"name": "daily_limit", "passed": true, "message": "Within limit ($76.50 remaining)"},
        {"name": "symbol", "passed": true, "message": "Symbol BTC/USDT is tradeable"},
        {"name": "order_size", "passed": true, "message": "Order size valid: 0.5 ($44.15K)"}
      ]
    },

    "liquidity": {
      "symbol": "BTC/USDT",
      "order_quantity": 0.5,
      "order_value_usd": 44150.00,
      "pct_of_top10_depth": 3.2,
      "pct_of_top20_depth": 1.6,
      "levels_to_fill": 2,
      "depth_available_usd": 2750000,
      "adv_usd": 2839482806,
      "pct_of_adv": 0.0016,
      "estimated_fill_time_taker_sec": 0,
      "estimated_fill_time_maker_sec": 180,
      "venue_liquidity": [
        {"venue": "gateio", "pct_of_depth": 1.6, "depth_usd": 693489.38, "book_confidence": 0.693}
      ]
    },

    "cost": {
      "total_cost_bps": 4.12,
      "total_cost_usd": 18.19,
      "estimated_execution_price": 88317.64,
      "confidence": 0.693,
      "fee_bps": 4.0,
      "fee_usd": 17.66,
      "fee_type": "taker",
      "slippage_bps": 0.01,
      "slippage_usd": 0.04,
      "market_impact_bps": 0.11,
      "market_impact_usd": 0.49,
      "mid_price": 88291.25,
      "arrival_price": 88291.25,
      "estimated_vwap": 88291.34,
      "vs_mid_bps": 4.12,
      "vs_arrival_bps": 4.12,
      "venue_costs": [
        {"venue": "gateio", "quantity": 0.5, "fee_bps": 4.0, "slippage_bps": 0.01, "total_bps": 4.01, "confidence": 0.693}
      ]
    },

    "scenarios": {
      "base_case": {"total_cost_bps": 4.12},
      "size_minus_20pct": {"total_cost_bps": 4.09, "quantity": 0.4},
      "size_plus_20pct": {"total_cost_bps": 4.14, "quantity": 0.6},
      "taker_estimate": {"total_cost_bps": 4.12, "fill_time_sec": 0},
      "maker_estimate": {"total_cost_bps": 2.02, "fill_time_sec": 900}
    },

    "summary": {
      "headline_cost_bps": 4.12,
      "headline_cost_usd": 18.19,
      "headline_recommendation": null,
      "primary_venue": "gateio",
      "primary_venue_pct": 100.0,
      "time_to_fill_estimate": "instant (taker)",
      "order_size_context": "Very small (0.00% of ADV)",
      "cost_breakdown": [
        {"label": "Trading fees (taker)", "bps": 4.0, "usd": 17.66},
        {"label": "Slippage", "bps": 0.01, "usd": 0.04},
        {"label": "Market impact", "bps": 0.11, "usd": 0.49}
      ],
      "warnings": [],
      "confidence_score": 0.693,
      "confidence_label": "Medium",
      "confidence_factors": ["Fresh orderbook data", "Good depth available", "Small order relative to volume"]
    }
  }
}

Response Example (Validation Failed)

{
  "isError": false,
  "statusCode": 200,
  "data": {
    "request_id": "pt-uuid-here",
    "timestamp": "2025-01-15T10:30:00Z",
    "symbol": "BTC/USDT",
    "side": "buy",
    "quantity": 0.1,
    "can_execute": false,

    "validation": {
      "passed": false,
      "checks": [
        {
          "name": "balance",
          "passed": false,
          "message": "Insufficient balance: need 9006.90 USDT, have 0.00",
          "details": {
            "required": 9006.90,
            "available": 0.0,
            "shortfall": 9006.90,
            "currency": "USDT"
          }
        },
        {
          "name": "daily_limit",
          "passed": false,
          "message": "Would exceed daily limit: $8830.30 order, $100.00 remaining",
          "details": {
            "order_value_usd": 8830.30,
            "remaining_usd": 100.00,
            "limit_usd": 100.00
          }
        },
        {"name": "symbol", "passed": true, "message": "Symbol BTC/USDT is tradeable"},
        {"name": "order_size", "passed": true, "message": "Order size valid: 0.1 ($8.83K)"}
      ]
    },

    "summary": {
      "warnings": [
        {"severity": "critical", "code": "INSUFFICIENT_BALANCE", "message": "Insufficient balance: need 9006.90 USDT, have 0.00"},
        {"severity": "critical", "code": "DAILY_LIMIT_EXCEEDED", "message": "Would exceed daily limit: $8830.30 order, $100.00 remaining"}
      ],
      "confidence_score": 0.0,
      "confidence_label": "Low"
    }
  }
}

Validation Checks

CheckDescription
balanceVerifies sufficient funds (quote for buy, base for sell)
daily_limitVerifies order won’t exceed daily trading limit
symbolVerifies trading pair exists and is active
order_sizeVerifies order meets minimum ($10) and exchange constraints

Warning Codes

CodeSeverityTrigger
INSUFFICIENT_BALANCEcriticalBalance check failed
DAILY_LIMIT_EXCEEDEDcriticalWould exceed daily limit
SYMBOL_NOT_FOUNDcriticalSymbol not tradeable
BELOW_MINIMUM_ORDERcriticalOrder below $10 minimum
LOW_LIQUIDITYwarningOrder > 20% of top-20 depth
VERY_LOW_LIQUIDITYcriticalOrder > 50% of top-20 depth
LARGE_ORDERwarningOrder > 5% of ADV
VERY_LARGE_ORDERcriticalOrder > 10% of ADV
STALE_FEEDwarningVenue staleness > 1s
WIDE_SPREADwarningSpread > 10 bps
HIGH_IMPACTwarningEstimated impact > 10 bps
LOW_CONFIDENCEwarningConfidence < 50%

POST /oems/pretrade/validate

Perform quick validation without full cost analysis. Use this for fast pre-flight checks.

Request Body (JSON)

  • symbol (string, required): Trading pair in CCXT format
  • side (string, required): Order side: “buy” or “sell”
  • quantity (number, required): Order quantity in base currency
  • exchange_account_ids (array, required): List of exchange account IDs to validate against

Request Example

curl -X POST http://localhost:8082/oems/pretrade/validate \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "BTC/USDT",
    "side": "buy",
    "quantity": 0.001,
    "exchange_account_ids": ["gateio-001"]
  }'

Response Example

{
  "isError": false,
  "statusCode": 200,
  "data": {
    "can_execute": true,
    "validation": {
      "passed": true,
      "checks": [
        {"name": "balance", "passed": true, "message": "Sufficient balance: 10000.00 USDT available"},
        {"name": "daily_limit", "passed": true, "message": "Within limit ($76.50 remaining)"}
      ]
    }
  }
}

GET /oems/pretrade/liquidity

Get current liquidity metrics for a trading pair. Requires an active orderbook subscription.

Query Parameters

  • symbol (string, required): Trading pair in CCXT format (e.g., “BTC/USDT”)

Request Example

curl "http://localhost:8082/oems/pretrade/liquidity?symbol=BTC/USDT"

Response Example (With Orderbook Data)

{
  "isError": false,
  "statusCode": 200,
  "data": {
    "symbol": "BTC/USDT",
    "available": true,
    "timestamp": "2025-01-15T10:30:00Z",
    "mid_price": 88291.25,
    "spread_bps": 0.01,
    "adv_usd": 2839482806.93,
    "depth_usd": {
      "top_10": 331920.93,
      "top_20": 693489.38
    },
    "by_venue": [
      {
        "venue": "gateio",
        "bid_depth": 398640.65,
        "ask_depth": 294848.73,
        "spread_bps": 0.01,
        "confidence": 0.693
      }
    ]
  }
}

Response Example (No Orderbook Data)

{
  "isError": false,
  "statusCode": 200,
  "data": {
    "symbol": "BTC/USDT",
    "available": false,
    "mid_price": null,
    "spread_bps": null,
    "adv_usd": null,
    "depth_usd": {"top_10": 0, "top_20": 0},
    "by_venue": []
  }
}

GET /oems/pretrade/fees

Get fee schedule for a venue, account, or all configured venues. Supports account-specific fees including VIP tiers, negotiated rates, and pair-specific overrides.

Query Parameters

  • venue (string, optional): Exchange venue name. Returns default venue fees from static configuration.
  • exchange_account_id (string, optional): Exchange account ID for account-specific fees. When provided, returns actual fees for the account including VIP tier rates from exchange API, negotiated rates from database overrides, and pair-specific fees if symbol is also provided.
  • symbol (string, optional): Trading pair for pair-specific fees. Only used with exchange_account_id.

Fee Resolution Priority

When exchange_account_id is provided, fees are resolved in this order:
  1. Pair-specific DB override: fee_overrides.pairs.{symbol} in exchange_accounts collection
  2. Account-level DB override: fee_overrides.maker_bps/taker_bps in exchange_accounts collection
  3. Exchange API: VIP tier from fetch_trading_fees() or fetch_trading_fee(symbol)
  4. Static config: Default venue fees from configuration

Request Examples

# Get account-specific fees (VIP tier, negotiated rates)
curl "http://localhost:8082/oems/pretrade/fees?exchange_account_id=gateio-001"

# Get pair-specific fees for an account
curl "http://localhost:8082/oems/pretrade/fees?exchange_account_id=gateio-001&symbol=BTC/USDT"

# Get default fees for a venue
curl "http://localhost:8082/oems/pretrade/fees?venue=gateio"

# Get all default fee schedules
curl "http://localhost:8082/oems/pretrade/fees"

Response Example (Account-Specific Fees)

{
  "isError": false,
  "statusCode": 200,
  "data": {
    "venue": "gateio",
    "exchange_account_id": "gateio-001",
    "symbol": "BTC/USDT",
    "maker_bps": 1.5,
    "taker_bps": 3.0,
    "source": "exchange_api",
    "tier": "VIP2",
    "tier_based": true,
    "last_updated": "2025-01-15T10:30:00.000Z"
  }
}

Response Example (Single Venue - Static Config)

{
  "isError": false,
  "statusCode": 200,
  "data": {
    "venue": "gateio",
    "maker_bps": 2,
    "taker_bps": 4,
    "source": "config",
    "last_updated": "2025-01-01T00:00:00Z"
  }
}

Response Example (All Venues)

{
  "isError": false,
  "statusCode": 200,
  "data": {
    "venues": [
      {"venue": "binance", "maker_bps": 2, "taker_bps": 4, "source": "config", "last_updated": "2025-01-01T00:00:00Z"},
      {"venue": "bybit", "maker_bps": 1, "taker_bps": 6, "source": "config", "last_updated": "2025-01-01T00:00:00Z"},
      {"venue": "gateio", "maker_bps": 2, "taker_bps": 4, "source": "config", "last_updated": "2025-01-01T00:00:00Z"},
      {"venue": "kraken", "maker_bps": 2, "taker_bps": 5, "source": "config", "last_updated": "2025-01-01T00:00:00Z"},
      {"venue": "hyperliquid", "maker_bps": 0, "taker_bps": 3.5, "source": "config", "last_updated": "2025-01-01T00:00:00Z"},
      {"venue": "okx", "maker_bps": 2, "taker_bps": 5, "source": "config", "last_updated": "2025-01-01T00:00:00Z"}
    ]
  }
}

Fee Sources

SourceDescription
db_pair_overridePair-specific override from exchange_accounts collection
db_account_overrideAccount-level override from exchange_accounts collection
exchange_apiReal-time VIP tier from exchange API
exchange_marketsFee info from exchange markets data
configStatic configuration defaults
defaultFallback default (5 bps maker / 10 bps taker)

Default Fee Schedule

VenueMaker (bps)Taker (bps)
Binance24
Bybit16
Gate.io24
Kraken25
Hyperliquid03.5
OKX25

Database Fee Overrides

Account-specific fees can be configured in the exchange_accounts collection:
{
  "_id": "gateio-001",
  "exchange": "gateio",
  "fee_overrides": {
    "maker_bps": 1.5,
    "taker_bps": 3.0,
    "tier": "VIP2",
    "pairs": {
      "BTC/USDT": {"maker_bps": 1.0, "taker_bps": 2.5},
      "ETH/USDT": {"maker_bps": 1.2, "taker_bps": 2.8}
    }
  }
}

Cost Model

The pre-trade cost estimation uses the following model:

Total Cost

total_cost_bps = fee_bps + slippage_bps + market_impact_bps
total_cost_usd = order_value_usd * total_cost_bps / 10000

Slippage Calculation

Slippage is calculated by walking the orderbook:
For BUY orders:
  Walk ask levels, calculate volume-weighted average price (VWAP)
  slippage_bps = (VWAP - mid_price) / mid_price * 10000

For SELL orders:
  Walk bid levels, calculate VWAP
  slippage_bps = (mid_price - VWAP) / mid_price * 10000

Market Impact Model

Uses a square-root model:
impact_bps = k * sqrt(pct_of_adv) * volatility_factor

Where:
  k = 5 (calibration constant)
  pct_of_adv = order_value / ADV * 100
  volatility_factor = 1.0 (default)
Impact examples:
  • Order = 1% ADV: impact ~5 bps
  • Order = 4% ADV: impact ~10 bps
  • Order = 9% ADV: impact ~15 bps

Confidence Scoring

Confidence starts at 1.0 and is reduced by:
FactorPenalty
Book staleness > 500ms-0.1 per 500ms (max -0.3)
Order > 20% of depth-0.2
Spread > 10 bps-0.1
No ADV data-0.2
Confidence labels:
  • Greater than 0.8: “High”
  • 0.5 - 0.8: “Medium”
  • Less than 0.5: “Low”