Skip to main content
Glama
phuihock

TA-Lib MCP Server

by phuihock

calculate_ema

Calculate Exponential Moving Average (EMA) for financial market analysis using TA-Lib technical indicators to identify price trends and support trading decisions.

Instructions

Calculate Exponential Moving Average (EMA).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
kwargsYes

Implementation Reference

  • Primary execution handler for the calculate_ema tool. Registered via @mcp.tool() decorator. Delegates computation to EMAIndicator from registry.
    @mcp.tool()
    async def calculate_ema(
        close: List[float],
        timeperiod: int = 20
    ) -> Dict[str, Any]:
        """Calculate Exponential Moving Average (EMA).
        
        Args:
            close: List of closing prices
            timeperiod: Number of periods for average (default: 20)
            
        Returns:
            Dictionary with EMA values and metadata
        """
        try:
            # Get indicator from registry
            indicator = registry.get_indicator("ema")
            if not indicator:
                raise ValueError("EMA indicator not found")
            
            # Create market data
            market_data = MarketData(close=close)
            
            # Calculate indicator
            result = await indicator.calculate(market_data, {"timeperiod": timeperiod})
            
            if result.success:
                return {
                    "success": True,
                    "values": result.values,
                    "metadata": result.metadata,
                }
            else:
                return {
                    "success": False,
                    "error": result.error_message,
                }
                
        except Exception as e:
            return {
                "success": False,
                "error": str(e),
            }
  • EMAIndicator class containing the core EMA calculation logic, input schema, and metadata handling used by the tool handler.
    class EMAIndicator(BaseIndicator):
        """Exponential Moving Average (EMA) indicator implementation."""
        
        def __init__(self):
            """Initialize EMA indicator."""
            super().__init__(
                name="ema",
                description="Exponential Moving Average (EMA) - gives more weight to recent prices"
            )
        
        @property
        def input_schema(self) -> Dict[str, Any]:
            return {
                "type": "object",
                "properties": {
                    "close_prices": {
                        "type": "array",
                        "items": {"type": "number"},
                        "description": "List of closing prices"
                    },
                    "timeperiod": {
                        "type": "integer",
                        "default": 20,
                        "description": "Number of periods for EMA calculation"
                    }
                },
                "required": ["close_prices"]
            }
        
        async def calculate(
            self, 
            market_data: MarketData, 
            options: Dict[str, Any] = None
        ) -> IndicatorResult:
            """Calculate EMA indicator."""
            if options is None:
                options = {}
            
            timeperiod = options.get("timeperiod", 20)
            close_prices = market_data.close
            
            if len(close_prices) < timeperiod:
                return IndicatorResult(
                    indicator_name=self.name,
                    success=False,
                    values={},
                    error_message=f"Not enough data points. Need at least {timeperiod}, got {len(close_prices)}"
                )
            
            # Calculate EMA
            # Multiplier: (2 / (timeperiod + 1))
            multiplier = 2.0 / (timeperiod + 1)
            
            # Initialize EMA with SMA of first timeperiod values
            ema_values = []
            initial_sma = sum(close_prices[:timeperiod]) / timeperiod
            ema_values.append(initial_sma)
            
            # Calculate EMA for remaining values
            for i in range(timeperiod, len(close_prices)):
                ema = (close_prices[i] - ema_values[-1]) * multiplier + ema_values[-1]
                ema_values.append(ema)
            
            return IndicatorResult(
                indicator_name=self.name,
                success=True,
                values={"ema": ema_values},
                metadata={
                    "timeperiod": timeperiod,
                    "multiplier": multiplier,
                    "input_points": len(close_prices),
                    "output_points": len(ema_values)
                }
            )
  • Registration of the EMAIndicator in the global indicator registry, enabling registry.get_indicator('ema') in the handler.
    registry.register("ema", EMAIndicator)
  • JSON schema definition for inputs to the EMA calculation.
    @property
    def input_schema(self) -> Dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "close_prices": {
                    "type": "array",
                    "items": {"type": "number"},
                    "description": "List of closing prices"
                },
                "timeperiod": {
                    "type": "integer",
                    "default": 20,
                    "description": "Number of periods for EMA calculation"
                }
            },
            "required": ["close_prices"]
        }

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/phuihock/mcp-talib'

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