Skip to main content
Glama
knishioka

IB Analytics MCP Server

by knishioka
validators.py4.57 kB
"""Data validators and helper functions""" import re from datetime import date, datetime def validate_date( value: str | date | datetime, fmt: str = "%Y-%m-%d", ) -> date: """ Validate and parse date Args: value: Date string, date, or datetime object fmt: Expected date format for string parsing Returns: date object Raises: ValueError: If date is invalid """ if isinstance(value, date): return value if isinstance(value, datetime): return value.date() if isinstance(value, str): try: return datetime.strptime(value, fmt).date() except ValueError as e: raise ValueError(f"Invalid date format: {value} (expected {fmt})") from e raise ValueError(f"Invalid date type: {type(value)}") def validate_cusip(cusip: str) -> bool: """ Validate CUSIP format (9 characters: 8 alphanumeric + 1 check digit) Args: cusip: CUSIP string Returns: True if valid, False otherwise """ if not cusip or len(cusip) != 9: return False # First 8 characters: alphanumeric if not cusip[:8].isalnum(): return False # Last character: digit if not cusip[8].isdigit(): return False # Calculate check digit total = 0 for i, char in enumerate(cusip[:8]): value = int(char) if char.isdigit() else ord(char.upper()) - ord("A") + 10 if i % 2 == 1: # Double odd positions value *= 2 total += value // 10 + value % 10 check_digit = (10 - (total % 10)) % 10 return int(cusip[8]) == check_digit def validate_isin(isin: str) -> bool: """ Validate ISIN format (12 characters: 2 country code + 9 identifier + 1 check digit) Args: isin: ISIN string Returns: True if valid, False otherwise """ if not isin or len(isin) != 12: return False # First 2 characters: country code (letters) if not isin[:2].isalpha(): return False # Characters 3-11: alphanumeric if not isin[2:11].isalnum(): return False # Last character: digit if not isin[11].isdigit(): return False # Luhn algorithm for check digit digits = [] for char in isin[:11]: if char.isdigit(): digits.append(char) else: # A=10, B=11, ..., Z=35 value = str(ord(char.upper()) - ord("A") + 10) digits.extend(value) # Double every second digit from right total = 0 reversed_digits = "".join(digits)[::-1] for i, digit in enumerate(reversed_digits): digit_value: int = int(digit) if i % 2 == 1: digit_value *= 2 if digit_value > 9: digit_value = digit_value // 10 + digit_value % 10 total += digit_value check_digit = (10 - (total % 10)) % 10 return int(isin[11]) == check_digit def validate_account_id(account_id: str) -> bool: """ Validate IB account ID format (typically U followed by 7-8 digits) Args: account_id: Account ID string Returns: True if valid, False otherwise """ if not account_id: return False # Pattern: U followed by 7-8 digits pattern = r"^U\d{7,8}$" return bool(re.match(pattern, account_id)) def parse_decimal_safe(value: str | int | float, default: float = 0.0) -> float: """ Safely parse decimal value Args: value: Value to parse default: Default value if parsing fails Returns: Parsed float value or default """ if value is None or value == "": return default try: if isinstance(value, str): # Remove commas and whitespace cleaned = value.replace(",", "").strip() return float(cleaned) return float(value) except (ValueError, TypeError): return default def validate_symbol(symbol: str) -> bool: """ Validate trading symbol format Supports: - US stocks: AAPL, TSLA, VOO - Cryptocurrencies: BTC-USD, ETH-USD - Forex pairs: USDJPY=X, EURUSD=X - ETFs and other securities Args: symbol: Symbol string Returns: True if valid, False otherwise """ if not symbol or not symbol.strip(): return False # Extended validation: 1-12 characters, allow dots, hyphens, equals # Supports forex (=X suffix) and crypto (-USD suffix) pattern = r"^[A-Z0-9.\-=]{1,12}$" return bool(re.match(pattern, symbol.upper()))

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/knishioka/ib-sec-mcp'

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