Skip to main content
Glama
patch-ridermg48

TradingView MCP Server

rating_filter

Filter cryptocurrency coins by Bollinger Band rating to identify trading opportunities based on technical analysis signals across multiple exchanges and timeframes.

Instructions

Filter coins by Bollinger Band rating.

Args:
    exchange: Exchange name like KUCOIN, BINANCE, BYBIT, etc.
    timeframe: One of 5m, 15m, 1h, 4h, 1D, 1W, 1M
    rating: BB rating (-3 to +3): -3=Strong Sell, -2=Sell, -1=Weak Sell, 1=Weak Buy, 2=Buy, 3=Strong Buy
    limit: Number of rows to return (max 50)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
exchangeNoKUCOIN
timeframeNo5m
ratingNo
limitNo

Implementation Reference

  • Main handler and registration for the rating_filter tool. Sanitizes parameters, fetches filtered trending analysis by BB rating, and returns formatted list of symbols with metrics.
    @mcp.tool()
    def rating_filter(exchange: str = "KUCOIN", timeframe: str = "5m", rating: int = 2, limit: int = 25) -> list[dict]:
        """Filter coins by Bollinger Band rating.
        
        Args:
            exchange: Exchange name like KUCOIN, BINANCE, BYBIT, etc.
            timeframe: One of 5m, 15m, 1h, 4h, 1D, 1W, 1M
            rating: BB rating (-3 to +3): -3=Strong Sell, -2=Sell, -1=Weak Sell, 1=Weak Buy, 2=Buy, 3=Strong Buy
            limit: Number of rows to return (max 50)
        """
        exchange = sanitize_exchange(exchange, "KUCOIN")
        timeframe = sanitize_timeframe(timeframe, "5m")
        rating = max(-3, min(3, rating))
        limit = max(1, min(limit, 50))
        
        rows = _fetch_trending_analysis(exchange, timeframe=timeframe, filter_type="rating", rating_filter=rating, limit=limit)
        # Convert Row objects to dicts
        return [{
            "symbol": row["symbol"],
            "changePercent": row["changePercent"],
            "indicators": dict(row["indicators"])
        } for row in rows]
  • Core helper that performs the actual data fetching from TradingView, computes metrics, and applies the rating filter by checking metrics['rating'] == rating_filter.
    def _fetch_trending_analysis(exchange: str, timeframe: str = "5m", filter_type: str = "", rating_filter: int = None, limit: int = 50) -> List[Row]:
        """Fetch trending coins analysis similar to the original app's trending endpoint."""
        if not TRADINGVIEW_TA_AVAILABLE:
            raise RuntimeError("tradingview_ta is missing; run `uv sync`.")
        
        symbols = load_symbols(exchange)
        if not symbols:
            raise RuntimeError(f"No symbols found for exchange: {exchange}")
        
        # Process symbols in batches due to TradingView API limits
        batch_size = 200  # Considering API limitations
        all_coins = []
        
        screener = EXCHANGE_SCREENER.get(exchange, "crypto")
        
        # Process symbols in batches
        for i in range(0, len(symbols), batch_size):
            batch_symbols = symbols[i:i + batch_size]
            
            try:
                analysis = get_multiple_analysis(screener=screener, interval=timeframe, symbols=batch_symbols)
            except Exception as e:
                continue  # If this batch fails, move to the next one
                
            # Process coins in this batch
            for key, value in analysis.items():
                try:
                    if value is None:
                        continue
                        
                    indicators = value.indicators
                    metrics = compute_metrics(indicators)
                    
                    if not metrics or metrics.get('bbw') is None:
                        continue
                    
                    # Apply rating filter if specified
                    if filter_type == "rating" and rating_filter is not None:
                        if metrics['rating'] != rating_filter:
                            continue
                    
                    all_coins.append(Row(
                        symbol=key,
                        changePercent=metrics['change'],
                        indicators=IndicatorMap(
                            open=metrics.get('open'),
                            close=metrics.get('price'),
                            SMA20=indicators.get("SMA20"),
                            BB_upper=indicators.get("BB.upper"),
                            BB_lower=indicators.get("BB.lower"),
                            EMA50=indicators.get("EMA50"),
                            RSI=indicators.get("RSI"),
                            volume=indicators.get("volume"),
                        )
                    ))
                    
                except (TypeError, ZeroDivisionError, KeyError):
                    continue
        
        # Sort all coins by change percentage
        all_coins.sort(key=lambda x: x["changePercent"], reverse=True)
        
        return all_coins[:limit]
  • Computes key metrics including the 'rating' value used for filtering, based on Bollinger Band position.
    def compute_metrics(indicators: Dict) -> Optional[Dict]:
        try:
            open_price = indicators["open"]
            close = indicators["close"]
            sma = indicators["SMA20"]
            bb_upper = indicators["BB.upper"]
            bb_lower = indicators["BB.lower"]
            bb_middle = sma
    
            change = compute_change(open_price, close)
            bbw = compute_bbw(sma, bb_upper, bb_lower)
            rating, signal = compute_bb_rating_signal(close, bb_upper, bb_middle, bb_lower)
    
            return {
                "price": round(close, 4),
                "change": round(change, 3),
                "bbw": round(bbw, 4) if bbw is not None else None,
                "rating": rating,
                "signal": signal,
            }
        except (KeyError, TypeError):
            return None
  • Exact computation of the BB 'rating' (-3 to +3) based on close price relative to Bollinger Bands.
    def compute_bb_rating_signal(close: float, bb_upper: float, bb_middle: float, bb_lower: float) -> Tuple[int, str]:
        rating = 0
        if close > bb_upper:
            rating = 3
        elif close > bb_middle + ((bb_upper - bb_middle) / 2):
            rating = 2
        elif close > bb_middle:
            rating = 1
        elif close < bb_lower:
            rating = -3
        elif close < bb_middle - ((bb_middle - bb_lower) / 2):
            rating = -2
        elif close < bb_middle:
            rating = -1
    
        signal = "NEUTRAL"
        if rating == 2:
            signal = "BUY"
        elif rating == -2:
            signal = "SELL"
        return rating, signal

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/patch-ridermg48/tradingview-mcp'

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