Table of Contents

Bodu.Financial Namespace

Bodu.Financial

Purpose

Bodu.Financial is the monetary-primitives package: type-safe money (Money<TCurrency>), runtime-tagged money (Money), multi-currency portfolios (MoneyBag), a shipped catalogue of 184 ISO 4217 currencies (in Bodu.Financial.Currencies), an exchange-rate core with both timeless and dated lookup (in Bodu.Financial.ExchangeRates), and - in the companion Bodu.Financial.Serialization.Json package - JSON converters with strict / lenient / compact policy shapes.

Reach for this library when you need monetary arithmetic that the compiler validates - adding USD to JPY should fail the build, not run with the wrong unit - and when you need audit-grade FX conversion that records which date, which provider, and which fallback policy produced a given rate.

Static documentation

Key types

Monetary value types

  • Money<TCurrency> - immutable, value-equatable monetary amount whose currency is encoded as the type parameter. Cross-currency arithmetic is a compile error. Provides arithmetic, allocation, conversion, formatting/parsing, cash rounding, minor-unit interop, and Fraction<BigInteger> interop.
  • Money - runtime-tagged sister type with the same surface, where the currency is a CurrencyCode enum value (its Code property). Cross-currency arithmetic throws InvalidOperationException at runtime. Use for deserialisation and generic invoicing.
  • MoneyBag - immutable mixed-currency portfolio. Aggregates per-ISO balances, prunes zero balances, enumerates in lexicographic ISO order.

Currency display

Rounding, allocation, formatting, and parsing

Related namespaces

  • Bodu.Financial.Currencies - the runtime currency metadata surface (ICurrency, CurrencyInfo, CurrencyRegistry, CurrencyLookupService, CurrencyCode) plus 184 sealed ISO 4217 tag types (155 active plus 29 historic / demonetised).
  • Bodu.Financial.ExchangeRates - the exchange-rate stack: values, series, in-memory tables, the timeless / dated provider contracts, and (via the separate Bodu.Financial.ExchangeRates package) the web-provider machinery the per-source feed packages build on.
  • Bodu.Financial.ExchangeRates.Caching - provider-agnostic read-through caching and aggregation over any provider.
  • Bodu.Financial.Serialization.Json - JSON converters and the FinancialJsonPolicy enum (Strict, Lenient, Compact), shipped in the companion Bodu.Financial.Serialization.Json package (the core library is serialization-agnostic).

Example

using Bodu.Financial;
using Bodu.Financial.Currencies;

Money<USD> dinner = new Money<USD>(54.30m);
Money<USD> tip    = dinner * 0.18m;
Money<USD> total  = dinner + tip;        // OK - same currency

Money<JPY> sushi = new Money<JPY>(2500m);
// var oops = dinner + sushi;            // Compile error - cannot mix currencies

// Fair allocation that preserves the original total exactly.
Money<USD>[] shares = new Money<USD>(0.10m).Allocate(3);
// [0.04, 0.03, 0.03]

Notes

  • Currency in the type system. Money<USD> and Money<JPY> are different types. The compiler enforces same-currency arithmetic; Convert<TTarget>(rate) is the explicit cross-currency boundary.
  • Banker's rounding default. Construction rounds to TCurrency.MinorUnits using MidpointRounding.ToEven. Pass an explicit MidpointRounding to opt out.
  • Audit-friendly FX. Dated lookups return RateLookupResult carrying the provider name, the date actually used, the offset-day distance from the requested date, the resolution policy that fired, and an inversion flag.
  • Sub-minor-unit precision. Money<T>.ToFraction() / FromFraction() / MultiplyExact() round-trip through Fraction<BigInteger> so chained multiplications and divisions do not accumulate rounding error. See Fraction<T>.
  • Zero balances are pruned. MoneyBag removes zero balances on every operation, so equality and enumeration are stable across insertion order and across serialisation round trips.
  • See also: the Money<TCurrency> guide, the Bodu.Financial.Currencies reference, and the Bodu.Financial.Serialization.Json reference.

Namespaces

Bodu.Financial.Currencies
Bodu.Financial.ExchangeRates
Bodu.Financial.Extensions
Bodu.Financial.Serialization.Json

Classes

FinancialOptions

Configuration-bindable options for the Bodu.Financial dependency-injection surface.

FinancialServiceBuilderExtensions

Provides the fluent registration surface for IFinancialServiceBuilder: currency lookup, named monetary contexts, and exchange-rate providers.

MidpointRoundingStrategy

An IRoundingStrategy backed by a MidpointRounding mode, rounding via Round(decimal, int, MidpointRounding).

MonetaryContext

Carries the rounding and scaling policy applied at a monetary operation boundary - multiplication, division, conversion, allocation, and the conversion of a high-precision calculation back to a settlement value.

MoneyBag

Aggregates monetary balances across multiple currencies. Immutable; every mutator returns a new instance.

MoneyFormatOptions

Configures how a MoneyFormatter renders a monetary value. Translates to the format-specifier vocabulary understood by Money and Money<TCurrency>.

MoneyFormatter

Renders Money and Money<TCurrency> values according to a fixed MoneyFormatOptions, translating the options into the format-specifier vocabulary of the monetary types.

MoneyFormatterBuilder

Fluently composes a MoneyFormatter for complex formatting scenarios.

MoneyParseOptions

Configures how Parse(string, MoneyParseOptions) and its TryParse counterpart interpret monetary text.

ServiceCollectionExtensions

Provides the AddFinancialService entry points that register the Bodu.Financial services into an IServiceCollection and return a fluent IFinancialServiceBuilder.

ServiceProviderExtensions

Provides the connector that promotes the container-registered ICurrencyLookup to the ambient CurrencyResolution default, so the runtime-tagged Money resolves currencies through the application's configured catalogue.

StochasticRoundingStrategy

An IRoundingStrategy that rounds a value up or down probabilistically, with the probability of rounding up equal to the fractional part discarded at the target scale. Over many roundings the expected value equals the raw amount, so the convention is statistically unbiased and does not accumulate the directional drift that a fixed midpoint rule can introduce across a long series of operations.

Structs

CalculatedMoney

Represents a high-precision, runtime-tagged monetary amount whose rounding is deferred until it is converted back to a settlement Money.

Money

Represents an immutable monetary amount whose currency is identified at runtime by ISO 4217 code, in contrast to Money<TCurrency> where the currency is a type parameter.

MoneyBagConversionAudit<TTarget>

Bundles the aggregated total produced by a dated bag conversion with the full per-line audit trail.

MoneyBagConversionLine

Captures the per-line audit metadata produced by ConvertToWithAudit<TTarget>(IDatedRateProvider, DateOnly, RateLookupOptions?, MoneyBagConversionRoundingPolicy) for a single source currency in the bag.

MoneyConversionResult

Captures the audit trail of a single runtime-tagged currency conversion: the source and settled target amounts, the exchange rate applied, the monetary context that governed rounding, and how much rounding moved the result.

MoneyConversionResult<TSource, TTarget>

Bundles the result of a single end-to-end strongly-typed money conversion together with the exchange-rate metadata that produced it, so consumers can audit which observed rate was used.

Money<TCurrency>

Represents an immutable monetary amount denominated in the currency identified by TCurrency.

Interfaces

IFinancialServiceBuilder

Defines the fluent registration surface returned by AddFinancialService(IServiceCollection, IConfiguration?, string) , mirroring the IHttpClientBuilder / IMvcBuilder pattern.

IRoundingStrategy

Rounds a raw monetary amount to a given number of fractional digits. Implementations encapsulate the rounding convention applied at operation boundaries - banker's rounding, away-from-zero, and so on.

Enums

AllocationPolicy

Specifies the algorithm a MonetaryContext uses to distribute residual minor units when allocating a monetary amount across shares.

CashRoundingPolicy

Specifies whether a MonetaryContext snaps results to the currency's physical cash denomination.

ConversionRoundingPolicy

Specifies when a MonetaryContext rounds the result of a currency conversion.

CurrencyDisplay

Specifies how MoneyFormatter renders the currency designator alongside the amount.

MoneyBagConversionRoundingPolicy

Selects the rounding policy used by ConvertTo<TTarget>(IRateProvider, MoneyBagConversionRoundingPolicy) when aggregating per-currency balances into a single target-currency total.

MoneyParseMode

Specifies how MoneyParseOptions interprets monetary text.

ScalePolicy

Specifies the fractional-digit scale a MonetaryContext rounds to at an operation boundary.