Skip to main content
Glama

place_order

Execute spot, linear, or inverse trading orders on Bybit. Specify category, symbol, side, order type, and quantity. Supports market, limit, TP/SL, and futures trading with position indexes for long/short positions.

Instructions

Execute order

Args:
    category (str): Category
        - spot: Spot trading
            * Minimum order quantity: 0.000011 BTC (up to 6 decimal places)
            * Minimum order amount: 5 USDT
            * If buying at market price, qty should be input in USDT units (e.g., "10" = 10 USDT)
            * If selling at market price, qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC)
            * If placing a limit order, qty should be input in BTC units
            * positionIdx is not used
        - linear: Futures trading (USDT margin)
            * positionIdx is required (1: Long, 2: Short)
        - inverse: Futures trading (coin margin)
            * positionIdx is required (1: Long, 2: Short)
    symbol (str): Symbol (e.g., BTCUSDT)
    side (str): Order direction (Buy, Sell)
    orderType (str): Order type (Market, Limit)
    qty (str): Order quantity
        - Market Buy: qty should be input in USDT units (e.g., "10" = 10 USDT)
        - Market Sell: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC, up to 6 decimal places)
        - Limit: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC, up to 6 decimal places)
    price (Optional[str]): Order price (for limit orders)
    positionIdx (Optional[str]): Position index
        - Required for futures (linear/inverse) trading
        - "1": Long position
        - "2": Short position
        - Not used for spot trading
    timeInForce (Optional[str]): Order validity period
        - GTC: Good Till Cancel (default, for limit orders)
        - IOC: Immediate or Cancel (market order)
        - FOK: Fill or Kill
        - PostOnly: Post Only
    orderLinkId (Optional[str]): Order link ID (unique value)
    isLeverage (Optional[int]): Use leverage (0: No, 1: Yes)
    orderFilter (Optional[str]): Order filter
        - Order: Regular order (default)
        - tpslOrder: TP/SL order
        - StopOrder: Stop order
    triggerPrice (Optional[str]): Trigger price
    triggerBy (Optional[str]): Trigger basis
    orderIv (Optional[str]): Order volatility
    takeProfit (Optional[str]): Take profit price
    stopLoss (Optional[str]): Stop loss price
    tpTriggerBy (Optional[str]): Take profit trigger basis
    slTriggerBy (Optional[str]): Stop loss trigger basis
    tpLimitPrice (Optional[str]): Take profit limit price
    slLimitPrice (Optional[str]): Stop loss limit price
    tpOrderType (Optional[str]): Take profit order type (Market, Limit)
    slOrderType (Optional[str]): Stop loss order type (Market, Limit)

Returns:
    Dict: Order result

Example:
    # Spot trading (SPOT account balance required)
    place_order("spot", "BTCUSDT", "Buy", "Market", "10")  # Buy market price for 10 USDT
    place_order("spot", "BTCUSDT", "Sell", "Market", "0.000100")  # Sell market price for 0.0001 BTC
    place_order("spot", "BTCUSDT", "Buy", "Limit", "0.000100", price="50000")  # Buy limit order for 0.0001 BTC

    # Spot trading - limit order + TP/SL
    place_order("spot", "BTCUSDT", "Buy", "Limit", "0.000100", price="50000",
               takeProfit="55000", stopLoss="45000",  # TP/SL setting
               tpOrderType="Market", slOrderType="Market")  # Execute TP/SL as market order

    # Futures trading
    place_order("linear", "BTCUSDT", "Buy", "Market", "0.001", positionIdx="1")  # Buy market price for long position
    place_order("linear", "BTCUSDT", "Sell", "Market", "0.001", positionIdx="2")  # Sell market price for short position

Notes:
    1. Spot trading order quantity restrictions:
        - Minimum order quantity: 0.000011 BTC
        - Minimum order amount: 5 USDT
        - BTC quantity is only allowed up to 6 decimal places (e.g., 0.000100 O, 0.0001234 X)
    2. Pay attention to unit when buying/selling at market price:
        - Buying: qty should be input in USDT units (e.g., "10" = 10 USDT)
        - Selling: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC)
    3. Futures trading requires positionIdx:
        - Long position: positionIdx="1"
        - Short position: positionIdx="2"
    4. positionIdx is not used for spot trading

Reference:
    https://bybit-exchange.github.io/docs/v5/order/create-order

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
categoryYesCategory (spot, linear, inverse, etc.)
isLeverageNoUse leverage (0: No, 1: Yes)
orderFilterNoOrder filter (Order, tpslOrder, StopOrder)
orderIvNoOrder volatility
orderLinkIdNoOrder link ID
orderTypeYesOrder type (Market, Limit)
positionIdxNoPosition index (1: Long, 2: Short)
priceNoOrder price (for limit orders)
qtyYesOrder quantity
sideYesOrder direction (Buy, Sell)
slLimitPriceNoStop loss limit price
slOrderTypeNoStop loss order type (Market, Limit)
slTriggerByNoStop loss trigger basis
stopLossNoStop loss price
symbolYesSymbol (e.g., BTCUSDT)
takeProfitNoTake profit price
timeInForceNoTime in force (GTC, IOC, FOK, PostOnly)
tpLimitPriceNoTake profit limit price
tpOrderTypeNoTake profit order type (Market, Limit)
tpTriggerByNoTake profit trigger basis
triggerByNoTrigger basis
triggerPriceNoTrigger price

Implementation Reference

  • The primary MCP tool handler for 'place_order', registered via @mcp.tool(). Defines input schema using Pydantic Field, calls the underlying BybitService.place_order method, handles API responses and errors.
    @mcp.tool()
    def place_order(
        category: str = Field(description="Category (spot, linear, inverse, etc.)"),
        symbol: str = Field(description="Symbol (e.g., BTCUSDT)"),
        side: str = Field(description="Order direction (Buy, Sell)"),
        orderType: str = Field(description="Order type (Market, Limit)"),
        qty: str = Field(description="Order quantity"),
        price: Optional[str] = Field(default=None, description="Order price (for limit orders)"),
        positionIdx: Optional[str] = Field(default=None, description="Position index (1: Long, 2: Short)"),
        timeInForce: Optional[str] = Field(default=None, description="Time in force (GTC, IOC, FOK, PostOnly)"),
        orderLinkId: Optional[str] = Field(default=None, description="Order link ID"),
        isLeverage: Optional[int] = Field(default=None, description="Use leverage (0: No, 1: Yes)"),
        orderFilter: Optional[str] = Field(default=None, description="Order filter (Order, tpslOrder, StopOrder)"),
        triggerPrice: Optional[str] = Field(default=None, description="Trigger price"),
        triggerBy: Optional[str] = Field(default=None, description="Trigger basis"),
        orderIv: Optional[str] = Field(default=None, description="Order volatility"),
        takeProfit: Optional[str] = Field(default=None, description="Take profit price"),
        stopLoss: Optional[str] = Field(default=None, description="Stop loss price"),
        tpTriggerBy: Optional[str] = Field(default=None, description="Take profit trigger basis"),
        slTriggerBy: Optional[str] = Field(default=None, description="Stop loss trigger basis"),
        tpLimitPrice: Optional[str] = Field(default=None, description="Take profit limit price"),
        slLimitPrice: Optional[str] = Field(default=None, description="Stop loss limit price"),
        tpOrderType: Optional[str] = Field(default=None, description="Take profit order type (Market, Limit)"),
        slOrderType: Optional[str] = Field(default=None, description="Stop loss order type (Market, Limit)")
    ) -> Dict:
        """
        Execute order
    
        Args:
            category (str): Category
                - spot: Spot trading
                    * Minimum order quantity: 0.000011 BTC (up to 6 decimal places)
                    * Minimum order amount: 5 USDT
                    * If buying at market price, qty should be input in USDT units (e.g., "10" = 10 USDT)
                    * If selling at market price, qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC)
                    * If placing a limit order, qty should be input in BTC units
                    * positionIdx is not used
                - linear: Futures trading (USDT margin)
                    * positionIdx is required (1: Long, 2: Short)
                - inverse: Futures trading (coin margin)
                    * positionIdx is required (1: Long, 2: Short)
            symbol (str): Symbol (e.g., BTCUSDT)
            side (str): Order direction (Buy, Sell)
            orderType (str): Order type (Market, Limit)
            qty (str): Order quantity
                - Market Buy: qty should be input in USDT units (e.g., "10" = 10 USDT)
                - Market Sell: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC, up to 6 decimal places)
                - Limit: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC, up to 6 decimal places)
            price (Optional[str]): Order price (for limit orders)
            positionIdx (Optional[str]): Position index
                - Required for futures (linear/inverse) trading
                - "1": Long position
                - "2": Short position
                - Not used for spot trading
            timeInForce (Optional[str]): Order validity period
                - GTC: Good Till Cancel (default, for limit orders)
                - IOC: Immediate or Cancel (market order)
                - FOK: Fill or Kill
                - PostOnly: Post Only
            orderLinkId (Optional[str]): Order link ID (unique value)
            isLeverage (Optional[int]): Use leverage (0: No, 1: Yes)
            orderFilter (Optional[str]): Order filter
                - Order: Regular order (default)
                - tpslOrder: TP/SL order
                - StopOrder: Stop order
            triggerPrice (Optional[str]): Trigger price
            triggerBy (Optional[str]): Trigger basis
            orderIv (Optional[str]): Order volatility
            takeProfit (Optional[str]): Take profit price
            stopLoss (Optional[str]): Stop loss price
            tpTriggerBy (Optional[str]): Take profit trigger basis
            slTriggerBy (Optional[str]): Stop loss trigger basis
            tpLimitPrice (Optional[str]): Take profit limit price
            slLimitPrice (Optional[str]): Stop loss limit price
            tpOrderType (Optional[str]): Take profit order type (Market, Limit)
            slOrderType (Optional[str]): Stop loss order type (Market, Limit)
    
        Returns:
            Dict: Order result
    
        Example:
            # Spot trading (SPOT account balance required)
            place_order("spot", "BTCUSDT", "Buy", "Market", "10")  # Buy market price for 10 USDT
            place_order("spot", "BTCUSDT", "Sell", "Market", "0.000100")  # Sell market price for 0.0001 BTC
            place_order("spot", "BTCUSDT", "Buy", "Limit", "0.000100", price="50000")  # Buy limit order for 0.0001 BTC
    
            # Spot trading - limit order + TP/SL
            place_order("spot", "BTCUSDT", "Buy", "Limit", "0.000100", price="50000",
                       takeProfit="55000", stopLoss="45000",  # TP/SL setting
                       tpOrderType="Market", slOrderType="Market")  # Execute TP/SL as market order
    
            # Futures trading
            place_order("linear", "BTCUSDT", "Buy", "Market", "0.001", positionIdx="1")  # Buy market price for long position
            place_order("linear", "BTCUSDT", "Sell", "Market", "0.001", positionIdx="2")  # Sell market price for short position
    
        Notes:
            1. Spot trading order quantity restrictions:
                - Minimum order quantity: 0.000011 BTC
                - Minimum order amount: 5 USDT
                - BTC quantity is only allowed up to 6 decimal places (e.g., 0.000100 O, 0.0001234 X)
            2. Pay attention to unit when buying/selling at market price:
                - Buying: qty should be input in USDT units (e.g., "10" = 10 USDT)
                - Selling: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC)
            3. Futures trading requires positionIdx:
                - Long position: positionIdx="1"
                - Short position: positionIdx="2"
            4. positionIdx is not used for spot trading
    
        Reference:
            https://bybit-exchange.github.io/docs/v5/order/create-order
        """
        try:
            result = bybit_service.place_order(
                category, symbol, side, orderType, qty, price, positionIdx,
                timeInForce, orderLinkId, isLeverage, orderFilter,
                triggerPrice, triggerBy, orderIv, takeProfit,
                stopLoss, tpTriggerBy, slTriggerBy, tpLimitPrice,
                slLimitPrice, tpOrderType, slOrderType
            )
            if result.get("retCode") != 0:
                logger.error(f"Failed to place order: {result.get('retMsg')}")
                return {"error": result.get("retMsg")}
            return result
        except Exception as e:
            logger.error(f"Failed to place order: {e}", exc_info=True)
            return {"error": str(e)}
  • Supporting helper method in BybitService class that implements the core order placement logic: sets defaults, validates parameters (e.g., positionIdx), builds the API request dict, and invokes pybit.unified_trading.HTTP.client.place_order.
    def place_order(self, category: str, symbol: str, side: str, orderType: str,
                    qty: str, price: Optional[str] = None,
                    timeInForce: Optional[str] = None, orderLinkId: Optional[str] = None,
                    isLeverage: Optional[int] = None, orderFilter: Optional[str] = None,
                    triggerPrice: Optional[str] = None, triggerBy: Optional[str] = None,
                    orderIv: Optional[str] = None, positionIdx: Optional[int] = None,
                    takeProfit: Optional[str] = None, stopLoss: Optional[str] = None,
                    tpTriggerBy: Optional[str] = None, slTriggerBy: Optional[str] = None,
                    tpLimitPrice: Optional[str] = None, slLimitPrice: Optional[str] = None,
                    tpOrderType: Optional[str] = None, slOrderType: Optional[str] = None) -> Dict:
        """
        Execute order
    
        Args:
            category (str): Category
                - spot: Spot trading
                    * Minimum order quantity: 0.000011 BTC (up to 6 decimal places)
                    * Minimum order amount: 5 USDT
                    * If buying at market price, qty should be input in USDT units (e.g., "10" = 10 USDT)
                    * If selling at market price, qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC)
                    * If placing a limit order, qty should be input in BTC units
                    * positionIdx is not used
                - linear: Futures trading (USDT margin)
                    * positionIdx is required (1: Long, 2: Short)
                - inverse: Futures trading (coin margin)
                    * positionIdx is required (1: Long, 2: Short)
            symbol (str): Symbol (e.g., BTCUSDT)
            side (str): Order direction (Buy, Sell)
            orderType (str): Order type (Market, Limit)
            qty (str): Order quantity
                - Market Buy: qty should be input in USDT units (e.g., "10" = 10 USDT)
                - Market Sell: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC, up to 6 decimal places)
                - Limit: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC, up to 6 decimal places)
            price (Optional[str]): Order price (for limit order)
            timeInForce (Optional[str]): Order validity period
                - GTC: Good Till Cancel (default, for limit order)
                - IOC: Immediate or Cancel (market order)
                - FOK: Fill or Kill
                - PostOnly: Post Only
            orderLinkId (Optional[str]): Order link ID (unique value)
            isLeverage (Optional[int]): Use leverage (0: No use, 1: Use)
            orderFilter (Optional[str]): Order filter
                - Order: General order (default)
                - tpslOrder: TP/SL order
                - StopOrder: Stop order
            triggerPrice (Optional[str]): Trigger price
            triggerBy (Optional[str]): Trigger basis
            orderIv (Optional[str]): Order volatility
            positionIdx (Optional[int]): Position index
                - Required for futures (linear/inverse) trading
                - 1: Long position
                - 2: Short position
                - positionIdx is not used for spot trading
            takeProfit (Optional[str]): Take profit price
            stopLoss (Optional[str]): Stop loss price
            tpTriggerBy (Optional[str]): Take profit trigger basis
            slTriggerBy (Optional[str]): Stop loss trigger basis
            tpLimitPrice (Optional[str]): Take profit limit price
            slLimitPrice (Optional[str]): Stop loss limit price
            tpOrderType (Optional[str]): Take profit order type (Market, Limit)
            slOrderType (Optional[str]): Stop loss order type (Market, Limit)
    
        Returns:
            Dict: Order result
    
        Example:
            # Spot trading (SPOT account balance required)
            place_order("spot", "BTCUSDT", "Buy", "Market", "10")  # Buy market price for 10 USDT
            place_order("spot", "BTCUSDT", "Sell", "Market", "0.000100")  # Sell market price for 0.0001 BTC
            place_order("spot", "BTCUSDT", "Buy", "Limit", "0.000100", price="50000")  # Buy limit order for 0.0001 BTC
            
            # Spot trading - limit order + TP/SL
            place_order("spot", "BTCUSDT", "Buy", "Limit", "0.000100", price="50000",
                       takeProfit="55000", stopLoss="45000",  # TP/SL setting
                       tpOrderType="Market", slOrderType="Market")  # Execute TP/SL as market order
    
            # Futures trading
            place_order("linear", "BTCUSDT", "Buy", "Market", "0.001", positionIdx=1)  # Buy market price for long position
            place_order("linear", "BTCUSDT", "Sell", "Market", "0.001", positionIdx=2)  # Sell market price for short position
    
        Notes:
            1. Spot trading order quantity restrictions:
                - Minimum order quantity: 0.000011 BTC
                - Minimum order amount: 5 USDT
                - BTC quantity is only allowed up to 6 decimal places (e.g., 0.000100 O, 0.0001234 X)
            2. Pay attention to unit when buying/selling at market price:
                - Buying: qty should be input in USDT units (e.g., "10" = 10 USDT)
                - Selling: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC)
            3. Futures trading requires positionIdx:
                - Long position: positionIdx=1
                - Short position: positionIdx=2
            4. positionIdx is not used for spot trading
    
        Reference site:
            https://bybit-exchange.github.io/docs/v5/order/create-order
        """
        try:
            # Default settings
            if timeInForce is None:
                timeInForce = "IOC" if orderType == "Market" else "GTC"
            if orderFilter is None:
                orderFilter = "Order"
            if isLeverage is None:
                isLeverage = 0
    
            # Check positionIdx for futures trading
            if category in ["linear", "inverse"]:
                if not positionIdx or positionIdx not in ["1", "2"]:
                    return {"error": "positionIdx is required for futures trading (1: Long position, 2: Short position)"}
            
            # Ignore positionIdx for spot trading
            if category == "spot":
                positionIdx = None
    
            # Prepare request data
            request_data = {
                "category": category,
                "symbol": symbol,
                "side": side,
                "orderType": orderType,
                "qty": qty,
                "timeInForce": timeInForce,
                "orderFilter": orderFilter,
                "isLeverage": isLeverage
            }
    
            # Add optional parameters
            if price is not None:
                request_data["price"] = price
            if orderLinkId is not None:
                request_data["orderLinkId"] = orderLinkId
            if triggerPrice is not None:
                request_data["triggerPrice"] = triggerPrice
            if triggerBy is not None:
                request_data["triggerBy"] = triggerBy
            if orderIv is not None:
                request_data["orderIv"] = orderIv
            if positionIdx is not None:
                request_data["positionIdx"] = positionIdx
            if takeProfit is not None:
                request_data["takeProfit"] = takeProfit
            if stopLoss is not None:
                request_data["stopLoss"] = stopLoss
            if tpTriggerBy is not None:
                request_data["tpTriggerBy"] = tpTriggerBy
            if slTriggerBy is not None:
                request_data["slTriggerBy"] = slTriggerBy
            if tpLimitPrice is not None:
                request_data["tpLimitPrice"] = tpLimitPrice
            if slLimitPrice is not None:
                request_data["slLimitPrice"] = slLimitPrice
            if tpOrderType is not None:
                request_data["tpOrderType"] = tpOrderType
            if slOrderType is not None:
                request_data["slOrderType"] = slOrderType
    
            # Execute order
            result = self.client.place_order(**request_data)
    
            # Check minimum order quantity/amount
            if isinstance(result, dict) and "error" in result:
                if "min_qty" in result and "min_amt" in result:
                    # Minimum order quantity/amount verification failed
                    logger.error(f"Order execution failed: {result['error']}")
                    return {
                        "error": f"{result['error']} (Minimum order quantity: {result['min_qty']} {symbol.replace('USDT', '')}, Minimum order amount: {result['min_amt']} USDT)"
                    }
                else:
                    logger.error(f"Order execution failed: {result['error']}")
                    return {"error": result['error']}
            elif result.get("retCode") != 0:
                logger.error(f"Order execution failed: {result.get('retMsg')}")
                return {"error": result.get("retMsg")}
            return result
        except Exception as e:
            logger.error(f"Order execution failed: {e}", exc_info=True)
            return {"error": str(e)}
  • src/server.py:227-227 (registration)
    The @mcp.tool() decorator registers the place_order function as an MCP tool.
    @mcp.tool()
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden. It discloses important behavioral traits: minimum order quantities/amounts, decimal precision limits, unit conventions for market orders, and positionIdx requirements. However, it doesn't mention critical aspects like authentication needs, rate limits, whether this is a destructive/write operation (implied but not stated), error conditions, or what happens with insufficient funds.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is comprehensive but overly long and poorly structured. While it starts with a brief purpose statement, it immediately dives into detailed parameter documentation that could be better organized. The 'Notes' section repeats information already covered. However, all content is relevant and the examples are valuable, so it's not wasteful despite its length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex trading tool with 22 parameters, no annotations, and no output schema, the description does an excellent job covering parameter semantics, usage patterns, and constraints. The examples are particularly helpful. It falls short on some behavioral aspects (authentication, error handling) and doesn't describe the return value beyond 'Dict: Order result', but given the complexity, it's quite complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 100% schema description coverage, the description adds substantial value beyond the schema. It provides crucial semantic context: category-specific behaviors (spot vs futures), unit conventions for qty based on side/orderType, positionIdx usage rules, timeInForce defaults, and detailed examples showing parameter interactions. This goes far beyond what the basic schema descriptions provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with 'Execute order' which clearly states the verb and resource. It distinguishes between spot, linear, and inverse trading categories, providing specific context about what the tool does. However, it doesn't explicitly differentiate from sibling tools like cancel_order or set_trading_stop beyond the basic action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context about when to use specific parameter values (e.g., positionIdx required for futures, not for spot; unit differences for market buys/sells). It includes examples for different trading scenarios. However, it doesn't explicitly state when NOT to use this tool versus alternatives like cancel_order or set_trading_stop, nor does it mention prerequisites like account balances or authentication.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dlwjdtn535/mcp-bybit-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server