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

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

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
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It mentions the rating scale and limit constraint ('max 50'), which adds some context. However, it lacks details on permissions, rate limits, error handling, or what the output contains (though an output schema exists). The description provides minimal behavioral insight beyond basic parameter info.

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

Conciseness4/5

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

The description is appropriately sized and front-loaded with the purpose, followed by a structured parameter list. Each sentence earns its place by clarifying parameters, though it could be more concise by integrating the purpose with parameter details. No wasted text, but minor room for optimization.

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?

Given 4 parameters with 0% schema coverage and an output schema present, the description does well by fully explaining parameters and their semantics. It covers the tool's core functionality adequately. However, it lacks context on when to use it versus siblings, and behavioral details are minimal, leaving some gaps in completeness.

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?

Schema description coverage is 0%, so the description must compensate. It adds significant meaning beyond the schema by explaining each parameter: exchange examples, timeframe options, rating scale with interpretations, and limit constraint. This fully documents all 4 parameters, making it highly valuable for understanding inputs.

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 clearly states the tool's purpose: 'Filter coins by Bollinger Band rating.' It specifies the verb ('filter') and resource ('coins'), though it doesn't explicitly differentiate from siblings like 'bollinger_scan' or 'coin_analysis' which might have overlapping functionality. The purpose is specific but lacks sibling comparison.

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool versus alternatives. The description lists parameters but doesn't explain scenarios or prerequisites for filtering by Bollinger Band rating, nor does it mention sibling tools like 'bollinger_scan' for comparison. Usage is implied only through the parameter details.

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

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