Skip to main content

Unrealized Gain/Loss Service API

Creates unrealized gain/loss journal entries for equity and bond holdings by comparing cost basis against market value. The service still throws Error instances when dependencies or accounts are missing.

Location: worker/services/accounting/unrealized-gain-loss.ts

Dependencies

  • IAccountingService – double-entry accounting API used to post journal entries
  • EquityPortfolioService & BondPortfolioService – provide holdings and market values (equity service returns Result values)
  • UNREALIZED_GAIN_LOSS_ACCOUNTS – shared account name constants
  • createLogger – structured logging around batch processing

Public Methods

createEquityUnrealizedGainLossEntries(fundId: string, date: string): Promise<void> : Retrieves equity holdings via EquityPortfolioService.getHoldingsForDate. If the Result is an error, the method throws using the embedded message. Validates required gain/loss accounts and creates entries for each holding with positive quantity.

createBondUnrealizedGainLossEntries(fundId: string, date: string): Promise<void> : Fetches bond holdings, validates required accounts, and posts gain/loss entries. Throws when market data is missing or accounts are absent.

createUnrealizedGainLossEntry(request: CreateUnrealizedGainLossRequest): Promise<UnrealizedGainLossEntry | null> (internal) : Calculates gain/loss, builds balanced journal entries, and posts them through the accounting service. Returns null when market value is missing or when the gain/loss is zero.

Error Semantics

  • Throws Error when holdings cannot be retrieved (Result from equity service is Err)
  • Throws when required accounting accounts (securities/gain/loss) are missing
  • Propagates accounting service errors when journal entry creation fails

Wrap invocations in try/catch and map errors to domain-friendly BusinessLogicError instances before surfacing to tRPC.

Logging

Service logs:

  • Successful batch creation (Created unrealized gain/loss entries ...)
  • Skipped holdings due to missing market data or zero gain/loss
  • Errors with fund/date context when processing fails

Last Validated: 2025-11-10 against commit 0342a62e