Skip to main content
Glama
knishioka

IB Analytics MCP Server

by knishioka
trade.py3.45 kB
"""Trade data model""" from datetime import date, datetime from decimal import Decimal from enum import Enum from pydantic import BaseModel, Field, field_validator class BuySell(str, Enum): """Buy/Sell indicator""" BUY = "BUY" SELL = "SELL" class AssetClass(str, Enum): """Asset class types""" STOCK = "STK" BOND = "BOND" OPTION = "OPT" FUTURE = "FUT" FOREX = "CASH" FUND = "FUND" OTHER = "OTHER" class Trade(BaseModel): """Trade record""" account_id: str = Field(..., description="Account ID") trade_id: str = Field(..., description="Unique trade ID") trade_date: date = Field(..., description="Trade execution date") settle_date: date | None = Field(None, description="Settlement date") symbol: str = Field(..., description="Trading symbol") description: str | None = Field(None, description="Security description") asset_class: AssetClass = Field(..., description="Asset class") cusip: str | None = Field(None, description="CUSIP") isin: str | None = Field(None, description="ISIN") buy_sell: BuySell = Field(..., description="Buy or Sell") quantity: Decimal = Field(..., description="Trade quantity") trade_price: Decimal = Field(..., description="Execution price") trade_money: Decimal = Field(..., description="Trade proceeds (negative for buys)") currency: str = Field("USD", description="Currency") fx_rate_to_base: Decimal = Field(Decimal("1.0"), description="FX rate to base currency") ib_commission: Decimal = Field(Decimal("0"), description="IB commission") ib_commission_currency: str = Field("USD", description="Commission currency") fifo_pnl_realized: Decimal = Field(Decimal("0"), description="Realized P&L (FIFO)") mtm_pnl: Decimal = Field(Decimal("0"), description="Mark-to-market P&L") order_id: str | None = Field(None, description="Order ID") execution_id: str | None = Field(None, description="Execution ID") order_time: datetime | None = Field(None, description="Order time") notes: str | None = Field(None, description="Additional notes") @field_validator("quantity", "trade_price", mode="before") @classmethod def convert_to_decimal(cls, v: int | float | str | Decimal) -> Decimal: """Convert numeric fields to Decimal""" if isinstance(v, (int, float, str)): return Decimal(str(v)) return v @property def gross_amount(self) -> Decimal: """Gross trade amount (before commissions)""" return abs(self.trade_money) @property def net_amount(self) -> Decimal: """Net trade amount (after commissions)""" return abs(self.trade_money) - abs(self.ib_commission) @property def is_buy(self) -> bool: """Check if trade is a buy""" return self.buy_sell == BuySell.BUY @property def is_sell(self) -> bool: """Check if trade is a sell""" return self.buy_sell == BuySell.SELL @property def commission_rate(self) -> Decimal: """Commission as percentage of trade value""" if self.gross_amount == 0: return Decimal("0") return abs(self.ib_commission) / self.gross_amount * 100 class Config: """Pydantic config""" json_encoders = { date: lambda v: v.isoformat(), datetime: lambda v: v.isoformat(), Decimal: lambda v: str(v), }

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