Skip to main content
Glama
knishioka

IB Analytics MCP Server

by knishioka
base.py3.89 kB
"""Base analyzer class""" from abc import ABC, abstractmethod from decimal import Decimal from typing import Any from ib_sec_mcp.models.account import Account from ib_sec_mcp.models.portfolio import Portfolio from ib_sec_mcp.models.position import Position from ib_sec_mcp.models.trade import Trade class AnalysisResult(dict[str, Any]): """ Analysis result container Flexible dictionary-based result with metadata """ def __init__(self, analyzer_name: str, **kwargs: Any) -> None: super().__init__(**kwargs) self["analyzer"] = analyzer_name self["timestamp"] = None # Set during analysis class BaseAnalyzer(ABC): """ Base class for all analyzers Provides common interface and utilities for analysis modules """ def __init__( self, portfolio: Portfolio | None = None, account: Account | None = None, ): """ Initialize analyzer Args: portfolio: Portfolio to analyze (for multi-account) account: Single account to analyze Raises: ValueError: If neither portfolio nor account is provided """ if portfolio is None and account is None: raise ValueError("Either portfolio or account must be provided") self.portfolio = portfolio self.account = account self.is_multi_account = portfolio is not None @property def analyzer_name(self) -> str: """Get analyzer name (class name without 'Analyzer' suffix)""" return self.__class__.__name__.replace("Analyzer", "") @abstractmethod def analyze(self) -> AnalysisResult: """ Run analysis Returns: AnalysisResult with findings """ pass def _create_result(self, **kwargs: Any) -> AnalysisResult: """ Create analysis result with metadata Args: **kwargs: Result data Returns: AnalysisResult instance """ from datetime import datetime result = AnalysisResult(self.analyzer_name, **kwargs) result["timestamp"] = datetime.now().isoformat() result["is_multi_account"] = self.is_multi_account if self.is_multi_account and self.portfolio: result["account_count"] = self.portfolio.account_count result["from_date"] = self.portfolio.from_date.isoformat() result["to_date"] = self.portfolio.to_date.isoformat() elif self.account: result["account_id"] = self.account.account_id result["from_date"] = self.account.from_date.isoformat() result["to_date"] = self.account.to_date.isoformat() return result def get_trades(self) -> list[Trade]: """Get trades from portfolio or account""" if self.is_multi_account and self.portfolio: return self.portfolio.all_trades elif self.account: return self.account.trades return [] def get_positions(self) -> list[Position]: """Get positions from portfolio or account""" if self.is_multi_account and self.portfolio: return self.portfolio.all_positions elif self.account: return self.account.positions return [] def get_total_value(self) -> Decimal: """Get total value from portfolio or account""" if self.is_multi_account and self.portfolio: return self.portfolio.total_value elif self.account: return self.account.total_value return Decimal("0") def get_total_cash(self) -> Decimal: """Get total cash from portfolio or account""" if self.is_multi_account and self.portfolio: return self.portfolio.total_cash elif self.account: return self.account.total_cash return Decimal("0")

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