All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.objectlab.kit.fxcalc.FxRateCalculatorBuilder Maven / Gradle / Ivy

package net.objectlab.kit.fxcalc;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Parameters for an immutable FxRateCalculator.
 * The FX Calculator requires Base Rates to return rates, inverse rates or cross rates.  There are 3 ways to import rates via the FxRateCalculatorBuilder.
      
  1. addRateSnapshot(FxRate rate): add the rate to an internal map per CurrencyPair, an immutable map will be given to the Calculator so the bases rates will NOT change.
  2. ratesSnapshot(Collection<FxRate> rates): add a collection of rates to an internal map per CurrencyPair, an immutable map will be given to the Calculator so the bases rates will NOT change.
  3. baseFxRateProvider(BaseFxRateProvider) You then control when the Base Rates change, the Calculator will call the required CurrencyPair you either every time or once (if cacheBaseRates is true).
*
 * final FxRateCalculatorBuilder builder = new FxRateCalculatorBuilder() //
        .addRateSnapshot(new FxRateImpl(CurrencyPair.of("EUR", "USD"), null, true, BigDecimalUtil.bd("1.6"), BigDecimalUtil.bd("1.61")))//
        .addRateSnapshot(new FxRateImpl(CurrencyPair.of("GBP", "CHF"), null, true, BigDecimalUtil.bd("2.1702"), BigDecimalUtil.bd("2.1707")))//
        .addRateSnapshot(new FxRateImpl(CurrencyPair.of("EUR", "GBP"), null, true, BigDecimalUtil.bd("0.7374"), BigDecimalUtil.bd("0.7379")))//
        .orderedCurrenciesForCross(Lists.newArrayList("GBP", "USD")) // Use GBP as the first cross ccy, if that doesn't work use USD
        .majorCurrencyRanking(StandardMajorCurrencyRanking.getdefault())
        .precisionForFxRate(6)
        .precisionForInverseFxRate(12)
        .cacheResults(true) // only calculate a cross Fx once, cache for subsequent requests
        .cacheBaseRates(true); // if a BaseFxRateRateProvider is used, cache the rates instead of calling again for same currency pair
 * 
* @author Benoit Xhenseval */ public class FxRateCalculatorBuilder { /** * Snapshot of FxRate, typically they are the Base FX Rates (e.g. vs USD) */ private Map ratesSnapshot = new HashMap<>(); /** * If it is important for you to get the latest rates every time, you can provide a rate provider using this interface. */ private BaseFxRateProvider baseFxRateProvider; /** * The interface to determine which currency is major, defaults to StandardMajorCurrencyRanking. */ private MajorCurrencyRanking majorCurrencyRanking = StandardMajorCurrencyRanking.getDefault(); /** * If the rate required from the calculator is not immediately available, use a cross currency to calculate it; this * gives you the opportunity to select which currencies to use in which order. Defaulted to USD and then EUR. */ private List orderedCurrenciesForCross = new ArrayList<>(); /** * Number of decimal places to use on a rate, defaulted to 6. */ private int precisionForFxRate = 6; /** * Number of decimal places to use for a calculation involving an inversed rate, defaulted to 12 */ private int precisionForInverseFxRate = 12; /** * Once a new rate has been calculated, should it be cached for any further request, defaulted to true. */ private boolean cacheResults = true; /** * If using the baseFxRateProvider, should the rate be cached in the calculator, defaulted to true. */ private boolean cacheBaseRates = true; public FxRateCalculatorBuilder() { orderedCurrenciesForCross.add("USD"); orderedCurrenciesForCross.add("EUR"); } /** * Check if the builder is valid i.e. * * precisions greater than 1 * * ratesSnapshot not empty or a BaseFxRateProvider was provided * @throws IllegalArgumentException if the validation fails. */ public void checkValid() { final StringBuilder b = new StringBuilder(); if (precisionForFxRate < 2) { b.append("Precision for FX should be >=2"); } if (precisionForInverseFxRate < 2) { if (b.length() > 0) { b.append(","); } b.append("Precision for 1/FX should be >=2"); } if (ratesSnapshot.isEmpty() && baseFxRateProvider == null) { if (b.length() > 0) { b.append(","); } b.append("You must provide Base Rates Snapshots OR a BaseFxRateProvider"); } if (b.length() > 0) { throw new IllegalArgumentException(b.toString()); } } /** * If it is important for you to get the latest rates every time, you can provide a rate provider using this interface. */ public FxRateCalculatorBuilder baseFxRateProvider(final BaseFxRateProvider baseFxRateProvider) { this.baseFxRateProvider = baseFxRateProvider; return this; } public MajorCurrencyRanking getMajorCurrencyRanking() { return majorCurrencyRanking; } public List getOrderedCurrenciesForCross() { return Collections.unmodifiableList(orderedCurrenciesForCross); } public int getPrecisionForFxRate() { return precisionForFxRate; } public int getPrecisionForInverseFxRate() { return precisionForInverseFxRate; } public boolean isCacheResults() { return cacheResults; } public boolean isCacheBaseRates() { return cacheBaseRates; } public BaseFxRateProvider getBaseFxRateProvider() { return baseFxRateProvider; } /** * Once a new rate has been calculated, should it be cached for any further request? */ public FxRateCalculatorBuilder cacheResults(final boolean cacheResults) { this.cacheResults = cacheResults; return this; } /** * If using the baseFxRateProvider, should the rate be cached in the calculator, defaulted to true. */ public FxRateCalculatorBuilder cacheBaseRates(final boolean cacheBaseRates) { this.cacheBaseRates = cacheBaseRates; return this; } /** * Number of decimal places to use on a rate, defaulted to 6. */ public FxRateCalculatorBuilder precisionForFxRate(final int precisionForFxRate) { this.precisionForFxRate = precisionForFxRate; return this; } /** * Number of decimal places to use for a calculation involving an inversed rate, defaulted to 12 */ public FxRateCalculatorBuilder precisionForInverseFxRate(final int precisionForInverseFxRate) { this.precisionForInverseFxRate = precisionForInverseFxRate; return this; } /** * If the rate required from the calculator is not immediately available, use a cross currency to calculate it; this * gives you the opportunity to select which currencies to use in which order. Defaulted to USD and then EUR. */ public FxRateCalculatorBuilder orderedCurrenciesForCross(final List orderedCurrenciesForCross) { if (orderedCurrenciesForCross != null) { this.orderedCurrenciesForCross = orderedCurrenciesForCross; } return this; } /** * The interface to determine which currency is major, defaults to StandardMajorCurrencyRanking. */ public FxRateCalculatorBuilder majorCurrencyRanking(final MajorCurrencyRanking majorCurrencyRanking) { if (majorCurrencyRanking != null) { this.majorCurrencyRanking = majorCurrencyRanking; } return this; } /** * Snapshot of FxRate, typically they are the Base FX Rates (e.g. vs USD) */ public FxRateCalculatorBuilder ratesSnapshot(final Collection rates) { if (rates != null) { this.ratesSnapshot.clear(); this.ratesSnapshot = rates.stream().collect(Collectors.toMap(t -> t.getCurrencyPair(), t -> t)); } return this; } /** * Snapshot of FxRate, typically they are the Base FX Rates (e.g. vs USD) */ public FxRateCalculatorBuilder addRateSnapshot(final FxRate rate) { if (rate != null) { this.ratesSnapshot.put(rate.getCurrencyPair(), rate); } return this; } public Map getRatesSnapshot() { return ratesSnapshot; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy