private static async Task <List <APICurrencyRates> > GenerateCurrencyPairsAsync(CurrencySourceLists sourceList, CurrencySource cs, Sources source) { IEnumerable <string> toRates; List <APICurrencyRates> rateList = new List <APICurrencyRates>(); toRates = sourceList.GetListOfToCurrencies(cs.SourceFrom, cs.CurrencyCd).Select(c => c.CurrencyCd); //take is test code //Parallel.ForEach(toRates, cd => foreach (string cd in toRates) { APICurrencyRates acr = new APICurrencyRates(cs.CurrencyCd, cd, SourceDelimiters[(int)source]); // Debug.WriteLineIf((acr.CurrencyCdFrom == "BTC"), acr.CurrencyPairID); rateList.Add(acr); } //); //Debug.WriteLine("got past currency pairs"); return(rateList); }
private static void CalculateCrossRates(ref List <APICurrencyRates> rates, string baseRate) { if (rates.Any(ra => ra.CurrencyCdFrom == baseRate && ra.Rate > 0)) { List <APICurrencyRates> otherRatesFound = rates.Where(r2 => r2.CurrencyCdFrom == baseRate && r2.Rate != 0).ToList(); IEnumerable <APICurrencyRates> ratesToCalc = rates.Where(r3 => otherRatesFound.Any(or => or.CurrencyCdTo == r3.CurrencyCdFrom) && r3.Rate == -1); foreach (APICurrencyRates rc in ratesToCalc.ToList()) { APICurrencyRates rate1 = rates.SingleOrDefault(r11 => r11.CurrencyCdFrom == baseRate && r11.CurrencyCdTo == rc.CurrencyCdTo); APICurrencyRates rate2 = rates.SingleOrDefault(r12 => r12.CurrencyCdFrom == baseRate && r12.CurrencyCdTo == rc.CurrencyCdFrom); if (rate1 != null && rate2 != null && rate1.Rate > 0 && rate2.Rate > 0) //if we somehow found a bad rate, don't use it { rc.Rate = rate1.Rate * (1 / rate2.Rate); rc.TimeUpdated = rate1.TimeUpdated; } } } }
private static void CalculateOppositePairsAndAddToList(ref List <APICurrencyRates> rates) { foreach (APICurrencyRates cr in rates.ToList()) { APICurrencyRates ocr; if (!rates.Any(r => r.CurrencyCdFrom == cr.CurrencyCdTo && r.CurrencyCdTo == cr.CurrencyCdFrom)) { ocr = new APICurrencyRates(cr.CurrencyCdTo, cr.CurrencyCdFrom, cr.Delimiter) { Rate = (cr.Rate == 0) ? 0 : (1 / cr.Rate), TimeUpdated = cr.TimeUpdated }; rates.Add(ocr); } else if (rates.Any(r => r.CurrencyCdFrom == cr.CurrencyCdTo && r.CurrencyCdTo == cr.CurrencyCdFrom && r.Rate <= 0)) { ocr = rates.SingleOrDefault(r => r.CurrencyCdFrom == cr.CurrencyCdTo && r.CurrencyCdTo == cr.CurrencyCdFrom); ocr.Rate = (cr.Rate == 0) ? 0 : (1 / cr.Rate); ocr.TimeUpdated = cr.TimeUpdated; } } }
private static void GetRatesFromAPI(ref List <APICurrencyRates> rates, Sources source) { if (rates.Any()) { //get rate from api if (source == Sources.CurrencyLayer) { if (!rates.Any(r => r.CurrencyCdFrom == "USD")) //if usd isn't the list, need it to be, so create them { CurrencySourceLists sourceList = new CurrencySourceLists(getActiveOnly, SourceCodes[(int)source]); List <CurrencySource> usdOnly = new List <CurrencySource>(); usdOnly.Add(new CurrencySource { CurrencyCd = "USD", SourceFrom = "LAYER", SourceTo = "LAYER", Active = true }); rates.AddRange(CreateCurrencyPairsForSourceListAsync(sourceList, usdOnly, source).Result); //build all the pairs for usd that are in the database and add } //Debug.WriteLine("calling currencylayer"); Data.APIHandlers.CurrencyLayerAPIHandler clAPI = new Data.APIHandlers.CurrencyLayerAPIHandler(); List <Data.Entities.BasicRateEntity> clRates = clAPI.GetUSDCurrencyRates(); //Debug.WriteLine("have rates?:" + clRates.Any()); foreach (Data.Entities.BasicRateEntity clr in clRates) { if (clr.CurrencyFrom != null) { APICurrencyRates ar = rates.SingleOrDefault(rr => rr.CurrencyCdFrom == clr.CurrencyFrom && rr.CurrencyCdTo == clr.CurrencyTo); if (ar != null) { ar.Rate = clr.Rate; ar.TimeUpdated = clr.TimeUpdated; } } } if (clRates.Any()) { CalculateCrossRates(ref rates, clRates.FirstOrDefault().CurrencyFrom); CalculateOppositePairsAndAddToList(ref rates); } // Debug.WriteLine("Done currencylayer"); } else if (source == Sources.Cryptonator) { //use btc if in db, else just get the first one and deal string baseRate = (rates.Any(r => r.CurrencyCdFrom == "BTC")) ? "BTC" : rates.FirstOrDefault(r => r.Rate == -1).CurrencyCdFrom; IEnumerable <APICurrencyRates> nextBaseRates = rates.Where(r => r.CurrencyCdFrom == baseRate); //Debug.WriteLine("got base rates to call: " + nextBaseRates.Any()); // while (.Any()) //while pairs in the queue for (int i = 0; i < nextBaseRates.Count(); i++) { APICurrencyRates pair = nextBaseRates.ElementAt(i); //calculateQueue.Dequeue(); //call api handler Data.APIHandlers.CryptonatorAPIHandler crAPI = new Data.APIHandlers.CryptonatorAPIHandler(); BasicRateEntity clr = crAPI.GetRateForCurrency(pair.CurrencyPairID); Debug.WriteLine("rate retrieved"); //we got something back if (clr.CurrencyFrom != null) { //update the rate APICurrencyRates ar = rates.SingleOrDefault(rr => rr.CurrencyCdFrom == clr.CurrencyFrom && rr.CurrencyCdTo == clr.CurrencyTo); if (ar != null) { ar.Rate = clr.Rate; ar.TimeUpdated = clr.TimeUpdated; } } } //then see if we can calculate any other pairs from this call given a pair set using cross rates. This keeps the api calls down, hopefully. CalculateCrossRates(ref rates, baseRate); CalculateOppositePairsAndAddToList(ref rates); //this should also keep calls down, doing this here. //Debug.WriteLine("Done crypto"); } else if (source == Sources.Yahoo) { //nothing right now } else { throw new NotSupportedException("The source provided is not a supported currency source."); } } }