Table of Contents

ImfRateProvider Class

Definition

Namespace
Bodu.Financial.ExchangeRates
Assembly
Bodu.Financial.ExchangeRates.Imf.dll
Package
Bodu.Financial.ExchangeRates.Imf 0.7.1
Source
ImfRateProvider.cs

Serves IMF (International Monetary Fund) Representative Exchange Rates as ExchangeRate values, implementing the Bodu.Financial provider contracts over the IMF's published monthly tab-separated report.

public sealed class ImfRateProvider : WebRateProvider, IDatedRateProvider, IRateProvider, IPairRateLoader, IHistoricalRateProvider, IDisposable
Inheritance
ImfRateProvider
Implements
Inherited Members
Extension Methods

Examples

using var imf = new ImfRateProvider(new ImfRateProviderOptions());
await imf.LoadRangeAsync(new DateOnly(2026, 4, 1), new DateOnly(2026, 4, 30));

RateLookupResult jpy = imf.GetRate("USD", "JPY", new DateOnly(2026, 4, 1));
RateLookupResult usd = imf.GetRate("JPY", "USD", new DateOnly(2026, 4, 1)); // inverted

Remarks

The provider derives from WebRateProvider, which supplies the in-memory accumulator, the immutable snapshot, the full synchronous and asynchronous lookup matrix, and ownership of the HttpClient when this provider creates one. Loading is month-based: one download covers every reported currency across each business day of a month, so a request for any date in a month loads the whole month. Use PreloadAsync(CancellationToken), LoadMonthAsync(ImfReportMonth, CancellationToken), or LoadRangeAsync(DateOnly, DateOnly, CancellationToken) to warm the store.

USD-anchored, keyless. Every rate the report publishes quotes a currency against the US dollar, so only USD/X and X/USD pairs are serviceable; a cross-currency pair is rejected. Direction is normalized on ingest - labels the IMF quotes in US dollars per currency unit are inverted - so the stored rate is always units of the quote currency per one US dollar. The report requires no API key.

HttpClient ownership. The constructor that takes only options builds and owns an HttpClient configured from UserAgent and HttpTimeout, disposing it with the provider. The constructor that takes an HttpClient uses the caller-supplied client as-is; this is the path the dependency-injection package uses.

Constructors

ImfRateProvider(ImfRateProviderOptions, ILogger?, TimeProvider?)

Initializes a new instance of the ImfRateProvider class backed by an HttpClient the provider creates and owns, configured from the supplied options.

public ImfRateProvider(ImfRateProviderOptions options, ILogger? logger = null, TimeProvider? timeProvider = null)

Parameters

options ImfRateProviderOptions

The provider options.

logger ILogger

The logger. null selects Instance.

timeProvider TimeProvider

The time source. null selects System.

Exceptions

ArgumentNullException

Thrown when options is null.

ArgumentException

Thrown when options fails validation.

ImfRateProvider(HttpClient, ImfRateProviderOptions, ILogger?, TimeProvider?)

Initializes a new instance of the ImfRateProvider class backed by the IMF report, downloaded with the caller-supplied HTTP client. The caller owns the client's configuration and lifetime.

public ImfRateProvider(HttpClient httpClient, ImfRateProviderOptions options, ILogger? logger = null, TimeProvider? timeProvider = null)

Parameters

httpClient HttpClient

The HTTP client used to download report files.

options ImfRateProviderOptions

The provider options.

logger ILogger

The logger. null selects Instance.

timeProvider TimeProvider

The time source. null selects System.

Exceptions

ArgumentNullException

Thrown when httpClient or options is null.

ArgumentException

Thrown when options fails validation.

Fields

BaseCurrency

The base currency the IMF report quotes against.

public const CurrencyCode BaseCurrency = USD

Field Value

CurrencyCode

ProviderName

The provider identifier stamped on every rate this provider produces.

public const string ProviderName = "IMF"

Field Value

string

Properties

AllowSynchronousNetworkAccess

Gets a value indicating whether a synchronous lookup may block to fetch a missing window on demand.

protected override bool AllowSynchronousNetworkAccess { get; }

Property Value

bool

true when synchronous getters may block on the network; otherwise false.

Remarks

When enabled, the synchronous getters block on the async fetch, which can deadlock if invoked on a thread carrying a captured SynchronizationContext (classic ASP.NET, a WPF/WinForms UI thread). The synchronous path guards against this by throwing InvalidOperationException when Current is non-null; enable this only for code that calls the getters from a thread-pool thread (or use the asynchronous API).

DefaultLookback

Gets the look-back window used when a single-rate lookup must fetch on demand; the provider fetches the window ending on the requested date and spanning this duration.

protected override TimeSpan DefaultLookback { get; }

Property Value

TimeSpan

The look-back window.

Remarks

The look-back is zero because the report is loaded a whole month at a time: any date in a requested window is covered by that month's single download, so no extra look-back window is needed.

HistoryAvailability

Gets the history depth this provider advertises: how far back it can serve rates.

public override RateHistoryAvailability HistoryAvailability { get; }

Property Value

RateHistoryAvailability

The advertised availability; the base reports Unbounded. A derived type whose feed publishes only a bounded window overrides this to declare it.

ProviderId

Gets the provider identifier stamped on every rate this provider produces.

protected override string ProviderId { get; }

Property Value

string

The provider identifier.

Methods

EnsureLoadedAsync(CurrencyPair, DateOnly, DateOnly, CancellationToken)

Ensures the inclusive window for a pair has been fetched and accumulated, idempotently. Implementations perform their own coverage check, request coalescing, fetch, and accumulation (via AddObservations(IEnumerable<ExchangeRate>, DateTimeOffset?) and RebuildSnapshot() under SyncRoot).

protected override ValueTask EnsureLoadedAsync(CurrencyPair pair, DateOnly startDate, DateOnly endDate, CancellationToken cancellationToken)

Parameters

pair CurrencyPair

The currency pair to ensure data for. Feeds that fetch by range, feed, or file may ignore it.

startDate DateOnly

The inclusive start of the window.

endDate DateOnly

The inclusive end of the window.

cancellationToken CancellationToken

A token to observe while awaiting the fetch.

Returns

ValueTask

A task that completes when the window has been loaded.

FormatRateNotFound(string, string, DateOnly)

Formats the message for the KeyNotFoundException thrown when a single-rate lookup fails. Derived types may override to use a feed-specific resource string.

protected override string FormatRateNotFound(string fromIsoCode, string toIsoCode, DateOnly date)

Parameters

fromIsoCode string

The source-currency ISO code.

toIsoCode string

The destination-currency ISO code.

date DateOnly

The requested date.

Returns

string

The exception message.

GetAvailablePairs()

Gets the currency pairs discovered across the months loaded so far.

public IReadOnlyCollection<ImfSeriesInfo> GetAvailablePairs()

Returns

IReadOnlyCollection<ImfSeriesInfo>

A snapshot of the discovered series, one per currency pair.

IsLoaded(CurrencyPair, DateOnly, DateOnly)

Reports whether the inclusive window for a pair has already been fetched, so the synchronous lookup path can skip a redundant blocking fetch.

protected override bool IsLoaded(CurrencyPair pair, DateOnly startDate, DateOnly endDate)

Parameters

pair CurrencyPair

The currency pair to test.

startDate DateOnly

The inclusive start of the window.

endDate DateOnly

The inclusive end of the window.

Returns

bool

true when the window is already covered; otherwise false.

LoadMonthAsync(ImfReportMonth, CancellationToken)

Downloads and loads a single month's report, if it has not already been loaded.

public Task LoadMonthAsync(ImfReportMonth month, CancellationToken cancellationToken = default)

Parameters

month ImfReportMonth

The report month to load.

cancellationToken CancellationToken

A token to observe while awaiting the load.

Returns

Task

A task that completes when the month has been loaded.

Exceptions

ArgumentNullException

Thrown when month is null.

LoadRangeAsync(DateOnly, DateOnly, CancellationToken)

Downloads and loads every month spanning an inclusive date range.

public Task LoadRangeAsync(DateOnly startDate, DateOnly endDate, CancellationToken cancellationToken = default)

Parameters

startDate DateOnly

The inclusive start of the range.

endDate DateOnly

The inclusive end of the range.

cancellationToken CancellationToken

A token to observe while awaiting the load.

Returns

Task

A task that completes when every covering month has been loaded.

Exceptions

ArgumentException

Thrown when endDate precedes startDate.

OnObservationIngested(ExchangeRate)

Called once per observation as it is ingested, for derived-type diagnostics. The default does nothing.

protected override void OnObservationIngested(ExchangeRate rate)

Parameters

rate ExchangeRate

The observation being ingested.

OnSynchronousNetworkFetch(DateOnly)

Called after a synchronous lookup blocks to fetch on demand, for derived-type diagnostics. The default does nothing.

protected override void OnSynchronousNetworkFetch(DateOnly date)

Parameters

date DateOnly

The date around which the fetch was performed.

PreloadAsync(CancellationToken)

Downloads and loads the report for the current month, warming the store with its published business days.

public Task PreloadAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

A token to observe while awaiting the load.

Returns

Task

A task that completes when the current month has been loaded.

ValidateRangeRequest(string, string, DateOnly, DateOnly)

Validates a range request against feed-specific preconditions before any fetch is attempted. The default does nothing; derived types may override to reject unsupported pairs (for example, a single-issuer feed that quotes only against one base currency).

protected override void ValidateRangeRequest(string fromIsoCode, string toIsoCode, DateOnly startDate, DateOnly endDate)

Parameters

fromIsoCode string

The source-currency ISO code.

toIsoCode string

The destination-currency ISO code.

startDate DateOnly

The inclusive start of the range.

endDate DateOnly

The inclusive end of the range.

Applies to

ProductVersions
.NET8, 10