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
optionsImfRateProviderOptionsThe provider options.
loggerILoggertimeProviderTimeProvider
Exceptions
- ArgumentNullException
Thrown when
optionsis null.- ArgumentException
Thrown when
optionsfails 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
httpClientHttpClientThe HTTP client used to download report files.
optionsImfRateProviderOptionsThe provider options.
loggerILoggertimeProviderTimeProvider
Exceptions
- ArgumentNullException
Thrown when
httpClientoroptionsis null.- ArgumentException
Thrown when
optionsfails validation.
Fields
BaseCurrency
The base currency the IMF report quotes against.
public const CurrencyCode BaseCurrency = USD
Field Value
ProviderName
The provider identifier stamped on every rate this provider produces.
public const string ProviderName = "IMF"
Field Value
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
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
pairCurrencyPairThe currency pair to ensure data for. Feeds that fetch by range, feed, or file may ignore it.
startDateDateOnlyThe inclusive start of the window.
endDateDateOnlyThe inclusive end of the window.
cancellationTokenCancellationTokenA 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
fromIsoCodestringThe source-currency ISO code.
toIsoCodestringThe destination-currency ISO code.
dateDateOnlyThe 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
pairCurrencyPairThe currency pair to test.
startDateDateOnlyThe inclusive start of the window.
endDateDateOnlyThe inclusive end of the window.
Returns
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
monthImfReportMonthThe report month to load.
cancellationTokenCancellationTokenA token to observe while awaiting the load.
Returns
- Task
A task that completes when the month has been loaded.
Exceptions
- ArgumentNullException
Thrown when
monthis 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
startDateDateOnlyThe inclusive start of the range.
endDateDateOnlyThe inclusive end of the range.
cancellationTokenCancellationTokenA token to observe while awaiting the load.
Returns
- Task
A task that completes when every covering month has been loaded.
Exceptions
- ArgumentException
Thrown when
endDateprecedesstartDate.
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
rateExchangeRateThe 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
dateDateOnlyThe 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
cancellationTokenCancellationTokenA 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
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |