# borsapy.search

Symbol search functionality for borsapy.

This module provides unified symbol search across TradingView and local KAP data.

Examples:

> > > import borsapy as bp bp.search("banka") # Search all assets ['AKBNK', 'GARAN', 'ISCTR', 'YKBNK', 'HALKB', ...]

> > >     >>> bp.search("gold", type="forex")  # Filter by type
> > >     ['XAUUSD', 'XAUTRY', ...]

> > >     >>> bp.search("GARAN", exchange="BIST")  # Filter by exchange
> > >     ['GARAN']

View Source

      1"""Symbol search functionality for borsapy.
      2
      3This module provides unified symbol search across TradingView and local KAP data.
      4
      5Examples:
      6    >>> import borsapy as bp
      7    >>> bp.search("banka")               # Search all assets
      8    ['AKBNK', 'GARAN', 'ISCTR', 'YKBNK', 'HALKB', ...]
      9
     10    >>> bp.search("gold", type="forex")  # Filter by type
     11    ['XAUUSD', 'XAUTRY', ...]
     12
     13    >>> bp.search("GARAN", exchange="BIST")  # Filter by exchange
     14    ['GARAN']
     15"""
     16
     17from __future__ import annotations
     18
     19import logging
     20from typing import Any
     21
     22logger = logging.getLogger(__name__)
     23
     24
     25def search(
     26    query: str,
     27    type: str | None = None,
     28    exchange: str | None = None,
     29    limit: int = 50,
     30    full_info: bool = False,
     31) -> list[str] | list[dict[str, Any]]:
     32    """Search for symbols matching the query.
     33
     34    Searches TradingView's symbol database and optionally merges with local
     35    KAP company data for comprehensive BIST coverage.
     36
     37    Args:
     38        query: Search query (e.g., "banka", "enerji", "THY", "gold")
     39        type: Filter by asset type:
     40              - "stock": Stocks/equities
     41              - "forex" or "fx": Forex pairs
     42              - "crypto": Cryptocurrencies
     43              - "index": Market indices
     44              - "futures": Futures contracts
     45              - "fund" or "etf": Funds and ETFs
     46              - "bond": Bonds
     47        exchange: Filter by exchange (e.g., "BIST", "NASDAQ", "NYSE")
     48        limit: Maximum number of results (default 50, max 100)
     49        full_info: If True, return full result dicts; if False, return symbol list
     50
     51    Returns:
     52        If full_info=False (default):
     53            List of symbol strings: ['AKBNK', 'GARAN', ...]
     54
     55        If full_info=True:
     56            List of result dicts:
     57            [
     58                {
     59                    "symbol": "AKBNK",
     60                    "full_name": "BIST:AKBNK",
     61                    "description": "AKBANK T.A.S.",
     62                    "exchange": "BIST",
     63                    "type": "stock",
     64                    "currency": "TRY",
     65                    "country": "TR"
     66                },
     67                ...
     68            ]
     69
     70    Examples:
     71        >>> import borsapy as bp
     72
     73        >>> # Simple search
     74        >>> bp.search("banka")
     75        ['AKBNK', 'GARAN', 'ISCTR', 'YKBNK', 'HALKB', ...]
     76
     77        >>> # Search with type filter
     78        >>> bp.search("gold", type="forex")
     79        ['XAUUSD', 'XAUTRY', ...]
     80
     81        >>> # Search with exchange filter
     82        >>> bp.search("THY", exchange="BIST")
     83        ['THYAO']
     84
     85        >>> # Get full info
     86        >>> bp.search("GARAN", full_info=True)
     87        [{'symbol': 'GARAN', 'description': 'TURKIYE GARANTI BANKASI A.S.', ...}]
     88
     89        >>> # Search crypto
     90        >>> bp.search("BTC", type="crypto")
     91        ['BTCUSD', 'BTCTRY', 'BTCUSDT', ...]
     92
     93        >>> # Search indices
     94        >>> bp.search("XU", type="index", exchange="BIST")
     95        ['XU100', 'XU030', 'XU050', ...]
     96
     97    Raises:
     98        ValueError: If query is empty
     99    """
    100    if not query or not query.strip():
    101        raise ValueError("Search query cannot be empty")
    102
    103    from borsapy._providers.tradingview_search import get_search_provider
    104
    105    provider = get_search_provider()
    106
    107    # Search TradingView
    108    results = provider.search(
    109        query=query,
    110        asset_type=type,
    111        exchange=exchange,
    112        limit=limit,
    113    )
    114
    115    # Try to enhance with KAP data for BIST stocks
    116    if not type or type.lower() == "stock":
    117        if not exchange or exchange.upper() == "BIST":
    118            results = _merge_with_kap(results, query)
    119
    120    if full_info:
    121        return results
    122    else:
    123        # Return just symbol list (deduplicated, maintaining order)
    124        seen = set()
    125        symbols = []
    126        for r in results:
    127            sym = r.get("symbol", "")
    128            if sym and sym not in seen:
    129                seen.add(sym)
    130                symbols.append(sym)
    131        return symbols
    132
    133
    134def _merge_with_kap(
    135    tv_results: list[dict[str, Any]], query: str
    136) -> list[dict[str, Any]]:
    137    """Merge TradingView results with KAP company data.
    138
    139    Adds any local KAP matches that TradingView might have missed.
    140
    141    Args:
    142        tv_results: TradingView search results
    143        query: Original search query
    144
    145    Returns:
    146        Merged results with KAP data appended
    147    """
    148    try:
    149        from borsapy.market import search_companies
    150
    151        # Get KAP matches
    152        kap_results = search_companies(query)
    153
    154        if not kap_results.empty:
    155            # Get symbols already in TV results
    156            tv_symbols = {r.get("symbol", "").upper() for r in tv_results}
    157
    158            # Add KAP results not already in TV
    159            for _, row in kap_results.iterrows():
    160                symbol = str(row.get("symbol", "")).upper()
    161                if symbol and symbol not in tv_symbols:
    162                    tv_results.append({
    163                        "symbol": symbol,
    164                        "full_name": f"BIST:{symbol}",
    165                        "description": str(row.get("company", "")),
    166                        "exchange": "BIST",
    167                        "type": "stock",
    168                        "currency": "TRY",
    169                        "country": "TR",
    170                        "source": "kap",
    171                    })
    172
    173    except Exception as e:
    174        logger.debug(f"KAP merge failed: {e}")
    175
    176    return tv_results
    177
    178
    179def search_bist(query: str, limit: int = 50) -> list[str]:
    180    """Search BIST symbols only.
    181
    182    Convenience function for Turkish stock search.
    183
    184    Args:
    185        query: Search query
    186        limit: Maximum results
    187
    188    Returns:
    189        List of BIST symbol strings
    190
    191    Examples:
    192        >>> bp.search_bist("banka")
    193        ['AKBNK', 'GARAN', 'ISCTR', 'YKBNK', 'HALKB']
    194    """
    195    return search(query, type="stock", exchange="BIST", limit=limit)
    196
    197
    198def search_crypto(query: str, limit: int = 50) -> list[str]:
    199    """Search cryptocurrency symbols.
    200
    201    Args:
    202        query: Search query (e.g., "BTC", "ETH")
    203        limit: Maximum results
    204
    205    Returns:
    206        List of crypto symbol strings
    207
    208    Examples:
    209        >>> bp.search_crypto("BTC")
    210        ['BTCUSD', 'BTCTRY', 'BTCUSDT', ...]
    211    """
    212    return search(query, type="crypto", limit=limit)
    213
    214
    215def search_forex(query: str, limit: int = 50) -> list[str]:
    216    """Search forex symbols.
    217
    218    Args:
    219        query: Search query (e.g., "USD", "EUR", "gold")
    220        limit: Maximum results
    221
    222    Returns:
    223        List of forex symbol strings
    224
    225    Examples:
    226        >>> bp.search_forex("gold")
    227        ['XAUUSD', 'XAUTRY', ...]
    228    """
    229    return search(query, type="forex", limit=limit)
    230
    231
    232def search_index(query: str, limit: int = 50) -> list[str]:
    233    """Search market index symbols.
    234
    235    Args:
    236        query: Search query (e.g., "XU", "SP500")
    237        limit: Maximum results
    238
    239    Returns:
    240        List of index symbol strings
    241
    242    Examples:
    243        >>> bp.search_index("XU")
    244        ['XU100', 'XU030', 'XU050', ...]
    245    """
    246    return search(query, type="index", limit=limit)
    247
    248
    249def search_viop(query: str, limit: int = 50) -> list[str]:
    250    """Search VIOP (Turkish derivatives) symbols.
    251
    252    Searches for futures and options contracts on BIST.
    253
    254    Args:
    255        query: Search query (e.g., "XU030", "AKBNK", "gold")
    256        limit: Maximum results
    257
    258    Returns:
    259        List of VIOP contract symbol strings
    260
    261    Examples:
    262        >>> bp.search_viop("XU030")
    263        ['XU030D', 'XU030DG2026', 'XU030DJ2026', ...]
    264
    265        >>> bp.search_viop("gold")
    266        ['XAUTRYD', 'XAUTRYG2026', ...]
    267    """
    268    return search(query, type="futures", exchange="BIST", limit=limit)
    269
    270
    271def viop_contracts(
    272    base_symbol: str,
    273    full_info: bool = False,
    274) -> list[str] | list[dict]:
    275    """Get available VIOP contracts for a base symbol.
    276
    277    Queries TradingView to find all active contracts (expiry months)
    278    for a given futures base symbol.
    279
    280    Args:
    281        base_symbol: Base futures symbol (e.g., "XU030D", "XAUTRYD", "USDTRYD")
    282                    Can be with or without 'D' suffix.
    283        full_info: If True, return full contract info dicts
    284
    285    Returns:
    286        If full_info=False (default):
    287            List of contract symbol strings: ['XU030DG2026', 'XU030DJ2026']
    288
    289        If full_info=True:
    290            List of contract dicts with month/year info
    291
    292    Note:
    293        Contract month codes:
    294        F=Jan, G=Feb, H=Mar, J=Apr, K=May, M=Jun,
    295        N=Jul, Q=Aug, U=Sep, V=Oct, X=Nov, Z=Dec
    296
    297    Examples:
    298        >>> import borsapy as bp
    299
    300        >>> # Get BIST30 futures contracts
    301        >>> bp.viop_contracts("XU030D")
    302        ['XU030DG2026', 'XU030DJ2026']
    303
    304        >>> # Get gold TRY futures
    305        >>> bp.viop_contracts("XAUTRYD")
    306        ['XAUTRYG2026', 'XAUTRYJ2026']
    307
    308        >>> # Get full contract info
    309        >>> bp.viop_contracts("XU030D", full_info=True)
    310        [
    311            {'symbol': 'XU030DG2026', 'month_code': 'G', 'year': '2026', ...},
    312            {'symbol': 'XU030DJ2026', 'month_code': 'J', 'year': '2026', ...},
    313        ]
    314
    315    See Also:
    316        search_viop: Search for VIOP symbols by keyword
    317    """
    318    from borsapy._providers.tradingview_search import get_search_provider
    319
    320    provider = get_search_provider()
    321    contracts = provider.get_viop_contracts(base_symbol)
    322
    323    if full_info:
    324        return contracts
    325    else:
    326        # Filter out continuous contracts (they don't work with streaming)
    327        return [c["symbol"] for c in contracts if not c.get("is_continuous", False)]

logger = <Logger borsapy.search (WARNING)>
def search( query: str, type: str | None = None, exchange: str | None = None, limit: int = 50, full_info: bool = False) -> list[str] | list[dict[str, typing.Any]]: View Source

     26def search(
     27    query: str,
     28    type: str | None = None,
     29    exchange: str | None = None,
     30    limit: int = 50,
     31    full_info: bool = False,
     32) -> list[str] | list[dict[str, Any]]:
     33    """Search for symbols matching the query.
     34
     35    Searches TradingView's symbol database and optionally merges with local
     36    KAP company data for comprehensive BIST coverage.
     37
     38    Args:
     39        query: Search query (e.g., "banka", "enerji", "THY", "gold")
     40        type: Filter by asset type:
     41              - "stock": Stocks/equities
     42              - "forex" or "fx": Forex pairs
     43              - "crypto": Cryptocurrencies
     44              - "index": Market indices
     45              - "futures": Futures contracts
     46              - "fund" or "etf": Funds and ETFs
     47              - "bond": Bonds
     48        exchange: Filter by exchange (e.g., "BIST", "NASDAQ", "NYSE")
     49        limit: Maximum number of results (default 50, max 100)
     50        full_info: If True, return full result dicts; if False, return symbol list
     51
     52    Returns:
     53        If full_info=False (default):
     54            List of symbol strings: ['AKBNK', 'GARAN', ...]
     55
     56        If full_info=True:
     57            List of result dicts:
     58            [
     59                {
     60                    "symbol": "AKBNK",
     61                    "full_name": "BIST:AKBNK",
     62                    "description": "AKBANK T.A.S.",
     63                    "exchange": "BIST",
     64                    "type": "stock",
     65                    "currency": "TRY",
     66                    "country": "TR"
     67                },
     68                ...
     69            ]
     70
     71    Examples:
     72        >>> import borsapy as bp
     73
     74        >>> # Simple search
     75        >>> bp.search("banka")
     76        ['AKBNK', 'GARAN', 'ISCTR', 'YKBNK', 'HALKB', ...]
     77
     78        >>> # Search with type filter
     79        >>> bp.search("gold", type="forex")
     80        ['XAUUSD', 'XAUTRY', ...]
     81
     82        >>> # Search with exchange filter
     83        >>> bp.search("THY", exchange="BIST")
     84        ['THYAO']
     85
     86        >>> # Get full info
     87        >>> bp.search("GARAN", full_info=True)
     88        [{'symbol': 'GARAN', 'description': 'TURKIYE GARANTI BANKASI A.S.', ...}]
     89
     90        >>> # Search crypto
     91        >>> bp.search("BTC", type="crypto")
     92        ['BTCUSD', 'BTCTRY', 'BTCUSDT', ...]
     93
     94        >>> # Search indices
     95        >>> bp.search("XU", type="index", exchange="BIST")
     96        ['XU100', 'XU030', 'XU050', ...]
     97
     98    Raises:
     99        ValueError: If query is empty
    100    """
    101    if not query or not query.strip():
    102        raise ValueError("Search query cannot be empty")
    103
    104    from borsapy._providers.tradingview_search import get_search_provider
    105
    106    provider = get_search_provider()
    107
    108    # Search TradingView
    109    results = provider.search(
    110        query=query,
    111        asset_type=type,
    112        exchange=exchange,
    113        limit=limit,
    114    )
    115
    116    # Try to enhance with KAP data for BIST stocks
    117    if not type or type.lower() == "stock":
    118        if not exchange or exchange.upper() == "BIST":
    119            results = _merge_with_kap(results, query)
    120
    121    if full_info:
    122        return results
    123    else:
    124        # Return just symbol list (deduplicated, maintaining order)
    125        seen = set()
    126        symbols = []
    127        for r in results:
    128            sym = r.get("symbol", "")
    129            if sym and sym not in seen:
    130                seen.add(sym)
    131                symbols.append(sym)
    132        return symbols

Search for symbols matching the query.

Searches TradingView's symbol database and optionally merges with local KAP company data for comprehensive BIST coverage.

Args: query: Search query (e.g., "banka", "enerji", "THY", "gold") type: Filter by asset type: - "stock": Stocks/equities - "forex" or "fx": Forex pairs - "crypto": Cryptocurrencies - "index": Market indices - "futures": Futures contracts - "fund" or "etf": Funds and ETFs - "bond": Bonds exchange: Filter by exchange (e.g., "BIST", "NASDAQ", "NYSE") limit: Maximum number of results (default 50, max 100) full_info: If True, return full result dicts; if False, return symbol list

Returns: If full_info=False (default): List of symbol strings: ['AKBNK', 'GARAN', ...]

    If full_info=True:
        List of result dicts:
        [
            {
                "symbol": "AKBNK",
                "full_name": "BIST:AKBNK",
                "description": "AKBANK T.A.S.",
                "exchange": "BIST",
                "type": "stock",
                "currency": "TRY",
                "country": "TR"
            },
            ...
        ]

Examples:

> > > import borsapy as bp

> > >     >>> # Simple search
> > >     >>> bp.search("banka")
> > >     ['AKBNK', 'GARAN', 'ISCTR', 'YKBNK', 'HALKB', ...]

> > >     >>> # Search with type filter
> > >     >>> bp.search("gold", type="forex")
> > >     ['XAUUSD', 'XAUTRY', ...]

> > >     >>> # Search with exchange filter
> > >     >>> bp.search("THY", exchange="BIST")
> > >     ['THYAO']

> > >     >>> # Get full info
> > >     >>> bp.search("GARAN", full_info=True)
> > >     [{'symbol': 'GARAN', 'description': 'TURKIYE GARANTI BANKASI A.S.', ...}]

> > >     >>> # Search crypto
> > >     >>> bp.search("BTC", type="crypto")
> > >     ['BTCUSD', 'BTCTRY', 'BTCUSDT', ...]

> > >     >>> # Search indices
> > >     >>> bp.search("XU", type="index", exchange="BIST")
> > >     ['XU100', 'XU030', 'XU050', ...]

> > > Raises: ValueError: If query is empty

def search_bist(query: str, limit: int = 50) -> list[str]: View Source

    180def search_bist(query: str, limit: int = 50) -> list[str]:
    181    """Search BIST symbols only.
    182
    183    Convenience function for Turkish stock search.
    184
    185    Args:
    186        query: Search query
    187        limit: Maximum results
    188
    189    Returns:
    190        List of BIST symbol strings
    191
    192    Examples:
    193        >>> bp.search_bist("banka")
    194        ['AKBNK', 'GARAN', 'ISCTR', 'YKBNK', 'HALKB']
    195    """
    196    return search(query, type="stock", exchange="BIST", limit=limit)

Search BIST symbols only.

Convenience function for Turkish stock search.

Args: query: Search query limit: Maximum results

Returns: List of BIST symbol strings

Examples:

> > > bp.search_bist("banka") ['AKBNK', 'GARAN', 'ISCTR', 'YKBNK', 'HALKB']

def search_crypto(query: str, limit: int = 50) -> list[str]: View Source

    199def search_crypto(query: str, limit: int = 50) -> list[str]:
    200    """Search cryptocurrency symbols.
    201
    202    Args:
    203        query: Search query (e.g., "BTC", "ETH")
    204        limit: Maximum results
    205
    206    Returns:
    207        List of crypto symbol strings
    208
    209    Examples:
    210        >>> bp.search_crypto("BTC")
    211        ['BTCUSD', 'BTCTRY', 'BTCUSDT', ...]
    212    """
    213    return search(query, type="crypto", limit=limit)

Search cryptocurrency symbols.

Args: query: Search query (e.g., "BTC", "ETH") limit: Maximum results

Returns: List of crypto symbol strings

Examples:

> > > bp.search_crypto("BTC") ['BTCUSD', 'BTCTRY', 'BTCUSDT', ...]

def search_forex(query: str, limit: int = 50) -> list[str]: View Source

    216def search_forex(query: str, limit: int = 50) -> list[str]:
    217    """Search forex symbols.
    218
    219    Args:
    220        query: Search query (e.g., "USD", "EUR", "gold")
    221        limit: Maximum results
    222
    223    Returns:
    224        List of forex symbol strings
    225
    226    Examples:
    227        >>> bp.search_forex("gold")
    228        ['XAUUSD', 'XAUTRY', ...]
    229    """
    230    return search(query, type="forex", limit=limit)

Search forex symbols.

Args: query: Search query (e.g., "USD", "EUR", "gold") limit: Maximum results

Returns: List of forex symbol strings

Examples:

> > > bp.search_forex("gold") ['XAUUSD', 'XAUTRY', ...]

def search_index(query: str, limit: int = 50) -> list[str]: View Source

    233def search_index(query: str, limit: int = 50) -> list[str]:
    234    """Search market index symbols.
    235
    236    Args:
    237        query: Search query (e.g., "XU", "SP500")
    238        limit: Maximum results
    239
    240    Returns:
    241        List of index symbol strings
    242
    243    Examples:
    244        >>> bp.search_index("XU")
    245        ['XU100', 'XU030', 'XU050', ...]
    246    """
    247    return search(query, type="index", limit=limit)

Search market index symbols.

Args: query: Search query (e.g., "XU", "SP500") limit: Maximum results

Returns: List of index symbol strings

Examples:

> > > bp.search_index("XU") ['XU100', 'XU030', 'XU050', ...]

def search_viop(query: str, limit: int = 50) -> list[str]: View Source

    250def search_viop(query: str, limit: int = 50) -> list[str]:
    251    """Search VIOP (Turkish derivatives) symbols.
    252
    253    Searches for futures and options contracts on BIST.
    254
    255    Args:
    256        query: Search query (e.g., "XU030", "AKBNK", "gold")
    257        limit: Maximum results
    258
    259    Returns:
    260        List of VIOP contract symbol strings
    261
    262    Examples:
    263        >>> bp.search_viop("XU030")
    264        ['XU030D', 'XU030DG2026', 'XU030DJ2026', ...]
    265
    266        >>> bp.search_viop("gold")
    267        ['XAUTRYD', 'XAUTRYG2026', ...]
    268    """
    269    return search(query, type="futures", exchange="BIST", limit=limit)

Search VIOP (Turkish derivatives) symbols.

Searches for futures and options contracts on BIST.

Args: query: Search query (e.g., "XU030", "AKBNK", "gold") limit: Maximum results

Returns: List of VIOP contract symbol strings

Examples:

> > > bp.search_viop("XU030") ['XU030D', 'XU030DG2026', 'XU030DJ2026', ...]

> > >     >>> bp.search_viop("gold")
> > >     ['XAUTRYD', 'XAUTRYG2026', ...]

def viop_contracts(base_symbol: str, full_info: bool = False) -> list[str] | list[dict]: View Source

    272def viop_contracts(
    273    base_symbol: str,
    274    full_info: bool = False,
    275) -> list[str] | list[dict]:
    276    """Get available VIOP contracts for a base symbol.
    277
    278    Queries TradingView to find all active contracts (expiry months)
    279    for a given futures base symbol.
    280
    281    Args:
    282        base_symbol: Base futures symbol (e.g., "XU030D", "XAUTRYD", "USDTRYD")
    283                    Can be with or without 'D' suffix.
    284        full_info: If True, return full contract info dicts
    285
    286    Returns:
    287        If full_info=False (default):
    288            List of contract symbol strings: ['XU030DG2026', 'XU030DJ2026']
    289
    290        If full_info=True:
    291            List of contract dicts with month/year info
    292
    293    Note:
    294        Contract month codes:
    295        F=Jan, G=Feb, H=Mar, J=Apr, K=May, M=Jun,
    296        N=Jul, Q=Aug, U=Sep, V=Oct, X=Nov, Z=Dec
    297
    298    Examples:
    299        >>> import borsapy as bp
    300
    301        >>> # Get BIST30 futures contracts
    302        >>> bp.viop_contracts("XU030D")
    303        ['XU030DG2026', 'XU030DJ2026']
    304
    305        >>> # Get gold TRY futures
    306        >>> bp.viop_contracts("XAUTRYD")
    307        ['XAUTRYG2026', 'XAUTRYJ2026']
    308
    309        >>> # Get full contract info
    310        >>> bp.viop_contracts("XU030D", full_info=True)
    311        [
    312            {'symbol': 'XU030DG2026', 'month_code': 'G', 'year': '2026', ...},
    313            {'symbol': 'XU030DJ2026', 'month_code': 'J', 'year': '2026', ...},
    314        ]
    315
    316    See Also:
    317        search_viop: Search for VIOP symbols by keyword
    318    """
    319    from borsapy._providers.tradingview_search import get_search_provider
    320
    321    provider = get_search_provider()
    322    contracts = provider.get_viop_contracts(base_symbol)
    323
    324    if full_info:
    325        return contracts
    326    else:
    327        # Filter out continuous contracts (they don't work with streaming)
    328        return [c["symbol"] for c in contracts if not c.get("is_continuous", False)]

Get available VIOP contracts for a base symbol.

Queries TradingView to find all active contracts (expiry months) for a given futures base symbol.

Args: base_symbol: Base futures symbol (e.g., "XU030D", "XAUTRYD", "USDTRYD") Can be with or without 'D' suffix. full_info: If True, return full contract info dicts

Returns: If full_info=False (default): List of contract symbol strings: ['XU030DG2026', 'XU030DJ2026']

    If full_info=True:
        List of contract dicts with month/year info

Note: Contract month codes: F=Jan, G=Feb, H=Mar, J=Apr, K=May, M=Jun, N=Jul, Q=Aug, U=Sep, V=Oct, X=Nov, Z=Dec

Examples:

> > > import borsapy as bp

> > >     >>> # Get BIST30 futures contracts
> > >     >>> bp.viop_contracts("XU030D")
> > >     ['XU030DG2026', 'XU030DJ2026']

> > >     >>> # Get gold TRY futures
> > >     >>> bp.viop_contracts("XAUTRYD")
> > >     ['XAUTRYG2026', 'XAUTRYJ2026']

> > >     >>> # Get full contract info
> > >     >>> bp.viop_contracts("XU030D", full_info=True)
> > >     [
> > >         {'symbol': 'XU030DG2026', 'month_code': 'G', 'year': '2026', ...},
> > >         {'symbol': 'XU030DJ2026', 'month_code': 'J', 'year': '2026', ...},
> > >     ]

> > > See Also: search_viop: Search for VIOP symbols by keyword