Table of Contents

ExchangeRate Struct

Definition

Namespace
Bodu.Financial.ExchangeRates
Assembly
Bodu.Financial.dll
Package
Bodu.Financial 1.0.0
Source
ExchangeRate.cs

Represents a single dated foreign-exchange rate observation produced by a named provider.

public readonly struct ExchangeRate : IEquatable<ExchangeRate>
Implements
Inherited Members
Extension Methods

Remarks

An ExchangeRate is an immutable value object intended to be passed back from a provider together with resolution metadata in an RateLookupResult. It carries enough context - direction, date, provider name, and inversion flag - for downstream auditability (for example, tax and accounting reports) without requiring the caller to reach back into the provider.

using Bodu.Financial;

// A single USD -> EUR observation published by "ECB" on a given day.
var rate = new ExchangeRate(
    CurrencyCode.USD, CurrencyCode.EUR, new DateOnly(2024, 3, 1), 0.92m, "ECB");

// Apply it; rounding is deferred to the money boundary.
decimal euros = rate.Convert(100m);   // 92.00

Constructors

ExchangeRate(CurrencyCode, CurrencyCode, DateOnly, decimal, string, bool, DateTimeOffset?)

Initializes a new instance of the ExchangeRate struct.

public ExchangeRate(CurrencyCode from, CurrencyCode to, DateOnly date, decimal rate, string provider, bool isInverted = false, DateTimeOffset? fetchedAtUtc = null)

Parameters

from CurrencyCode

The source currency.

to CurrencyCode

The destination currency.

date DateOnly

The calendar date on which the rate was observed.

rate decimal

The multiplier that converts a source-currency amount to the destination currency.

provider string

The non-empty identifier of the publishing source.

isInverted bool

true when the rate was derived from the reverse pair; otherwise false.

fetchedAtUtc DateTimeOffset?

The UTC instant at which the upstream data backing this rate was originally fetched, or null when not tracked.

Exceptions

ArgumentNullException

Thrown if provider is null.

ArgumentException

Thrown if provider is empty or white-space.

ArgumentOutOfRangeException

Thrown if from or to is not a defined currency, or if rate is zero or negative.

Properties

Date

Gets the calendar date on which the rate was observed.

public DateOnly Date { get; }

Property Value

DateOnly

The observation date.

FetchedAtUtc

Gets the UTC instant at which the upstream data backing this rate was originally fetched, or null when not tracked.

public DateTimeOffset? FetchedAtUtc { get; }

Property Value

DateTimeOffset?

The fetch instant when known; otherwise null.

Remarks

The value is provenance metadata describing when the load that produced this rate downloaded its source data. It is excluded from Equals(ExchangeRate) and GetHashCode(), so two rates that differ only in their fetch instant still compare equal.

From

Gets the source currency.

public CurrencyCode From { get; }

Property Value

CurrencyCode

The currency an amount is converted from.

IsInverted

Gets a value indicating whether this rate was derived from the reverse pair.

public bool IsInverted { get; }

Property Value

bool

true when Rate is the reciprocal of an originally published reverse-direction rate; otherwise false.

Pair

Gets the directional currency pair this rate quotes.

public CurrencyPair Pair { get; }

Property Value

CurrencyPair

An CurrencyPair of From and To.

Provider

Gets the non-empty identifier of the publishing source.

public string Provider { get; }

Property Value

string

The provider identifier.

Rate

Gets the multiplier that converts an amount in From to To.

public decimal Rate { get; }

Property Value

decimal

A strictly positive multiplier.

To

Gets the destination currency.

public CurrencyCode To { get; }

Property Value

CurrencyCode

The currency an amount is converted to.

Methods

Convert(decimal)

Converts amount from the source currency to the destination currency.

public decimal Convert(decimal amount)

Parameters

amount decimal

The amount in From to convert.

Returns

decimal

The converted amount in To, unrounded.

Remarks

A non-inverted rate multiplies by Rate; an inverted rate divides by the original reverse-pair rate rather than multiplying by a pre-rounded reciprocal, avoiding a double-rounding step. Rounding is intentionally deferred to the money boundary so the rate object stays decoupled from the destination currency's minor-unit precision.

Equals(ExchangeRate)

Determines whether this rate equals other by its public fields. The internal observed rate and the FetchedAtUtc fetch instant are excluded - both are provenance metadata - so two rates that report the same direction, date, multiplier, provider, and inversion compare equal regardless of how each was constructed or when its source data was fetched.

public bool Equals(ExchangeRate other)

Parameters

other ExchangeRate

The rate to compare with.

Returns

bool

true when the public fields match; otherwise false.

Equals(object)

Indicates whether this instance and a specified object are equal.

public override bool Equals(object obj)

Parameters

obj object

The object to compare with the current instance.

Returns

bool

true if obj and this instance are the same type and represent the same value; otherwise, false.

GetHashCode()

Returns a hash code over the public fields, consistent with Equals(ExchangeRate).

public override int GetHashCode()

Returns

int

The hash code.

ToString()

Returns the fully qualified type name of this instance.

public override string ToString()

Returns

string

The fully qualified type name.

WithFetchedAtUtc(DateTimeOffset?)

Returns a copy of this rate with the specified upstream fetch instant, preserving all other values.

public ExchangeRate WithFetchedAtUtc(DateTimeOffset? fetchedAtUtc)

Parameters

fetchedAtUtc DateTimeOffset?

The UTC instant the upstream data backing the returned rate was originally fetched, or null when not tracked.

Returns

ExchangeRate

A new ExchangeRate identical to this one except for its FetchedAtUtc value.

Remarks

The internal observed rate is carried over exactly, so an inverted rate's precise reverse-pair value survives the copy. Because FetchedAtUtc is excluded from equality, the returned rate compares equal to this one.

Operators

operator ==(ExchangeRate, ExchangeRate)

public static bool operator ==(ExchangeRate left, ExchangeRate right)

Parameters

left ExchangeRate
right ExchangeRate

Returns

bool

operator !=(ExchangeRate, ExchangeRate)

public static bool operator !=(ExchangeRate left, ExchangeRate right)

Parameters

left ExchangeRate
right ExchangeRate

Returns

bool

Applies to

ProductVersions
.NET8, 10