//! Extended FLEX statement types for v0.2.0+
//!
//! This module contains additional types beyond the core v0.1.0 types.
//! These include account information, NAV changes, performance summaries,
//! fee details, and more comprehensive trading data.

use chrono::NaiveDate;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};

use super::common::{
    AssetCategory, BuySell, DeliveredReceived, OpenClose, OptionAction, OrderType, PutCall,
    TradeType, TransferType,
};
use crate::parsers::xml_utils::{
    deserialize_optional_bool, deserialize_optional_date, deserialize_optional_decimal,
    deserialize_optional_string,
};

/// Account information and metadata
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct AccountInformation {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account type
    #[serde(rename = "@accountType", default)]
    pub account_type: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// Account name
    #[serde(rename = "@name", default)]
    pub name: Option<String>,

    /// Master account
    #[serde(rename = "@masterName", default)]
    pub master_name: Option<String>,

    /// Customer type
    #[serde(rename = "@customerType", default)]
    pub customer_type: Option<String>,

    /// Date account opened
    #[serde(
        rename = "@dateOpened",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date_opened: Option<NaiveDate>,

    /// Date account funded
    #[serde(
        rename = "@dateFunded",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date_funded: Option<NaiveDate>,

    /// Date closed
    #[serde(
        rename = "@dateClosed",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date_closed: Option<NaiveDate>,

    /// Primary email
    #[serde(rename = "@primaryEmail", default)]
    pub primary_email: Option<String>,

    /// Street address
    #[serde(rename = "@streetAddress", default)]
    pub street_address: Option<String>,

    /// Street address 2
    #[serde(rename = "@streetAddress2", default)]
    pub street_address2: Option<String>,

    /// City
    #[serde(rename = "@city", default)]
    pub city: Option<String>,

    /// State
    #[serde(rename = "@state", default)]
    pub state: Option<String>,

    /// Country
    #[serde(rename = "@country", default)]
    pub country: Option<String>,

    /// Postal code
    #[serde(rename = "@postalCode", default)]
    pub postal_code: Option<String>,

    /// Account capabilities
    #[serde(rename = "@accountCapabilities", default)]
    pub account_capabilities: Option<String>,

    /// Trading permissions
    #[serde(rename = "@tradingPermissions", default)]
    pub trading_permissions: Option<String>,

    /// Registered representative name
    #[serde(rename = "@registeredRepName", default)]
    pub registered_rep_name: Option<String>,

    /// Registered representative phone
    #[serde(rename = "@registeredRepPhone", default)]
    pub registered_rep_phone: Option<String>,

    /// IB entity
    #[serde(rename = "@ibEntity", default)]
    pub ib_entity: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// `street` (added for full ibflex coverage)
    #[serde(
        rename = "@street",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub street: Option<String>,

    /// `street2` (added for full ibflex coverage)
    #[serde(
        rename = "@street2",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub street2: Option<String>,

    /// `streetResidentialAddress` (added for full ibflex coverage)
    #[serde(
        rename = "@streetResidentialAddress",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub street_residential_address: Option<String>,

    /// `street2ResidentialAddress` (added for full ibflex coverage)
    #[serde(
        rename = "@street2ResidentialAddress",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub street2_residential_address: Option<String>,

    /// `cityResidentialAddress` (added for full ibflex coverage)
    #[serde(
        rename = "@cityResidentialAddress",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub city_residential_address: Option<String>,

    /// `stateResidentialAddress` (added for full ibflex coverage)
    #[serde(
        rename = "@stateResidentialAddress",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub state_residential_address: Option<String>,

    /// `countryResidentialAddress` (added for full ibflex coverage)
    #[serde(
        rename = "@countryResidentialAddress",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub country_residential_address: Option<String>,

    /// `postalCodeResidentialAddress` (added for full ibflex coverage)
    #[serde(
        rename = "@postalCodeResidentialAddress",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub postal_code_residential_address: Option<String>,

    /// `accountRepName` (added for full ibflex coverage)
    #[serde(
        rename = "@accountRepName",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_rep_name: Option<String>,

    /// `accountRepPhone` (added for full ibflex coverage)
    #[serde(
        rename = "@accountRepPhone",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_rep_phone: Option<String>,

    /// `lastTradedDate` (added for full ibflex coverage)
    #[serde(
        rename = "@lastTradedDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub last_traded_date: Option<NaiveDate>,
}

/// Change in portfolio NAV (Net Asset Value)
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct ChangeInNAV {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// From date
    #[serde(
        rename = "@fromDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub from_date: Option<NaiveDate>,

    /// To date
    #[serde(
        rename = "@toDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub to_date: Option<NaiveDate>,

    /// Starting NAV value
    #[serde(
        rename = "@startingValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub starting_value: Option<Decimal>,

    /// Ending NAV value
    #[serde(
        rename = "@endingValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_value: Option<Decimal>,

    /// Mark-to-market P&L
    #[serde(
        rename = "@mtm",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm: Option<Decimal>,

    /// Realized P&L
    #[serde(
        rename = "@realized",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized: Option<Decimal>,

    /// Change in unrealized P&L
    #[serde(
        rename = "@changeInUnrealized",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_unrealized: Option<Decimal>,

    /// Deposits and withdrawals
    #[serde(
        rename = "@depositsWithdrawals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposits_withdrawals: Option<Decimal>,

    /// Dividends received
    #[serde(
        rename = "@dividends",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividends: Option<Decimal>,

    /// Withholding tax
    #[serde(
        rename = "@withholdingTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_tax: Option<Decimal>,

    /// Change in dividend accruals
    #[serde(
        rename = "@changeInDividendAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_dividend_accruals: Option<Decimal>,

    /// Interest income
    #[serde(
        rename = "@interest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub interest: Option<Decimal>,

    /// Change in interest accruals
    #[serde(
        rename = "@changeInInterestAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_interest_accruals: Option<Decimal>,

    /// Advisor fees
    #[serde(
        rename = "@advisorFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub advisor_fees: Option<Decimal>,

    /// Client fees
    #[serde(
        rename = "@clientFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub client_fees: Option<Decimal>,

    /// Other fees
    #[serde(
        rename = "@otherFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_fees: Option<Decimal>,

    /// Commissions
    #[serde(
        rename = "@commissions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions: Option<Decimal>,

    /// FX translation P&L
    #[serde(
        rename = "@fxTranslation",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation: Option<Decimal>,

    /// Time-weighted return
    #[serde(
        rename = "@twr",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub twr: Option<Decimal>,

    /// Corporate action proceeds
    #[serde(
        rename = "@corporateActionProceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub corporate_action_proceeds: Option<Decimal>,

    /// `costAdjustments` (added for full ibflex coverage)
    #[serde(
        rename = "@costAdjustments",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost_adjustments: Option<Decimal>,

    /// `transferredPnlAdjustments` (added for full ibflex coverage)
    #[serde(
        rename = "@transferredPnlAdjustments",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transferred_pnl_adjustments: Option<Decimal>,

    /// `internalCashTransfers` (added for full ibflex coverage)
    #[serde(
        rename = "@internalCashTransfers",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub internal_cash_transfers: Option<Decimal>,

    /// `assetTransfers` (added for full ibflex coverage)
    #[serde(
        rename = "@assetTransfers",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub asset_transfers: Option<Decimal>,

    /// `debitCardActivity` (added for full ibflex coverage)
    #[serde(
        rename = "@debitCardActivity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub debit_card_activity: Option<Decimal>,

    /// `billPay` (added for full ibflex coverage)
    #[serde(
        rename = "@billPay",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bill_pay: Option<Decimal>,

    /// `withholding871m` (added for full ibflex coverage)
    #[serde(
        rename = "@withholding871m",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding871m: Option<Decimal>,

    /// `withholdingTaxCollected` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingTaxCollected",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_tax_collected: Option<Decimal>,

    /// `brokerFees` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees: Option<Decimal>,

    /// `changeInBrokerFeeAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInBrokerFeeAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_broker_fee_accruals: Option<Decimal>,

    /// `feesReceivables` (added for full ibflex coverage)
    #[serde(
        rename = "@feesReceivables",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fees_receivables: Option<Decimal>,

    /// `commissionReceivables` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionReceivables",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission_receivables: Option<Decimal>,

    /// `forexCommissions` (added for full ibflex coverage)
    #[serde(
        rename = "@forexCommissions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub forex_commissions: Option<Decimal>,

    /// `transactionTax` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transaction_tax: Option<Decimal>,

    /// `taxReceivables` (added for full ibflex coverage)
    #[serde(
        rename = "@taxReceivables",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_receivables: Option<Decimal>,

    /// `salesTax` (added for full ibflex coverage)
    #[serde(
        rename = "@salesTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub sales_tax: Option<Decimal>,

    /// `softDollars` (added for full ibflex coverage)
    #[serde(
        rename = "@softDollars",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub soft_dollars: Option<Decimal>,

    /// `netFxTrading` (added for full ibflex coverage)
    #[serde(
        rename = "@netFxTrading",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_fx_trading: Option<Decimal>,

    /// `linkingAdjustments` (added for full ibflex coverage)
    #[serde(
        rename = "@linkingAdjustments",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub linking_adjustments: Option<Decimal>,

    /// `other` (added for full ibflex coverage)
    #[serde(
        rename = "@other",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other: Option<Decimal>,

    /// `commissionCreditsRedemption` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCreditsRedemption",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission_credits_redemption: Option<Decimal>,

    /// `grantActivity` (added for full ibflex coverage)
    #[serde(
        rename = "@grantActivity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub grant_activity: Option<Decimal>,

    /// `excessFundSweep` (added for full ibflex coverage)
    #[serde(
        rename = "@excessFundSweep",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub excess_fund_sweep: Option<Decimal>,

    /// `billableSalesTax` (added for full ibflex coverage)
    #[serde(
        rename = "@billableSalesTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_sales_tax: Option<Decimal>,

    /// `mtmAtPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmAtPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_at_paxos: Option<Decimal>,

    /// `carbonCredits` (added for full ibflex coverage)
    #[serde(
        rename = "@carbonCredits",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub carbon_credits: Option<Decimal>,

    /// `donations` (added for full ibflex coverage)
    #[serde(
        rename = "@donations",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub donations: Option<Decimal>,

    /// `paxosTransfers` (added for full ibflex coverage)
    #[serde(
        rename = "@paxosTransfers",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub paxos_transfers: Option<Decimal>,

    /// `commissionsAtPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionsAtPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions_at_paxos: Option<Decimal>,

    /// `referralFee` (added for full ibflex coverage)
    #[serde(
        rename = "@referralFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub referral_fee: Option<Decimal>,

    /// `changeInIncentiveCouponAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInIncentiveCouponAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_incentive_coupon_accruals: Option<Decimal>,

    /// `otherIncome` (added for full ibflex coverage)
    #[serde(
        rename = "@otherIncome",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_income: Option<Decimal>,
}

/// Equity summary by report date in base currency
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct EquitySummaryByReportDateInBase {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Report date
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// Cash
    #[serde(
        rename = "@cash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash: Option<Decimal>,

    /// Cash long
    #[serde(
        rename = "@cashLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_long: Option<Decimal>,

    /// Cash short
    #[serde(
        rename = "@cashShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_short: Option<Decimal>,

    /// Settled cash
    #[serde(
        rename = "@settledCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub settled_cash: Option<Decimal>,

    /// Slb cash collateral
    #[serde(
        rename = "@slbCashCollateral",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_cash_collateral: Option<Decimal>,

    /// Stock value
    #[serde(
        rename = "@stock",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub stock: Option<Decimal>,

    /// Stock long
    #[serde(
        rename = "@stockLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub stock_long: Option<Decimal>,

    /// Stock short
    #[serde(
        rename = "@stockShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub stock_short: Option<Decimal>,

    /// Slb direct securities borrowed
    #[serde(
        rename = "@slbDirectSecuritiesBorrowed",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_direct_securities_borrowed: Option<Decimal>,

    /// Slb direct securities lent
    #[serde(
        rename = "@slbDirectSecuritiesLent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_direct_securities_lent: Option<Decimal>,

    /// Options value
    #[serde(
        rename = "@options",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub options: Option<Decimal>,

    /// Options long
    #[serde(
        rename = "@optionsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub options_long: Option<Decimal>,

    /// Options short
    #[serde(
        rename = "@optionsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub options_short: Option<Decimal>,

    /// Bonds value
    #[serde(
        rename = "@bonds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bonds: Option<Decimal>,

    /// Bonds long
    #[serde(
        rename = "@bondsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bonds_long: Option<Decimal>,

    /// Bonds short
    #[serde(
        rename = "@bondsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bonds_short: Option<Decimal>,

    /// Notes value
    #[serde(
        rename = "@notes",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub notes: Option<Decimal>,

    /// Funds value
    #[serde(
        rename = "@funds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub funds: Option<Decimal>,

    /// Futures value (unrealized P&L)
    #[serde(
        rename = "@futures",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub futures: Option<Decimal>,

    /// Futures long
    #[serde(
        rename = "@futuresLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub futures_long: Option<Decimal>,

    /// Futures short
    #[serde(
        rename = "@futuresShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub futures_short: Option<Decimal>,

    /// Commodities value
    #[serde(
        rename = "@commodities",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commodities: Option<Decimal>,

    /// Total
    #[serde(
        rename = "@total",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total: Option<Decimal>,

    /// Total long
    #[serde(
        rename = "@totalLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_long: Option<Decimal>,

    /// Total short
    #[serde(
        rename = "@totalShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_short: Option<Decimal>,

    /// Interest accruals
    #[serde(
        rename = "@interestAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub interest_accruals: Option<Decimal>,

    /// Dividend accruals
    #[serde(
        rename = "@dividendAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividend_accruals: Option<Decimal>,

    /// Accrued interest
    #[serde(
        rename = "@accruedInterest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub accrued_interest: Option<Decimal>,

    /// Accrued dividend
    #[serde(
        rename = "@accruedDividend",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub accrued_dividend: Option<Decimal>,

    /// Soft dollar value
    #[serde(
        rename = "@softDollars",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub soft_dollars: Option<Decimal>,

    /// Forex CFD unrealized P&L
    #[serde(
        rename = "@forexCfdUnrealizedPl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub forex_cfd_unrealized_pl: Option<Decimal>,

    /// CFD unrealized P&L
    #[serde(
        rename = "@cfdUnrealizedPl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_unrealized_pl: Option<Decimal>,

    /// Broker cash component
    #[serde(
        rename = "@brokerCashComponent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_cash_component: Option<Decimal>,

    /// Broker interest accruals component
    #[serde(
        rename = "@brokerInterestAccrualsComponent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest_accruals_component: Option<Decimal>,

    /// Gross position value
    #[serde(
        rename = "@grossPositionValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub gross_position_value: Option<Decimal>,

    /// Net liquidation value
    #[serde(
        rename = "@netLiquidation",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_liquidation: Option<Decimal>,

    /// Net liquidation uncertainty
    #[serde(
        rename = "@netLiquidationUncertainty",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_liquidation_uncertainty: Option<Decimal>,

    /// `currency` (added for full ibflex coverage)
    #[serde(
        rename = "@currency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub currency: Option<String>,

    /// `slbCashCollateralLong` (added for full ibflex coverage)
    #[serde(
        rename = "@slbCashCollateralLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_cash_collateral_long: Option<Decimal>,

    /// `slbCashCollateralShort` (added for full ibflex coverage)
    #[serde(
        rename = "@slbCashCollateralShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_cash_collateral_short: Option<Decimal>,

    /// `slbDirectSecuritiesBorrowedLong` (added for full ibflex coverage)
    #[serde(
        rename = "@slbDirectSecuritiesBorrowedLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_direct_securities_borrowed_long: Option<Decimal>,

    /// `slbDirectSecuritiesBorrowedShort` (added for full ibflex coverage)
    #[serde(
        rename = "@slbDirectSecuritiesBorrowedShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_direct_securities_borrowed_short: Option<Decimal>,

    /// `slbDirectSecuritiesLentLong` (added for full ibflex coverage)
    #[serde(
        rename = "@slbDirectSecuritiesLentLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_direct_securities_lent_long: Option<Decimal>,

    /// `slbDirectSecuritiesLentShort` (added for full ibflex coverage)
    #[serde(
        rename = "@slbDirectSecuritiesLentShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_direct_securities_lent_short: Option<Decimal>,

    /// `bondInterestAccrualsComponent` (added for full ibflex coverage)
    #[serde(
        rename = "@bondInterestAccrualsComponent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest_accruals_component: Option<Decimal>,

    /// `bondInterestAccrualsComponentLong` (added for full ibflex coverage)
    #[serde(
        rename = "@bondInterestAccrualsComponentLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest_accruals_component_long: Option<Decimal>,

    /// `bondInterestAccrualsComponentShort` (added for full ibflex coverage)
    #[serde(
        rename = "@bondInterestAccrualsComponentShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest_accruals_component_short: Option<Decimal>,

    /// `notesLong` (added for full ibflex coverage)
    #[serde(
        rename = "@notesLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub notes_long: Option<Decimal>,

    /// `notesShort` (added for full ibflex coverage)
    #[serde(
        rename = "@notesShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub notes_short: Option<Decimal>,

    /// `incentiveCouponAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@incentiveCouponAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub incentive_coupon_accruals: Option<Decimal>,

    /// `interestAccrualsLong` (added for full ibflex coverage)
    #[serde(
        rename = "@interestAccrualsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub interest_accruals_long: Option<Decimal>,

    /// `interestAccrualsShort` (added for full ibflex coverage)
    #[serde(
        rename = "@interestAccrualsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub interest_accruals_short: Option<Decimal>,

    /// `softDollarsLong` (added for full ibflex coverage)
    #[serde(
        rename = "@softDollarsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub soft_dollars_long: Option<Decimal>,

    /// `softDollarsShort` (added for full ibflex coverage)
    #[serde(
        rename = "@softDollarsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub soft_dollars_short: Option<Decimal>,

    /// `dividendAccrualsLong` (added for full ibflex coverage)
    #[serde(
        rename = "@dividendAccrualsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividend_accruals_long: Option<Decimal>,

    /// `dividendAccrualsShort` (added for full ibflex coverage)
    #[serde(
        rename = "@dividendAccrualsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividend_accruals_short: Option<Decimal>,

    /// `commoditiesLong` (added for full ibflex coverage)
    #[serde(
        rename = "@commoditiesLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commodities_long: Option<Decimal>,

    /// `commoditiesShort` (added for full ibflex coverage)
    #[serde(
        rename = "@commoditiesShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commodities_short: Option<Decimal>,

    /// `fundsLong` (added for full ibflex coverage)
    #[serde(
        rename = "@fundsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub funds_long: Option<Decimal>,

    /// `fundsShort` (added for full ibflex coverage)
    #[serde(
        rename = "@fundsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub funds_short: Option<Decimal>,

    /// `forexCfdUnrealizedPlLong` (added for full ibflex coverage)
    #[serde(
        rename = "@forexCfdUnrealizedPlLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub forex_cfd_unrealized_pl_long: Option<Decimal>,

    /// `forexCfdUnrealizedPlShort` (added for full ibflex coverage)
    #[serde(
        rename = "@forexCfdUnrealizedPlShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub forex_cfd_unrealized_pl_short: Option<Decimal>,

    /// `brokerFeesAccrualsComponent` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesAccrualsComponent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_accruals_component: Option<Decimal>,

    /// `brokerFeesAccrualsComponentLong` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesAccrualsComponentLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_accruals_component_long: Option<Decimal>,

    /// `brokerFeesAccrualsComponentShort` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesAccrualsComponentShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_accruals_component_short: Option<Decimal>,

    /// `eventContractInterestAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@eventContractInterestAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub event_contract_interest_accruals: Option<Decimal>,

    /// `marginFinancingChargeAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@marginFinancingChargeAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub margin_financing_charge_accruals: Option<Decimal>,

    /// `insuredBankDepositRedemptionCashComponent` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredBankDepositRedemptionCashComponent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_bank_deposit_redemption_cash_component: Option<Decimal>,

    /// `fdicInsuredBankSweepAccount` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredBankSweepAccount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_bank_sweep_account: Option<Decimal>,

    /// `fdicInsuredBankSweepAccountLong` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredBankSweepAccountLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_bank_sweep_account_long: Option<Decimal>,

    /// `fdicInsuredBankSweepAccountShort` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredBankSweepAccountShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_bank_sweep_account_short: Option<Decimal>,

    /// `fdicInsuredBankSweepAccountCashComponent` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredBankSweepAccountCashComponent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_bank_sweep_account_cash_component: Option<Decimal>,

    /// `fdicInsuredBankSweepAccountCashComponentLong` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredBankSweepAccountCashComponentLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_bank_sweep_account_cash_component_long: Option<Decimal>,

    /// `fdicInsuredBankSweepAccountCashComponentShort` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredBankSweepAccountCashComponentShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_bank_sweep_account_cash_component_short: Option<Decimal>,

    /// `fdicInsuredAccountInterestAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredAccountInterestAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_account_interest_accruals: Option<Decimal>,

    /// `fdicInsuredAccountInterestAccrualsLong` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredAccountInterestAccrualsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_account_interest_accruals_long: Option<Decimal>,

    /// `fdicInsuredAccountInterestAccrualsShort` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredAccountInterestAccrualsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_account_interest_accruals_short: Option<Decimal>,

    /// `fdicInsuredAccountInterestAccrualsComponent` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredAccountInterestAccrualsComponent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_account_interest_accruals_component: Option<Decimal>,

    /// `fdicInsuredAccountInterestAccrualsComponentLong` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredAccountInterestAccrualsComponentLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_account_interest_accruals_component_long: Option<Decimal>,

    /// `fdicInsuredAccountInterestAccrualsComponentShort` (added for full ibflex coverage)
    #[serde(
        rename = "@fdicInsuredAccountInterestAccrualsComponentShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fdic_insured_account_interest_accruals_component_short: Option<Decimal>,

    /// `brokerCashComponentLong` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerCashComponentLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_cash_component_long: Option<Decimal>,

    /// `brokerCashComponentShort` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerCashComponentShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_cash_component_short: Option<Decimal>,

    /// `brokerInterestAccrualsComponentLong` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerInterestAccrualsComponentLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest_accruals_component_long: Option<Decimal>,

    /// `brokerInterestAccrualsComponentShort` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerInterestAccrualsComponentShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest_accruals_component_short: Option<Decimal>,

    /// `cfdUnrealizedPlLong` (added for full ibflex coverage)
    #[serde(
        rename = "@cfdUnrealizedPlLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_unrealized_pl_long: Option<Decimal>,

    /// `cfdUnrealizedPlShort` (added for full ibflex coverage)
    #[serde(
        rename = "@cfdUnrealizedPlShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_unrealized_pl_short: Option<Decimal>,

    /// `ipoSubscription` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscription",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription: Option<Decimal>,

    /// `ipoSubscriptionLong` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscriptionLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription_long: Option<Decimal>,

    /// `ipoSubscriptionShort` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscriptionShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription_short: Option<Decimal>,

    /// `crypto` (added for full ibflex coverage)
    #[serde(
        rename = "@crypto",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub crypto: Option<Decimal>,

    /// `physDel` (added for full ibflex coverage)
    #[serde(
        rename = "@physDel",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub phys_del: Option<Decimal>,

    /// `physDelLong` (added for full ibflex coverage)
    #[serde(
        rename = "@physDelLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub phys_del_long: Option<Decimal>,

    /// `physDelShort` (added for full ibflex coverage)
    #[serde(
        rename = "@physDelShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub phys_del_short: Option<Decimal>,

    /// `insuredBankDepositRedemptionCashComponentLong` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredBankDepositRedemptionCashComponentLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_bank_deposit_redemption_cash_component_long: Option<Decimal>,

    /// `insuredBankDepositRedemptionCashComponentShort` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredBankDepositRedemptionCashComponentShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_bank_deposit_redemption_cash_component_short: Option<Decimal>,

    /// `incentiveCouponAccrualsLong` (added for full ibflex coverage)
    #[serde(
        rename = "@incentiveCouponAccrualsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub incentive_coupon_accruals_long: Option<Decimal>,

    /// `incentiveCouponAccrualsShort` (added for full ibflex coverage)
    #[serde(
        rename = "@incentiveCouponAccrualsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub incentive_coupon_accruals_short: Option<Decimal>,

    /// `eventContractInterestAccrualsLong` (added for full ibflex coverage)
    #[serde(
        rename = "@eventContractInterestAccrualsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub event_contract_interest_accruals_long: Option<Decimal>,

    /// `eventContractInterestAccrualsShort` (added for full ibflex coverage)
    #[serde(
        rename = "@eventContractInterestAccrualsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub event_contract_interest_accruals_short: Option<Decimal>,

    /// `marginFinancingChargeAccrualsLong` (added for full ibflex coverage)
    #[serde(
        rename = "@marginFinancingChargeAccrualsLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub margin_financing_charge_accruals_long: Option<Decimal>,

    /// `marginFinancingChargeAccrualsShort` (added for full ibflex coverage)
    #[serde(
        rename = "@marginFinancingChargeAccrualsShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub margin_financing_charge_accruals_short: Option<Decimal>,

    /// `cryptoLong` (added for full ibflex coverage)
    #[serde(
        rename = "@cryptoLong",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub crypto_long: Option<Decimal>,

    /// `cryptoShort` (added for full ibflex coverage)
    #[serde(
        rename = "@cryptoShort",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub crypto_short: Option<Decimal>,

    /// `liteSurchargeAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@liteSurchargeAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub lite_surcharge_accruals: Option<Decimal>,
}

/// Cash report by currency
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct CashReportCurrency {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Currency
    #[serde(
        rename = "@currency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub currency: Option<String>,

    /// From date
    #[serde(
        rename = "@fromDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub from_date: Option<NaiveDate>,

    /// To date
    #[serde(
        rename = "@toDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub to_date: Option<NaiveDate>,

    /// Starting cash
    #[serde(
        rename = "@startingCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub starting_cash: Option<Decimal>,

    /// Starting cash (securities segment)
    #[serde(
        rename = "@startingCashSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub starting_cash_sec: Option<Decimal>,

    /// Starting cash (commodities segment)
    #[serde(
        rename = "@startingCashCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub starting_cash_com: Option<Decimal>,

    /// Commissions paid
    #[serde(
        rename = "@commissions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions: Option<Decimal>,

    /// Commissions (securities segment)
    #[serde(
        rename = "@commissionsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions_sec: Option<Decimal>,

    /// Commissions (commodities segment)
    #[serde(
        rename = "@commissionsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions_com: Option<Decimal>,

    /// Deposits
    #[serde(
        rename = "@deposits",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposits: Option<Decimal>,

    /// Withdrawals
    #[serde(
        rename = "@withdrawals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withdrawals: Option<Decimal>,

    /// Dividends
    #[serde(
        rename = "@dividends",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividends: Option<Decimal>,

    /// Broker interest received
    #[serde(
        rename = "@brokerInterest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest: Option<Decimal>,

    /// Bond interest received
    #[serde(
        rename = "@bondInterest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest: Option<Decimal>,

    /// Withholding tax
    #[serde(
        rename = "@withholdingTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_tax: Option<Decimal>,

    /// Net trades sales
    #[serde(
        rename = "@netTradesSales",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_sales: Option<Decimal>,

    /// Net trades purchases
    #[serde(
        rename = "@netTradesPurchases",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_purchases: Option<Decimal>,

    /// Account transfers
    #[serde(
        rename = "@accountTransfers",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub account_transfers: Option<Decimal>,

    /// Internal transfers
    #[serde(
        rename = "@internalTransfers",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub internal_transfers: Option<Decimal>,

    /// External transfers
    #[serde(
        rename = "@externalTransfers",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub external_transfers: Option<Decimal>,

    /// Link interest
    #[serde(
        rename = "@linkingAdjustments",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub linking_adjustments: Option<Decimal>,

    /// Other fees
    #[serde(
        rename = "@otherFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_fees: Option<Decimal>,

    /// FX translation P&L
    #[serde(
        rename = "@fxTranslationPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation_pnl: Option<Decimal>,

    /// Billable sales tax
    #[serde(
        rename = "@billableSalesTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_sales_tax: Option<Decimal>,

    /// Realized forex P&L
    #[serde(
        rename = "@realizedForexPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_forex_pnl: Option<Decimal>,

    /// Debit card activity
    #[serde(
        rename = "@debitCardActivity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub debit_card_activity: Option<Decimal>,

    /// Client fees
    #[serde(
        rename = "@clientFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub client_fees: Option<Decimal>,

    /// Cash settling MTM
    #[serde(
        rename = "@cashSettlingMtm",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_settling_mtm: Option<Decimal>,

    /// Soft dollar fees
    #[serde(
        rename = "@softDollars",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub soft_dollars: Option<Decimal>,

    /// Ending cash
    #[serde(
        rename = "@endingCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_cash: Option<Decimal>,

    /// Ending cash (securities segment)
    #[serde(
        rename = "@endingCashSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_cash_sec: Option<Decimal>,

    /// Ending cash (commodities segment)
    #[serde(
        rename = "@endingCashCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_cash_com: Option<Decimal>,

    /// Ending settled cash
    #[serde(
        rename = "@endingSettledCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_settled_cash: Option<Decimal>,

    /// Ending settled cash (securities segment)
    #[serde(
        rename = "@endingSettledCashSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_settled_cash_sec: Option<Decimal>,

    /// Ending settled cash (commodities segment)
    #[serde(
        rename = "@endingSettledCashCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_settled_cash_com: Option<Decimal>,

    /// `startingCashPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@startingCashPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub starting_cash_paxos: Option<Decimal>,

    /// `clientFeesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@clientFeesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub client_fees_sec: Option<Decimal>,

    /// `clientFeesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@clientFeesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub client_fees_com: Option<Decimal>,

    /// `billableCommissions` (added for full ibflex coverage)
    #[serde(
        rename = "@billableCommissions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_commissions: Option<Decimal>,

    /// `billableCommissionsSec` (added for full ibflex coverage)
    #[serde(
        rename = "@billableCommissionsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_commissions_sec: Option<Decimal>,

    /// `billableCommissionsCom` (added for full ibflex coverage)
    #[serde(
        rename = "@billableCommissionsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_commissions_com: Option<Decimal>,

    /// `billableSalesTaxIBUKL` (added for full ibflex coverage)
    #[serde(
        rename = "@billableSalesTaxIBUKL",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_sales_tax_ibukl: Option<Decimal>,

    /// `depositWithdrawals` (added for full ibflex coverage)
    #[serde(
        rename = "@depositWithdrawals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposit_withdrawals: Option<Decimal>,

    /// `depositWithdrawalsSec` (added for full ibflex coverage)
    #[serde(
        rename = "@depositWithdrawalsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposit_withdrawals_sec: Option<Decimal>,

    /// `depositWithdrawalsCom` (added for full ibflex coverage)
    #[serde(
        rename = "@depositWithdrawalsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposit_withdrawals_com: Option<Decimal>,

    /// `depositsSec` (added for full ibflex coverage)
    #[serde(
        rename = "@depositsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposits_sec: Option<Decimal>,

    /// `depositsCom` (added for full ibflex coverage)
    #[serde(
        rename = "@depositsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposits_com: Option<Decimal>,

    /// `withdrawalsSec` (added for full ibflex coverage)
    #[serde(
        rename = "@withdrawalsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withdrawals_sec: Option<Decimal>,

    /// `withdrawalsCom` (added for full ibflex coverage)
    #[serde(
        rename = "@withdrawalsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withdrawals_com: Option<Decimal>,

    /// `accountTransfersSec` (added for full ibflex coverage)
    #[serde(
        rename = "@accountTransfersSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub account_transfers_sec: Option<Decimal>,

    /// `accountTransfersCom` (added for full ibflex coverage)
    #[serde(
        rename = "@accountTransfersCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub account_transfers_com: Option<Decimal>,

    /// `internalTransfersSec` (added for full ibflex coverage)
    #[serde(
        rename = "@internalTransfersSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub internal_transfers_sec: Option<Decimal>,

    /// `internalTransfersCom` (added for full ibflex coverage)
    #[serde(
        rename = "@internalTransfersCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub internal_transfers_com: Option<Decimal>,

    /// `dividendsSec` (added for full ibflex coverage)
    #[serde(
        rename = "@dividendsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividends_sec: Option<Decimal>,

    /// `dividendsCom` (added for full ibflex coverage)
    #[serde(
        rename = "@dividendsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividends_com: Option<Decimal>,

    /// `brokerFees` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees: Option<Decimal>,

    /// `brokerFeesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_sec: Option<Decimal>,

    /// `brokerFeesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_com: Option<Decimal>,

    /// `brokerFeesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_mtd: Option<Decimal>,

    /// `brokerFeesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_ytd: Option<Decimal>,

    /// `brokerFeesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_paxos: Option<Decimal>,

    /// `brokerInterestSec` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerInterestSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest_sec: Option<Decimal>,

    /// `brokerInterestCom` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerInterestCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest_com: Option<Decimal>,

    /// `bondInterestSec` (added for full ibflex coverage)
    #[serde(
        rename = "@bondInterestSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest_sec: Option<Decimal>,

    /// `bondInterestCom` (added for full ibflex coverage)
    #[serde(
        rename = "@bondInterestCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest_com: Option<Decimal>,

    /// `bondInterestPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@bondInterestPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest_paxos: Option<Decimal>,

    /// `cashSettlingMtmSec` (added for full ibflex coverage)
    #[serde(
        rename = "@cashSettlingMtmSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_settling_mtm_sec: Option<Decimal>,

    /// `cashSettlingMtmCom` (added for full ibflex coverage)
    #[serde(
        rename = "@cashSettlingMtmCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_settling_mtm_com: Option<Decimal>,

    /// `cfdCharges` (added for full ibflex coverage)
    #[serde(
        rename = "@cfdCharges",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_charges: Option<Decimal>,

    /// `cfdChargesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@cfdChargesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_charges_sec: Option<Decimal>,

    /// `cfdChargesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@cfdChargesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_charges_com: Option<Decimal>,

    /// `netTradesSalesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesSalesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_sales_sec: Option<Decimal>,

    /// `netTradesSalesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesSalesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_sales_com: Option<Decimal>,

    /// `netTradesPurchasesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesPurchasesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_purchases_sec: Option<Decimal>,

    /// `netTradesPurchasesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesPurchasesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_purchases_com: Option<Decimal>,

    /// `feesReceivables` (added for full ibflex coverage)
    #[serde(
        rename = "@feesReceivables",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fees_receivables: Option<Decimal>,

    /// `feesReceivablesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@feesReceivablesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fees_receivables_sec: Option<Decimal>,

    /// `feesReceivablesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@feesReceivablesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fees_receivables_com: Option<Decimal>,

    /// `paymentInLieu` (added for full ibflex coverage)
    #[serde(
        rename = "@paymentInLieu",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub payment_in_lieu: Option<Decimal>,

    /// `paymentInLieuSec` (added for full ibflex coverage)
    #[serde(
        rename = "@paymentInLieuSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub payment_in_lieu_sec: Option<Decimal>,

    /// `paymentInLieuCom` (added for full ibflex coverage)
    #[serde(
        rename = "@paymentInLieuCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub payment_in_lieu_com: Option<Decimal>,

    /// `paymentInLieuIBUKL` (added for full ibflex coverage)
    #[serde(
        rename = "@paymentInLieuIBUKL",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub payment_in_lieu_ibukl: Option<Decimal>,

    /// `transactionTax` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transaction_tax: Option<Decimal>,

    /// `transactionTaxSec` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionTaxSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transaction_tax_sec: Option<Decimal>,

    /// `transactionTaxCom` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionTaxCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transaction_tax_com: Option<Decimal>,

    /// `withholdingTaxSec` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingTaxSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_tax_sec: Option<Decimal>,

    /// `withholdingTaxCom` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingTaxCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_tax_com: Option<Decimal>,

    /// `fxTranslationGainLoss` (added for full ibflex coverage)
    #[serde(
        rename = "@fxTranslationGainLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation_gain_loss: Option<Decimal>,

    /// `fxTranslationGainLossSec` (added for full ibflex coverage)
    #[serde(
        rename = "@fxTranslationGainLossSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation_gain_loss_sec: Option<Decimal>,

    /// `fxTranslationGainLossCom` (added for full ibflex coverage)
    #[serde(
        rename = "@fxTranslationGainLossCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation_gain_loss_com: Option<Decimal>,

    /// `fxTranslationGainLossPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@fxTranslationGainLossPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation_gain_loss_paxos: Option<Decimal>,

    /// `otherFeesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@otherFeesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_fees_sec: Option<Decimal>,

    /// `otherFeesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@otherFeesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_fees_com: Option<Decimal>,

    /// `endingCashPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@endingCashPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_cash_paxos: Option<Decimal>,

    /// `endingSettledCashPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@endingSettledCashPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_settled_cash_paxos: Option<Decimal>,

    /// `endingCashIBUKL` (added for full ibflex coverage)
    #[serde(
        rename = "@endingCashIBUKL",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_cash_ibukl: Option<Decimal>,

    /// `clientFeesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@clientFeesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub client_fees_mtd: Option<Decimal>,

    /// `clientFeesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@clientFeesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub client_fees_ytd: Option<Decimal>,

    /// `clientFeesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@clientFeesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub client_fees_paxos: Option<Decimal>,

    /// `commissionsMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionsMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions_mtd: Option<Decimal>,

    /// `commissionsYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionsYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions_ytd: Option<Decimal>,

    /// `commissionsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions_paxos: Option<Decimal>,

    /// `billableCommissionsMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@billableCommissionsMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_commissions_mtd: Option<Decimal>,

    /// `billableCommissionsYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@billableCommissionsYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_commissions_ytd: Option<Decimal>,

    /// `billableCommissionsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@billableCommissionsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_commissions_paxos: Option<Decimal>,

    /// `depositWithdrawalsMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@depositWithdrawalsMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposit_withdrawals_mtd: Option<Decimal>,

    /// `depositWithdrawalsYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@depositWithdrawalsYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposit_withdrawals_ytd: Option<Decimal>,

    /// `depositWithdrawalsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@depositWithdrawalsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposit_withdrawals_paxos: Option<Decimal>,

    /// `depositsMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@depositsMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposits_mtd: Option<Decimal>,

    /// `depositsYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@depositsYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposits_ytd: Option<Decimal>,

    /// `depositsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@depositsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub deposits_paxos: Option<Decimal>,

    /// `withdrawalsMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@withdrawalsMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withdrawals_mtd: Option<Decimal>,

    /// `withdrawalsYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@withdrawalsYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withdrawals_ytd: Option<Decimal>,

    /// `withdrawalsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@withdrawalsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withdrawals_paxos: Option<Decimal>,

    /// `accountTransfersMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@accountTransfersMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub account_transfers_mtd: Option<Decimal>,

    /// `accountTransfersYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@accountTransfersYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub account_transfers_ytd: Option<Decimal>,

    /// `accountTransfersPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@accountTransfersPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub account_transfers_paxos: Option<Decimal>,

    /// `internalTransfersMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@internalTransfersMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub internal_transfers_mtd: Option<Decimal>,

    /// `internalTransfersYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@internalTransfersYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub internal_transfers_ytd: Option<Decimal>,

    /// `internalTransfersPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@internalTransfersPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub internal_transfers_paxos: Option<Decimal>,

    /// `paxosTransfersPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@paxosTransfersPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub paxos_transfers_paxos: Option<Decimal>,

    /// `excessFundSweep` (added for full ibflex coverage)
    #[serde(
        rename = "@excessFundSweep",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub excess_fund_sweep: Option<Decimal>,

    /// `excessFundSweepSec` (added for full ibflex coverage)
    #[serde(
        rename = "@excessFundSweepSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub excess_fund_sweep_sec: Option<Decimal>,

    /// `excessFundSweepCom` (added for full ibflex coverage)
    #[serde(
        rename = "@excessFundSweepCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub excess_fund_sweep_com: Option<Decimal>,

    /// `excessFundSweepMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@excessFundSweepMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub excess_fund_sweep_mtd: Option<Decimal>,

    /// `excessFundSweepYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@excessFundSweepYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub excess_fund_sweep_ytd: Option<Decimal>,

    /// `excessFundSweepPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@excessFundSweepPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub excess_fund_sweep_paxos: Option<Decimal>,

    /// `dividendsMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@dividendsMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividends_mtd: Option<Decimal>,

    /// `dividendsYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@dividendsYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividends_ytd: Option<Decimal>,

    /// `dividendsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@dividendsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividends_paxos: Option<Decimal>,

    /// `insuredDepositInterestMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredDepositInterestMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_deposit_interest_mtd: Option<Decimal>,

    /// `insuredDepositInterestYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredDepositInterestYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_deposit_interest_ytd: Option<Decimal>,

    /// `insuredDepositInteresPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredDepositInteresPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_deposit_interes_paxos: Option<Decimal>,

    /// `brokerInterestMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerInterestMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest_mtd: Option<Decimal>,

    /// `brokerInterestYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerInterestYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest_ytd: Option<Decimal>,

    /// `brokerInterestPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerInterestPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_interest_paxos: Option<Decimal>,

    /// `bondInterestMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@bondInterestMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest_mtd: Option<Decimal>,

    /// `bondInterestYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@bondInterestYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bond_interest_ytd: Option<Decimal>,

    /// `cashSettlingMtmMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@cashSettlingMtmMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_settling_mtm_mtd: Option<Decimal>,

    /// `cashSettlingMtmYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@cashSettlingMtmYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_settling_mtm_ytd: Option<Decimal>,

    /// `cashSettlingMtmPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@cashSettlingMtmPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_settling_mtm_paxos: Option<Decimal>,

    /// `realizedVmMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedVmMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_vm_mtd: Option<Decimal>,

    /// `realizedVmYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedVmYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_vm_ytd: Option<Decimal>,

    /// `realizedVmPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedVmPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_vm_paxos: Option<Decimal>,

    /// `cfdChargesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@cfdChargesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_charges_mtd: Option<Decimal>,

    /// `cfdChargesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@cfdChargesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_charges_ytd: Option<Decimal>,

    /// `cfdChargesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@cfdChargesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cfd_charges_paxos: Option<Decimal>,

    /// `netTradesSalesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesSalesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_sales_mtd: Option<Decimal>,

    /// `netTradesSalesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesSalesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_sales_ytd: Option<Decimal>,

    /// `netTradesSalesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesSalesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_sales_paxos: Option<Decimal>,

    /// `advisorFeesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@advisorFeesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub advisor_fees_mtd: Option<Decimal>,

    /// `advisorFeesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@advisorFeesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub advisor_fees_ytd: Option<Decimal>,

    /// `advisorFeePaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@advisorFeePaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub advisor_fee_paxos: Option<Decimal>,

    /// `feesReceivablesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@feesReceivablesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fees_receivables_mtd: Option<Decimal>,

    /// `feesReceivablesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@feesReceivablesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fees_receivables_ytd: Option<Decimal>,

    /// `feesReceivablesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@feesReceivablesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fees_receivables_paxos: Option<Decimal>,

    /// `netTradesPurchasesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesPurchasesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_purchases_mtd: Option<Decimal>,

    /// `netTradesPurchasesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesPurchasesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_purchases_ytd: Option<Decimal>,

    /// `netTradesPurchasesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradesPurchasesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trades_purchases_paxos: Option<Decimal>,

    /// `paymentInLieuMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@paymentInLieuMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub payment_in_lieu_mtd: Option<Decimal>,

    /// `paymentInLieuYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@paymentInLieuYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub payment_in_lieu_ytd: Option<Decimal>,

    /// `paymentInLieuPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@paymentInLieuPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub payment_in_lieu_paxos: Option<Decimal>,

    /// `transactionTaxMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionTaxMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transaction_tax_mtd: Option<Decimal>,

    /// `transactionTaxYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionTaxYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transaction_tax_ytd: Option<Decimal>,

    /// `transactionTaxPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionTaxPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transaction_tax_paxos: Option<Decimal>,

    /// `taxReceivablesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@taxReceivablesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_receivables_mtd: Option<Decimal>,

    /// `taxReceivablesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@taxReceivablesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_receivables_ytd: Option<Decimal>,

    /// `taxReceivablesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@taxReceivablesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_receivables_paxos: Option<Decimal>,

    /// `withholdingTaxMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingTaxMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_tax_mtd: Option<Decimal>,

    /// `withholdingTaxYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingTaxYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_tax_ytd: Option<Decimal>,

    /// `withholdingTaxPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingTaxPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_tax_paxos: Option<Decimal>,

    /// `withholding871mMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@withholding871mMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding871m_mtd: Option<Decimal>,

    /// `withholding871mYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@withholding871mYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding871m_ytd: Option<Decimal>,

    /// `withholding871mPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@withholding871mPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding871m_paxos: Option<Decimal>,

    /// `withholdingCollectedTaxMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingCollectedTaxMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_collected_tax_mtd: Option<Decimal>,

    /// `withholdingCollectedTaxYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingCollectedTaxYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_collected_tax_ytd: Option<Decimal>,

    /// `withholdingCollectedTaxPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingCollectedTaxPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_collected_tax_paxos: Option<Decimal>,

    /// `salesTaxMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@salesTaxMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub sales_tax_mtd: Option<Decimal>,

    /// `salesTaxYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@salesTaxYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub sales_tax_ytd: Option<Decimal>,

    /// `salesTaxPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@salesTaxPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub sales_tax_paxos: Option<Decimal>,

    /// `otherIncome` (added for full ibflex coverage)
    #[serde(
        rename = "@otherIncome",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_income: Option<Decimal>,

    /// `otherIncomeMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@otherIncomeMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_income_mtd: Option<Decimal>,

    /// `otherIncomeYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@otherIncomeYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_income_ytd: Option<Decimal>,

    /// `otherIncomeSec` (added for full ibflex coverage)
    #[serde(
        rename = "@otherIncomeSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_income_sec: Option<Decimal>,

    /// `otherIncomeCom` (added for full ibflex coverage)
    #[serde(
        rename = "@otherIncomeCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_income_com: Option<Decimal>,

    /// `otherFeesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@otherFeesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_fees_mtd: Option<Decimal>,

    /// `otherFeesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@otherFeesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_fees_ytd: Option<Decimal>,

    /// `otherFeesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@otherFeesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_fees_paxos: Option<Decimal>,

    /// `avgCreditBalance` (added for full ibflex coverage)
    #[serde(
        rename = "@avgCreditBalance",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub avg_credit_balance: Option<Decimal>,

    /// `avgCreditBalanceSec` (added for full ibflex coverage)
    #[serde(
        rename = "@avgCreditBalanceSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub avg_credit_balance_sec: Option<Decimal>,

    /// `avgCreditBalanceCom` (added for full ibflex coverage)
    #[serde(
        rename = "@avgCreditBalanceCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub avg_credit_balance_com: Option<Decimal>,

    /// `avgDebitBalance` (added for full ibflex coverage)
    #[serde(
        rename = "@avgDebitBalance",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub avg_debit_balance: Option<Decimal>,

    /// `avgDebitBalanceSec` (added for full ibflex coverage)
    #[serde(
        rename = "@avgDebitBalanceSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub avg_debit_balance_sec: Option<Decimal>,

    /// `avgDebitBalanceCom` (added for full ibflex coverage)
    #[serde(
        rename = "@avgDebitBalanceCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub avg_debit_balance_com: Option<Decimal>,

    /// `linkingAdjustmentsSec` (added for full ibflex coverage)
    #[serde(
        rename = "@linkingAdjustmentsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub linking_adjustments_sec: Option<Decimal>,

    /// `linkingAdjustmentsCom` (added for full ibflex coverage)
    #[serde(
        rename = "@linkingAdjustmentsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub linking_adjustments_com: Option<Decimal>,

    /// `linkingAdjustmentsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@linkingAdjustmentsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub linking_adjustments_paxos: Option<Decimal>,

    /// `insuredDepositInterest` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredDepositInterest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_deposit_interest: Option<Decimal>,

    /// `insuredDepositInterestSec` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredDepositInterestSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_deposit_interest_sec: Option<Decimal>,

    /// `insuredDepositInterestCom` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredDepositInterestCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_deposit_interest_com: Option<Decimal>,

    /// `insuredDepositInterestPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@insuredDepositInterestPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub insured_deposit_interest_paxos: Option<Decimal>,

    /// `realizedVm` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedVm",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_vm: Option<Decimal>,

    /// `realizedVmSec` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedVmSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_vm_sec: Option<Decimal>,

    /// `realizedVmCom` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedVmCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_vm_com: Option<Decimal>,

    /// `advisorFees` (added for full ibflex coverage)
    #[serde(
        rename = "@advisorFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub advisor_fees: Option<Decimal>,

    /// `advisorFeesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@advisorFeesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub advisor_fees_sec: Option<Decimal>,

    /// `advisorFeesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@advisorFeesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub advisor_fees_com: Option<Decimal>,

    /// `advisorFeesPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@advisorFeesPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub advisor_fees_paxos: Option<Decimal>,

    /// `taxReceivables` (added for full ibflex coverage)
    #[serde(
        rename = "@taxReceivables",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_receivables: Option<Decimal>,

    /// `taxReceivablesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@taxReceivablesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_receivables_sec: Option<Decimal>,

    /// `taxReceivablesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@taxReceivablesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_receivables_com: Option<Decimal>,

    /// `withholding871m` (added for full ibflex coverage)
    #[serde(
        rename = "@withholding871m",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding871m: Option<Decimal>,

    /// `withholding871mSec` (added for full ibflex coverage)
    #[serde(
        rename = "@withholding871mSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding871m_sec: Option<Decimal>,

    /// `withholding871mCom` (added for full ibflex coverage)
    #[serde(
        rename = "@withholding871mCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding871m_com: Option<Decimal>,

    /// `withholdingCollectedTax` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingCollectedTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_collected_tax: Option<Decimal>,

    /// `withholdingCollectedTaxSec` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingCollectedTaxSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_collected_tax_sec: Option<Decimal>,

    /// `withholdingCollectedTaxCom` (added for full ibflex coverage)
    #[serde(
        rename = "@withholdingCollectedTaxCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub withholding_collected_tax_com: Option<Decimal>,

    /// `salesTax` (added for full ibflex coverage)
    #[serde(
        rename = "@salesTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub sales_tax: Option<Decimal>,

    /// `salesTaxSec` (added for full ibflex coverage)
    #[serde(
        rename = "@salesTaxSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub sales_tax_sec: Option<Decimal>,

    /// `salesTaxCom` (added for full ibflex coverage)
    #[serde(
        rename = "@salesTaxCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub sales_tax_com: Option<Decimal>,

    /// `other` (added for full ibflex coverage)
    #[serde(
        rename = "@other",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other: Option<Decimal>,

    /// `otherSec` (added for full ibflex coverage)
    #[serde(
        rename = "@otherSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_sec: Option<Decimal>,

    /// `otherCom` (added for full ibflex coverage)
    #[serde(
        rename = "@otherCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_com: Option<Decimal>,

    /// `otherPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@otherPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_paxos: Option<Decimal>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `debitCardActivitySec` (added for full ibflex coverage)
    #[serde(
        rename = "@debitCardActivitySec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub debit_card_activity_sec: Option<Decimal>,

    /// `debitCardActivityCom` (added for full ibflex coverage)
    #[serde(
        rename = "@debitCardActivityCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub debit_card_activity_com: Option<Decimal>,

    /// `debitCardActivityMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@debitCardActivityMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub debit_card_activity_mtd: Option<Decimal>,

    /// `debitCardActivityYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@debitCardActivityYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub debit_card_activity_ytd: Option<Decimal>,

    /// `debitCardActivityPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@debitCardActivityPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub debit_card_activity_paxos: Option<Decimal>,

    /// `billPay` (added for full ibflex coverage)
    #[serde(
        rename = "@billPay",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bill_pay: Option<Decimal>,

    /// `billPaySec` (added for full ibflex coverage)
    #[serde(
        rename = "@billPaySec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bill_pay_sec: Option<Decimal>,

    /// `billPayCom` (added for full ibflex coverage)
    #[serde(
        rename = "@billPayCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bill_pay_com: Option<Decimal>,

    /// `billPayMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@billPayMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bill_pay_mtd: Option<Decimal>,

    /// `billPayYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@billPayYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bill_pay_ytd: Option<Decimal>,

    /// `billPayPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@billPayPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub bill_pay_paxos: Option<Decimal>,

    /// `realizedForexVm` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedForexVm",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_forex_vm: Option<Decimal>,

    /// `realizedForexVmSec` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedForexVmSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_forex_vm_sec: Option<Decimal>,

    /// `realizedForexVmCom` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedForexVmCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_forex_vm_com: Option<Decimal>,

    /// `realizedForexVmMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedForexVmMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_forex_vm_mtd: Option<Decimal>,

    /// `realizedForexVmYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedForexVmYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_forex_vm_ytd: Option<Decimal>,

    /// `realizedForexVmPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedForexVmPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_forex_vm_paxos: Option<Decimal>,

    /// `ipoSubscription` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscription",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription: Option<Decimal>,

    /// `ipoSubscriptionSec` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscriptionSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription_sec: Option<Decimal>,

    /// `ipoSubscriptionCom` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscriptionCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription_com: Option<Decimal>,

    /// `ipoSubscriptionMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscriptionMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription_mtd: Option<Decimal>,

    /// `ipoSubscriptionYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscriptionYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription_ytd: Option<Decimal>,

    /// `ipoSubscriptionPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@ipoSubscriptionPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ipo_subscription_paxos: Option<Decimal>,

    /// `billableSalesTaxSec` (added for full ibflex coverage)
    #[serde(
        rename = "@billableSalesTaxSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_sales_tax_sec: Option<Decimal>,

    /// `billableSalesTaxCom` (added for full ibflex coverage)
    #[serde(
        rename = "@billableSalesTaxCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_sales_tax_com: Option<Decimal>,

    /// `billableSalesTaxMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@billableSalesTaxMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_sales_tax_mtd: Option<Decimal>,

    /// `billableSalesTaxYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@billableSalesTaxYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_sales_tax_ytd: Option<Decimal>,

    /// `billableSalesTaxPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@billableSalesTaxPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub billable_sales_tax_paxos: Option<Decimal>,

    /// `commissionCreditsRedemption` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCreditsRedemption",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission_credits_redemption: Option<Decimal>,

    /// `commissionCreditsRedemptionSec` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCreditsRedemptionSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission_credits_redemption_sec: Option<Decimal>,

    /// `commissionCreditsRedemptionCom` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCreditsRedemptionCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission_credits_redemption_com: Option<Decimal>,

    /// `commissionCreditsRedemptionMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCreditsRedemptionMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission_credits_redemption_mtd: Option<Decimal>,

    /// `commissionCreditsRedemptionYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCreditsRedemptionYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission_credits_redemption_ytd: Option<Decimal>,

    /// `commissionCreditsRedemptionPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCreditsRedemptionPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission_credits_redemption_paxos: Option<Decimal>,

    /// `referralFee` (added for full ibflex coverage)
    #[serde(
        rename = "@referralFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub referral_fee: Option<Decimal>,

    /// `referralFeePaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@referralFeePaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub referral_fee_paxos: Option<Decimal>,

    /// `referralFeeSec` (added for full ibflex coverage)
    #[serde(
        rename = "@referralFeeSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub referral_fee_sec: Option<Decimal>,

    /// `referralFeeCom` (added for full ibflex coverage)
    #[serde(
        rename = "@referralFeeCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub referral_fee_com: Option<Decimal>,

    /// `referralFeeMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@referralFeeMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub referral_fee_mtd: Option<Decimal>,

    /// `referralFeeYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@referralFeeYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub referral_fee_ytd: Option<Decimal>,

    /// `carbonCredits` (added for full ibflex coverage)
    #[serde(
        rename = "@carbonCredits",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub carbon_credits: Option<Decimal>,

    /// `carbonCreditsSec` (added for full ibflex coverage)
    #[serde(
        rename = "@carbonCreditsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub carbon_credits_sec: Option<Decimal>,

    /// `carbonCreditsCom` (added for full ibflex coverage)
    #[serde(
        rename = "@carbonCreditsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub carbon_credits_com: Option<Decimal>,

    /// `carbonCreditsMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@carbonCreditsMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub carbon_credits_mtd: Option<Decimal>,

    /// `carbonCreditsYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@carbonCreditsYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub carbon_credits_ytd: Option<Decimal>,

    /// `carbonCreditsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@carbonCreditsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub carbon_credits_paxos: Option<Decimal>,

    /// `donations` (added for full ibflex coverage)
    #[serde(
        rename = "@donations",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub donations: Option<Decimal>,

    /// `donationsSec` (added for full ibflex coverage)
    #[serde(
        rename = "@donationsSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub donations_sec: Option<Decimal>,

    /// `donationsCom` (added for full ibflex coverage)
    #[serde(
        rename = "@donationsCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub donations_com: Option<Decimal>,

    /// `donationsMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@donationsMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub donations_mtd: Option<Decimal>,

    /// `donationsYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@donationsYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub donations_ytd: Option<Decimal>,

    /// `donationsPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@donationsPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub donations_paxos: Option<Decimal>,

    /// `paxosTransfers` (added for full ibflex coverage)
    #[serde(
        rename = "@paxosTransfers",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub paxos_transfers: Option<Decimal>,

    /// `paxosTransfersSec` (added for full ibflex coverage)
    #[serde(
        rename = "@paxosTransfersSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub paxos_transfers_sec: Option<Decimal>,

    /// `paxosTransfersCom` (added for full ibflex coverage)
    #[serde(
        rename = "@paxosTransfersCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub paxos_transfers_com: Option<Decimal>,

    /// `paxosTransfersMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@paxosTransfersMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub paxos_transfers_mtd: Option<Decimal>,

    /// `paxosTransfersYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@paxosTransfersYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub paxos_transfers_ytd: Option<Decimal>,

    /// `slbStartingCashCollateral` (added for full ibflex coverage)
    #[serde(
        rename = "@slbStartingCashCollateral",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_starting_cash_collateral: Option<Decimal>,

    /// `slbStartingCashCollateralSec` (added for full ibflex coverage)
    #[serde(
        rename = "@slbStartingCashCollateralSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_starting_cash_collateral_sec: Option<Decimal>,

    /// `slbStartingCashCollateralCom` (added for full ibflex coverage)
    #[serde(
        rename = "@slbStartingCashCollateralCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_starting_cash_collateral_com: Option<Decimal>,

    /// `slbStartingCashCollateralPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@slbStartingCashCollateralPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_starting_cash_collateral_paxos: Option<Decimal>,

    /// `slbNetSecuritiesLentActivity` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetSecuritiesLentActivity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_securities_lent_activity: Option<Decimal>,

    /// `slbNetSecuritiesLentActivityCom` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetSecuritiesLentActivityCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_securities_lent_activity_com: Option<Decimal>,

    /// `slbNetSecuritiesLentActivitySec` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetSecuritiesLentActivitySec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_securities_lent_activity_sec: Option<Decimal>,

    /// `slbNetSecuritiesLentActivityPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetSecuritiesLentActivityPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_securities_lent_activity_paxos: Option<Decimal>,

    /// `slbEndingCashCollateral` (added for full ibflex coverage)
    #[serde(
        rename = "@slbEndingCashCollateral",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_ending_cash_collateral: Option<Decimal>,

    /// `slbEndingCashCollateralSec` (added for full ibflex coverage)
    #[serde(
        rename = "@slbEndingCashCollateralSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_ending_cash_collateral_sec: Option<Decimal>,

    /// `slbEndingCashCollateralCom` (added for full ibflex coverage)
    #[serde(
        rename = "@slbEndingCashCollateralCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_ending_cash_collateral_com: Option<Decimal>,

    /// `slbEndingCashCollateralPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@slbEndingCashCollateralPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_ending_cash_collateral_paxos: Option<Decimal>,

    /// `slbNetCash` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_cash: Option<Decimal>,

    /// `slbNetCashSec` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetCashSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_cash_sec: Option<Decimal>,

    /// `slbNetCashCom` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetCashCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_cash_com: Option<Decimal>,

    /// `slbNetCashPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetCashPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_cash_paxos: Option<Decimal>,

    /// `slbNetSettledCash` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetSettledCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_settled_cash: Option<Decimal>,

    /// `slbNetSettledCashSec` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetSettledCashSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_settled_cash_sec: Option<Decimal>,

    /// `slbNetSettledCashCom` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetSettledCashCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_settled_cash_com: Option<Decimal>,

    /// `slbNetSettledCashPaxos` (added for full ibflex coverage)
    #[serde(
        rename = "@slbNetSettledCashPaxos",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub slb_net_settled_cash_paxos: Option<Decimal>,
}

/// Trade confirmation
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct TradeConfirm {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Execution ID
    #[serde(
        rename = "@execID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exec_id: Option<String>,

    /// Transaction ID
    #[serde(rename = "@transactionID", default)]
    pub transaction_id: Option<String>,

    /// Trade ID
    #[serde(rename = "@tradeID", default)]
    pub trade_id: Option<String>,

    /// Order ID
    #[serde(rename = "@orderID", default)]
    pub order_id: Option<String>,

    /// Trade date
    #[serde(
        rename = "@tradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub trade_date: Option<NaiveDate>,

    /// Trade time
    #[serde(rename = "@tradeTime", default)]
    pub trade_time: Option<String>,

    /// Date time
    #[serde(rename = "@dateTime", default)]
    pub date_time: Option<String>,

    /// Settlement date
    #[serde(
        rename = "@settleDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date: Option<NaiveDate>,

    /// Symbol
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    // Security identifiers
    /// CUSIP
    #[serde(rename = "@cusip", default)]
    pub cusip: Option<String>,

    /// ISIN
    #[serde(rename = "@isin", default)]
    pub isin: Option<String>,

    /// FIGI
    #[serde(rename = "@figi", default)]
    pub figi: Option<String>,

    /// Listing exchange
    #[serde(rename = "@listingExchange", default)]
    pub listing_exchange: Option<String>,

    // Options fields
    /// Strike
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// Expiry
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// Put/Call
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<String>,

    /// Multiplier
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    // Underlying
    /// Underlying symbol
    #[serde(rename = "@underlyingSymbol", default)]
    pub underlying_symbol: Option<String>,

    /// Underlying contract ID
    #[serde(rename = "@underlyingConid", default)]
    pub underlying_conid: Option<String>,

    // Trade details
    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Price
    #[serde(
        rename = "@price",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub price: Option<Decimal>,

    /// Proceeds
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub proceeds: Option<Decimal>,

    /// Commission
    #[serde(
        rename = "@commission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission: Option<Decimal>,

    /// Taxes
    #[serde(
        rename = "@tax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax: Option<Decimal>,

    /// Net cash
    #[serde(
        rename = "@netCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_cash: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// Buy/Sell
    #[serde(rename = "@buySell", default)]
    pub buy_sell: Option<String>,

    /// Order type
    #[serde(rename = "@orderType", default)]
    pub order_type: Option<String>,

    /// Exchange
    #[serde(rename = "@exchange", default)]
    pub exchange: Option<String>,

    /// Clearing ID
    #[serde(rename = "@clearingID", default)]
    pub clearing_id: Option<String>,

    /// Away broker commission
    #[serde(
        rename = "@awayBrokerCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub away_broker_commission: Option<Decimal>,

    /// Regulatory fee
    #[serde(
        rename = "@regulatoryFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub regulatory_fee: Option<Decimal>,

    /// Order reference
    #[serde(rename = "@orderReference", default)]
    pub order_reference: Option<String>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// `transactionType` (added for full ibflex coverage)
    #[serde(rename = "@transactionType", default)]
    pub transaction_type: Option<TradeType>,

    /// `openCloseIndicator` (added for full ibflex coverage)
    #[serde(rename = "@openCloseIndicator", default)]
    pub open_close_indicator: Option<OpenClose>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `rfqID` (added for full ibflex coverage)
    #[serde(
        rename = "@rfqID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub rfq_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `reportDate` (added for full ibflex coverage)
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `settleDateTarget` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDateTarget",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date_target: Option<NaiveDate>,

    /// `tradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// `tradeMoney` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeMoney",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_money: Option<Decimal>,

    /// `taxes` (added for full ibflex coverage)
    #[serde(
        rename = "@taxes",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub taxes: Option<Decimal>,

    /// `ibCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ib_commission: Option<Decimal>,

    /// `ibCommissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_commission_currency: Option<String>,

    /// `closePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@closePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub close_price: Option<Decimal>,

    /// `notes` (added for full ibflex coverage)
    #[serde(
        rename = "@notes",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub notes: Option<String>,

    /// `cost` (added for full ibflex coverage)
    #[serde(
        rename = "@cost",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost: Option<Decimal>,

    /// `fifoPnlRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@fifoPnlRealized",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fifo_pnl_realized: Option<Decimal>,

    /// `fxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@fxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_pnl: Option<Decimal>,

    /// `mtmPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_pnl: Option<Decimal>,

    /// `origTradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub orig_trade_price: Option<Decimal>,

    /// `origTradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub orig_trade_date: Option<NaiveDate>,

    /// `origTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_trade_id: Option<String>,

    /// `origOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@origOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_order_id: Option<String>,

    /// `clearingFirmID` (added for full ibflex coverage)
    #[serde(
        rename = "@clearingFirmID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub clearing_firm_id: Option<String>,

    /// `openDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@openDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub open_date_time: Option<String>,

    /// `holdingPeriodDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@holdingPeriodDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub holding_period_date_time: Option<String>,

    /// `whenRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@whenRealized",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_realized: Option<String>,

    /// `whenReopened` (added for full ibflex coverage)
    #[serde(
        rename = "@whenReopened",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_reopened: Option<String>,

    /// `commissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commission_currency: Option<String>,

    /// `thirdPartyClearingCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyClearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_clearing_commission: Option<Decimal>,

    /// `allocatedTo` (added for full ibflex coverage)
    #[serde(
        rename = "@allocatedTo",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub allocated_to: Option<String>,

    /// `thirdPartyRegulatoryCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyRegulatoryCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_regulatory_commission: Option<Decimal>,

    /// `brokerExecutionCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerExecutionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_execution_commission: Option<Decimal>,

    /// `thirdPartyExecutionCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyExecutionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_execution_commission: Option<Decimal>,

    /// `amount` (added for full ibflex coverage)
    #[serde(
        rename = "@amount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub amount: Option<Decimal>,

    /// `otherCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@otherCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_commission: Option<Decimal>,

    /// `brokerClearingCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerClearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_clearing_commission: Option<Decimal>,

    /// `ibOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@ibOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_order_id: Option<String>,

    /// `ibExecID` (added for full ibflex coverage)
    #[serde(
        rename = "@ibExecID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_exec_id: Option<String>,

    /// `brokerageOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerageOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub brokerage_order_id: Option<String>,

    /// `volatilityOrderLink` (added for full ibflex coverage)
    #[serde(
        rename = "@volatilityOrderLink",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub volatility_order_link: Option<String>,

    /// `exchOrderId` (added for full ibflex coverage)
    #[serde(
        rename = "@exchOrderId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exch_order_id: Option<String>,

    /// `extExecID` (added for full ibflex coverage)
    #[serde(
        rename = "@extExecID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ext_exec_id: Option<String>,

    /// `orderTime` (added for full ibflex coverage)
    #[serde(
        rename = "@orderTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub order_time: Option<String>,

    /// `changeInPrice` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_price: Option<Decimal>,

    /// `changeInQuantity` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_quantity: Option<Decimal>,

    /// `traderID` (added for full ibflex coverage)
    #[serde(
        rename = "@traderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trader_id: Option<String>,

    /// `isAPIOrder` (added for full ibflex coverage)
    #[serde(
        rename = "@isAPIOrder",
        default,
        deserialize_with = "deserialize_optional_bool"
    )]
    pub is_api_order: Option<bool>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `accruedInt` (added for full ibflex coverage)
    #[serde(
        rename = "@accruedInt",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub accrued_int: Option<Decimal>,

    /// `relatedTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_trade_id: Option<String>,

    /// `relatedTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_transaction_id: Option<String>,

    /// `blockID` (added for full ibflex coverage)
    #[serde(
        rename = "@blockID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub block_id: Option<String>,
}

/// Option exercise/assignment/expiration
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct OptionEAE {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Transaction ID
    #[serde(rename = "@transactionID", default)]
    pub transaction_id: Option<String>,

    /// Action ID
    #[serde(rename = "@actionID", default)]
    pub action_id: Option<String>,

    /// Action type
    #[serde(rename = "@type", default)]
    pub action_type: Option<OptionAction>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Date time
    #[serde(rename = "@dateTime", default)]
    pub date_time: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Symbol
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    // Security identifiers
    /// CUSIP
    #[serde(rename = "@cusip", default)]
    pub cusip: Option<String>,

    /// ISIN
    #[serde(rename = "@isin", default)]
    pub isin: Option<String>,

    /// FIGI
    #[serde(rename = "@figi", default)]
    pub figi: Option<String>,

    /// Listing exchange
    #[serde(rename = "@listingExchange", default)]
    pub listing_exchange: Option<String>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Strike
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// Expiry
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// Put/Call
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<String>,

    /// Multiplier
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// Underlying symbol
    #[serde(rename = "@underlyingSymbol", default)]
    pub underlying_symbol: Option<String>,

    /// Underlying contract ID
    #[serde(rename = "@underlyingConid", default)]
    pub underlying_conid: Option<String>,

    /// Trade price
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// Proceeds
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub proceeds: Option<Decimal>,

    /// Commission
    #[serde(
        rename = "@commission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// FIFO P&L realized
    #[serde(
        rename = "@fifoPnlRealized",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fifo_pnl_realized: Option<Decimal>,

    /// Notes/codes
    #[serde(rename = "@notes", default)]
    pub notes: Option<String>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// `transactionType` (added for full ibflex coverage)
    #[serde(rename = "@transactionType", default)]
    pub transaction_type: Option<OptionAction>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `markPrice` (added for full ibflex coverage)
    #[serde(
        rename = "@markPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mark_price: Option<Decimal>,

    /// `commisionsAndTax` (added for full ibflex coverage)
    #[serde(
        rename = "@commisionsAndTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commisions_and_tax: Option<Decimal>,

    /// `costBasis` (added for full ibflex coverage)
    #[serde(
        rename = "@costBasis",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost_basis: Option<Decimal>,

    /// `realizedPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_pnl: Option<Decimal>,

    /// `capitalGainsPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@capitalGainsPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub capital_gains_pnl: Option<Decimal>,

    /// `fxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@fxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_pnl: Option<Decimal>,

    /// `mtmPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_pnl: Option<Decimal>,

    /// `tradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `relatedTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_trade_id: Option<String>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `origTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_transaction_id: Option<String>,

    /// `relatedTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_transaction_id: Option<String>,

    /// `rtn` (added for full ibflex coverage)
    #[serde(
        rename = "@rtn",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub rtn: Option<String>,

    /// `initialInvestment` (added for full ibflex coverage)
    #[serde(
        rename = "@initialInvestment",
        default,
        deserialize_with = "deserialize_optional_bool"
    )]
    pub initial_investment: Option<bool>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,
}

/// Foreign exchange transaction
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct FxTransaction {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Transaction ID
    #[serde(rename = "@transactionID", default)]
    pub transaction_id: Option<String>,

    /// Action ID
    #[serde(rename = "@actionID", default)]
    pub action_id: Option<String>,

    /// Report date
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// Date/time
    #[serde(rename = "@dateTime", default)]
    pub date_time: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Functional currency
    #[serde(rename = "@functionalCurrency", default)]
    pub functional_currency: Option<String>,

    /// From currency
    #[serde(
        rename = "@fromCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub from_currency: Option<String>,

    /// To currency
    #[serde(
        rename = "@toCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub to_currency: Option<String>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Proceeds
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub proceeds: Option<Decimal>,

    /// Cost
    #[serde(
        rename = "@cost",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost: Option<Decimal>,

    /// Realized P&L
    #[serde(
        rename = "@realizedPL",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_pl: Option<Decimal>,

    /// FX rate
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<String>,

    /// `fxCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@fxCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub fx_currency: Option<String>,

    /// `activityDescription` (added for full ibflex coverage)
    #[serde(
        rename = "@activityDescription",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub activity_description: Option<String>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,
}

/// Change in dividend accruals
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct ChangeInDividendAccrual {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Symbol
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Security ID
    #[serde(rename = "@securityID", default)]
    pub security_id: Option<String>,

    /// Security ID type
    #[serde(rename = "@securityIDType", default)]
    pub security_id_type: Option<String>,

    /// CUSIP
    #[serde(rename = "@cusip", default)]
    pub cusip: Option<String>,

    /// ISIN
    #[serde(rename = "@isin", default)]
    pub isin: Option<String>,

    /// FIGI
    #[serde(rename = "@figi", default)]
    pub figi: Option<String>,

    /// Listing exchange
    #[serde(rename = "@listingExchange", default)]
    pub listing_exchange: Option<String>,

    /// Ex date
    #[serde(
        rename = "@exDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub ex_date: Option<NaiveDate>,

    /// Pay date
    #[serde(
        rename = "@payDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub pay_date: Option<NaiveDate>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Tax
    #[serde(
        rename = "@tax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax: Option<Decimal>,

    /// Fee
    #[serde(
        rename = "@fee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fee: Option<Decimal>,

    /// Gross rate
    #[serde(
        rename = "@grossRate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub gross_rate: Option<Decimal>,

    /// Gross amount
    #[serde(
        rename = "@grossAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub gross_amount: Option<Decimal>,

    /// Net amount
    #[serde(
        rename = "@netAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_amount: Option<Decimal>,

    /// From accrual (prior period)
    #[serde(
        rename = "@fromAccrual",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub from_accrual: Option<Decimal>,

    /// To accrual (current period)
    #[serde(
        rename = "@toAccrual",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub to_accrual: Option<Decimal>,

    /// Code
    #[serde(rename = "@code", default)]
    pub code: Option<String>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `reportDate` (added for full ibflex coverage)
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `fromAcct` (added for full ibflex coverage)
    #[serde(
        rename = "@fromAcct",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub from_acct: Option<String>,

    /// `toAcct` (added for full ibflex coverage)
    #[serde(
        rename = "@toAcct",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub to_acct: Option<String>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `actionID` (added for full ibflex coverage)
    #[serde(
        rename = "@actionID",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub action_id: Option<Decimal>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub serial_number: Option<Decimal>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub delivery_type: Option<Decimal>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub weight: Option<Decimal>,
}

/// Open dividend accruals
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct OpenDividendAccrual {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Symbol
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Security ID
    #[serde(rename = "@securityID", default)]
    pub security_id: Option<String>,

    /// Security ID type
    #[serde(rename = "@securityIDType", default)]
    pub security_id_type: Option<String>,

    /// CUSIP
    #[serde(rename = "@cusip", default)]
    pub cusip: Option<String>,

    /// ISIN
    #[serde(rename = "@isin", default)]
    pub isin: Option<String>,

    /// FIGI
    #[serde(rename = "@figi", default)]
    pub figi: Option<String>,

    /// Listing exchange
    #[serde(rename = "@listingExchange", default)]
    pub listing_exchange: Option<String>,

    /// Ex date
    #[serde(
        rename = "@exDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub ex_date: Option<NaiveDate>,

    /// Pay date
    #[serde(
        rename = "@payDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub pay_date: Option<NaiveDate>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Tax
    #[serde(
        rename = "@tax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax: Option<Decimal>,

    /// Fee
    #[serde(
        rename = "@fee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fee: Option<Decimal>,

    /// Gross rate
    #[serde(
        rename = "@grossRate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub gross_rate: Option<Decimal>,

    /// Gross amount
    #[serde(
        rename = "@grossAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub gross_amount: Option<Decimal>,

    /// Net amount
    #[serde(
        rename = "@netAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_amount: Option<Decimal>,

    /// Code
    #[serde(rename = "@code", default)]
    pub code: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `fromAcct` (added for full ibflex coverage)
    #[serde(
        rename = "@fromAcct",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub from_acct: Option<String>,

    /// `toAcct` (added for full ibflex coverage)
    #[serde(
        rename = "@toAcct",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub to_acct: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,
}

/// Interest accruals by currency
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct InterestAccrualsCurrency {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Currency
    #[serde(
        rename = "@currency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub currency: Option<String>,

    /// From date
    #[serde(
        rename = "@fromDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub from_date: Option<NaiveDate>,

    /// To date
    #[serde(
        rename = "@toDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub to_date: Option<NaiveDate>,

    /// Starting accrual balance
    #[serde(
        rename = "@startingAccrualBalance",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub starting_balance: Option<Decimal>,

    /// Interest accrued
    #[serde(
        rename = "@interestAccrued",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub interest_accrued: Option<Decimal>,

    /// Ending accrual balance
    #[serde(
        rename = "@endingAccrualBalance",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_balance: Option<Decimal>,

    /// `accrualReversal` (added for full ibflex coverage)
    #[serde(
        rename = "@accrualReversal",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub accrual_reversal: Option<Decimal>,

    /// `acctAlias` (added for full ibflex coverage)
    #[serde(
        rename = "@acctAlias",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub acct_alias: Option<String>,

    /// `model` (added for full ibflex coverage)
    #[serde(
        rename = "@model",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub model: Option<String>,

    /// `fxTranslation` (added for full ibflex coverage)
    #[serde(
        rename = "@fxTranslation",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation: Option<Decimal>,
}

/// Security transfer
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Transfer {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Transaction ID
    #[serde(rename = "@transactionID", default)]
    pub transaction_id: Option<String>,

    /// Transfer type
    #[serde(rename = "@type", default)]
    pub transfer_type: Option<TransferType>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Symbol
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    // Security identifiers
    /// CUSIP
    #[serde(rename = "@cusip", default)]
    pub cusip: Option<String>,

    /// ISIN
    #[serde(rename = "@isin", default)]
    pub isin: Option<String>,

    /// FIGI
    #[serde(rename = "@figi", default)]
    pub figi: Option<String>,

    /// Listing exchange
    #[serde(rename = "@listingExchange", default)]
    pub listing_exchange: Option<String>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Price
    #[serde(
        rename = "@transferPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transfer_price: Option<Decimal>,

    /// Position amount
    #[serde(
        rename = "@positionAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub position_amount: Option<Decimal>,

    /// Position amount in base
    #[serde(
        rename = "@positionAmountInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub position_amount_in_base: Option<Decimal>,

    /// Cash transfer
    #[serde(
        rename = "@cashTransfer",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cash_transfer: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// Direction
    #[serde(rename = "@direction", default)]
    pub direction: Option<String>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Payer/payee account
    #[serde(rename = "@ppiPayerPayeeAccount", default)]
    pub ppi_payer_payee_account: Option<String>,

    /// Delivering/receiving broker
    #[serde(rename = "@deliveringReceivingBroker", default)]
    pub delivering_receiving_broker: Option<String>,

    // Options fields
    /// Strike
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// Expiry
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// Put/Call
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<String>,

    /// Multiplier
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `reportDate` (added for full ibflex coverage)
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `dateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@dateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub date_time: Option<String>,

    /// `account` (added for full ibflex coverage)
    #[serde(
        rename = "@account",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account: Option<String>,

    /// `deliveringBroker` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveringBroker",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivering_broker: Option<String>,

    /// `capitalGainsPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@capitalGainsPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub capital_gains_pnl: Option<Decimal>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `clientReference` (added for full ibflex coverage)
    #[serde(
        rename = "@clientReference",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub client_reference: Option<String>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `company` (added for full ibflex coverage)
    #[serde(
        rename = "@company",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub company: Option<String>,

    /// `accountName` (added for full ibflex coverage)
    #[serde(
        rename = "@accountName",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_name: Option<String>,

    /// `pnlAmount` (added for full ibflex coverage)
    #[serde(
        rename = "@pnlAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub pnl_amount: Option<Decimal>,

    /// `pnlAmountInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@pnlAmountInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub pnl_amount_in_base: Option<Decimal>,

    /// `fxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@fxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_pnl: Option<Decimal>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `settleDate` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date: Option<NaiveDate>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `positionInstructionID` (added for full ibflex coverage)
    #[serde(
        rename = "@positionInstructionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub position_instruction_id: Option<String>,

    /// `positionInstructionSetID` (added for full ibflex coverage)
    #[serde(
        rename = "@positionInstructionSetID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub position_instruction_set_id: Option<String>,
}

// =============================================================================
// Performance Summary Types
// =============================================================================

/// Mark-to-market performance summary by underlying security
///
/// Provides MTM performance metrics for each security in the portfolio,
/// including realized and unrealized P&L, commissions, and transaction MTM.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct MTMPerformanceSummaryUnderlying {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Report date
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    // Security identifiers
    /// CUSIP
    #[serde(rename = "@cusip", default)]
    pub cusip: Option<String>,

    /// ISIN
    #[serde(rename = "@isin", default)]
    pub isin: Option<String>,

    /// Listing exchange
    #[serde(rename = "@listingExchange", default)]
    pub listing_exchange: Option<String>,

    /// Underlying symbol
    #[serde(rename = "@underlyingSymbol", default)]
    pub underlying_symbol: Option<String>,

    /// Underlying contract ID
    #[serde(rename = "@underlyingConid", default)]
    pub underlying_conid: Option<String>,

    /// Underlying listing exchange
    #[serde(rename = "@underlyingListingExchange", default)]
    pub underlying_listing_exchange: Option<String>,

    // P&L fields
    /// Cost adjustment
    #[serde(
        rename = "@costAdj",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost_adj: Option<Decimal>,

    /// Realized short-term profit
    #[serde(
        rename = "@realizedSTProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_st_profit: Option<Decimal>,

    /// Realized short-term loss
    #[serde(
        rename = "@realizedSTLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_st_loss: Option<Decimal>,

    /// Realized long-term profit
    #[serde(
        rename = "@realizedLTProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_lt_profit: Option<Decimal>,

    /// Realized long-term loss
    #[serde(
        rename = "@realizedLTLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_lt_loss: Option<Decimal>,

    /// Unrealized short-term profit
    #[serde(
        rename = "@unrealizedSTProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_st_profit: Option<Decimal>,

    /// Unrealized short-term loss
    #[serde(
        rename = "@unrealizedSTLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_st_loss: Option<Decimal>,

    /// Unrealized long-term profit
    #[serde(
        rename = "@unrealizedLTProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_lt_profit: Option<Decimal>,

    /// Unrealized long-term loss
    #[serde(
        rename = "@unrealizedLTLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_lt_loss: Option<Decimal>,

    /// Transaction MTM
    #[serde(
        rename = "@transactionMtm",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transaction_mtm: Option<Decimal>,

    /// Commissions
    #[serde(
        rename = "@commissions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commissions: Option<Decimal>,

    /// Other fees
    #[serde(
        rename = "@other",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other: Option<Decimal>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `prevCloseQuantity` (added for full ibflex coverage)
    #[serde(
        rename = "@prevCloseQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub prev_close_quantity: Option<Decimal>,

    /// `prevClosePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@prevClosePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub prev_close_price: Option<Decimal>,

    /// `closeQuantity` (added for full ibflex coverage)
    #[serde(
        rename = "@closeQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub close_quantity: Option<Decimal>,

    /// `closePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@closePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub close_price: Option<Decimal>,

    /// `priorOpenMtm` (added for full ibflex coverage)
    #[serde(
        rename = "@priorOpenMtm",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub prior_open_mtm: Option<Decimal>,

    /// `total` (added for full ibflex coverage)
    #[serde(
        rename = "@total",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total: Option<Decimal>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `corpActionMtm` (added for full ibflex coverage)
    #[serde(
        rename = "@corpActionMtm",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub corp_action_mtm: Option<Decimal>,

    /// `dividends` (added for full ibflex coverage)
    #[serde(
        rename = "@dividends",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub dividends: Option<Decimal>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `otherWithAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@otherWithAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_with_accruals: Option<Decimal>,

    /// `totalWithAccruals` (added for full ibflex coverage)
    #[serde(
        rename = "@totalWithAccruals",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_with_accruals: Option<Decimal>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,
}

/// FIFO performance summary by underlying security
///
/// Provides FIFO-based performance metrics including realized and unrealized
/// P&L calculated using FIFO cost basis method.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct FIFOPerformanceSummaryUnderlying {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Report date
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    // Security identifiers
    /// CUSIP
    #[serde(rename = "@cusip", default)]
    pub cusip: Option<String>,

    /// ISIN
    #[serde(rename = "@isin", default)]
    pub isin: Option<String>,

    /// Listing exchange
    #[serde(rename = "@listingExchange", default)]
    pub listing_exchange: Option<String>,

    /// Underlying symbol
    #[serde(rename = "@underlyingSymbol", default)]
    pub underlying_symbol: Option<String>,

    /// Underlying contract ID
    #[serde(rename = "@underlyingConid", default)]
    pub underlying_conid: Option<String>,

    // P&L fields
    /// Realized short-term P&L
    #[serde(
        rename = "@realizedShortTermPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_short_term_pnl: Option<Decimal>,

    /// Realized long-term P&L
    #[serde(
        rename = "@realizedLongTermPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_long_term_pnl: Option<Decimal>,

    /// Realized total P&L
    #[serde(
        rename = "@realizedTotalPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_total_pnl: Option<Decimal>,

    /// Unrealized short-term P&L
    #[serde(
        rename = "@unrealizedShortTermPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_short_term_pnl: Option<Decimal>,

    /// Unrealized long-term P&L
    #[serde(
        rename = "@unrealizedLongTermPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_long_term_pnl: Option<Decimal>,

    /// Unrealized total P&L
    #[serde(
        rename = "@unrealizedTotalPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_total_pnl: Option<Decimal>,

    /// Total income
    #[serde(
        rename = "@totalIncome",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_income: Option<Decimal>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `realizedSTProfit` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedSTProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_st_profit: Option<Decimal>,

    /// `realizedSTLoss` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedSTLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_st_loss: Option<Decimal>,

    /// `realizedLTProfit` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedLTProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_lt_profit: Option<Decimal>,

    /// `realizedLTLoss` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedLTLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_lt_loss: Option<Decimal>,

    /// `totalRealizedPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalRealizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_realized_pnl: Option<Decimal>,

    /// `unrealizedProfit` (added for full ibflex coverage)
    #[serde(
        rename = "@unrealizedProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_profit: Option<Decimal>,

    /// `unrealizedLoss` (added for full ibflex coverage)
    #[serde(
        rename = "@unrealizedLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_loss: Option<Decimal>,

    /// `totalUnrealizedPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalUnrealizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_unrealized_pnl: Option<Decimal>,

    /// `totalFifoPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalFifoPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_fifo_pnl: Option<Decimal>,

    /// `totalRealizedCapitalGainsPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalRealizedCapitalGainsPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_realized_capital_gains_pnl: Option<Decimal>,

    /// `totalRealizedFxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalRealizedFxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_realized_fx_pnl: Option<Decimal>,

    /// `totalUnrealizedCapitalGainsPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalUnrealizedCapitalGainsPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_unrealized_capital_gains_pnl: Option<Decimal>,

    /// `totalUnrealizedFxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalUnrealizedFxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_unrealized_fx_pnl: Option<Decimal>,

    /// `totalCapitalGainsPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalCapitalGainsPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_capital_gains_pnl: Option<Decimal>,

    /// `totalFxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@totalFxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_fx_pnl: Option<Decimal>,

    /// `transferredPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@transferredPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transferred_pnl: Option<Decimal>,

    /// `transferredCapitalGainsPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@transferredCapitalGainsPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transferred_capital_gains_pnl: Option<Decimal>,

    /// `transferredFxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@transferredFxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transferred_fx_pnl: Option<Decimal>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `unrealizedSTProfit` (added for full ibflex coverage)
    #[serde(
        rename = "@unrealizedSTProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_st_profit: Option<Decimal>,

    /// `unrealizedSTLoss` (added for full ibflex coverage)
    #[serde(
        rename = "@unrealizedSTLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_st_loss: Option<Decimal>,

    /// `unrealizedLTProfit` (added for full ibflex coverage)
    #[serde(
        rename = "@unrealizedLTProfit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_lt_profit: Option<Decimal>,

    /// `unrealizedLTLoss` (added for full ibflex coverage)
    #[serde(
        rename = "@unrealizedLTLoss",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_lt_loss: Option<Decimal>,

    /// `costAdj` (added for full ibflex coverage)
    #[serde(
        rename = "@costAdj",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost_adj: Option<Decimal>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,
}

/// Month-to-date/Year-to-date performance summary
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct MTDYTDPerformanceSummary {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    // MTD fields
    /// MTD realized P&L
    #[serde(
        rename = "@mtdRealizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtd_realized_pnl: Option<Decimal>,

    /// MTD unrealized P&L
    #[serde(
        rename = "@mtdUnrealizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtd_unrealized_pnl: Option<Decimal>,

    /// MTD commissions
    #[serde(
        rename = "@mtdCommissions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtd_commissions: Option<Decimal>,

    /// MTD fees
    #[serde(
        rename = "@mtdFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtd_fees: Option<Decimal>,

    // YTD fields
    /// YTD realized P&L
    #[serde(
        rename = "@ytdRealizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ytd_realized_pnl: Option<Decimal>,

    /// YTD unrealized P&L
    #[serde(
        rename = "@ytdUnrealizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ytd_unrealized_pnl: Option<Decimal>,

    /// YTD commissions
    #[serde(
        rename = "@ytdCommissions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ytd_commissions: Option<Decimal>,

    /// YTD fees
    #[serde(
        rename = "@ytdFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ytd_fees: Option<Decimal>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// `description` (added for full ibflex coverage)
    #[serde(
        rename = "@description",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub description: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `mtmMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_mtd: Option<Decimal>,

    /// `mtmYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_ytd: Option<Decimal>,

    /// `realSTMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realSTMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub real_stmtd: Option<Decimal>,

    /// `realSTYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realSTYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub real_stytd: Option<Decimal>,

    /// `realLTMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realLTMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub real_ltmtd: Option<Decimal>,

    /// `realLTYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realLTYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub real_ltytd: Option<Decimal>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `realizedPnlMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedPnlMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_pnl_mtd: Option<Decimal>,

    /// `realizedCapitalGainsPnlMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedCapitalGainsPnlMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_capital_gains_pnl_mtd: Option<Decimal>,

    /// `realizedFxPnlMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedFxPnlMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_fx_pnl_mtd: Option<Decimal>,

    /// `realizedPnlYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedPnlYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_pnl_ytd: Option<Decimal>,

    /// `realizedCapitalGainsPnlYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedCapitalGainsPnlYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_capital_gains_pnl_ytd: Option<Decimal>,

    /// `realizedFxPnlYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@realizedFxPnlYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_fx_pnl_ytd: Option<Decimal>,

    /// `brokerFees` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFees",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees: Option<Decimal>,

    /// `brokerFeesSec` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesSec",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_sec: Option<Decimal>,

    /// `brokerFeesCom` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesCom",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_com: Option<Decimal>,

    /// `brokerFeesMTD` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesMTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_mtd: Option<Decimal>,

    /// `brokerFeesYTD` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerFeesYTD",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_fees_ytd: Option<Decimal>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,
}

// =============================================================================
// Statement of Funds Types
// =============================================================================

/// Statement of funds line item
///
/// Represents a single cash flow entry in the statement of funds,
/// tracking debits and credits with running balance.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct StatementOfFundsLine {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Report date
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// Activity code
    #[serde(rename = "@activityCode", default)]
    pub activity_code: Option<String>,

    /// Activity description
    #[serde(rename = "@activityDescription", default)]
    pub activity_description: Option<String>,

    /// Trade ID
    #[serde(rename = "@tradeID", default)]
    pub trade_id: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Debit amount
    #[serde(
        rename = "@debit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub debit: Option<Decimal>,

    /// Credit amount
    #[serde(
        rename = "@credit",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub credit: Option<Decimal>,

    /// Amount
    #[serde(
        rename = "@amount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub amount: Option<Decimal>,

    /// Balance
    #[serde(
        rename = "@balance",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub balance: Option<Decimal>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// `assetCategory` (added for full ibflex coverage)
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// `buySell` (added for full ibflex coverage)
    #[serde(
        rename = "@buySell",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub buy_sell: Option<String>,

    /// `description` (added for full ibflex coverage)
    #[serde(
        rename = "@description",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub description: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `settleDate` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date: Option<NaiveDate>,

    /// `orderID` (added for full ibflex coverage)
    #[serde(
        rename = "@orderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub order_id: Option<String>,

    /// `tradeQuantity` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_quantity: Option<Decimal>,

    /// `tradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// `tradeGross` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeGross",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_gross: Option<Decimal>,

    /// `tradeCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_commission: Option<Decimal>,

    /// `tradeTax` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_tax: Option<Decimal>,

    /// `tradeCode` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_code: Option<String>,

    /// `transactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `actionID` (added for full ibflex coverage)
    #[serde(
        rename = "@actionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub action_id: Option<String>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `relatedTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_trade_id: Option<String>,

    /// `origTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_transaction_id: Option<String>,

    /// `relatedTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_transaction_id: Option<String>,
}

// =============================================================================
// Position Value Change Types
// =============================================================================

/// Change in position value for reconciliation
///
/// Tracks how position values changed due to various factors like
/// transactions, MTM changes, corporate actions, and FX translation.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct ChangeInPositionValue {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Report date
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// Prior period value
    #[serde(
        rename = "@priorPeriodValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub prior_period_value: Option<Decimal>,

    /// Transactions
    #[serde(
        rename = "@transactions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transactions: Option<Decimal>,

    /// MTM prior period positions
    #[serde(
        rename = "@mtmPriorPeriodPositions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_prior_period_positions: Option<Decimal>,

    /// MTM transactions
    #[serde(
        rename = "@mtmTransactions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_transactions: Option<Decimal>,

    /// Corporate actions
    #[serde(
        rename = "@corporateActions",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub corporate_actions: Option<Decimal>,

    /// FX translation
    #[serde(
        rename = "@fxTranslation",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation: Option<Decimal>,

    /// Other
    #[serde(
        rename = "@other",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other: Option<Decimal>,

    /// Ending value
    #[serde(
        rename = "@endingValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ending_value: Option<Decimal>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// `accountTransfers` (added for full ibflex coverage)
    #[serde(
        rename = "@accountTransfers",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub account_transfers: Option<Decimal>,

    /// `fxTranslationPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@fxTranslationPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_translation_pnl: Option<Decimal>,

    /// `futurePriceAdjustments` (added for full ibflex coverage)
    #[serde(
        rename = "@futurePriceAdjustments",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub future_price_adjustments: Option<Decimal>,

    /// `settledCash` (added for full ibflex coverage)
    #[serde(
        rename = "@settledCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub settled_cash: Option<Decimal>,

    /// `endOfPeriodValue` (added for full ibflex coverage)
    #[serde(
        rename = "@endOfPeriodValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub end_of_period_value: Option<Decimal>,

    /// `linkingAdjustments` (added for full ibflex coverage)
    #[serde(
        rename = "@linkingAdjustments",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub linking_adjustments: Option<Decimal>,
}

// =============================================================================
// Fee Detail Types
// =============================================================================

/// Unbundled commission detail
///
/// Breaks down commission charges into components: execution, clearing,
/// regulatory, third-party, and exchange fees.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct UnbundledCommissionDetail {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Execution ID
    #[serde(rename = "@execID", default)]
    pub exec_id: Option<String>,

    /// Order ID
    #[serde(rename = "@orderID", default)]
    pub order_id: Option<String>,

    /// Trade ID
    #[serde(rename = "@tradeID", default)]
    pub trade_id: Option<String>,

    /// Trade date/time (format: YYYYMMDD;HHMMSS)
    #[serde(rename = "@dateTime", default)]
    pub date_time: Option<String>,

    /// Exchange
    #[serde(rename = "@exchange", default)]
    pub exchange: Option<String>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Price
    #[serde(
        rename = "@price",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub price: Option<Decimal>,

    /// Execution commission
    #[serde(
        rename = "@executionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub execution_commission: Option<Decimal>,

    /// Clearing commission
    #[serde(
        rename = "@clearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub clearing_commission: Option<Decimal>,

    /// Regulatory commission
    #[serde(
        rename = "@regulatoryCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub regulatory_commission: Option<Decimal>,

    /// Third party commission
    #[serde(
        rename = "@thirdPartyCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_commission: Option<Decimal>,

    /// Third party regulatory commission
    #[serde(
        rename = "@thirdPartyRegulatoryCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_regulatory_commission: Option<Decimal>,

    /// Total commission
    #[serde(
        rename = "@totalCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_commission: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// `buySell` (added for full ibflex coverage)
    #[serde(rename = "@buySell", default)]
    pub buy_sell: Option<BuySell>,

    /// `fxRateToBase` (added for full ibflex coverage)
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `orderReference` (added for full ibflex coverage)
    #[serde(
        rename = "@orderReference",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub order_reference: Option<String>,

    /// `brokerExecutionCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerExecutionCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_execution_charge: Option<Decimal>,

    /// `brokerClearingCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerClearingCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_clearing_charge: Option<Decimal>,

    /// `thirdPartyExecutionCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyExecutionCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_execution_charge: Option<Decimal>,

    /// `thirdPartyClearingCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyClearingCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_clearing_charge: Option<Decimal>,

    /// `thirdPartyRegulatoryCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyRegulatoryCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_regulatory_charge: Option<Decimal>,

    /// `regFINRATradingActivityFee` (added for full ibflex coverage)
    #[serde(
        rename = "@regFINRATradingActivityFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub reg_finra_trading_activity_fee: Option<Decimal>,

    /// `regSection31TransactionFee` (added for full ibflex coverage)
    #[serde(
        rename = "@regSection31TransactionFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub reg_section31_transaction_fee: Option<Decimal>,

    /// `regOther` (added for full ibflex coverage)
    #[serde(
        rename = "@regOther",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub reg_other: Option<Decimal>,

    /// `other` (added for full ibflex coverage)
    #[serde(
        rename = "@other",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other: Option<Decimal>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub serial_number: Option<Decimal>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub delivery_type: Option<Decimal>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub weight: Option<Decimal>,
}

/// Client fee (advisory/service fees)
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct ClientFee {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// Revenue
    #[serde(
        rename = "@revenue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub revenue: Option<Decimal>,

    /// Expense
    #[serde(
        rename = "@expense",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub expense: Option<Decimal>,

    /// Net
    #[serde(
        rename = "@net",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net: Option<Decimal>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// `fxRateToBase` (added for full ibflex coverage)
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `feeType` (added for full ibflex coverage)
    #[serde(
        rename = "@feeType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub fee_type: Option<String>,

    /// `expenseIndicator` (added for full ibflex coverage)
    #[serde(
        rename = "@expenseIndicator",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub expense_indicator: Option<String>,

    /// `revenueInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@revenueInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub revenue_in_base: Option<Decimal>,

    /// `expenseInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@expenseInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub expense_in_base: Option<Decimal>,

    /// `netInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@netInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_in_base: Option<Decimal>,

    /// `tradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `execID` (added for full ibflex coverage)
    #[serde(
        rename = "@execID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exec_id: Option<String>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `assetCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@assetCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub asset_category: Option<String>,

    /// `settleDate` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDate",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub settle_date: Option<String>,

    /// `buySell` (added for full ibflex coverage)
    #[serde(
        rename = "@buySell",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub buy_sell: Option<String>,

    /// `quantity` (added for full ibflex coverage)
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub quantity: Option<String>,

    /// `tradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_price: Option<String>,

    /// `proceeds` (added for full ibflex coverage)
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub proceeds: Option<String>,

    /// `symbol` (added for full ibflex coverage)
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub multiplier: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,
}

/// Client fee detail
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct ClientFeesDetail {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// Fee type
    #[serde(rename = "@feeType", default)]
    pub fee_type: Option<String>,

    /// Revenue
    #[serde(
        rename = "@revenue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub revenue: Option<Decimal>,

    /// Expense
    #[serde(
        rename = "@expense",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub expense: Option<Decimal>,

    /// Net
    #[serde(
        rename = "@net",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net: Option<Decimal>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `tradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `execID` (added for full ibflex coverage)
    #[serde(
        rename = "@execID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exec_id: Option<String>,

    /// `totalRevenue` (added for full ibflex coverage)
    #[serde(
        rename = "@totalRevenue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_revenue: Option<Decimal>,

    /// `totalCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@totalCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_commission: Option<Decimal>,

    /// `brokerExecutionCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerExecutionCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_execution_charge: Option<Decimal>,

    /// `clearingCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@clearingCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub clearing_charge: Option<Decimal>,

    /// `thirdPartyExecutionCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyExecutionCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_execution_charge: Option<Decimal>,

    /// `thirdPartyRegulatoryCharge` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyRegulatoryCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_regulatory_charge: Option<Decimal>,

    /// `regFINRATradingActivityFee` (added for full ibflex coverage)
    #[serde(
        rename = "@regFINRATradingActivityFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub reg_finra_trading_activity_fee: Option<Decimal>,

    /// `regSection31TransactionFee` (added for full ibflex coverage)
    #[serde(
        rename = "@regSection31TransactionFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub reg_section31_transaction_fee: Option<Decimal>,

    /// `regOther` (added for full ibflex coverage)
    #[serde(
        rename = "@regOther",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub reg_other: Option<Decimal>,

    /// `totalNet` (added for full ibflex coverage)
    #[serde(
        rename = "@totalNet",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_net: Option<Decimal>,

    /// `totalNetInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@totalNetInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_net_in_base: Option<Decimal>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `other` (added for full ibflex coverage)
    #[serde(
        rename = "@other",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other: Option<Decimal>,
}

// =============================================================================
// Securities Lending Types
// =============================================================================

/// Securities lending/borrowing activity
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct SLBActivity {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Activity date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Activity type
    #[serde(rename = "@type", default)]
    pub activity_type: Option<String>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Collateral amount
    #[serde(
        rename = "@collateralAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub collateral_amount: Option<Decimal>,

    /// Fee/rate
    #[serde(
        rename = "@feeRate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fee_rate: Option<Decimal>,

    /// Net lend fee
    #[serde(
        rename = "@netLendFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_lend_fee: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `slbTransactionId` (added for full ibflex coverage)
    #[serde(
        rename = "@slbTransactionId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub slb_transaction_id: Option<String>,

    /// `activityDescription` (added for full ibflex coverage)
    #[serde(
        rename = "@activityDescription",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub activity_description: Option<String>,

    /// `exchange` (added for full ibflex coverage)
    #[serde(
        rename = "@exchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exchange: Option<String>,

    /// `markQuantity` (added for full ibflex coverage)
    #[serde(
        rename = "@markQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mark_quantity: Option<Decimal>,

    /// `markPriorPrice` (added for full ibflex coverage)
    #[serde(
        rename = "@markPriorPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mark_prior_price: Option<Decimal>,

    /// `markCurrentPrice` (added for full ibflex coverage)
    #[serde(
        rename = "@markCurrentPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mark_current_price: Option<Decimal>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub serial_number: Option<Decimal>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub delivery_type: Option<Decimal>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub weight: Option<Decimal>,
}

/// Securities lending fee
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct SLBFee {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Value date
    #[serde(
        rename = "@valueDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub value_date: Option<NaiveDate>,

    /// Start date
    #[serde(
        rename = "@startDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub start_date: Option<NaiveDate>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Collateral amount
    #[serde(
        rename = "@collateralAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub collateral_amount: Option<Decimal>,

    /// Fee rate
    #[serde(
        rename = "@feeRate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fee_rate: Option<Decimal>,

    /// Fee
    #[serde(
        rename = "@fee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fee: Option<Decimal>,

    /// Carry charge
    #[serde(
        rename = "@carryCharge",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub carry_charge: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,
}

/// Hard to borrow stock details
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct HardToBorrowDetail {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Value date
    #[serde(
        rename = "@valueDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub value_date: Option<NaiveDate>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Price
    #[serde(
        rename = "@price",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub price: Option<Decimal>,

    /// Value
    #[serde(
        rename = "@value",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub value: Option<Decimal>,

    /// Borrow fee rate
    #[serde(
        rename = "@borrowFeeRate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub borrow_fee_rate: Option<Decimal>,

    /// Borrow fee
    #[serde(
        rename = "@borrowFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub borrow_fee: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `fromAcct` (added for full ibflex coverage)
    #[serde(
        rename = "@fromAcct",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub from_acct: Option<String>,

    /// `toAcct` (added for full ibflex coverage)
    #[serde(
        rename = "@toAcct",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub to_acct: Option<String>,
}

// =============================================================================
// FX Lot Types
// =============================================================================

/// FX position lot detail
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct FxLot {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<String>,

    /// Report date
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// Functional currency
    #[serde(rename = "@functionalCurrency", default)]
    pub functional_currency: Option<String>,

    /// FX currency
    #[serde(rename = "@fxCurrency", default)]
    pub fx_currency: Option<String>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Cost price
    #[serde(
        rename = "@costPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost_price: Option<Decimal>,

    /// Cost basis
    #[serde(
        rename = "@costBasis",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost_basis: Option<Decimal>,

    /// Close price
    #[serde(
        rename = "@closePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub close_price: Option<Decimal>,

    /// Value
    #[serde(
        rename = "@value",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub value: Option<Decimal>,

    /// Unrealized P&L
    #[serde(
        rename = "@unrealizedPL",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub unrealized_pl: Option<Decimal>,

    /// Level of detail
    #[serde(rename = "@levelOfDetail", default)]
    pub level_of_detail: Option<String>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `lotDescription` (added for full ibflex coverage)
    #[serde(
        rename = "@lotDescription",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub lot_description: Option<String>,

    /// `lotOpenDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@lotOpenDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub lot_open_date_time: Option<String>,
}

// =============================================================================
// Transfer Types
// =============================================================================

/// Unsettled transfer
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct UnsettledTransfer {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Direction
    #[serde(rename = "@direction", default)]
    pub direction: Option<String>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Expected date
    #[serde(
        rename = "@expectedDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expected_date: Option<NaiveDate>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `stage` (added for full ibflex coverage)
    #[serde(
        rename = "@stage",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub stage: Option<String>,

    /// `tradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub trade_date: Option<NaiveDate>,

    /// `targetSettlement` (added for full ibflex coverage)
    #[serde(
        rename = "@targetSettlement",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub target_settlement: Option<NaiveDate>,

    /// `contra` (added for full ibflex coverage)
    #[serde(
        rename = "@contra",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub contra: Option<String>,

    /// `tradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// `tradeAmount` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_amount: Option<Decimal>,

    /// `tradeAmountInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeAmountInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_amount_in_base: Option<Decimal>,

    /// `transactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id: Option<String>,
}

/// Trade transfer between accounts/brokers
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct TradeTransfer {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Transfer type
    #[serde(rename = "@transferType", default)]
    pub transfer_type: Option<String>,

    /// Direction
    #[serde(rename = "@direction", default)]
    pub direction: Option<String>,

    /// Delivery type
    #[serde(rename = "@deliveryType", default)]
    pub delivery_type: Option<String>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Transfer price
    #[serde(
        rename = "@transferPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub transfer_price: Option<Decimal>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Executing broker
    #[serde(rename = "@executingBroker", default)]
    pub executing_broker: Option<String>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `transactionType` (added for full ibflex coverage)
    #[serde(rename = "@transactionType", default)]
    pub transaction_type: Option<TradeType>,

    /// `openCloseIndicator` (added for full ibflex coverage)
    #[serde(rename = "@openCloseIndicator", default)]
    pub open_close_indicator: Option<OpenClose>,

    /// `deliveredReceived` (added for full ibflex coverage)
    #[serde(rename = "@deliveredReceived", default)]
    pub delivered_received: Option<DeliveredReceived>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `tradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `reportDate` (added for full ibflex coverage)
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `tradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub trade_date: Option<NaiveDate>,

    /// `tradeTime` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_time: Option<String>,

    /// `settleDateTarget` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDateTarget",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date_target: Option<NaiveDate>,

    /// `exchange` (added for full ibflex coverage)
    #[serde(
        rename = "@exchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exchange: Option<String>,

    /// `tradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// `tradeMoney` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeMoney",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_money: Option<Decimal>,

    /// `taxes` (added for full ibflex coverage)
    #[serde(
        rename = "@taxes",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub taxes: Option<Decimal>,

    /// `ibCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ib_commission: Option<Decimal>,

    /// `ibCommissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_commission_currency: Option<String>,

    /// `closePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@closePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub close_price: Option<Decimal>,

    /// `notes` (added for full ibflex coverage)
    #[serde(
        rename = "@notes",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub notes: Option<String>,

    /// `cost` (added for full ibflex coverage)
    #[serde(
        rename = "@cost",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost: Option<Decimal>,

    /// `fifoPnlRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@fifoPnlRealized",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fifo_pnl_realized: Option<Decimal>,

    /// `mtmPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_pnl: Option<Decimal>,

    /// `brokerName` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerName",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub broker_name: Option<String>,

    /// `brokerAccount` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerAccount",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub broker_account: Option<String>,

    /// `awayBrokerCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@awayBrokerCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub away_broker_commission: Option<Decimal>,

    /// `regulatoryFee` (added for full ibflex coverage)
    #[serde(
        rename = "@regulatoryFee",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub regulatory_fee: Option<Decimal>,

    /// `netTradeMoney` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradeMoney",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trade_money: Option<Decimal>,

    /// `netTradeMoneyInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradeMoneyInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trade_money_in_base: Option<Decimal>,

    /// `netTradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@netTradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_trade_price: Option<Decimal>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `proceeds` (added for full ibflex coverage)
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub proceeds: Option<Decimal>,

    /// `fxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@fxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_pnl: Option<Decimal>,

    /// `netCash` (added for full ibflex coverage)
    #[serde(
        rename = "@netCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_cash: Option<Decimal>,

    /// `origTradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub orig_trade_price: Option<Decimal>,

    /// `origTradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub orig_trade_date: Option<NaiveDate>,

    /// `origTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_trade_id: Option<String>,

    /// `origOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@origOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_order_id: Option<String>,

    /// `clearingFirmID` (added for full ibflex coverage)
    #[serde(
        rename = "@clearingFirmID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub clearing_firm_id: Option<String>,

    /// `transactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id: Option<String>,

    /// `openDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@openDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub open_date_time: Option<String>,

    /// `holdingPeriodDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@holdingPeriodDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub holding_period_date_time: Option<String>,

    /// `whenRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@whenRealized",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_realized: Option<String>,

    /// `whenReopened` (added for full ibflex coverage)
    #[serde(
        rename = "@whenReopened",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_reopened: Option<String>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,
}

// =============================================================================
// Prior Period Types
// =============================================================================

/// Prior period position
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct PriorPeriodPosition {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Prior MTM P&L
    #[serde(
        rename = "@priorMtmPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub prior_mtm_pnl: Option<Decimal>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Quantity
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// Price
    #[serde(
        rename = "@price",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub price: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// `fxRateToBase` (added for full ibflex coverage)
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `sedol` (added for full ibflex coverage)
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub serial_number: Option<Decimal>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub delivery_type: Option<Decimal>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub weight: Option<Decimal>,
}

// =============================================================================
// Interest Detail Types
// =============================================================================

/// Tier interest detail
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct TierInterestDetail {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base currency
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// Interest type (e.g., "Debit Interest", "Short Credit Interest")
    #[serde(rename = "@interestType", default)]
    pub interest_type: Option<String>,

    /// Report date
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// Value date
    #[serde(
        rename = "@valueDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub value_date: Option<NaiveDate>,

    /// Tier break (Roman numerals like "I", "II", etc.)
    #[serde(rename = "@tierBreak", default)]
    pub tier_break: Option<String>,

    /// Balance threshold
    #[serde(
        rename = "@balanceThreshold",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub balance_threshold: Option<Decimal>,

    /// Securities principal
    #[serde(
        rename = "@securitiesPrincipal",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub securities_principal: Option<Decimal>,

    /// Commodities principal
    #[serde(
        rename = "@commoditiesPrincipal",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commodities_principal: Option<Decimal>,

    /// IBUKL principal
    #[serde(
        rename = "@ibuklPrincipal",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ibukl_principal: Option<Decimal>,

    /// Total principal
    #[serde(
        rename = "@totalPrincipal",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_principal: Option<Decimal>,

    /// Interest rate
    #[serde(
        rename = "@rate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub rate: Option<Decimal>,

    /// Securities interest
    #[serde(
        rename = "@securitiesInterest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub securities_interest: Option<Decimal>,

    /// Commodities interest
    #[serde(
        rename = "@commoditiesInterest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commodities_interest: Option<Decimal>,

    /// IBUKL interest
    #[serde(
        rename = "@ibuklInterest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ibukl_interest: Option<Decimal>,

    /// Total interest
    #[serde(
        rename = "@totalInterest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_interest: Option<Decimal>,

    /// Code
    #[serde(rename = "@code", default)]
    pub code: Option<String>,

    /// From account
    #[serde(rename = "@fromAcct", default)]
    pub from_acct: Option<String>,

    /// To account
    #[serde(rename = "@toAcct", default)]
    pub to_acct: Option<String>,

    /// Margin balance
    #[serde(rename = "@marginBalance", default)]
    pub margin_balance: Option<String>,

    // Legacy fields (may appear in older reports)
    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// From date
    #[serde(
        rename = "@fromDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub from_date: Option<NaiveDate>,

    /// To date
    #[serde(
        rename = "@toDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub to_date: Option<NaiveDate>,

    /// Balance (legacy)
    #[serde(
        rename = "@balance",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub balance: Option<Decimal>,

    /// Interest rate (legacy field name)
    #[serde(
        rename = "@interestRate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub interest_rate: Option<Decimal>,

    /// Interest (legacy)
    #[serde(
        rename = "@interest",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub interest: Option<Decimal>,
}

// =============================================================================
// Miscellaneous Activity Types
// =============================================================================

/// Debit card activity
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct DebitCardActivity {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Merchant
    #[serde(rename = "@merchant", default)]
    pub merchant: Option<String>,

    /// Category
    #[serde(rename = "@category", default)]
    pub category: Option<String>,

    /// Status
    #[serde(rename = "@status", default)]
    pub status: Option<String>,

    /// Transaction type
    #[serde(rename = "@transactionType", default)]
    pub transaction_type: Option<String>,

    /// Amount
    #[serde(
        rename = "@amount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub amount: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `assetCategory` (added for full ibflex coverage)
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// `reportDate` (added for full ibflex coverage)
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `postingDate` (added for full ibflex coverage)
    #[serde(
        rename = "@postingDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub posting_date: Option<NaiveDate>,

    /// `transactionDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_date_time: Option<String>,

    /// `merchantNameLocation` (added for full ibflex coverage)
    #[serde(
        rename = "@merchantNameLocation",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub merchant_name_location: Option<String>,
}

/// Sales tax
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct SalesTax {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Date
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Tax type
    #[serde(rename = "@taxType", default)]
    pub tax_type: Option<String>,

    /// Tax amount
    #[serde(
        rename = "@taxAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_amount: Option<Decimal>,

    /// Proceeds
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub proceeds: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// FX rate to base
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `assetCategory` (added for full ibflex coverage)
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `country` (added for full ibflex coverage)
    #[serde(
        rename = "@country",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub country: Option<String>,

    /// `payer` (added for full ibflex coverage)
    #[serde(
        rename = "@payer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub payer: Option<String>,

    /// `taxableDescription` (added for full ibflex coverage)
    #[serde(
        rename = "@taxableDescription",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub taxable_description: Option<String>,

    /// `taxableAmount` (added for full ibflex coverage)
    #[serde(
        rename = "@taxableAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub taxable_amount: Option<Decimal>,

    /// `taxRate` (added for full ibflex coverage)
    #[serde(
        rename = "@taxRate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_rate: Option<Decimal>,

    /// `salesTax` (added for full ibflex coverage)
    #[serde(
        rename = "@salesTax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub sales_tax: Option<Decimal>,

    /// `taxableTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@taxableTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub taxable_transaction_id: Option<String>,

    /// `transactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,
}

// =============================================================================
// Summary Types
// =============================================================================

/// Symbol summary (aggregated trading data by symbol)
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct SymbolSummary {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Total buy quantity
    #[serde(
        rename = "@totalBuyQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_buy_quantity: Option<Decimal>,

    /// Total sell quantity
    #[serde(
        rename = "@totalSellQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_sell_quantity: Option<Decimal>,

    /// Total buy value
    #[serde(
        rename = "@totalBuyValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_buy_value: Option<Decimal>,

    /// Total sell value
    #[serde(
        rename = "@totalSellValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_sell_value: Option<Decimal>,

    /// Total commission
    #[serde(
        rename = "@totalCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_commission: Option<Decimal>,

    /// Realized P&L
    #[serde(
        rename = "@realizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_pnl: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `transactionType` (added for full ibflex coverage)
    #[serde(rename = "@transactionType", default)]
    pub transaction_type: Option<TradeType>,

    /// `tradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `orderID` (added for full ibflex coverage)
    #[serde(
        rename = "@orderID",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub order_id: Option<Decimal>,

    /// `execID` (added for full ibflex coverage)
    #[serde(
        rename = "@execID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exec_id: Option<String>,

    /// `brokerageOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerageOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub brokerage_order_id: Option<String>,

    /// `orderReference` (added for full ibflex coverage)
    #[serde(
        rename = "@orderReference",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub order_reference: Option<String>,

    /// `volatilityOrderLink` (added for full ibflex coverage)
    #[serde(
        rename = "@volatilityOrderLink",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub volatility_order_link: Option<String>,

    /// `clearingFirmID` (added for full ibflex coverage)
    #[serde(
        rename = "@clearingFirmID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub clearing_firm_id: Option<String>,

    /// `origTradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub orig_trade_price: Option<Decimal>,

    /// `origTradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub orig_trade_date: Option<NaiveDate>,

    /// `origTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_trade_id: Option<String>,

    /// `orderTime` (added for full ibflex coverage)
    #[serde(
        rename = "@orderTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub order_time: Option<String>,

    /// `dateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@dateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub date_time: Option<String>,

    /// `reportDate` (added for full ibflex coverage)
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `settleDate` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date: Option<NaiveDate>,

    /// `tradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub trade_date: Option<NaiveDate>,

    /// `exchange` (added for full ibflex coverage)
    #[serde(
        rename = "@exchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exchange: Option<String>,

    /// `buySell` (added for full ibflex coverage)
    #[serde(rename = "@buySell", default)]
    pub buy_sell: Option<BuySell>,

    /// `quantity` (added for full ibflex coverage)
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// `price` (added for full ibflex coverage)
    #[serde(
        rename = "@price",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub price: Option<Decimal>,

    /// `amount` (added for full ibflex coverage)
    #[serde(
        rename = "@amount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub amount: Option<Decimal>,

    /// `proceeds` (added for full ibflex coverage)
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub proceeds: Option<Decimal>,

    /// `commission` (added for full ibflex coverage)
    #[serde(
        rename = "@commission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission: Option<Decimal>,

    /// `brokerExecutionCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerExecutionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_execution_commission: Option<Decimal>,

    /// `brokerClearingCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerClearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_clearing_commission: Option<Decimal>,

    /// `thirdPartyExecutionCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyExecutionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_execution_commission: Option<Decimal>,

    /// `thirdPartyClearingCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyClearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_clearing_commission: Option<Decimal>,

    /// `thirdPartyRegulatoryCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyRegulatoryCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_regulatory_commission: Option<Decimal>,

    /// `otherCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@otherCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_commission: Option<Decimal>,

    /// `commissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commission_currency: Option<String>,

    /// `tax` (added for full ibflex coverage)
    #[serde(
        rename = "@tax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax: Option<Decimal>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `orderType` (added for full ibflex coverage)
    #[serde(rename = "@orderType", default)]
    pub order_type: Option<OrderType>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `traderID` (added for full ibflex coverage)
    #[serde(
        rename = "@traderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trader_id: Option<String>,

    /// `isAPIOrder` (added for full ibflex coverage)
    #[serde(
        rename = "@isAPIOrder",
        default,
        deserialize_with = "deserialize_optional_bool"
    )]
    pub is_api_order: Option<bool>,

    /// `allocatedTo` (added for full ibflex coverage)
    #[serde(
        rename = "@allocatedTo",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub allocated_to: Option<String>,

    /// `accruedInt` (added for full ibflex coverage)
    #[serde(
        rename = "@accruedInt",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub accrued_int: Option<Decimal>,

    /// `fxRateToBase` (added for full ibflex coverage)
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `relatedTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_trade_id: Option<String>,

    /// `origTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_transaction_id: Option<String>,

    /// `relatedTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_transaction_id: Option<String>,

    /// `positionActionID` (added for full ibflex coverage)
    #[serde(
        rename = "@positionActionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub position_action_id: Option<String>,

    /// `ibExecID` (added for full ibflex coverage)
    #[serde(
        rename = "@ibExecID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_exec_id: Option<String>,

    /// `extExecID` (added for full ibflex coverage)
    #[serde(
        rename = "@extExecID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ext_exec_id: Option<String>,

    /// `exchOrderId` (added for full ibflex coverage)
    #[serde(
        rename = "@exchOrderId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exch_order_id: Option<String>,

    /// `transactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id: Option<String>,

    /// `openDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@openDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub open_date_time: Option<String>,

    /// `holdingPeriodDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@holdingPeriodDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub holding_period_date_time: Option<String>,

    /// `settleDateTarget` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDateTarget",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date_target: Option<NaiveDate>,

    /// `taxes` (added for full ibflex coverage)
    #[serde(
        rename = "@taxes",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub taxes: Option<Decimal>,

    /// `tradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// `tradeMoney` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeMoney",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_money: Option<Decimal>,

    /// `changeInPrice` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_price: Option<Decimal>,

    /// `changeInQuantity` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_quantity: Option<Decimal>,

    /// `closePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@closePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub close_price: Option<Decimal>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `cost` (added for full ibflex coverage)
    #[serde(
        rename = "@cost",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost: Option<Decimal>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `fifoPnlRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@fifoPnlRealized",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fifo_pnl_realized: Option<Decimal>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `ibCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ib_commission: Option<Decimal>,

    /// `ibCommissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_commission_currency: Option<String>,

    /// `ibOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@ibOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_order_id: Option<String>,

    /// `initialInvestment` (added for full ibflex coverage)
    #[serde(
        rename = "@initialInvestment",
        default,
        deserialize_with = "deserialize_optional_bool"
    )]
    pub initial_investment: Option<bool>,

    /// `mtmPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_pnl: Option<Decimal>,

    /// `netCash` (added for full ibflex coverage)
    #[serde(
        rename = "@netCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_cash: Option<Decimal>,

    /// `netCashInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@netCashInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_cash_in_base: Option<Decimal>,

    /// `notes` (added for full ibflex coverage)
    #[serde(
        rename = "@notes",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub notes: Option<String>,

    /// `openCloseIndicator` (added for full ibflex coverage)
    #[serde(rename = "@openCloseIndicator", default)]
    pub open_close_indicator: Option<OpenClose>,

    /// `origOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@origOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_order_id: Option<String>,

    /// `rtn` (added for full ibflex coverage)
    #[serde(
        rename = "@rtn",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub rtn: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `whenRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@whenRealized",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_realized: Option<String>,

    /// `whenReopened` (added for full ibflex coverage)
    #[serde(
        rename = "@whenReopened",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_reopened: Option<String>,
}

/// Asset summary (aggregated trading data by asset class)
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct AssetSummary {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Total buy quantity
    #[serde(
        rename = "@totalBuyQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_buy_quantity: Option<Decimal>,

    /// Total sell quantity
    #[serde(
        rename = "@totalSellQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_sell_quantity: Option<Decimal>,

    /// Total buy value
    #[serde(
        rename = "@totalBuyValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_buy_value: Option<Decimal>,

    /// Total sell value
    #[serde(
        rename = "@totalSellValue",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_sell_value: Option<Decimal>,

    /// Total commission
    #[serde(
        rename = "@totalCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total_commission: Option<Decimal>,

    /// Realized P&L
    #[serde(
        rename = "@realizedPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub realized_pnl: Option<Decimal>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// `symbol` (added for full ibflex coverage)
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// `description` (added for full ibflex coverage)
    #[serde(
        rename = "@description",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub description: Option<String>,

    /// `conid` (added for full ibflex coverage)
    #[serde(
        rename = "@conid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub conid: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `transactionType` (added for full ibflex coverage)
    #[serde(rename = "@transactionType", default)]
    pub transaction_type: Option<TradeType>,

    /// `tradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `orderID` (added for full ibflex coverage)
    #[serde(
        rename = "@orderID",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub order_id: Option<Decimal>,

    /// `execID` (added for full ibflex coverage)
    #[serde(
        rename = "@execID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exec_id: Option<String>,

    /// `brokerageOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerageOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub brokerage_order_id: Option<String>,

    /// `orderReference` (added for full ibflex coverage)
    #[serde(
        rename = "@orderReference",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub order_reference: Option<String>,

    /// `volatilityOrderLink` (added for full ibflex coverage)
    #[serde(
        rename = "@volatilityOrderLink",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub volatility_order_link: Option<String>,

    /// `clearingFirmID` (added for full ibflex coverage)
    #[serde(
        rename = "@clearingFirmID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub clearing_firm_id: Option<String>,

    /// `origTradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub orig_trade_price: Option<Decimal>,

    /// `TradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@TradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// `tradeMoney` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeMoney",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_money: Option<Decimal>,

    /// `taxes` (added for full ibflex coverage)
    #[serde(
        rename = "@taxes",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub taxes: Option<Decimal>,

    /// `origTradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub orig_trade_date: Option<NaiveDate>,

    /// `origTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_trade_id: Option<String>,

    /// `tradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price_trad: Option<Decimal>,

    /// `orderTime` (added for full ibflex coverage)
    #[serde(
        rename = "@orderTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub order_time: Option<String>,

    /// `exchOrderId` (added for full ibflex coverage)
    #[serde(
        rename = "@exchOrderId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exch_order_id: Option<String>,

    /// `dateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@dateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub date_time: Option<String>,

    /// `fxRateToBase` (added for full ibflex coverage)
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `reportDate` (added for full ibflex coverage)
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `ibExecID` (added for full ibflex coverage)
    #[serde(
        rename = "@ibExecID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_exec_id: Option<String>,

    /// `settleDateTarget` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDateTarget",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date_target: Option<NaiveDate>,

    /// `cost` (added for full ibflex coverage)
    #[serde(
        rename = "@cost",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost: Option<Decimal>,

    /// `extExecID` (added for full ibflex coverage)
    #[serde(
        rename = "@extExecID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ext_exec_id: Option<String>,

    /// `openDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@openDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub open_date_time: Option<String>,

    /// `holdingPeriodDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@holdingPeriodDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub holding_period_date_time: Option<String>,

    /// `whenRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@whenRealized",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_realized: Option<String>,

    /// `whenReopened` (added for full ibflex coverage)
    #[serde(
        rename = "@whenReopened",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_reopened: Option<String>,

    /// `changeInPrice` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_price: Option<Decimal>,

    /// `changeInQuantity` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_quantity: Option<Decimal>,

    /// `ibOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@ibOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_order_id: Option<String>,

    /// `origOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@origOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_order_id: Option<String>,

    /// `transactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id: Option<String>,

    /// `tradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub trade_date: Option<NaiveDate>,

    /// `openCloseIndicator` (added for full ibflex coverage)
    #[serde(rename = "@openCloseIndicator", default)]
    pub open_close_indicator: Option<OpenClose>,

    /// `notes` (added for full ibflex coverage)
    #[serde(
        rename = "@notes",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub notes: Option<String>,

    /// `fxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@fxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_pnl: Option<Decimal>,

    /// `mtmPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_pnl: Option<Decimal>,

    /// `fifoPnlRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@fifoPnlRealized",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fifo_pnl_realized: Option<Decimal>,

    /// `closePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@closePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub close_price: Option<Decimal>,

    /// `exchange` (added for full ibflex coverage)
    #[serde(
        rename = "@exchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exchange: Option<String>,

    /// `ibCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ib_commission: Option<Decimal>,

    /// `ibCommissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_commission_currency: Option<String>,

    /// `netCash` (added for full ibflex coverage)
    #[serde(
        rename = "@netCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_cash: Option<Decimal>,

    /// `netCashInBase` (added for full ibflex coverage)
    #[serde(
        rename = "@netCashInBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_cash_in_base: Option<Decimal>,

    /// `buySell` (added for full ibflex coverage)
    #[serde(rename = "@buySell", default)]
    pub buy_sell: Option<BuySell>,

    /// `quantity` (added for full ibflex coverage)
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// `price` (added for full ibflex coverage)
    #[serde(
        rename = "@price",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub price: Option<Decimal>,

    /// `amount` (added for full ibflex coverage)
    #[serde(
        rename = "@amount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub amount: Option<Decimal>,

    /// `proceeds` (added for full ibflex coverage)
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub proceeds: Option<Decimal>,

    /// `commission` (added for full ibflex coverage)
    #[serde(
        rename = "@commission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission: Option<Decimal>,

    /// `brokerExecutionCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerExecutionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_execution_commission: Option<Decimal>,

    /// `brokerClearingCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerClearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_clearing_commission: Option<Decimal>,

    /// `thirdPartyExecutionCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyExecutionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_execution_commission: Option<Decimal>,

    /// `thirdPartyClearingCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyClearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_clearing_commission: Option<Decimal>,

    /// `thirdPartyRegulatoryCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyRegulatoryCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_regulatory_commission: Option<Decimal>,

    /// `otherCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@otherCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_commission: Option<Decimal>,

    /// `commissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commission_currency: Option<String>,

    /// `tax` (added for full ibflex coverage)
    #[serde(
        rename = "@tax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax: Option<Decimal>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `orderType` (added for full ibflex coverage)
    #[serde(rename = "@orderType", default)]
    pub order_type: Option<OrderType>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `traderID` (added for full ibflex coverage)
    #[serde(
        rename = "@traderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trader_id: Option<String>,

    /// `isAPIOrder` (added for full ibflex coverage)
    #[serde(
        rename = "@isAPIOrder",
        default,
        deserialize_with = "deserialize_optional_bool"
    )]
    pub is_api_order: Option<bool>,

    /// `allocatedTo` (added for full ibflex coverage)
    #[serde(
        rename = "@allocatedTo",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub allocated_to: Option<String>,

    /// `accruedInt` (added for full ibflex coverage)
    #[serde(
        rename = "@accruedInt",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub accrued_int: Option<Decimal>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `relatedTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_trade_id: Option<String>,

    /// `origTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_transaction_id: Option<String>,

    /// `relatedTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_transaction_id: Option<String>,

    /// `rtn` (added for full ibflex coverage)
    #[serde(
        rename = "@rtn",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub rtn: Option<String>,

    /// `initialInvestment` (added for full ibflex coverage)
    #[serde(
        rename = "@initialInvestment",
        default,
        deserialize_with = "deserialize_optional_bool"
    )]
    pub initial_investment: Option<bool>,

    /// `positionActionID` (added for full ibflex coverage)
    #[serde(
        rename = "@positionActionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub position_action_id: Option<String>,
}

/// Order record
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Order {
    /// Account ID
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// Account alias
    #[serde(rename = "@acctAlias", default)]
    pub acct_alias: Option<String>,

    /// Model
    #[serde(rename = "@model", default)]
    pub model: Option<String>,

    /// Order ID
    #[serde(rename = "@orderID", default)]
    pub order_id: Option<String>,

    /// Symbol
    #[serde(rename = "@symbol", default)]
    pub symbol: Option<String>,

    /// Description
    #[serde(rename = "@description", default)]
    pub description: Option<String>,

    /// Contract ID
    #[serde(rename = "@conid", default)]
    pub conid: Option<String>,

    /// Asset category
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// Order time
    #[serde(rename = "@orderTime", default)]
    pub order_time: Option<String>,

    /// Order type
    #[serde(rename = "@orderType", default)]
    pub order_type: Option<String>,

    /// Side (buy/sell)
    #[serde(rename = "@side", default)]
    pub side: Option<String>,

    /// Time in force
    #[serde(rename = "@tif", default)]
    pub tif: Option<String>,

    /// Order quantity
    #[serde(
        rename = "@orderQty",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub order_qty: Option<Decimal>,

    /// Limit price
    #[serde(
        rename = "@limitPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub limit_price: Option<Decimal>,

    /// Stop price
    #[serde(
        rename = "@stopPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub stop_price: Option<Decimal>,

    /// Filled quantity
    #[serde(
        rename = "@filledQty",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub filled_qty: Option<Decimal>,

    /// Average fill price
    #[serde(
        rename = "@avgPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub avg_price: Option<Decimal>,

    /// Remaining quantity
    #[serde(
        rename = "@remainingQty",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub remaining_qty: Option<Decimal>,

    /// Order status
    #[serde(rename = "@status", default)]
    pub status: Option<String>,

    /// Currency
    #[serde(rename = "@currency", default)]
    pub currency: Option<String>,

    /// `securityID` (added for full ibflex coverage)
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType` (added for full ibflex coverage)
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip` (added for full ibflex coverage)
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin` (added for full ibflex coverage)
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingSecurityID` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange` (added for full ibflex coverage)
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer` (added for full ibflex coverage)
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier` (added for full ibflex coverage)
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike` (added for full ibflex coverage)
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry` (added for full ibflex coverage)
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall` (added for full ibflex coverage)
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor` (added for full ibflex coverage)
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `transactionType` (added for full ibflex coverage)
    #[serde(rename = "@transactionType", default)]
    pub transaction_type: Option<TradeType>,

    /// `tradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `execID` (added for full ibflex coverage)
    #[serde(
        rename = "@execID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exec_id: Option<String>,

    /// `brokerageOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerageOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub brokerage_order_id: Option<String>,

    /// `orderReference` (added for full ibflex coverage)
    #[serde(
        rename = "@orderReference",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub order_reference: Option<String>,

    /// `volatilityOrderLink` (added for full ibflex coverage)
    #[serde(
        rename = "@volatilityOrderLink",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub volatility_order_link: Option<String>,

    /// `clearingFirmID` (added for full ibflex coverage)
    #[serde(
        rename = "@clearingFirmID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub clearing_firm_id: Option<String>,

    /// `origTradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub orig_trade_price: Option<Decimal>,

    /// `origTradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub orig_trade_date: Option<NaiveDate>,

    /// `origTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_trade_id: Option<String>,

    /// `dateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@dateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub date_time: Option<String>,

    /// `reportDate` (added for full ibflex coverage)
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `settleDate` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date: Option<NaiveDate>,

    /// `tradeDate` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub trade_date: Option<NaiveDate>,

    /// `exchange` (added for full ibflex coverage)
    #[serde(
        rename = "@exchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exchange: Option<String>,

    /// `buySell` (added for full ibflex coverage)
    #[serde(rename = "@buySell", default)]
    pub buy_sell: Option<BuySell>,

    /// `quantity` (added for full ibflex coverage)
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// `price` (added for full ibflex coverage)
    #[serde(
        rename = "@price",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub price: Option<Decimal>,

    /// `amount` (added for full ibflex coverage)
    #[serde(
        rename = "@amount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub amount: Option<Decimal>,

    /// `proceeds` (added for full ibflex coverage)
    #[serde(
        rename = "@proceeds",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub proceeds: Option<Decimal>,

    /// `commission` (added for full ibflex coverage)
    #[serde(
        rename = "@commission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub commission: Option<Decimal>,

    /// `brokerExecutionCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerExecutionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_execution_commission: Option<Decimal>,

    /// `brokerClearingCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@brokerClearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub broker_clearing_commission: Option<Decimal>,

    /// `thirdPartyExecutionCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyExecutionCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_execution_commission: Option<Decimal>,

    /// `thirdPartyClearingCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyClearingCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_clearing_commission: Option<Decimal>,

    /// `thirdPartyRegulatoryCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@thirdPartyRegulatoryCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub third_party_regulatory_commission: Option<Decimal>,

    /// `otherCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@otherCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub other_commission: Option<Decimal>,

    /// `commissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@commissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commission_currency: Option<String>,

    /// `tax` (added for full ibflex coverage)
    #[serde(
        rename = "@tax",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax: Option<Decimal>,

    /// `code` (added for full ibflex coverage)
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `levelOfDetail` (added for full ibflex coverage)
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `traderID` (added for full ibflex coverage)
    #[serde(
        rename = "@traderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trader_id: Option<String>,

    /// `isAPIOrder` (added for full ibflex coverage)
    #[serde(
        rename = "@isAPIOrder",
        default,
        deserialize_with = "deserialize_optional_bool"
    )]
    pub is_api_order: Option<bool>,

    /// `allocatedTo` (added for full ibflex coverage)
    #[serde(
        rename = "@allocatedTo",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub allocated_to: Option<String>,

    /// `accruedInt` (added for full ibflex coverage)
    #[serde(
        rename = "@accruedInt",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub accrued_int: Option<Decimal>,

    /// `netCash` (added for full ibflex coverage)
    #[serde(
        rename = "@netCash",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_cash: Option<Decimal>,

    /// `tradePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// `ibCommission` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommission",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub ib_commission: Option<Decimal>,

    /// `ibOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@ibOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_order_id: Option<String>,

    /// `fxRateToBase` (added for full ibflex coverage)
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `settleDateTarget` (added for full ibflex coverage)
    #[serde(
        rename = "@settleDateTarget",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub settle_date_target: Option<NaiveDate>,

    /// `tradeMoney` (added for full ibflex coverage)
    #[serde(
        rename = "@tradeMoney",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_money: Option<Decimal>,

    /// `taxes` (added for full ibflex coverage)
    #[serde(
        rename = "@taxes",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub taxes: Option<Decimal>,

    /// `ibCommissionCurrency` (added for full ibflex coverage)
    #[serde(
        rename = "@ibCommissionCurrency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_commission_currency: Option<String>,

    /// `closePrice` (added for full ibflex coverage)
    #[serde(
        rename = "@closePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub close_price: Option<Decimal>,

    /// `openCloseIndicator` (added for full ibflex coverage)
    #[serde(rename = "@openCloseIndicator", default)]
    pub open_close_indicator: Option<OpenClose>,

    /// `notes` (added for full ibflex coverage)
    #[serde(
        rename = "@notes",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub notes: Option<String>,

    /// `cost` (added for full ibflex coverage)
    #[serde(
        rename = "@cost",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub cost: Option<Decimal>,

    /// `fifoPnlRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@fifoPnlRealized",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fifo_pnl_realized: Option<Decimal>,

    /// `fxPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@fxPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_pnl: Option<Decimal>,

    /// `mtmPnl` (added for full ibflex coverage)
    #[serde(
        rename = "@mtmPnl",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub mtm_pnl: Option<Decimal>,

    /// `origOrderID` (added for full ibflex coverage)
    #[serde(
        rename = "@origOrderID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_order_id: Option<String>,

    /// `transactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@transactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id: Option<String>,

    /// `ibExecID` (added for full ibflex coverage)
    #[serde(
        rename = "@ibExecID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ib_exec_id: Option<String>,

    /// `exchOrderId` (added for full ibflex coverage)
    #[serde(
        rename = "@exchOrderId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exch_order_id: Option<String>,

    /// `extExecID` (added for full ibflex coverage)
    #[serde(
        rename = "@extExecID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub ext_exec_id: Option<String>,

    /// `openDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@openDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub open_date_time: Option<String>,

    /// `holdingPeriodDateTime` (added for full ibflex coverage)
    #[serde(
        rename = "@holdingPeriodDateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub holding_period_date_time: Option<String>,

    /// `whenRealized` (added for full ibflex coverage)
    #[serde(
        rename = "@whenRealized",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_realized: Option<String>,

    /// `whenReopened` (added for full ibflex coverage)
    #[serde(
        rename = "@whenReopened",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub when_reopened: Option<String>,

    /// `changeInPrice` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInPrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_price: Option<Decimal>,

    /// `changeInQuantity` (added for full ibflex coverage)
    #[serde(
        rename = "@changeInQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub change_in_quantity: Option<Decimal>,

    /// `subCategory` (added for full ibflex coverage)
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi` (added for full ibflex coverage)
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode` (added for full ibflex coverage)
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `relatedTradeID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_trade_id: Option<String>,

    /// `origTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@origTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub orig_transaction_id: Option<String>,

    /// `relatedTransactionID` (added for full ibflex coverage)
    #[serde(
        rename = "@relatedTransactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub related_transaction_id: Option<String>,

    /// `rtn` (added for full ibflex coverage)
    #[serde(
        rename = "@rtn",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub rtn: Option<String>,

    /// `initialInvestment` (added for full ibflex coverage)
    #[serde(
        rename = "@initialInvestment",
        default,
        deserialize_with = "deserialize_optional_bool"
    )]
    pub initial_investment: Option<bool>,

    /// `serialNumber` (added for full ibflex coverage)
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType` (added for full ibflex coverage)
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType` (added for full ibflex coverage)
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness` (added for full ibflex coverage)
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight` (added for full ibflex coverage)
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `positionActionID` (added for full ibflex coverage)
    #[serde(
        rename = "@positionActionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub position_action_id: Option<String>,
}

/// Net stock position combining long stock and option-equivalent exposure.
///
/// Mirrors the ibflex `NetStockPosition` element; all attributes are optional as IB may
/// omit any of them.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct NetStockPosition {
    /// `assetCategory`
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// `accountId`
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// `acctAlias`
    #[serde(
        rename = "@acctAlias",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub acct_alias: Option<String>,

    /// `model`
    #[serde(
        rename = "@model",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub model: Option<String>,

    /// `currency`
    #[serde(
        rename = "@currency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub currency: Option<String>,

    /// `symbol`
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// `description`
    #[serde(
        rename = "@description",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub description: Option<String>,

    /// `conid`
    #[serde(
        rename = "@conid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub conid: Option<String>,

    /// `securityID`
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType`
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip`
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin`
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `sedol`
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `listingExchange`
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid`
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol`
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingSecurityID`
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange`
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer`
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier`
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike`
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry`
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall`
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor`
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `reportDate`
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `sharesAtIb`
    #[serde(
        rename = "@sharesAtIb",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub shares_at_ib: Option<Decimal>,

    /// `sharesBorrowed`
    #[serde(
        rename = "@sharesBorrowed",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub shares_borrowed: Option<Decimal>,

    /// `sharesLent`
    #[serde(
        rename = "@sharesLent",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub shares_lent: Option<Decimal>,

    /// `netShares`
    #[serde(
        rename = "@netShares",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub net_shares: Option<Decimal>,

    /// `serialNumber`
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType`
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType`
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness`
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight`
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub weight: Option<String>,

    /// `subCategory`
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `figi`
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `issuerCountryCode`
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,
}

/// Per-transaction tax detail (e.g. UK stamp duty, financial transaction taxes).
///
/// Mirrors the ibflex `TransactionTax` element; all attributes are optional as IB may
/// omit any of them.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct TransactionTax {
    /// `accountId`
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// `acctAlias`
    #[serde(
        rename = "@acctAlias",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub acct_alias: Option<String>,

    /// `model`
    #[serde(
        rename = "@model",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub model: Option<String>,

    /// `currency`
    #[serde(
        rename = "@currency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub currency: Option<String>,

    /// `fxRateToBase`
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `assetCategory`
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// `symbol`
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// `description`
    #[serde(
        rename = "@description",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub description: Option<String>,

    /// `conid`
    #[serde(
        rename = "@conid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub conid: Option<String>,

    /// `securityID`
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType`
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip`
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin`
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange`
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid`
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSecurityID`
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingSymbol`
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingListingExchange`
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer`
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier`
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike`
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry`
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall`
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor`
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `date`
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub date: Option<String>,

    /// `taxDescription`
    #[serde(
        rename = "@taxDescription",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub tax_description: Option<String>,

    /// `quantity`
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// `reportDate`
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `taxAmount`
    #[serde(
        rename = "@taxAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub tax_amount: Option<Decimal>,

    /// `tradeId`
    #[serde(
        rename = "@tradeId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `tradePrice`
    #[serde(
        rename = "@tradePrice",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub trade_price: Option<Decimal>,

    /// `source`
    #[serde(
        rename = "@source",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub source: Option<String>,

    /// `code`
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `levelOfDetail`
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,
}

/// Contract-for-difference financing charge.
///
/// Mirrors the ibflex `CFDCharge` element; all attributes are optional as IB may
/// omit any of them.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct CFDCharge {
    /// `assetCategory`
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// `accountId`
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// `currency`
    #[serde(
        rename = "@currency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub currency: Option<String>,

    /// `fxRateToBase`
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `description`
    #[serde(
        rename = "@description",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub description: Option<String>,

    /// `conid`
    #[serde(
        rename = "@conid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub conid: Option<String>,

    /// `securityID`
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `cusip`
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin`
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `listingExchange`
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid`
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSecurityID`
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange`
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `amount`
    #[serde(
        rename = "@amount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub amount: Option<Decimal>,

    /// `dateTime`
    #[serde(
        rename = "@dateTime",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub date_time: Option<String>,

    /// `sedol`
    #[serde(
        rename = "@sedol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sedol: Option<String>,

    /// `symbol`
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// `securityIDType`
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `underlyingSymbol`
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `issuer`
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `multiplier`
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike`
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry`
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall`
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor`
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `tradeID`
    #[serde(
        rename = "@tradeID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub trade_id: Option<String>,

    /// `code`
    #[serde(
        rename = "@code",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub code: Option<String>,

    /// `transactionID`
    #[serde(
        rename = "@transactionID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id: Option<String>,

    /// `reportDate`
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `date`
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// `received`
    #[serde(
        rename = "@received",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub received: Option<Decimal>,

    /// `paid`
    #[serde(
        rename = "@paid",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub paid: Option<Decimal>,

    /// `total`
    #[serde(
        rename = "@total",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub total: Option<Decimal>,

    /// `transactionId`
    #[serde(
        rename = "@transactionId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub transaction_id_lc: Option<String>,

    /// `activityDescription`
    #[serde(
        rename = "@activityDescription",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub activity_description: Option<String>,

    /// `clientReference`
    #[serde(
        rename = "@clientReference",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub client_reference: Option<String>,

    /// `acctAlias`
    #[serde(
        rename = "@acctAlias",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub acct_alias: Option<String>,

    /// `model`
    #[serde(
        rename = "@model",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub model: Option<String>,

    /// `levelOfDetail`
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,
}

/// Open stock-loan/borrow contract.
///
/// Mirrors the ibflex `SLBOpenContract` element; all attributes are optional as IB may
/// omit any of them.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct SLBOpenContract {
    /// `accountId`
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// `acctAlias`
    #[serde(
        rename = "@acctAlias",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub acct_alias: Option<String>,

    /// `model`
    #[serde(
        rename = "@model",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub model: Option<String>,

    /// `currency`
    #[serde(
        rename = "@currency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub currency: Option<String>,

    /// `fxRateToBase`
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `description`
    #[serde(
        rename = "@description",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub description: Option<String>,

    /// `conid`
    #[serde(
        rename = "@conid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub conid: Option<String>,

    /// `securityID`
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `cusip`
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin`
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `assetCategory`
    #[serde(
        rename = "@assetCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub asset_category: Option<String>,

    /// `subCategory`
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `symbol`
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// `securityIDType`
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `figi`
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `listingExchange`
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid`
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol`
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingSecurityID`
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange`
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer`
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `issuerCountryCode`
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `multiplier`
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike`
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry`
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall`
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor`
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `date`
    #[serde(
        rename = "@date",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub date: Option<NaiveDate>,

    /// `type`
    #[serde(
        rename = "@type",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub r#type: Option<String>,

    /// `slbTransactionId`
    #[serde(
        rename = "@slbTransactionId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub slb_transaction_id: Option<String>,

    /// `exchange`
    #[serde(
        rename = "@exchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub exchange: Option<String>,

    /// `quantity`
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// `excessQuantity`
    #[serde(
        rename = "@excessQuantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub excess_quantity: Option<Decimal>,

    /// `feeRate`
    #[serde(
        rename = "@feeRate",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fee_rate: Option<Decimal>,

    /// `collateralAmount`
    #[serde(
        rename = "@collateralAmount",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub collateral_amount: Option<Decimal>,

    /// `levelOfDetail`
    #[serde(
        rename = "@levelOfDetail",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub level_of_detail: Option<String>,

    /// `serialNumber`
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub serial_number: Option<Decimal>,

    /// `deliveryType`
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub delivery_type: Option<Decimal>,

    /// `commodityType`
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness`
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight`
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub weight: Option<Decimal>,
}

/// Employee stock grant / vesting activity.
///
/// Mirrors the ibflex `StockGrantActivity` element; all attributes are optional as IB may
/// omit any of them.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct StockGrantActivity {
    /// `accountId`
    #[serde(
        rename = "@accountId",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub account_id: Option<String>,

    /// `acctAlias`
    #[serde(
        rename = "@acctAlias",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub acct_alias: Option<String>,

    /// `model`
    #[serde(
        rename = "@model",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub model: Option<String>,

    /// `currency`
    #[serde(
        rename = "@currency",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub currency: Option<String>,

    /// `fxRateToBase`
    #[serde(
        rename = "@fxRateToBase",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fx_rate_to_base: Option<Decimal>,

    /// `assetCategory`
    #[serde(rename = "@assetCategory", default)]
    pub asset_category: Option<AssetCategory>,

    /// `subCategory`
    #[serde(
        rename = "@subCategory",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub sub_category: Option<String>,

    /// `symbol`
    #[serde(
        rename = "@symbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub symbol: Option<String>,

    /// `description`
    #[serde(
        rename = "@description",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub description: Option<String>,

    /// `conid`
    #[serde(
        rename = "@conid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub conid: Option<String>,

    /// `securityID`
    #[serde(
        rename = "@securityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id: Option<String>,

    /// `securityIDType`
    #[serde(
        rename = "@securityIDType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub security_id_type: Option<String>,

    /// `cusip`
    #[serde(
        rename = "@cusip",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub cusip: Option<String>,

    /// `isin`
    #[serde(
        rename = "@isin",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub isin: Option<String>,

    /// `figi`
    #[serde(
        rename = "@figi",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub figi: Option<String>,

    /// `listingExchange`
    #[serde(
        rename = "@listingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub listing_exchange: Option<String>,

    /// `underlyingConid`
    #[serde(
        rename = "@underlyingConid",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_conid: Option<String>,

    /// `underlyingSymbol`
    #[serde(
        rename = "@underlyingSymbol",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_symbol: Option<String>,

    /// `underlyingSecurityID`
    #[serde(
        rename = "@underlyingSecurityID",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_security_id: Option<String>,

    /// `underlyingListingExchange`
    #[serde(
        rename = "@underlyingListingExchange",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub underlying_listing_exchange: Option<String>,

    /// `issuer`
    #[serde(
        rename = "@issuer",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer: Option<String>,

    /// `issuerCountryCode`
    #[serde(
        rename = "@issuerCountryCode",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub issuer_country_code: Option<String>,

    /// `multiplier`
    #[serde(
        rename = "@multiplier",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub multiplier: Option<Decimal>,

    /// `strike`
    #[serde(
        rename = "@strike",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub strike: Option<Decimal>,

    /// `expiry`
    #[serde(
        rename = "@expiry",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub expiry: Option<NaiveDate>,

    /// `putCall`
    #[serde(rename = "@putCall", default)]
    pub put_call: Option<PutCall>,

    /// `principalAdjustFactor`
    #[serde(
        rename = "@principalAdjustFactor",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub principal_adjust_factor: Option<Decimal>,

    /// `reportDate`
    #[serde(
        rename = "@reportDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub report_date: Option<NaiveDate>,

    /// `activityDescription`
    #[serde(
        rename = "@activityDescription",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub activity_description: Option<String>,

    /// `awardDate`
    #[serde(
        rename = "@awardDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub award_date: Option<NaiveDate>,

    /// `vestingDate`
    #[serde(
        rename = "@vestingDate",
        default,
        deserialize_with = "deserialize_optional_date"
    )]
    pub vesting_date: Option<NaiveDate>,

    /// `quantity`
    #[serde(
        rename = "@quantity",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub quantity: Option<Decimal>,

    /// `price`
    #[serde(
        rename = "@price",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub price: Option<Decimal>,

    /// `value`
    #[serde(
        rename = "@value",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub value: Option<Decimal>,

    /// `serialNumber`
    #[serde(
        rename = "@serialNumber",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub serial_number: Option<String>,

    /// `deliveryType`
    #[serde(
        rename = "@deliveryType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub delivery_type: Option<String>,

    /// `commodityType`
    #[serde(
        rename = "@commodityType",
        default,
        deserialize_with = "deserialize_optional_string"
    )]
    pub commodity_type: Option<String>,

    /// `fineness`
    #[serde(
        rename = "@fineness",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub fineness: Option<Decimal>,

    /// `weight`
    #[serde(
        rename = "@weight",
        default,
        deserialize_with = "deserialize_optional_decimal"
    )]
    pub weight: Option<Decimal>,
}
