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']
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)]
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
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']
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', ...]
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', ...]
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', ...]
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', ...]
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