use chrono::NaiveDate;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use super::common::{
AssetCategory, BuySell, DerivativeInfo, LevelOfDetail, OpenClose, OrderType, PutCall,
SecurityIdType, SubCategory, TradeType,
};
use crate::parsers::xml_utils::{
deserialize_optional_bool, deserialize_optional_date, deserialize_optional_decimal,
};
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename = "FlexQueryResponse")]
pub struct FlexQueryResponse {
#[serde(rename = "@queryName", default)]
pub query_name: Option<String>,
#[serde(rename = "@type", default)]
pub query_type: Option<String>,
#[serde(rename = "FlexStatements")]
pub statements: FlexStatementsWrapper,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct FlexStatementsWrapper {
#[serde(rename = "@count", default)]
pub count: Option<String>,
#[serde(rename = "FlexStatement")]
pub statements: Vec<ActivityFlexStatement>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename = "FlexStatement")]
pub struct ActivityFlexStatement {
#[serde(rename = "@accountId")]
pub account_id: String,
#[serde(
rename = "@fromDate",
deserialize_with = "crate::parsers::xml_utils::deserialize_flex_date"
)]
pub from_date: NaiveDate,
#[serde(
rename = "@toDate",
deserialize_with = "crate::parsers::xml_utils::deserialize_flex_date"
)]
pub to_date: NaiveDate,
#[serde(rename = "@whenGenerated")]
pub when_generated: String,
#[serde(rename = "Trades", default)]
pub trades: TradesWrapper,
#[serde(rename = "OpenPositions", default)]
pub positions: PositionsWrapper,
#[serde(rename = "CashTransactions", default)]
pub cash_transactions: CashTransactionsWrapper,
#[serde(rename = "CorporateActions", default)]
pub corporate_actions: CorporateActionsWrapper,
#[serde(rename = "SecuritiesInfo", default)]
pub securities_info: SecuritiesInfoWrapper,
#[serde(rename = "ConversionRates", default)]
pub conversion_rates: ConversionRatesWrapper,
#[serde(rename = "AccountInformation", default)]
pub account_information: Option<super::extended::AccountInformation>,
#[serde(rename = "ChangeInNAV", default)]
pub change_in_nav: Option<super::extended::ChangeInNAV>,
#[serde(rename = "EquitySummaryInBase", default)]
pub equity_summary: EquitySummaryWrapper,
#[serde(rename = "CashReport", default)]
pub cash_report: CashReportWrapper,
#[serde(rename = "TradeConfirms", default)]
pub trade_confirms: TradeConfirmsWrapper,
#[serde(rename = "OptionEAE", default)]
pub option_eae: OptionEAEWrapper,
#[serde(rename = "FxTransactions", default)]
pub fx_transactions: FxTransactionsWrapper,
#[serde(rename = "ChangeInDividendAccruals", default)]
pub change_in_dividend_accruals: ChangeInDividendAccrualsWrapper,
#[serde(rename = "OpenDividendAccruals", default)]
pub open_dividend_accruals: OpenDividendAccrualsWrapper,
#[serde(rename = "InterestAccruals", default)]
pub interest_accruals: InterestAccrualsWrapper,
#[serde(rename = "Transfers", default)]
pub transfers: TransfersWrapper,
#[serde(rename = "MTMPerformanceSummaryInBase", default)]
pub mtm_performance_summary: MTMPerformanceSummaryWrapper,
#[serde(rename = "FIFOPerformanceSummaryInBase", default)]
pub fifo_performance_summary: FIFOPerformanceSummaryWrapper,
#[serde(rename = "MTDYTDPerformanceSummary", default)]
pub mtd_ytd_performance_summary: MTDYTDPerformanceSummaryWrapper,
#[serde(rename = "StmtFunds", default)]
pub statement_of_funds: StatementOfFundsWrapper,
#[serde(rename = "ChangeInPositionValues", default)]
pub change_in_position_values: ChangeInPositionValueWrapper,
#[serde(rename = "UnbundledCommissionDetails", default)]
pub unbundled_commission_details: UnbundledCommissionDetailWrapper,
#[serde(rename = "ClientFees", default)]
pub client_fees: ClientFeesWrapper,
#[serde(rename = "ClientFeesDetails", default)]
pub client_fees_detail: ClientFeesDetailWrapper,
#[serde(rename = "SLBActivities", default)]
pub slb_activities: SLBActivitiesWrapper,
#[serde(rename = "SLBFees", default)]
pub slb_fees: SLBFeesWrapper,
#[serde(rename = "HardToBorrowDetails", default)]
pub hard_to_borrow_details: HardToBorrowDetailsWrapper,
#[serde(rename = "FxLots", default)]
pub fx_lots: FxLotsWrapper,
#[serde(rename = "UnsettledTransfers", default)]
pub unsettled_transfers: UnsettledTransfersWrapper,
#[serde(rename = "TradeTransfers", default)]
pub trade_transfers: TradeTransfersWrapper,
#[serde(rename = "PriorPeriodPositions", default)]
pub prior_period_positions: PriorPeriodPositionsWrapper,
#[serde(rename = "TierInterestDetails", default)]
pub tier_interest_details: TierInterestDetailsWrapper,
#[serde(rename = "DebitCardActivities", default)]
pub debit_card_activities: DebitCardActivitiesWrapper,
#[serde(rename = "SalesTaxes", default)]
pub sales_tax: SalesTaxWrapper,
#[serde(rename = "DepositsOnHold", default, skip_serializing)]
deposits_on_hold: IgnoredSection,
#[serde(rename = "FxPositions", default, skip_serializing)]
fx_positions: IgnoredSection,
#[serde(rename = "NetStockPositions", default, skip_serializing)]
net_stock_positions: IgnoredSection,
#[serde(rename = "ComplexPositions", default, skip_serializing)]
complex_positions: IgnoredSection,
#[serde(rename = "CFDCharges", default, skip_serializing)]
cfd_charges: IgnoredSection,
#[serde(rename = "CommissionCredits", default, skip_serializing)]
commission_credits: IgnoredSection,
#[serde(rename = "FdicInsuredDepositsByBank", default, skip_serializing)]
fdic_insured_deposits: IgnoredSection,
#[serde(rename = "HKIPOOpenSubscriptions", default, skip_serializing)]
hk_ipo_open_subscriptions: IgnoredSection,
#[serde(rename = "HKIPOSubscriptionActivity", default, skip_serializing)]
hk_ipo_subscription_activity: IgnoredSection,
#[serde(rename = "IBGNoteTransactions", default, skip_serializing)]
ibg_note_transactions: IgnoredSection,
#[serde(rename = "IncentiveCouponAccrualDetails", default, skip_serializing)]
incentive_coupon_accruals: IgnoredSection,
#[serde(rename = "MutualFundDividendDetails", default, skip_serializing)]
mutual_fund_dividends: IgnoredSection,
#[serde(rename = "NetStockPositionSummary", default, skip_serializing)]
net_stock_position_summary: IgnoredSection,
#[serde(rename = "PendingExcercises", default, skip_serializing)]
pending_exercises: IgnoredSection,
#[serde(rename = "RoutingCommissions", default, skip_serializing)]
routing_commissions: IgnoredSection,
#[serde(rename = "SLBCollaterals", default, skip_serializing)]
slb_collaterals: IgnoredSection,
#[serde(rename = "SLBOpenContracts", default, skip_serializing)]
slb_open_contracts: IgnoredSection,
#[serde(rename = "SoftDollars", default, skip_serializing)]
soft_dollars: IgnoredSection,
#[serde(rename = "StockGrantActivities", default, skip_serializing)]
stock_grant_activities: IgnoredSection,
#[serde(rename = "TransactionTaxes", default, skip_serializing)]
transaction_taxes: IgnoredSection,
#[serde(rename = "UnbookedTrades", default, skip_serializing)]
unbooked_trades: IgnoredSection,
}
#[derive(Debug, Clone, PartialEq, Default)]
struct IgnoredSection;
impl<'de> serde::Deserialize<'de> for IgnoredSection {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
serde::de::IgnoredAny::deserialize(deserializer)?;
Ok(IgnoredSection)
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
enum TradesItem {
Trade(Trade),
Order(Trade),
SymbolSummary(Trade),
AssetSummary(Trade),
WashSale(Trade),
Lot(Trade),
}
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct TradesWrapper {
pub items: Vec<Trade>,
pub wash_sales: Vec<Trade>,
}
impl<'de> serde::Deserialize<'de> for TradesWrapper {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
struct Raw {
#[serde(rename = "$value", default)]
items: Vec<TradesItem>,
}
let raw = Raw::deserialize(deserializer)?;
let mut trades = Vec::new();
let mut wash_sales = Vec::new();
for item in raw.items {
match item {
TradesItem::Trade(t) => trades.push(t),
TradesItem::WashSale(t) => wash_sales.push(t),
_ => {}
}
}
Ok(TradesWrapper {
items: trades,
wash_sales,
})
}
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct PositionsWrapper {
#[serde(rename = "OpenPosition", default)]
pub items: Vec<Position>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct CashTransactionsWrapper {
#[serde(rename = "CashTransaction", default)]
pub items: Vec<CashTransaction>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct CorporateActionsWrapper {
#[serde(rename = "CorporateAction", default)]
pub items: Vec<CorporateAction>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Trade {
#[serde(rename = "@accountId")]
pub account_id: String,
#[serde(rename = "@transactionID", default)]
pub transaction_id: Option<String>,
#[serde(rename = "@conid")]
pub conid: String,
#[serde(rename = "@symbol")]
pub symbol: String,
#[serde(rename = "@description", default)]
pub description: Option<String>,
#[serde(rename = "@assetCategory")]
pub asset_category: AssetCategory,
#[serde(rename = "@cusip", default)]
pub cusip: Option<String>,
#[serde(rename = "@isin", default)]
pub isin: Option<String>,
#[serde(rename = "@figi", default)]
pub figi: Option<String>,
#[serde(rename = "@securityID", default)]
pub security_id: Option<String>,
#[serde(rename = "@securityIDType", default)]
pub security_id_type: Option<SecurityIdType>,
#[serde(
rename = "@multiplier",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub multiplier: Option<Decimal>,
#[serde(
rename = "@strike",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub strike: Option<Decimal>,
#[serde(
rename = "@expiry",
default,
deserialize_with = "deserialize_optional_date"
)]
pub expiry: Option<NaiveDate>,
#[serde(rename = "@putCall", default)]
pub put_call: Option<PutCall>,
#[serde(rename = "@underlyingConid", default)]
pub underlying_conid: Option<String>,
#[serde(rename = "@underlyingSymbol", default)]
pub underlying_symbol: Option<String>,
#[serde(
rename = "@tradeDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub trade_date: Option<NaiveDate>,
#[serde(
rename = "@settleDateTarget",
default,
deserialize_with = "deserialize_optional_date"
)]
pub settle_date: Option<NaiveDate>,
#[serde(rename = "@buySell", default)]
pub buy_sell: Option<BuySell>,
#[serde(rename = "@openCloseIndicator", default)]
pub open_close: Option<OpenClose>,
#[serde(rename = "@transactionType", default)]
pub transaction_type: Option<TradeType>,
#[serde(
rename = "@quantity",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub quantity: Option<Decimal>,
#[serde(
rename = "@price",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub price: Option<Decimal>,
#[serde(
rename = "@proceeds",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub proceeds: Option<Decimal>,
#[serde(
rename = "@cost",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub cost: Option<Decimal>,
#[serde(
rename = "@ibCommission",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub commission: Option<Decimal>,
#[serde(
rename = "@taxes",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub taxes: Option<Decimal>,
#[serde(
rename = "@netCash",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub net_cash: Option<Decimal>,
#[serde(
rename = "@fifoPnlRealized",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fifo_pnl_realized: Option<Decimal>,
#[serde(
rename = "@mtmPnl",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub mtm_pnl: Option<Decimal>,
#[serde(
rename = "@fxPnl",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fx_pnl: Option<Decimal>,
#[serde(rename = "@currency")]
pub currency: String,
#[serde(
rename = "@fxRateToBase",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fx_rate_to_base: Option<Decimal>,
#[serde(
rename = "@origTradeDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub orig_trade_date: Option<NaiveDate>,
#[serde(
rename = "@origTradePrice",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub orig_trade_price: Option<Decimal>,
#[serde(rename = "@origTradeID", default)]
pub orig_trade_id: Option<String>,
#[serde(rename = "@holdingPeriodDateTime", default)]
pub holding_period_date_time: Option<String>,
#[serde(rename = "@openDateTime", default)]
pub open_date_time: Option<String>,
#[serde(rename = "@whenReopened", default)]
pub when_reopened: Option<String>,
#[serde(rename = "@notes", default)]
pub notes: Option<String>,
#[serde(rename = "@orderID", default)]
pub ib_order_id: Option<String>,
#[serde(rename = "@execID", default)]
pub exec_id: Option<String>,
#[serde(rename = "@tradeID", default)]
pub trade_id: Option<String>,
#[serde(rename = "@origTransactionID", default)]
pub orig_transaction_id: Option<String>,
#[serde(rename = "@origOrderID", default)]
pub orig_order_id: Option<String>,
#[serde(rename = "@dateTime", default)]
pub trade_time: Option<String>,
#[serde(rename = "@whenRealized", default)]
pub when_realized: Option<String>,
#[serde(rename = "@orderTime", default)]
pub order_time: Option<String>,
#[serde(rename = "@orderType", default)]
pub order_type: Option<OrderType>,
#[serde(rename = "@brokerageOrderID", default)]
pub brokerage_order_id: Option<String>,
#[serde(rename = "@orderReference", default)]
pub order_reference: Option<String>,
#[serde(rename = "@exchOrderId", default)]
pub exch_order_id: Option<String>,
#[serde(rename = "@extExecID", default)]
pub ext_exec_id: Option<String>,
#[serde(rename = "@ibExecID", default)]
pub ib_exec_id: Option<String>,
#[serde(rename = "@issuer", default)]
pub issuer: Option<String>,
#[serde(rename = "@issuerCountryCode", default)]
pub issuer_country_code: Option<String>,
#[serde(rename = "@subCategory", default)]
pub sub_category: Option<SubCategory>,
#[serde(rename = "@listingExchange", default)]
pub listing_exchange: Option<String>,
#[serde(rename = "@underlyingListingExchange", default)]
pub underlying_listing_exchange: Option<String>,
#[serde(rename = "@underlyingSecurityID", default)]
pub underlying_security_id: Option<String>,
#[serde(rename = "@traderID", default)]
pub trader_id: Option<String>,
#[serde(
rename = "@isAPIOrder",
default,
deserialize_with = "deserialize_optional_bool"
)]
pub is_api_order: Option<bool>,
#[serde(rename = "@volatilityOrderLink", default)]
pub volatility_order_link: Option<String>,
#[serde(rename = "@clearingFirmID", default)]
pub clearing_firm_id: Option<String>,
#[serde(rename = "@levelOfDetail", default)]
pub level_of_detail: Option<LevelOfDetail>,
#[serde(
rename = "@amount",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub amount: Option<Decimal>,
#[serde(
rename = "@tradeMoney",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub trade_money: Option<Decimal>,
#[serde(
rename = "@closePrice",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub close_price: Option<Decimal>,
#[serde(
rename = "@changeInPrice",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub change_in_price: Option<Decimal>,
#[serde(
rename = "@changeInQuantity",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub change_in_quantity: Option<Decimal>,
#[serde(rename = "@ibCommissionCurrency", default)]
pub commission_currency: Option<String>,
#[serde(rename = "@relatedTradeID", default)]
pub related_trade_id: Option<String>,
#[serde(rename = "@relatedTransactionID", default)]
pub related_transaction_id: Option<String>,
#[serde(
rename = "@accruedInt",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub accrued_int: Option<Decimal>,
#[serde(
rename = "@principalAdjustFactor",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub principal_adjust_factor: Option<Decimal>,
#[serde(rename = "@serialNumber", default)]
pub serial_number: Option<String>,
#[serde(rename = "@deliveryType", default)]
pub delivery_type: Option<String>,
#[serde(rename = "@commodityType", default)]
pub commodity_type: Option<String>,
#[serde(
rename = "@fineness",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fineness: Option<Decimal>,
#[serde(rename = "@weight", default)]
pub weight: Option<String>,
#[serde(
rename = "@reportDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub report_date: Option<NaiveDate>,
#[serde(rename = "@exchange", default)]
pub exchange: Option<String>,
#[serde(rename = "@model", default)]
pub model: Option<String>,
#[serde(rename = "@acctAlias", default)]
pub acct_alias: Option<String>,
#[serde(rename = "@rtn", default)]
pub rtn: Option<String>,
#[serde(rename = "@positionActionID", default)]
pub position_action_id: Option<String>,
#[serde(
rename = "@initialInvestment",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub initial_investment: Option<Decimal>,
}
impl Trade {
pub fn derivative(&self) -> Option<DerivativeInfo> {
match self.asset_category {
AssetCategory::Option => {
let strike = self.strike?;
let expiry = self.expiry?;
let put_call = self.put_call?;
let underlying_symbol = self.underlying_symbol.clone()?;
Some(DerivativeInfo::Option {
strike,
expiry,
put_call,
underlying_symbol,
underlying_conid: self.underlying_conid.clone(),
})
}
AssetCategory::Future => {
let expiry = self.expiry?;
let underlying_symbol = self.underlying_symbol.clone()?;
Some(DerivativeInfo::Future {
expiry,
underlying_symbol,
underlying_conid: self.underlying_conid.clone(),
})
}
AssetCategory::FutureOption => {
let strike = self.strike?;
let expiry = self.expiry?;
let put_call = self.put_call?;
let underlying_symbol = self.underlying_symbol.clone()?;
Some(DerivativeInfo::FutureOption {
strike,
expiry,
put_call,
underlying_symbol,
underlying_conid: self.underlying_conid.clone(),
})
}
AssetCategory::Warrant => {
let underlying_symbol = self.underlying_symbol.clone()?;
Some(DerivativeInfo::Warrant {
strike: self.strike,
expiry: self.expiry,
underlying_symbol: Some(underlying_symbol),
})
}
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Position {
#[serde(rename = "@accountId")]
pub account_id: String,
#[serde(rename = "@conid")]
pub conid: String,
#[serde(rename = "@symbol")]
pub symbol: String,
#[serde(rename = "@description", default)]
pub description: Option<String>,
#[serde(rename = "@assetCategory")]
pub asset_category: AssetCategory,
#[serde(rename = "@cusip", default)]
pub cusip: Option<String>,
#[serde(rename = "@isin", default)]
pub isin: Option<String>,
#[serde(rename = "@figi", default)]
pub figi: Option<String>,
#[serde(rename = "@securityID", default)]
pub security_id: Option<String>,
#[serde(rename = "@securityIDType", default)]
pub security_id_type: Option<SecurityIdType>,
#[serde(
rename = "@multiplier",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub multiplier: Option<Decimal>,
#[serde(
rename = "@strike",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub strike: Option<Decimal>,
#[serde(
rename = "@expiry",
default,
deserialize_with = "deserialize_optional_date"
)]
pub expiry: Option<NaiveDate>,
#[serde(rename = "@putCall", default)]
pub put_call: Option<PutCall>,
#[serde(rename = "@underlyingConid", default)]
pub underlying_conid: Option<String>,
#[serde(rename = "@underlyingSymbol", default)]
pub underlying_symbol: Option<String>,
#[serde(rename = "@position")]
pub quantity: Decimal,
#[serde(rename = "@markPrice")]
pub mark_price: Decimal,
#[serde(rename = "@positionValue")]
pub position_value: Decimal,
#[serde(rename = "@side", default)]
pub side: Option<String>,
#[serde(
rename = "@openPrice",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub open_price: Option<Decimal>,
#[serde(
rename = "@costBasisPrice",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub cost_basis_price: Option<Decimal>,
#[serde(
rename = "@costBasisMoney",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub cost_basis_money: Option<Decimal>,
#[serde(
rename = "@fifoPnlUnrealized",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fifo_pnl_unrealized: Option<Decimal>,
#[serde(
rename = "@percentOfNAV",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub percent_of_nav: Option<Decimal>,
#[serde(rename = "@currency")]
pub currency: String,
#[serde(
rename = "@fxRateToBase",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fx_rate_to_base: Option<Decimal>,
#[serde(
rename = "@reportDate",
deserialize_with = "crate::parsers::xml_utils::deserialize_flex_date"
)]
pub report_date: NaiveDate,
#[serde(rename = "@holdingPeriodDateTime", default)]
pub holding_period_date_time: Option<String>,
#[serde(rename = "@openDateTime", default)]
pub open_date_time: Option<String>,
#[serde(rename = "@originatingTransactionID", default)]
pub originating_transaction_id: Option<String>,
#[serde(rename = "@code", default)]
pub code: Option<String>,
#[serde(rename = "@originatingOrderID", default)]
pub originating_order_id: Option<String>,
#[serde(rename = "@issuer", default)]
pub issuer: Option<String>,
#[serde(rename = "@issuerCountryCode", default)]
pub issuer_country_code: Option<String>,
#[serde(rename = "@subCategory", default)]
pub sub_category: Option<SubCategory>,
#[serde(rename = "@listingExchange", default)]
pub listing_exchange: Option<String>,
#[serde(rename = "@underlyingListingExchange", default)]
pub underlying_listing_exchange: Option<String>,
#[serde(rename = "@underlyingSecurityID", default)]
pub underlying_security_id: Option<String>,
#[serde(
rename = "@accruedInt",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub accrued_int: Option<Decimal>,
#[serde(
rename = "@principalAdjustFactor",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub principal_adjust_factor: Option<Decimal>,
#[serde(rename = "@serialNumber", default)]
pub serial_number: Option<String>,
#[serde(rename = "@deliveryType", default)]
pub delivery_type: Option<String>,
#[serde(rename = "@commodityType", default)]
pub commodity_type: Option<String>,
#[serde(
rename = "@fineness",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fineness: Option<Decimal>,
#[serde(rename = "@weight", default)]
pub weight: Option<String>,
#[serde(rename = "@levelOfDetail", default)]
pub level_of_detail: Option<LevelOfDetail>,
#[serde(rename = "@model", default)]
pub model: Option<String>,
#[serde(rename = "@acctAlias", default)]
pub acct_alias: Option<String>,
#[serde(
rename = "@vestingDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub vesting_date: Option<NaiveDate>,
}
impl Position {
pub fn derivative(&self) -> Option<DerivativeInfo> {
match self.asset_category {
AssetCategory::Option => {
let strike = self.strike?;
let expiry = self.expiry?;
let put_call = self.put_call?;
let underlying_symbol = self.underlying_symbol.clone()?;
Some(DerivativeInfo::Option {
strike,
expiry,
put_call,
underlying_symbol,
underlying_conid: self.underlying_conid.clone(),
})
}
AssetCategory::Future => {
let expiry = self.expiry?;
let underlying_symbol = self.underlying_symbol.clone()?;
Some(DerivativeInfo::Future {
expiry,
underlying_symbol,
underlying_conid: self.underlying_conid.clone(),
})
}
AssetCategory::FutureOption => {
let strike = self.strike?;
let expiry = self.expiry?;
let put_call = self.put_call?;
let underlying_symbol = self.underlying_symbol.clone()?;
Some(DerivativeInfo::FutureOption {
strike,
expiry,
put_call,
underlying_symbol,
underlying_conid: self.underlying_conid.clone(),
})
}
AssetCategory::Warrant => {
let underlying_symbol = self.underlying_symbol.clone()?;
Some(DerivativeInfo::Warrant {
strike: self.strike,
expiry: self.expiry,
underlying_symbol: Some(underlying_symbol),
})
}
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct CashTransaction {
#[serde(rename = "@accountId")]
pub account_id: String,
#[serde(rename = "@transactionID", default)]
pub transaction_id: Option<String>,
#[serde(rename = "@type", default)]
pub transaction_type: Option<String>,
#[serde(rename = "@description", default)]
pub description: Option<String>,
#[serde(rename = "@amount")]
pub amount: Decimal,
#[serde(rename = "@currency")]
pub currency: String,
#[serde(
rename = "@fxRateToBase",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fx_rate_to_base: Option<Decimal>,
#[serde(
rename = "@date",
default,
deserialize_with = "deserialize_optional_date"
)]
pub date: Option<NaiveDate>,
#[serde(
rename = "@settleDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub settle_date: Option<NaiveDate>,
#[serde(
rename = "@exDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub ex_date: Option<NaiveDate>,
#[serde(rename = "@conid", default)]
pub conid: Option<String>,
#[serde(rename = "@symbol", default)]
pub symbol: Option<String>,
#[serde(rename = "@assetCategory", default)]
pub asset_category: Option<AssetCategory>,
#[serde(rename = "@cusip", default)]
pub cusip: Option<String>,
#[serde(rename = "@isin", default)]
pub isin: Option<String>,
#[serde(rename = "@figi", default)]
pub figi: Option<String>,
#[serde(rename = "@securityID", default)]
pub security_id: Option<String>,
#[serde(rename = "@securityIDType", default)]
pub security_id_type: Option<SecurityIdType>,
#[serde(
rename = "@multiplier",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub multiplier: Option<Decimal>,
#[serde(
rename = "@strike",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub strike: Option<Decimal>,
#[serde(
rename = "@expiry",
default,
deserialize_with = "deserialize_optional_date"
)]
pub expiry: Option<NaiveDate>,
#[serde(rename = "@putCall", default)]
pub put_call: Option<PutCall>,
#[serde(rename = "@underlyingConid", default)]
pub underlying_conid: Option<String>,
#[serde(rename = "@underlyingSymbol", default)]
pub underlying_symbol: Option<String>,
#[serde(rename = "@code", default)]
pub code: Option<String>,
#[serde(rename = "@dateTime", default)]
pub date_time: Option<String>,
#[serde(
rename = "@reportDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub report_date: Option<NaiveDate>,
#[serde(
rename = "@availableForTradingDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub available_for_trading_date: Option<NaiveDate>,
#[serde(rename = "@actionID", default)]
pub action_id: Option<String>,
#[serde(rename = "@tradeID", default)]
pub trade_id: Option<String>,
#[serde(rename = "@clientReference", default)]
pub client_reference: Option<String>,
#[serde(rename = "@issuer", default)]
pub issuer: Option<String>,
#[serde(rename = "@issuerCountryCode", default)]
pub issuer_country_code: Option<String>,
#[serde(rename = "@subCategory", default)]
pub sub_category: Option<SubCategory>,
#[serde(rename = "@listingExchange", default)]
pub listing_exchange: Option<String>,
#[serde(rename = "@underlyingListingExchange", default)]
pub underlying_listing_exchange: Option<String>,
#[serde(rename = "@underlyingSecurityID", default)]
pub underlying_security_id: Option<String>,
#[serde(
rename = "@principalAdjustFactor",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub principal_adjust_factor: Option<Decimal>,
#[serde(rename = "@serialNumber", default)]
pub serial_number: Option<String>,
#[serde(rename = "@deliveryType", default)]
pub delivery_type: Option<String>,
#[serde(rename = "@commodityType", default)]
pub commodity_type: Option<String>,
#[serde(
rename = "@fineness",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fineness: Option<Decimal>,
#[serde(rename = "@weight", default)]
pub weight: Option<String>,
#[serde(rename = "@levelOfDetail", default)]
pub level_of_detail: Option<String>,
#[serde(rename = "@model", default)]
pub model: Option<String>,
#[serde(rename = "@acctAlias", default)]
pub acct_alias: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct CorporateAction {
#[serde(rename = "@accountId")]
pub account_id: String,
#[serde(rename = "@transactionID", default)]
pub transaction_id: Option<String>,
#[serde(rename = "@type", default)]
pub action_type: Option<String>,
#[serde(rename = "@description", default)]
pub description: Option<String>,
#[serde(
rename = "@date",
default,
deserialize_with = "deserialize_optional_date"
)]
pub action_date: Option<NaiveDate>,
#[serde(
rename = "@reportDate",
deserialize_with = "crate::parsers::xml_utils::deserialize_flex_date"
)]
pub report_date: NaiveDate,
#[serde(
rename = "@exDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub ex_date: Option<NaiveDate>,
#[serde(
rename = "@payDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub pay_date: Option<NaiveDate>,
#[serde(
rename = "@recordDate",
default,
deserialize_with = "deserialize_optional_date"
)]
pub record_date: Option<NaiveDate>,
#[serde(rename = "@conid")]
pub conid: String,
#[serde(rename = "@symbol")]
pub symbol: String,
#[serde(rename = "@assetCategory", default)]
pub asset_category: Option<AssetCategory>,
#[serde(rename = "@cusip", default)]
pub cusip: Option<String>,
#[serde(rename = "@isin", default)]
pub isin: Option<String>,
#[serde(rename = "@figi", default)]
pub figi: Option<String>,
#[serde(rename = "@securityID", default)]
pub security_id: Option<String>,
#[serde(rename = "@securityIDType", default)]
pub security_id_type: Option<SecurityIdType>,
#[serde(
rename = "@multiplier",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub multiplier: Option<Decimal>,
#[serde(
rename = "@strike",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub strike: Option<Decimal>,
#[serde(
rename = "@expiry",
default,
deserialize_with = "deserialize_optional_date"
)]
pub expiry: Option<NaiveDate>,
#[serde(rename = "@putCall", default)]
pub put_call: Option<PutCall>,
#[serde(rename = "@underlyingConid", default)]
pub underlying_conid: Option<String>,
#[serde(rename = "@underlyingSymbol", default)]
pub underlying_symbol: Option<String>,
#[serde(
rename = "@quantity",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub quantity: Option<Decimal>,
#[serde(
rename = "@amount",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub amount: Option<Decimal>,
#[serde(
rename = "@proceeds",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub proceeds: Option<Decimal>,
#[serde(
rename = "@value",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub value: Option<Decimal>,
#[serde(
rename = "@cost",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub cost: Option<Decimal>,
#[serde(
rename = "@fifoPnlRealized",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fifo_pnl_realized: Option<Decimal>,
#[serde(
rename = "@mtmPnl",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub mtm_pnl: Option<Decimal>,
#[serde(rename = "@currency", default)]
pub currency: Option<String>,
#[serde(
rename = "@fxRateToBase",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fx_rate_to_base: Option<Decimal>,
#[serde(rename = "@code", default)]
pub code: Option<String>,
#[serde(rename = "@actionID", default)]
pub action_id: Option<String>,
#[serde(rename = "@dateTime", default)]
pub date_time: Option<String>,
#[serde(rename = "@issuer", default)]
pub issuer: Option<String>,
#[serde(rename = "@issuerCountryCode", default)]
pub issuer_country_code: Option<String>,
#[serde(rename = "@subCategory", default)]
pub sub_category: Option<SubCategory>,
#[serde(rename = "@listingExchange", default)]
pub listing_exchange: Option<String>,
#[serde(rename = "@underlyingListingExchange", default)]
pub underlying_listing_exchange: Option<String>,
#[serde(rename = "@underlyingSecurityID", default)]
pub underlying_security_id: Option<String>,
#[serde(
rename = "@accruedInt",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub accrued_int: Option<Decimal>,
#[serde(
rename = "@principalAdjustFactor",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub principal_adjust_factor: Option<Decimal>,
#[serde(rename = "@serialNumber", default)]
pub serial_number: Option<String>,
#[serde(rename = "@deliveryType", default)]
pub delivery_type: Option<String>,
#[serde(rename = "@commodityType", default)]
pub commodity_type: Option<String>,
#[serde(
rename = "@fineness",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fineness: Option<Decimal>,
#[serde(rename = "@weight", default)]
pub weight: Option<String>,
#[serde(rename = "@levelOfDetail", default)]
pub level_of_detail: Option<String>,
#[serde(rename = "@model", default)]
pub model: Option<String>,
#[serde(rename = "@acctAlias", default)]
pub acct_alias: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct SecurityInfo {
#[serde(rename = "@assetCategory")]
pub asset_category: AssetCategory,
#[serde(rename = "@symbol")]
pub symbol: String,
#[serde(rename = "@description", default)]
pub description: Option<String>,
#[serde(rename = "@conid")]
pub conid: String,
#[serde(rename = "@securityID", default)]
pub security_id: Option<String>,
#[serde(rename = "@securityIDType", default)]
pub security_id_type: Option<SecurityIdType>,
#[serde(rename = "@cusip", default)]
pub cusip: Option<String>,
#[serde(rename = "@isin", default)]
pub isin: Option<String>,
#[serde(rename = "@figi", default)]
pub figi: Option<String>,
#[serde(rename = "@sedol", default)]
pub sedol: Option<String>,
#[serde(
rename = "@multiplier",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub multiplier: Option<Decimal>,
#[serde(
rename = "@strike",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub strike: Option<Decimal>,
#[serde(
rename = "@expiry",
default,
deserialize_with = "deserialize_optional_date"
)]
pub expiry: Option<NaiveDate>,
#[serde(rename = "@putCall", default)]
pub put_call: Option<PutCall>,
#[serde(rename = "@underlyingConid", default)]
pub underlying_conid: Option<String>,
#[serde(rename = "@underlyingSymbol", default)]
pub underlying_symbol: Option<String>,
#[serde(
rename = "@maturity",
default,
deserialize_with = "deserialize_optional_date"
)]
pub maturity: Option<NaiveDate>,
#[serde(
rename = "@principalAdjustFactor",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub principal_adjust_factor: Option<Decimal>,
#[serde(rename = "@currency", default)]
pub currency: Option<String>,
#[serde(rename = "@listingExchange", default)]
pub listing_exchange: Option<String>,
#[serde(rename = "@underlyingSecurityID", default)]
pub underlying_security_id: Option<String>,
#[serde(rename = "@underlyingListingExchange", default)]
pub underlying_listing_exchange: Option<String>,
#[serde(rename = "@issuer", default)]
pub issuer: Option<String>,
#[serde(rename = "@issuerCountryCode", default)]
pub issuer_country_code: Option<String>,
#[serde(rename = "@subCategory", default)]
pub sub_category: Option<SubCategory>,
#[serde(rename = "@deliveryMonth", default)]
pub delivery_month: Option<String>,
#[serde(rename = "@serialNumber", default)]
pub serial_number: Option<String>,
#[serde(rename = "@deliveryType", default)]
pub delivery_type: Option<String>,
#[serde(rename = "@commodityType", default)]
pub commodity_type: Option<String>,
#[serde(
rename = "@fineness",
default,
deserialize_with = "deserialize_optional_decimal"
)]
pub fineness: Option<Decimal>,
#[serde(rename = "@weight", default)]
pub weight: Option<String>,
#[serde(rename = "@code", default)]
pub code: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct ConversionRate {
#[serde(
rename = "@reportDate",
deserialize_with = "crate::parsers::xml_utils::deserialize_flex_date"
)]
pub report_date: NaiveDate,
#[serde(rename = "@fromCurrency")]
pub from_currency: String,
#[serde(rename = "@toCurrency")]
pub to_currency: String,
#[serde(rename = "@rate")]
pub rate: Decimal,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct SecuritiesInfoWrapper {
#[serde(rename = "SecurityInfo", default)]
pub items: Vec<SecurityInfo>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct ConversionRatesWrapper {
#[serde(rename = "ConversionRate", default)]
pub items: Vec<ConversionRate>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct EquitySummaryWrapper {
#[serde(rename = "EquitySummaryByReportDateInBase", default)]
pub items: Vec<super::extended::EquitySummaryByReportDateInBase>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct CashReportWrapper {
#[serde(rename = "CashReportCurrency", default)]
pub items: Vec<super::extended::CashReportCurrency>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct TradeConfirmsWrapper {
#[serde(rename = "TradeConfirm", default)]
pub items: Vec<super::extended::TradeConfirm>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct OptionEAEWrapper {
#[serde(rename = "OptionEAE", default)]
pub items: Vec<super::extended::OptionEAE>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct FxTransactionsWrapper {
#[serde(rename = "FxTransaction", default)]
pub items: Vec<super::extended::FxTransaction>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct ChangeInDividendAccrualsWrapper {
#[serde(rename = "ChangeInDividendAccrual", default)]
pub items: Vec<super::extended::ChangeInDividendAccrual>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct OpenDividendAccrualsWrapper {
#[serde(rename = "OpenDividendAccrual", default)]
pub items: Vec<super::extended::OpenDividendAccrual>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct InterestAccrualsWrapper {
#[serde(rename = "InterestAccrualsCurrency", default)]
pub items: Vec<super::extended::InterestAccrualsCurrency>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct TransfersWrapper {
#[serde(rename = "Transfer", default)]
pub items: Vec<super::extended::Transfer>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct MTMPerformanceSummaryWrapper {
#[serde(rename = "MTMPerformanceSummaryUnderlying", default)]
pub items: Vec<super::extended::MTMPerformanceSummaryUnderlying>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct FIFOPerformanceSummaryWrapper {
#[serde(rename = "FIFOPerformanceSummaryUnderlying", default)]
pub items: Vec<super::extended::FIFOPerformanceSummaryUnderlying>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct MTDYTDPerformanceSummaryWrapper {
#[serde(rename = "MTDYTDPerformanceSummaryUnderlying", default)]
pub items: Vec<super::extended::MTDYTDPerformanceSummary>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct StatementOfFundsWrapper {
#[serde(rename = "StatementOfFundsLine", default)]
pub items: Vec<super::extended::StatementOfFundsLine>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct ChangeInPositionValueWrapper {
#[serde(rename = "ChangeInPositionValue", default)]
pub items: Vec<super::extended::ChangeInPositionValue>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct UnbundledCommissionDetailWrapper {
#[serde(rename = "UnbundledCommissionDetail", default)]
pub items: Vec<super::extended::UnbundledCommissionDetail>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct ClientFeesWrapper {
#[serde(rename = "ClientFee", default)]
pub items: Vec<super::extended::ClientFee>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct ClientFeesDetailWrapper {
#[serde(rename = "ClientFeesDetail", default)]
pub items: Vec<super::extended::ClientFeesDetail>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct SLBActivitiesWrapper {
#[serde(rename = "SLBActivity", default)]
pub items: Vec<super::extended::SLBActivity>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct SLBFeesWrapper {
#[serde(rename = "SLBFee", default)]
pub items: Vec<super::extended::SLBFee>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct HardToBorrowDetailsWrapper {
#[serde(rename = "HardToBorrowDetail", default)]
pub items: Vec<super::extended::HardToBorrowDetail>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct FxLotsWrapper {
#[serde(rename = "FxLot", default)]
pub items: Vec<super::extended::FxLot>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct UnsettledTransfersWrapper {
#[serde(rename = "UnsettledTransfer", default)]
pub items: Vec<super::extended::UnsettledTransfer>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct TradeTransfersWrapper {
#[serde(rename = "TradeTransfer", default)]
pub items: Vec<super::extended::TradeTransfer>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct PriorPeriodPositionsWrapper {
#[serde(rename = "PriorPeriodPosition", default)]
pub items: Vec<super::extended::PriorPeriodPosition>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct TierInterestDetailsWrapper {
#[serde(rename = "TierInterestDetail", default)]
pub items: Vec<super::extended::TierInterestDetail>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct DebitCardActivitiesWrapper {
#[serde(rename = "DebitCardActivity", default)]
pub items: Vec<super::extended::DebitCardActivity>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct SalesTaxWrapper {
#[serde(rename = "SalesTax", default)]
pub items: Vec<super::extended::SalesTax>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct SymbolSummaryWrapper {
#[serde(rename = "SymbolSummary", default)]
pub items: Vec<super::extended::SymbolSummary>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct AssetSummaryWrapper {
#[serde(rename = "AssetSummary", default)]
pub items: Vec<super::extended::AssetSummary>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct OrdersWrapper {
#[serde(rename = "Order", default)]
pub items: Vec<super::extended::Order>,
}