remove deprecated International Monetary Fund exchange rate data source

This commit is contained in:
MaysWind
2026-01-31 00:30:55 +08:00
parent 0020f4ede9
commit ab38d33e31
6 changed files with 17 additions and 465 deletions
-1
View File
@@ -509,7 +509,6 @@ custom_map_tile_server_default_zoom_level = 14
# "swiss_national_bank": https://www.snb.ch/en/the-snb/mandates-goals/statistics/statistics-pub/current_interest_exchange_rates
# "national_bank_of_ukraine": https://bank.gov.ua/ua/markets/exchangerates
# "central_bank_of_uzbekistan": https://cbu.uz/en/arkhiv-kursov-valyut/
# "international_monetary_fund": https://www.imf.org/external/np/fin/data/param_rms_mth.aspx
# "user_custom": users set their own exchange rates data in the UI
data_source = euro_central_bank
@@ -295,22 +295,6 @@ func TestExchangeRatesApiLatestExchangeRateHandler_CentralBankOfUzbekistanDataSo
checkExchangeRatesHaveSpecifiedCurrencies(t, exchangeRateResponse.BaseCurrency, supportedCurrencyCodes, exchangeRateResponse.ExchangeRates)
}
func TestExchangeRatesApiLatestExchangeRateHandler_InternationalMonetaryFundDataSource(t *testing.T) {
exchangeRateResponse := executeLatestExchangeRateHandler(t, settings.InternationalMonetaryFundDataSource)
if exchangeRateResponse == nil {
return
}
assert.Equal(t, "USD", exchangeRateResponse.BaseCurrency)
supportedCurrencyCodes := []string{"AED", "AUD", "BND", "BRL", "BWP", "CAD", "CHF", "CLP", "CNY", "CZK",
"DKK", "DZD", "EUR", "GBP", "ILS", "INR", "JPY", "KRW", "KWD", "MUR", "MXN", "MYR", "NOK", "NZD",
"OMR", "PEN", "PHP", "PLN", "QAR", "SAR", "SEK", "SGD", "THB", "TTD", "UYU"}
checkExchangeRatesHaveSpecifiedCurrencies(t, exchangeRateResponse.BaseCurrency, supportedCurrencyCodes, exchangeRateResponse.ExchangeRates)
}
func executeLatestExchangeRateHandler(t *testing.T, dataSourceType string) *models.LatestExchangeRateResponse {
if os.Getenv("BUILD_PIPELINE") == "1" && os.Getenv("CHECK_3RD_API") != "1" {
return nil
@@ -67,9 +67,6 @@ func InitializeExchangeRatesDataSource(config *settings.Config) error {
} else if config.ExchangeRatesDataSource == settings.CentralBankOfUzbekistanDataSource {
Container.current = newCommonHttpExchangeRatesDataProvider(config, &CentralBankOfUzbekistanDataSource{})
return nil
} else if config.ExchangeRatesDataSource == settings.InternationalMonetaryFundDataSource {
Container.current = newCommonHttpExchangeRatesDataProvider(config, &InternationalMonetaryFundDataSource{})
return nil
} else if config.ExchangeRatesDataSource == settings.UserCustomExchangeRatesDataSource {
Container.current = newUserCustomExchangeRatesDataProvider()
return nil
@@ -1,238 +0,0 @@
package exchangerates
import (
"net/http"
"strings"
"time"
orderedmap "github.com/wk8/go-ordered-map/v2"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/log"
"github.com/mayswind/ezbookkeeping/pkg/models"
"github.com/mayswind/ezbookkeeping/pkg/utils"
"github.com/mayswind/ezbookkeeping/pkg/validators"
)
const internationalMonetaryFundExchangeRateUrl = "https://www.imf.org/external/np/fin/data/rms_five.aspx?tsvflag=Y"
const internationalMonetaryFundExchangeRateReferenceUrl = "https://www.imf.org/external/np/fin/data/param_rms_mth.aspx"
const internationalMonetaryFundDataSource = "International Monetary Fund"
const internationalMonetaryFundBaseCurrency = "USD"
const internationalMonetaryFundDataUpdateDateFormat = "January 02, 2006 15:04"
const internationalMonetaryFundDataUpdateDateTimezone = "America/New_York"
var internationalMonetaryFundCurrencyNameCodeMap map[string]string
// InternationalMonetaryFundDataSource defines the structure of exchange rates data source of international monetary fund
type InternationalMonetaryFundDataSource struct {
HttpExchangeRatesDataSource
}
func init() {
internationalMonetaryFundCurrencyNameCodeMap = make(map[string]string, 38)
internationalMonetaryFundCurrencyNameCodeMap["Chinese yuan"] = "CNY"
internationalMonetaryFundCurrencyNameCodeMap["Euro"] = "EUR"
internationalMonetaryFundCurrencyNameCodeMap["Japanese yen"] = "JPY"
internationalMonetaryFundCurrencyNameCodeMap["U.K. pound"] = "GBP"
internationalMonetaryFundCurrencyNameCodeMap["U.S. dollar"] = "USD"
internationalMonetaryFundCurrencyNameCodeMap["Algerian dinar"] = "DZD"
internationalMonetaryFundCurrencyNameCodeMap["Australian dollar"] = "AUD"
internationalMonetaryFundCurrencyNameCodeMap["Botswana pula"] = "BWP"
internationalMonetaryFundCurrencyNameCodeMap["Brazilian real"] = "BRL"
internationalMonetaryFundCurrencyNameCodeMap["Brunei dollar"] = "BND"
internationalMonetaryFundCurrencyNameCodeMap["Canadian dollar"] = "CAD"
internationalMonetaryFundCurrencyNameCodeMap["Chilean peso"] = "CLP"
internationalMonetaryFundCurrencyNameCodeMap["Czech koruna"] = "CZK"
internationalMonetaryFundCurrencyNameCodeMap["Danish krone"] = "DKK"
internationalMonetaryFundCurrencyNameCodeMap["Indian rupee"] = "INR"
internationalMonetaryFundCurrencyNameCodeMap["Israeli New Shekel"] = "ILS"
internationalMonetaryFundCurrencyNameCodeMap["Korean won"] = "KRW"
internationalMonetaryFundCurrencyNameCodeMap["Kuwaiti dinar"] = "KWD"
internationalMonetaryFundCurrencyNameCodeMap["Malaysian ringgit"] = "MYR"
internationalMonetaryFundCurrencyNameCodeMap["Mauritian rupee"] = "MUR"
internationalMonetaryFundCurrencyNameCodeMap["Mexican peso"] = "MXN"
internationalMonetaryFundCurrencyNameCodeMap["New Zealand dollar"] = "NZD"
internationalMonetaryFundCurrencyNameCodeMap["Norwegian krone"] = "NOK"
internationalMonetaryFundCurrencyNameCodeMap["Omani rial"] = "OMR"
internationalMonetaryFundCurrencyNameCodeMap["Peruvian sol"] = "PEN"
internationalMonetaryFundCurrencyNameCodeMap["Philippine peso"] = "PHP"
internationalMonetaryFundCurrencyNameCodeMap["Polish zloty"] = "PLN"
internationalMonetaryFundCurrencyNameCodeMap["Qatari riyal"] = "QAR"
internationalMonetaryFundCurrencyNameCodeMap["Saudi Arabian riyal"] = "SAR"
internationalMonetaryFundCurrencyNameCodeMap["Singapore dollar"] = "SGD"
internationalMonetaryFundCurrencyNameCodeMap["Swedish krona"] = "SEK"
internationalMonetaryFundCurrencyNameCodeMap["Swiss franc"] = "CHF"
internationalMonetaryFundCurrencyNameCodeMap["Thai baht"] = "THB"
internationalMonetaryFundCurrencyNameCodeMap["Trinidadian dollar"] = "TTD"
internationalMonetaryFundCurrencyNameCodeMap["U.A.E. dirham"] = "AED"
internationalMonetaryFundCurrencyNameCodeMap["Uruguayan peso"] = "UYU"
}
// BuildRequests returns the international monetary fund exchange rates http requests
func (e *InternationalMonetaryFundDataSource) BuildRequests() ([]*http.Request, error) {
req, err := http.NewRequest("GET", internationalMonetaryFundExchangeRateUrl, nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", "") // Do not set custom user agent
return []*http.Request{req}, nil
}
// Parse returns the common response entity according to the international monetary fund data source raw response
func (e *InternationalMonetaryFundDataSource) Parse(c core.Context, content []byte) (*models.LatestExchangeRateResponse, error) {
lines := strings.Split(string(content), "\n")
if len(lines) < 1 {
log.Errorf(c, "[international_monetary_fund_datasource.Parse] content is invalid, content is %s", string(content))
return nil, errs.ErrFailedToRequestRemoteApi
}
exchangeRatesToSDR := orderedmap.New[string, float64]()
latestUpdateDate := ""
findSDRsPerCurrencyUnitLine := false
findExchangeRateDataHeader := false
for i := 0; i < len(lines); i++ {
line := lines[i]
if line == "" {
continue
}
line = strings.ReplaceAll(line, "\r", "")
if strings.Index(line, "Currency units per SDR") == 0 {
break
}
if strings.Index(line, "SDRs per Currency unit") == 0 {
findSDRsPerCurrencyUnitLine = true
continue
}
if findExchangeRateDataHeader {
items := strings.Split(line, "\t")
if len(items) != 6 {
continue
}
currencyCode, exchangeRate := e.parseExchangeRate(c, line, items)
if currencyCode != nil && exchangeRate != nil {
exchangeRatesToSDR.Set(*currencyCode, *exchangeRate)
}
continue
}
if findSDRsPerCurrencyUnitLine {
items := strings.Split(line, "\t")
if len(items) != 6 {
continue
}
if items[0] == "Currency" {
findExchangeRateDataHeader = true
latestUpdateDate = items[1]
continue
}
}
}
if latestUpdateDate == "" {
log.Errorf(c, "[international_monetary_fund_datasource.Parse] latest update date is empty")
return nil, errs.ErrFailedToRequestRemoteApi
}
if exchangeRatesToSDR.Len() < 1 {
log.Errorf(c, "[international_monetary_fund_datasource.Parse] exchange rates date is empty")
return nil, errs.ErrFailedToRequestRemoteApi
}
defaultCurrencyExchangeRateToSDR, exists := exchangeRatesToSDR.Get(internationalMonetaryFundBaseCurrency)
if !exists {
log.Errorf(c, "[international_monetary_fund_datasource.Parse] exchange rates date does not have default currency \"%s\"", internationalMonetaryFundBaseCurrency)
return nil, errs.ErrFailedToRequestRemoteApi
}
exchangeRates := make(models.LatestExchangeRateSlice, 0, exchangeRatesToSDR.Len())
for pair := exchangeRatesToSDR.Oldest(); pair != nil; pair = pair.Next() {
exchangeRates = append(exchangeRates, &models.LatestExchangeRate{
Currency: pair.Key,
Rate: utils.Float64ToString(defaultCurrencyExchangeRateToSDR / pair.Value),
})
}
timezone, err := time.LoadLocation(internationalMonetaryFundDataUpdateDateTimezone)
if err != nil {
log.Errorf(c, "[international_monetary_fund_datasource.Parse] failed to get timezone, timezone name is %s", internationalMonetaryFundDataUpdateDateTimezone)
return nil, errs.ErrFailedToRequestRemoteApi
}
updateDateTime := latestUpdateDate + " 11:00" // The IMF posts Representative and SDR exchange rates every 20 minutes from 11:00 AM to 6:00 PM U.S. EST Monday to Friday except for these holidays
updateTime, err := time.ParseInLocation(internationalMonetaryFundDataUpdateDateFormat, updateDateTime, timezone)
if err != nil {
log.Errorf(c, "[international_monetary_fund_datasource.Parse] failed to parse update date, datetime is %s", updateDateTime)
return nil, errs.ErrFailedToRequestRemoteApi
}
latestExchangeRateResp := &models.LatestExchangeRateResponse{
DataSource: internationalMonetaryFundDataSource,
ReferenceUrl: internationalMonetaryFundExchangeRateReferenceUrl,
UpdateTime: updateTime.Unix(),
BaseCurrency: internationalMonetaryFundBaseCurrency,
ExchangeRates: exchangeRates,
}
return latestExchangeRateResp, nil
}
func (e *InternationalMonetaryFundDataSource) parseExchangeRate(c core.Context, line string, lineItems []string) (*string, *float64) {
currencyCode, exists := internationalMonetaryFundCurrencyNameCodeMap[lineItems[0]]
if !exists {
log.Warnf(c, "[international_monetary_fund_datasource.parseExchangeRate] unknown currency name %s, line is %s", lineItems[0], line)
return nil, nil
}
if _, exists := validators.AllCurrencyNames[currencyCode]; !exists {
return nil, nil
}
for i := 1; i < 6; i++ {
item := lineItems[i]
if item == "" {
continue
}
rate, err := utils.StringToFloat64(item)
if err != nil {
log.Warnf(c, "[international_monetary_fund_datasource.parseExchangeRate] failed to parse rate, line is %s", line)
return nil, nil
}
if rate <= 0 {
log.Warnf(c, "[international_monetary_fund_datasource.parseExchangeRate] rate is invalid, line is %s", line)
return nil, nil
}
return &currencyCode, &rate
}
log.Warnf(c, "[international_monetary_fund_datasource.parseExchangeRate] no exchange rate data exists for currency \"%s\", line is %s", currencyCode, line)
return nil, nil
}
@@ -1,188 +0,0 @@
package exchangerates
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/models"
)
const internationalMonetaryFundMinimumRequiredContent = "SDRs per Currency unit and Currency units per SDR (1)\n" +
"last five days\n" +
"SDRs per Currency unit (2)\n" +
"\n" +
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n" +
"Chinese yuan\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n" +
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"
func TestInternationalMonetaryFundDataSource_StandardDataExtractBaseCurrency(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(internationalMonetaryFundMinimumRequiredContent))
assert.Equal(t, nil, err)
assert.Equal(t, "USD", actualLatestExchangeRateResponse.BaseCurrency)
}
func TestInternationalMonetaryFundDataSource_StandardDataExtractUpdateTime(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(internationalMonetaryFundMinimumRequiredContent))
assert.Equal(t, nil, err)
assert.Equal(t, int64(1724857200), actualLatestExchangeRateResponse.UpdateTime)
}
func TestInternationalMonetaryFundDataSource_StandardDataExtractExchangeRates(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(internationalMonetaryFundMinimumRequiredContent))
assert.Equal(t, nil, err)
assert.Contains(t, actualLatestExchangeRateResponse.ExchangeRates, &models.LatestExchangeRate{
Currency: "USD",
Rate: "1",
})
assert.Contains(t, actualLatestExchangeRateResponse.ExchangeRates, &models.LatestExchangeRate{
Currency: "CNY",
Rate: "7.128474224426247",
})
}
func TestInternationalMonetaryFundDataSource_BlankContent(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
_, err := dataSource.Parse(context, []byte(""))
assert.NotEqual(t, nil, err)
}
func TestInternationalMonetaryFundDataSource_OnlyHeader(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
_, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)"))
assert.NotEqual(t, nil, err)
}
func TestInternationalMonetaryFundDataSource_OnlyHeaderAndTitle(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
_, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)\n"+
"\n"+
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"))
assert.NotEqual(t, nil, err)
}
func TestInternationalMonetaryFundDataSource_MissingHeader(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
_, err := dataSource.Parse(context, []byte("Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
"Chinese yuan\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n"+
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
assert.NotEqual(t, nil, err)
}
func TestInternationalMonetaryFundDataSource_MissingDefaultCurrencyData(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
_, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)\n"+
"\n"+
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
"Chinese yuan\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n"))
assert.NotEqual(t, nil, err)
}
func TestInternationalMonetaryFundDataSource_DefaultCurrencyDataInvalid(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
_, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)\n"+
"\n"+
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
"Chinese yuan\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n"+
"U.S. dollar\t0\t0\t0\t0\t0\n"))
assert.NotEqual(t, nil, err)
}
func TestInternationalMonetaryFundDataSource_InvalidCurrency(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)\n"+
"\n"+
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
"Foo bar\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n"+
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
assert.Equal(t, nil, err)
assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 1)
}
func TestInternationalMonetaryFundDataSource_InvalidRate(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)\n"+
"\n"+
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
"Chinese yuan\tnull\tnull\tnull\tnull\tnull\n"+
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
assert.Equal(t, nil, err)
assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 1)
actualLatestExchangeRateResponse, err = dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)\n"+
"\n"+
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
"Chinese yuan\t0\t0\t0\t0\t0\n"+
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
assert.Equal(t, nil, err)
assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 1)
actualLatestExchangeRateResponse, err = dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)\n"+
"\n"+
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
"Chinese yuan\t\t\t\t\t\n"+
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
assert.Equal(t, nil, err)
assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 1)
}
func TestInternationalMonetaryFundDataSource_LatestDateNotHasRate(t *testing.T) {
dataSource := &InternationalMonetaryFundDataSource{}
context := core.NewNullContext()
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
"last five days\n"+
"SDRs per Currency unit (2)\n"+
"\n"+
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"+
"U.A.E. dirham\t\t0.2017770000\t0.2017230000\t\t0.2021240000\n"))
assert.Equal(t, nil, err)
assert.Contains(t, actualLatestExchangeRateResponse.ExchangeRates, &models.LatestExchangeRate{
Currency: "AED",
Rate: "3.675998751096507",
})
}
+17 -19
View File
@@ -125,24 +125,23 @@ const (
// Exchange rates data source types
const (
ReserveBankOfAustraliaDataSource string = "reserve_bank_of_australia"
BankOfCanadaDataSource string = "bank_of_canada"
CzechNationalBankDataSource string = "czech_national_bank"
DanmarksNationalbankDataSource string = "danmarks_national_bank"
EuroCentralBankDataSource string = "euro_central_bank"
NationalBankOfGeorgiaDataSource string = "national_bank_of_georgia"
CentralBankOfHungaryDataSource string = "central_bank_of_hungary"
BankOfIsraelDataSource string = "bank_of_israel"
CentralBankOfMyanmarDataSource string = "central_bank_of_myanmar"
NorgesBankDataSource string = "norges_bank"
NationalBankOfPolandDataSource string = "national_bank_of_poland"
NationalBankOfRomaniaDataSource string = "national_bank_of_romania"
BankOfRussiaDataSource string = "bank_of_russia"
SwissNationalBankDataSource string = "swiss_national_bank"
NationalBankOfUkraineDataSource string = "national_bank_of_ukraine"
CentralBankOfUzbekistanDataSource string = "central_bank_of_uzbekistan"
InternationalMonetaryFundDataSource string = "international_monetary_fund"
UserCustomExchangeRatesDataSource string = "user_custom"
ReserveBankOfAustraliaDataSource string = "reserve_bank_of_australia"
BankOfCanadaDataSource string = "bank_of_canada"
CzechNationalBankDataSource string = "czech_national_bank"
DanmarksNationalbankDataSource string = "danmarks_national_bank"
EuroCentralBankDataSource string = "euro_central_bank"
NationalBankOfGeorgiaDataSource string = "national_bank_of_georgia"
CentralBankOfHungaryDataSource string = "central_bank_of_hungary"
BankOfIsraelDataSource string = "bank_of_israel"
CentralBankOfMyanmarDataSource string = "central_bank_of_myanmar"
NorgesBankDataSource string = "norges_bank"
NationalBankOfPolandDataSource string = "national_bank_of_poland"
NationalBankOfRomaniaDataSource string = "national_bank_of_romania"
BankOfRussiaDataSource string = "bank_of_russia"
SwissNationalBankDataSource string = "swiss_national_bank"
NationalBankOfUkraineDataSource string = "national_bank_of_ukraine"
CentralBankOfUzbekistanDataSource string = "central_bank_of_uzbekistan"
UserCustomExchangeRatesDataSource string = "user_custom"
)
const (
@@ -1180,7 +1179,6 @@ func loadExchangeRatesConfiguration(config *Config, configFile *ini.File, sectio
dataSource == SwissNationalBankDataSource ||
dataSource == NationalBankOfUkraineDataSource ||
dataSource == CentralBankOfUzbekistanDataSource ||
dataSource == InternationalMonetaryFundDataSource ||
dataSource == UserCustomExchangeRatesDataSource {
config.ExchangeRatesDataSource = dataSource
} else {