Skip to main content
Glama
patch-ridermg48

TradingView MCP Server

bollinger_scan

Identify cryptocurrency trading opportunities by scanning for coins with low Bollinger Band Width, indicating potential volatility breakouts.

Instructions

Scan for coins with low Bollinger Band Width (squeeze detection).

Args: exchange: Exchange name like KUCOIN, BINANCE, BYBIT, etc. timeframe: One of 5m, 15m, 1h, 4h, 1D, 1W, 1M bbw_threshold: Maximum BBW value to filter (default 0.04) limit: Number of rows to return (max 100)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
exchangeNoKUCOIN
timeframeNo4h
bbw_thresholdNo
limitNo

Implementation Reference

  • The primary handler function for the 'bollinger_scan' tool. Registered via @mcp.tool() decorator. Sanitizes inputs, fetches data via helper, and returns formatted list of results.
    @mcp.tool() def bollinger_scan(exchange: str = "KUCOIN", timeframe: str = "4h", bbw_threshold: float = 0.04, limit: int = 50) -> list[dict]: """Scan for coins with low Bollinger Band Width (squeeze detection). Args: exchange: Exchange name like KUCOIN, BINANCE, BYBIT, etc. timeframe: One of 5m, 15m, 1h, 4h, 1D, 1W, 1M bbw_threshold: Maximum BBW value to filter (default 0.04) limit: Number of rows to return (max 100) """ exchange = sanitize_exchange(exchange, "KUCOIN") timeframe = sanitize_timeframe(timeframe, "4h") limit = max(1, min(limit, 100)) rows = _fetch_bollinger_analysis(exchange, timeframe=timeframe, bbw_filter=bbw_threshold, limit=limit) # Convert Row objects to dicts return [{ "symbol": row["symbol"], "changePercent": row["changePercent"], "indicators": dict(row["indicators"]) } for row in rows]
  • Core helper function that loads symbols, fetches TradingView analysis, computes metrics, applies BBW threshold filter, and returns sorted rows of results.
    def _fetch_bollinger_analysis(exchange: str, timeframe: str = "4h", limit: int = 50, bbw_filter: float = None) -> List[Row]: """Fetch analysis using tradingview_ta with bollinger band logic from the original screener.""" if not TRADINGVIEW_TA_AVAILABLE: raise RuntimeError("tradingview_ta is missing; run `uv sync`.") # Load symbols from coinlist files symbols = load_symbols(exchange) if not symbols: raise RuntimeError(f"No symbols found for exchange: {exchange}") # Limit symbols for performance symbols = symbols[:limit * 2] # Get more to filter later # Get screener type based on exchange screener = EXCHANGE_SCREENER.get(exchange, "crypto") try: analysis = get_multiple_analysis(screener=screener, interval=timeframe, symbols=symbols) except Exception as e: raise RuntimeError(f"Analysis failed: {str(e)}") rows: List[Row] = [] 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 BBW filter if specified if bbw_filter is not None and (metrics['bbw'] >= bbw_filter or metrics['bbw'] <= 0): continue # Check if we have required indicators if not (indicators.get("EMA50") and indicators.get("RSI")): continue rows.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 by change percentage in descending order (highest gainers first) rows.sort(key=lambda x: x["changePercent"], reverse=True) # Return the requested limit return rows[:limit]
  • Computes essential metrics for Bollinger Band analysis including price change, BBW (Bollinger Band Width), rating, and signal, crucial for filtering in bollinger_scan.
    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
  • Input validation functions for timeframe and exchange parameters used in bollinger_scan to sanitize user inputs.
    def sanitize_timeframe(tf: str, default: str = "5m") -> str: if not tf: return default tfs = tf.strip() return tfs if tfs in ALLOWED_TIMEFRAMES else default def sanitize_exchange(ex: str, default: str = "kucoin") -> str: if not ex: return default exs = ex.strip().lower() return exs if exs in EXCHANGE_SCREENER else default

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