//check if the ertmp node is fully filled in; if so - update er object public bool CheckAndPush(ERTMP node) { if (node.am == 0 || node.cd == null || node.rt == 0.0F) { return(false); } if (node.am > 1) { node.rt = node.rt / node.am; node.am = 1; } er = new ExchangeRate(new Currency(node.cd), new Currency("CZK"), (decimal)node.rt); return(true); }
/// <summary> /// Should return exchange rates among the specified currencies that are defined by the source. But only those defined /// by the source, do not return calculated exchange rates. E.g. if the source contains "EUR/USD" but not "USD/EUR", /// do not return exchange rate "USD/EUR" with value calculated as 1 / "EUR/USD". If the source does not provide /// some of the currencies, ignore them. /// </summary> public IEnumerable <ExchangeRate> GetExchangeRates(IEnumerable <Currency> currencies) { List <ExchangeRate> exchangeRates = new List <ExchangeRate>(); IRateProvider rateProvider = RateProviderFactory.Create(); IDictionary <string, decimal> exchangeRatesDictionary = rateProvider.GetExchangeRates(); foreach (Currency currency in currencies) { if (exchangeRatesDictionary.ContainsKey(currency.Code)) { ExchangeRate exchangeRate = ExchangeRateFactory.Create(rateProvider.SourceCurrencyCode, currency, exchangeRatesDictionary[currency.Code]); exchangeRates.Add(exchangeRate); } } return(exchangeRates); }
private void ParseData(string data, string baseCurrencyCode, IEnumerable <Currency> currencies, List <ExchangeRate> exchangeRates) { var lines = data.Split('\n').Skip(2).Where(x => !String.IsNullOrWhiteSpace(x)); // první dva řádky jsou headery; var baseCurrency = new Currency(baseCurrencyCode); // všechno děláme v poměru ke koruně try { foreach (var line in lines) { var parts = line.Split('|'); // země|měna|množství|kód|kurz var currencyCode = parts[3]; var definedCurrency = currencies.FirstOrDefault(x => x.Code.ToLower() == currencyCode.ToLower()); if (definedCurrency == null) { continue; } int amount = 0; if (!int.TryParse(parts[2], out amount)) { throw new FormatException($"Nepovedlo se naparsovat amount hodnotu '{parts[2]}' na int."); } decimal rate = 0m; if (!decimal.TryParse(parts[4], out rate)) { throw new FormatException($"Nepovedlo se naparsovat rate hodnotu '{parts[4]}' na decimal."); } var currency = new Currency(currencyCode); var exchangeRate = new ExchangeRate(baseCurrency, currency, rate / amount); // některé měny nejsou 1:1, ale např. Filipíny|peso|100|PHP|43,861 => za 100 peso dostanu 43 korun. exchangeRates.Add(exchangeRate); } } catch (Exception ex) { throw new Exception($"Došlo k následující chybě během zpracování obsahu, zkontrolujte vstupní data. Chyba: '{ex.ToString()}'. Data: {data}."); } }
private void ParseFeed(string txtFeed) { // Row follows pattern country|currency name|multiplier|code|value List <string> lines = txtFeed.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList(); lines.RemoveRange(0, 2); foreach (string line in lines) { string[] splitRow = line.Split('|'); if (splitRow.Count() < 5) { throw new Exception("Data source doesn't follow specified pattern"); } // CNB has only currency/CZK exchange rates available in TXT feed Currency sourceCurrency = new Currency(splitRow[3]); Currency targetCurrency = new Currency("CZK"); decimal value = 0; bool decSuccess = decimal.TryParse(splitRow[4], out value); if (!decSuccess) { throw new Exception("Value in feed is not a number"); } int multiplier = 1; bool intSuccess = int.TryParse(splitRow[2], out multiplier); if (!decSuccess) { throw new Exception("Multiplier in feed is not a number"); } ExchangeRate rate = new ExchangeRate(sourceCurrency, targetCurrency, value / multiplier); Rates.Add(rate); } }
public IEnumerable <ExchangeRate> GetExchangeRates() { var xmldoc = new XmlDocument(); xmldoc.Load(@"https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.xml"); XmlNodeList nodes = xmldoc.SelectNodes("//*[@kod]"); if (nodes != null) { foreach (XmlNode node in nodes) { if (node.Attributes != null) { var rate = new ExchangeRate(("CZK"), (node.Attributes["kod"].Value), Decimal.Parse(node.Attributes["kurz"].Value, NumberStyles.Any, new CultureInfo("cs-CZ"))); yield return(rate); } } } }
public IEnumerable <ExchangeRate> GetExchangeRates(IEnumerable <Currency> currencies) { // getting html code from the webpage var client = new WebClient(); var text = client.DownloadString( "https://www.cnb.cz/en/financial_markets/foreign_exchange_market/exchange_rate_fixing/daily.jsp"); // processing the html code string, using regular expressions StringReader sr = new StringReader(text); string s = null; Regex rgx = new Regex(@"kurzy_tisk"); // I studied the initial html code and after the lines with "kurzy tisk" there are a few lines with // the codes and rates that we need, so I just made a simple loop which breaks as soon as I find those // works as follows: finds "kurzy tisk", then for 20 lines (enough to read all rates) processes another // regular expression to extract the required info and parses to another method while (true) { s = sr.ReadLine(); if (rgx.IsMatch(s)) { for (int i = 0; i < 20; i++) { String k = sr.ReadLine(); MatchCollection mc = Regex.Matches(k, @"(<td>|<td align=.right.>)(.+?)</td>"); int c = 0; // iterator for matches of the regex (because the expression extracts some extra info which we need to dispose of) int y = 0; // iterator for the insides of ertmp class ERTMP tmp = new ERTMP(); foreach (Match m in mc) { if (c % 5 < 2) // we don't need names of the countries and names of their currencies { y = 0; c++; continue; } else { String x = m.Groups[2].Value; //once we reach what we need, we push it to the corresponding values of a node //pushing info to different fields of the ertmp class switch (y) { case 0: tmp.am = int.Parse(x); break; case 1: tmp.cd = x; break; case 2: tmp.rt = float.Parse(x); break; } // if our temp class is fully filled with info, we process it, push to the list and renew if (CheckAndPush(tmp)) { tmp = new ERTMP(); foreach (Currency cu in currencies) { if (cu.Code.Equals(er.SourceCurrency.Code)) { data.Add(er); er = new ExchangeRate(new Currency(""), new Currency(""), 0); break; } } } c++; y++; } } } break; } } return(data); }
public IEnumerable <ExchangeRate> GetExchangeRates(IEnumerable <Currency> currencies, ExchangeRateType rateType) { string[] lines = File.ReadAllText(ExchangeRateFile).Split('\n'); var rates = new List <ExchangeRate>(); var sourceCurrency = new Currency(ExchangeRateSourceCurrency); foreach (var row in lines.Skip(2)) { var fields = row.Split(';'); string currency = fields[0].Trim().ToUpper(); if (currencies.Any(x => x.Code == currency)) { var targetCurency = new Currency(currency); decimal value = 0; switch (rateType) { case ExchangeRateType.BuyInCash: { decimal.TryParse(fields[1].Trim(), out value); break; } case ExchangeRateType.SellInCash: { decimal.TryParse(fields[2].Trim(), out value); break; } case ExchangeRateType.MiddleInCash: { decimal value1 = 0; decimal value2 = 0; decimal.TryParse(fields[1].Trim(), out value1); decimal.TryParse(fields[2].Trim(), out value2); value = (value1 + value2) / 2; break; } case ExchangeRateType.BuyTransfer: { decimal.TryParse(fields[3].Trim(), out value); break; } case ExchangeRateType.SellTransfer: { decimal.TryParse(fields[3].Trim(), out value); break; } case ExchangeRateType.MiddleTransfer: { decimal value1 = 0; decimal value2 = 0; decimal.TryParse(fields[3].Trim(), out value1); decimal.TryParse(fields[4].Trim(), out value2); value = (value1 + value2) / 2; break; } case ExchangeRateType.CentralBank: { decimal.TryParse(fields[5].Trim(), out value); break; } default: { break; } } var rate = new ExchangeRate(sourceCurrency, targetCurency, rateType, value); rates.Add(rate); } } return(rates.ToArray()); }
/* Parse rates from CNB into Dictionary */ public void ParseRatesFromCNB(string data) { string line; int lineNo = 0; string[] fields; Decimal multipler; Currency curr; Decimal rate; ExchangeRate exRate; AllExchangeRates = new Dictionary <Currency, ExchangeRate>(new CurrencyComparer()); //AllExchangeRates = new Dictionary<Currency, ExchangeRate>(); using (StringReader reader = new StringReader(data)) { while ((line = reader.ReadLine()) != null) { lineNo += 1; // System.Console.WriteLine($"Read line {lineNo} [{line}]"); /* Parse file header */ if (lineNo == 1) { fields = line.Split(' '); if (fields.Length != 2) { throw new Exception($"Unsupported file format - wrong head [{line}]"); } try { /* Parse datestamp of the file */ LastLoadDate = DateTime.Parse(fields[0]); /* Parse dayNo of the file */ Match match = Regex.Match(fields[1], @"^\s*#(\d+)\s*$"); if (match.Success) { DayNo = Int32.Parse(match.Groups[1].Value); } else { System.Console.WriteLine($"Cannot parse day number from [{line}]"); } } catch (Exception ex) { throw new Exception($"Cannot parse file datestamp or date number [{line}]:[{ex.Message}]"); } // System.Console.WriteLine($"Parsed file header [{LastLoadDate.ToShortDateString()}] [{DayNo}]"); continue; } /* Check table header */ if (lineNo == 2) { if (line.CompareTo(CNB_EXPECTED_RATE_TABLE_HEADER) != 0) { throw new Exception($"Table header is not as expected [{line}] vs [{CNB_EXPECTED_RATE_TABLE_HEADER}]"); } // System.Console.WriteLine($"Table header accepted"); continue; } /* Parse rates */ fields = line.Split('|'); if (fields.Length != EXPECTED_COLUMNS) { throw new Exception($"Unsupported number of fields [{fields.Length}] vs [{EXPECTED_COLUMNS}]"); } try { multipler = Decimal.Parse(fields[POS_MUTIPLIER]); curr = new Currency(fields[POS_CURRENCY]); rate = Decimal.Parse(fields[POS_RATE]); exRate = new ExchangeRate(curr, czk_curr, rate / multipler); AllExchangeRates.Add(curr, exRate); // System.Console.WriteLine($"Parsed rate {lineNo-2}: {exRate}"); } catch (Exception ex) { throw new Exception($"Cannot parse rate from [{line}]:[{ex.Message}]"); } } } }