/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Linq; using System.Globalization; using System.Text.RegularExpressions; namespace QuantConnect { /// /// Provides commonly used currency pairs and symbols /// public static class Currencies { /// /// USD (United States Dollar) currency string /// public const string USD = "USD"; /// /// EUR (Euro) currency string /// public const string EUR = "EUR"; /// /// GBP (British pound sterling) currency string /// public const string GBP = "GBP"; /// /// INR (Indian rupee) currency string /// public const string INR = "INR"; /// /// IDR (Indonesian rupiah) currency string /// public const string IDR = "IDR"; /// /// CNH (Chinese Yuan Renminbi) currency string /// public const string CNH = "CNH"; /// /// CHF (Swiss Franc) currency string /// public const string CHF = "CHF"; /// /// HKD (Hong Kong dollar) currency string /// public const string HKD = "HKD"; /// /// JPY (Japanese yen) currency string /// public const string JPY = "JPY"; /// /// Null currency used when a real one is not required /// public const string NullCurrency = "QCC"; /// /// A mapping of currency codes to their display symbols /// /// /// Now used by Forex and CFD, should probably be moved out into its own class /// public static readonly IReadOnlyDictionary CurrencySymbols = new Dictionary { {USD, "$"}, {GBP, "₤"}, {JPY, "¥"}, {EUR, "€"}, {"NZD", "$"}, {"AUD", "$"}, {"CAD", "$"}, {CHF, "Fr"}, {HKD, "$"}, {"SGD", "$"}, {"XAG", "Ag"}, {"XAU", "Au"}, {CNH, "¥"}, {"CNY", "¥"}, {"CZK", "Kč"}, {"DKK", "kr"}, {"HUF", "Ft"}, {"INR", "₹"}, {"MXN", "$"}, {"NOK", "kr"}, {"PLN", "zł"}, {"SAR", "﷼"}, {"SEK", "kr"}, {"THB", "฿"}, {"TRY", "₺"}, {"TWD", "NT$"}, {"ZAR", "R"}, {"RUB", "₽"}, {"BRL", "R$"}, {"GNF", "Fr"}, {IDR, "Rp"}, {"BTC", "₿"}, {"BCH", "Ƀ"}, {"BSV", "Ɓ"}, {"LTC", "Ł"}, {"ETH", "Ξ"}, {"EOS", "ε"}, {"XRP", "✕"}, {"XLM", "*"}, {"ETC", "ξ"}, {"ZRX", "ZRX"}, {"USDT", "₮"}, {"ADA", "₳"}, {"SOL", "◎"}, {"DOT", "●"}, {"DOGE", "Ð"}, {"DAI", "◈"}, {"ALGO", "Ⱥ"}, {"ICP", "∞"}, {"XMR", "ɱ"}, {"XTZ", "ꜩ"}, {"IOTA", "ɨ"}, {"MIOTA", "ɨ"}, {"MKR", "Μ"}, {"ZEC", "ⓩ"}, {"DASH", "Đ"}, {"XNO", "Ӿ"}, {"REP", "Ɍ"}, {"STEEM", "ȿ"}, {"THETA", "ϑ"}, {"FIL", "⨎"}, {"BAT", "⟁"}, {"LSK", "Ⱡ"}, {"NAV", "Ꞥ"} }; /// /// Stable pairs in GDAX. We defined them because they have different fees in GDAX market /// [Obsolete("StablePairsGDAX is deprecated. Use StablePairsCoinbase instead.")] public static readonly HashSet StablePairsGDAX = StablePairsCoinbase; /// /// Stable pairs in Coinbase. We defined them because they have different fees in Coinbase market /// public static readonly HashSet StablePairsCoinbase = new() { "DAIUSDC", "DAIUSD", "GYENUSD", "PAXUSD", "PAXUSDT", "MUSDUSD", "USDCEUR", "USDCGBP", "USDTEUR", "USDTGBP", "USDTUSD", "USDTUSDC", "USTEUR", "USTUSD", "USTUSDT", "WBTCBTC" }; /// /// Define some StableCoins that don't have direct pairs for base currencies in our SPDB in Coinbase market /// This is because some CryptoExchanges do not define direct pairs with the stablecoins they offer. /// /// We use this to allow setting cash amounts for these stablecoins without needing a conversion /// security. /// private static readonly HashSet _stableCoinsWithoutPairsCoinbase = new HashSet { "USDCUSD" }; /// /// Define some StableCoins that don't have direct pairs for base currencies in our SPDB in Binance market /// This is because some CryptoExchanges do not define direct pairs with the stablecoins they offer. /// /// We use this to allow setting cash amounts for these stablecoins without needing a conversion /// security. /// private static readonly HashSet _stableCoinsWithoutPairsBinance = new HashSet { "USDCUSD", "USDTUSD", "USDPUSD", "SUSDUSD", "BUSDUSD", "USTUSD", "TUSDUSD", "FDUSDUSD", "DAIUSD", "IDRTIDR", "BNFCRUSD" }; /// /// Define some StableCoins that don't have direct pairs for base currencies in our SPDB in Bitfinex market /// This is because some CryptoExchanges do not define direct pairs with the stablecoins they offer. /// /// We use this to allow setting cash amounts for these stablecoins without needing a conversion /// security. /// private static readonly HashSet _stableCoinsWithoutPairsBitfinex = new HashSet { "EURSEUR", "XCHFCHF" }; /// /// Define some StableCoins that don't have direct pairs for base currencies in our SPDB in Binance market /// This is because some CryptoExchanges do not define direct pairs with the stablecoins they offer. /// /// We use this to allow setting cash amounts for these stablecoins without needing a conversion /// security. /// private static readonly HashSet _stableCoinsWithoutPairsBybit = new HashSet { "USDCUSD", "USDTUSD", "USDPUSD", "SUSDUSD", "BUSDUSD", "USTUSD", "TUSDUSD", "DAIUSD" }; /// /// Dictionary to save StableCoins in different Markets /// private static readonly Dictionary> _stableCoinsWithoutPairsMarkets = new Dictionary> { { Market.Binance , _stableCoinsWithoutPairsBinance}, { Market.Bitfinex , _stableCoinsWithoutPairsBitfinex}, { Market.Coinbase, _stableCoinsWithoutPairsCoinbase}, { Market.Bybit , _stableCoinsWithoutPairsBybit}, }; /// /// Checks whether or not certain symbol is a StableCoin without pair in a given market /// /// The Symbol from wich we want to know if it's a StableCoin without pair /// The market in which we want to search for that StableCoin /// True if the given symbol is a StableCoin without pair in the given market public static bool IsStableCoinWithoutPair(string symbol, string market) { if (_stableCoinsWithoutPairsMarkets.TryGetValue(market, out var stableCoins) && stableCoins.Contains(symbol)) { return true; } return false; } /// /// Gets the currency symbol for the specified currency code /// /// The currency code /// The currency symbol public static string GetCurrencySymbol(string currency) { if (string.IsNullOrEmpty(currency)) { return string.Empty; } return CurrencySymbols.TryGetValue(currency, out var currencySymbol) ? currencySymbol : currency; } /// /// Converts the string representation of number with currency in the format {currency}{value} to its decimal equivalent. /// It throws if the value cannot be converted to a decimal number. /// /// The value with currency /// The decimal equivalent to the value public static decimal Parse(string value) { decimal parsedValue; if (!TryParse(value, out parsedValue)) { throw new ArgumentException(Messages.Currencies.FailedConversionToDecimal(value)); } return parsedValue; } /// /// Converts the string representation of number with currency in the format {currency}{value} to its decimal equivalent. /// /// The value with currency /// The decimal equivalent to the string value after conversion /// True if the value was succesfuly converted public static bool TryParse(string value, out decimal parsedValue) { // Strip out the currency (any character before the first number) ignoring blank spaces since they are not supposed to be in numbers with currency value = Regex.Replace(value, @"^[^\d\s-+]+", string.Empty); return decimal.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out parsedValue); } } }