Skip to main content
Glama

place_order

Submit market or limit orders to Alpaca paper trading for buying or selling stocks using specified symbols, quantities, and order types.

Instructions

Submits a market or limit order to Alpaca paper trading.

Args:
    symbol: Ticker symbol.
    side: 'buy' or 'sell'.
    qty: Quantity to trade.
    order_type: 'market' or 'limit'.
    limit_price: Required if order_type is 'limit'.
    
Returns:
    Confirmation message or error

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
symbolYes
sideYes
qtyYes
order_typeNomarket
limit_priceNo

Implementation Reference

  • Core handler function for the 'place_order' tool. Implements order submission to Alpaca (market/limit), pre-trade risk validation via validate_trade, price fetching via yfinance, logging, and detailed success/error responses.
    def place_order(
        symbol: str, 
        side: Literal["buy", "sell"], 
        qty: float, 
        order_type: Literal["market", "limit"] = "market", 
        limit_price: Optional[float] = None
    ) -> str:
        """
        Submits a market or limit order to Alpaca paper trading.
        
        Args:
            symbol: Ticker symbol.
            side: 'buy' or 'sell'.
            qty: Quantity to trade.
            order_type: 'market' or 'limit'.
            limit_price: Required if order_type is 'limit'.
            
        Returns:
            Confirmation message or error
        """
        if broker is None:
            return "ERROR: Alpaca broker not initialized. Check your API credentials in .env file."
        
        # Import here to avoid circular dependency
        from tools.risk_engine import validate_trade
        
        try:
            # Get current price for risk validation
            ticker = yf.Ticker(symbol)
            try:
                current_price = ticker.fast_info.last_price
            except:
                return f"Failed to get price for {symbol}"
            
            if current_price is None:
                return f"Failed to get price for {symbol}"
            
            # Pre-Trade Risk Check
            risk_error = validate_trade(symbol, side, qty, current_price)
            if risk_error:
                logger.warning(f"Trade rejected by risk engine: {risk_error}")
                return risk_error
            
            # Submit order to Alpaca
            if order_type == "market":
                logger.info(f"Submitting MARKET order: {side.upper()} {qty} {symbol}")
                order_result = broker.submit_market_order(symbol, side, qty)
                logger.info(f"Order submitted successfully: ID={order_result['order_id']}")
                return (
                    f"✅ Market Order Submitted: {side.upper()} {qty} {symbol}\n"
                    f"Order ID: {order_result['order_id']}\n"
                    f"Status: {order_result['status']}\n"
                    f"Submitted at: {order_result['submitted_at']}"
                )
            
            elif order_type == "limit":
                if not limit_price:
                    return "ERROR: Limit price required for limit orders."
                
                # Validate limit price direction
                if side == "buy" and limit_price > current_price:
                    logger.warning(f"Buy limit {limit_price} is above market {current_price}")
                if side == "sell" and limit_price < current_price:
                    logger.warning(f"Sell limit {limit_price} is below market {current_price}")
                
                logger.info(f"Submitting LIMIT order: {side.upper()} {qty} {symbol} @ ${limit_price}")
                order_result = broker.submit_limit_order(symbol, side, qty, limit_price)
                logger.info(f"Order submitted successfully: ID={order_result['order_id']}")
                return (
                    f"✅ Limit Order Submitted: {side.upper()} {qty} {symbol} @ ${limit_price:.2f}\n"
                    f"Order ID: {order_result['order_id']}\n"
                    f"Status: {order_result['status']}\n"
                    f"Submitted at: {order_result['submitted_at']}"
                )
            else:
                logger.error(f"Unknown order type requested: {order_type}")
                return f"ERROR: Unknown order type: {order_type}"
                
        except Exception as e:
            logger.error(f"Order failed: {e}", exc_info=True)
            return f"ERROR: Order failed - {str(e)}"
  • server.py:375-378 (registration)
    Registers the place_order function as an MCP tool by including it in the execution tools list passed to register_tools, which applies the @mcp.tool() decorator.
    register_tools(
        [place_order, cancel_order, get_positions, flatten, get_order_history],
        "Execution"
    )
  • Helper function used to batch-register MCP tools, including place_order, by dynamically applying the @mcp.tool() decorator to each function in the list.
    def register_tools(tools: List[Callable], category: str):
        """Helper to register multiple tools with logging."""
        for tool in tools:
            try:
                mcp.tool()(tool)
                logger.info(f"Registered {category} tool: {tool.__name__}")
            except Exception as e:
                logger.error(f"Failed to register {tool.__name__}: {e}")
                raise

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/N-lia/MonteWalk'

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