mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-17 15:09:59 +00:00
Fixes issue: https://github.com/thrasher-/gocryptotrader/issues/131 Supersedes: https://github.com/thrasher-/gocryptotrader/pull/123
202 lines
5.7 KiB
Go
202 lines
5.7 KiB
Go
package currency
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/thrasher-/gocryptotrader/common"
|
|
"github.com/thrasher-/gocryptotrader/currency/forexprovider"
|
|
"github.com/thrasher-/gocryptotrader/currency/pair"
|
|
)
|
|
|
|
const (
|
|
// DefaultBaseCurrency is the base currency used for conversion
|
|
DefaultBaseCurrency = "USD"
|
|
// DefaultCurrencies has the default minimum of FIAT values
|
|
DefaultCurrencies = "USD,AUD,EUR,CNY"
|
|
// DefaultCryptoCurrencies has the default minimum of crytpocurrency values
|
|
DefaultCryptoCurrencies = "BTC,LTC,ETH,DOGE,DASH,XRP,XMR"
|
|
)
|
|
|
|
// Manager is the overarching type across this package
|
|
var (
|
|
FXRates map[string]float64
|
|
|
|
FiatCurrencies []string
|
|
CryptoCurrencies []string
|
|
|
|
BaseCurrency string
|
|
FXProviders *forexprovider.ForexProviders
|
|
)
|
|
|
|
// SetDefaults sets the default currency provider and settings for
|
|
// currency conversion used outside of the bot setting
|
|
func SetDefaults() {
|
|
FXRates = make(map[string]float64)
|
|
BaseCurrency = DefaultBaseCurrency
|
|
|
|
FXProviders = forexprovider.NewDefaultFXProvider()
|
|
err := SeedCurrencyData(DefaultCurrencies)
|
|
if err != nil {
|
|
log.Printf("Failed to seed currency data. Err: %s", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
// SeedCurrencyData returns rates correlated with suported currencies
|
|
func SeedCurrencyData(currencies string) error {
|
|
if FXRates == nil {
|
|
FXRates = make(map[string]float64)
|
|
}
|
|
|
|
if FXProviders == nil {
|
|
FXProviders = forexprovider.NewDefaultFXProvider()
|
|
}
|
|
|
|
newRates, err := FXProviders.GetCurrencyData(BaseCurrency, currencies)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for key, value := range newRates {
|
|
FXRates[key] = value
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetExchangeRates returns the currency exchange rates
|
|
func GetExchangeRates() map[string]float64 {
|
|
return FXRates
|
|
}
|
|
|
|
// IsDefaultCurrency checks if the currency passed in matches the default fiat
|
|
// currency
|
|
func IsDefaultCurrency(currency string) bool {
|
|
defaultCurrencies := common.SplitStrings(DefaultCurrencies, ",")
|
|
return common.StringDataCompare(defaultCurrencies, common.StringToUpper(currency))
|
|
}
|
|
|
|
// IsDefaultCryptocurrency checks if the currency passed in matches the default
|
|
// cryptocurrency
|
|
func IsDefaultCryptocurrency(currency string) bool {
|
|
cryptoCurrencies := common.SplitStrings(DefaultCryptoCurrencies, ",")
|
|
return common.StringDataCompare(cryptoCurrencies, common.StringToUpper(currency))
|
|
}
|
|
|
|
// IsFiatCurrency checks if the currency passed is an enabled fiat currency
|
|
func IsFiatCurrency(currency string) bool {
|
|
return common.StringDataCompare(FiatCurrencies, common.StringToUpper(currency))
|
|
}
|
|
|
|
// IsCryptocurrency checks if the currency passed is an enabled CRYPTO currency.
|
|
func IsCryptocurrency(currency string) bool {
|
|
return common.StringDataCompare(CryptoCurrencies, common.StringToUpper(currency))
|
|
}
|
|
|
|
// IsCryptoPair checks to see if the pair is a crypto pair e.g. BTCLTC
|
|
func IsCryptoPair(p pair.CurrencyPair) bool {
|
|
return IsCryptocurrency(p.FirstCurrency.String()) &&
|
|
IsCryptocurrency(p.SecondCurrency.String())
|
|
}
|
|
|
|
// IsCryptoFiatPair checks to see if the pair is a crypto fiat pair e.g. BTCUSD
|
|
func IsCryptoFiatPair(p pair.CurrencyPair) bool {
|
|
return IsCryptocurrency(p.FirstCurrency.String()) && !IsCryptocurrency(p.SecondCurrency.String()) ||
|
|
!IsCryptocurrency(p.FirstCurrency.String()) && IsCryptocurrency(p.SecondCurrency.String())
|
|
}
|
|
|
|
// IsFiatPair checks to see if the pair is a fiat pair e.g. EURUSD
|
|
func IsFiatPair(p pair.CurrencyPair) bool {
|
|
return IsFiatCurrency(p.FirstCurrency.String()) &&
|
|
IsFiatCurrency(p.SecondCurrency.String())
|
|
}
|
|
|
|
// Update updates the local crypto currency or base currency store
|
|
func Update(input []string, cryptos bool) {
|
|
for x := range input {
|
|
if cryptos {
|
|
if !common.StringDataCompare(CryptoCurrencies, input[x]) {
|
|
CryptoCurrencies = append(CryptoCurrencies, common.StringToUpper(input[x]))
|
|
}
|
|
} else {
|
|
if !common.StringDataCompare(FiatCurrencies, input[x]) {
|
|
FiatCurrencies = append(FiatCurrencies, common.StringToUpper(input[x]))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func extractBaseCurrency() string {
|
|
for k := range FXRates {
|
|
return k[0:3]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// ConvertCurrency for example converts $1 USD to the equivalent Japanese Yen
|
|
// or vice versa.
|
|
func ConvertCurrency(amount float64, from, to string) (float64, error) {
|
|
if FXProviders == nil {
|
|
SetDefaults()
|
|
}
|
|
|
|
from = common.StringToUpper(from)
|
|
to = common.StringToUpper(to)
|
|
|
|
if from == to {
|
|
return amount, nil
|
|
}
|
|
|
|
if from == "RUR" {
|
|
from = "RUB"
|
|
}
|
|
|
|
if to == "RUR" {
|
|
to = "RUB"
|
|
}
|
|
|
|
if len(FXRates) == 0 {
|
|
SeedCurrencyData(from + "," + to)
|
|
}
|
|
|
|
// Need to extract the base currency to see if we actually got it from the Forex API
|
|
// Fixer free API sets the base currency to EUR
|
|
baseCurr := extractBaseCurrency()
|
|
|
|
var resultFrom float64
|
|
var resultTo float64
|
|
|
|
// check to see if we're converting from the base currency
|
|
if to == baseCurr {
|
|
resultFrom, ok := FXRates[baseCurr+from]
|
|
if !ok {
|
|
return 0, fmt.Errorf("Currency conversion failed. Unable to find %s in currency map [%s -> %s]", from, from, to)
|
|
}
|
|
return amount / resultFrom, nil
|
|
}
|
|
|
|
// Check to see if we're converting from the base currency
|
|
if from == baseCurr {
|
|
resultTo, ok := FXRates[baseCurr+to]
|
|
if !ok {
|
|
return 0, fmt.Errorf("Currency conversion failed. Unable to find %s in currency map [%s -> %s]", to, from, to)
|
|
}
|
|
return resultTo * amount, nil
|
|
}
|
|
|
|
// Otherwise convert to base currency, then to the target currency
|
|
resultFrom, ok := FXRates[baseCurr+from]
|
|
if !ok {
|
|
return 0, fmt.Errorf("Currency conversion failed. Unable to find %s in currency map [%s -> %s]", from, from, to)
|
|
}
|
|
|
|
converted := amount / resultFrom
|
|
resultTo, ok = FXRates[baseCurr+to]
|
|
if !ok {
|
|
return 0, fmt.Errorf("Currency conversion failed. Unable to find %s in currency map [%s -> %s]", to, from, to)
|
|
}
|
|
|
|
return converted * resultTo, nil
|
|
}
|