コード例 #1
0
        private void DownloadQuotes()
        {
            try
            {
                while (!_cancelled)
                {
                    int    remaining = 0;
                    string symbol    = null;
                    lock (_pending)
                    {
                        if (_pending.Count == 0)
                        {
                            lock (_retry)
                            {
                                foreach (var item in _retry)
                                {
                                    _completed--;
                                    _pending.Add(item);
                                }
                                _retry.Clear();
                            }
                        }
                        if (_pending.Count > 0)
                        {
                            symbol = _pending.FirstOrDefault();
                            _pending.Remove(symbol);
                            remaining = _pending.Count;
                        }
                    }
                    if (symbol == null)
                    {
                        // done!
                        break;
                    }
                    // even if it fails, we consider the job complete (from a progress point of view).
                    _completed++;

                    // weed out any securities that have no symbol or have a
                    if (string.IsNullOrEmpty(symbol))
                    {
                        // skip securities that have no symbol.
                    }
                    else if (symbol.IndexOfAny(illegalUrlChars) >= 0)
                    {
                        // since we are passing the symbol on an HTTP URI line, we can't pass Uri illegal characters...
                        OnError(string.Format(Walkabout.Properties.Resources.SkippingSecurityIllegalSymbol, symbol));
                        OnSymbolNotFound(symbol);
                    }
                    else
                    {
                        try
                        {
                            // this service doesn't want too many calls per second.
                            int ms = _throttle.GetSleep();
                            while (ms > 0)
                            {
                                if (ms > 1000)
                                {
                                    int seconds = ms / 1000;
                                    OnError("AlphaVantage quote service needs to sleep for " + seconds + " seconds");
                                }
                                else
                                {
                                    OnError("AlphaVantage quote service needs to sleep for " + ms.ToString() + " ms");
                                }
                                OnSuspended(true);
                                while (!_cancelled && ms > 0)
                                {
                                    Thread.Sleep(1000);
                                    ms -= 1000;
                                }
                                OnSuspended(false);
                                ms = _throttle.GetSleep();
                            }
                            if (_cancelled)
                            {
                                break;
                            }

                            string         uri = string.Format(address, symbol, _settings.ApiKey);
                            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
                            req.UserAgent             = "USER_AGENT=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)";
                            req.Method                = "GET";
                            req.Timeout               = 10000;
                            req.UseDefaultCredentials = false;
                            _current = req;

                            Debug.WriteLine("AlphaVantage fetching quote " + symbol);

                            WebResponse resp = req.GetResponse();
                            _throttle.RecordCall();
                            using (Stream stm = resp.GetResponseStream())
                            {
                                using (StreamReader sr = new StreamReader(stm, Encoding.UTF8))
                                {
                                    string     json  = sr.ReadToEnd();
                                    JObject    o     = JObject.Parse(json);
                                    StockQuote quote = ParseStockQuote(o);
                                    if (quote == null || quote.Symbol == null)
                                    {
                                        OnError(string.Format(Walkabout.Properties.Resources.ErrorFetchingSymbols, symbol));
                                        OnSymbolNotFound(symbol);
                                    }
                                    else if (string.Compare(quote.Symbol, symbol, StringComparison.OrdinalIgnoreCase) != 0)
                                    {
                                        // todo: show appropriate error...
                                    }
                                    else
                                    {
                                        OnQuoteAvailable(quote);
                                    }
                                }
                            }

                            OnError(string.Format(Walkabout.Properties.Resources.FetchedStockQuotes, symbol));
                        }
                        catch (System.Net.WebException we)
                        {
                            if (we.Status != WebExceptionStatus.RequestCanceled)
                            {
                                OnError(string.Format(Walkabout.Properties.Resources.ErrorFetchingSymbols, symbol) + "\r\n" + we.Message);
                            }
                            else
                            {
                                // we cancelled, so bail.
                                _cancelled = true;
                                break;
                            }

                            HttpWebResponse http = we.Response as HttpWebResponse;
                            if (http != null)
                            {
                                // certain http error codes are fatal.
                                switch (http.StatusCode)
                                {
                                case HttpStatusCode.ServiceUnavailable:
                                case HttpStatusCode.InternalServerError:
                                case HttpStatusCode.Unauthorized:
                                    OnError(http.StatusDescription);
                                    _cancelled = true;
                                    break;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            // continue
                            string message = string.Format(Walkabout.Properties.Resources.ErrorFetchingSymbols, symbol) + "\r\n" + e.Message;

                            if (message.Contains("Please visit https://www.alphavantage.co/premium/"))
                            {
                                lock (_retry)
                                {
                                    _retry.Add(symbol);
                                }
                                _throttle.CallsThisMinute += this._settings.ApiRequestsPerMinuteLimit;
                            }
                            OnComplete(PendingCount == 0, message);
                        }

                        Thread.Sleep(1000); // this is so we don't starve out the download service.
                    }
                }
            }
            catch
            {
            }
            _completed = 0;
            if (PendingCount == 0)
            {
                OnComplete(true, "AlphaVantage download complete");
            }
            else
            {
                OnComplete(false, "AlphaVantage download cancelled");
            }
            _downloadThread = null;
            _current        = null;
        }
コード例 #2
0
ファイル: IEXCloud.cs プロジェクト: clovett/MyMoney.Net
        private void DownloadQuotes()
        {
            try
            {
                // This is on a background thread
                int           max_batch = 100;
                List <string> batch     = new List <string>();
                int           remaining = 0;
                while (!_cancelled)
                {
                    string symbol = null;
                    lock (_pending)
                    {
                        if (_pending.Count > 0)
                        {
                            symbol = _pending.FirstOrDefault();
                            _pending.Remove(symbol);
                            remaining = _pending.Count;
                        }
                    }
                    if (symbol == null)
                    {
                        // done!
                        break;
                    }

                    // weed out any securities that have no symbol or have a symbol that would be invalid.
                    if (string.IsNullOrEmpty(symbol))
                    {
                        // skip securities that have no symbol.
                    }
                    else if (symbol.IndexOfAny(illegalUrlChars) >= 0)
                    {
                        // since we are passing the symbol on an HTTP URI line, we can't pass Uri illegal characters...
                        OnSymbolNotFound(symbol);
                        OnError(string.Format(Walkabout.Properties.Resources.SkippingSecurityIllegalSymbol, symbol));
                    }
                    else
                    {
                        batch.Add(symbol);
                    }

                    if (batch.Count() == max_batch || remaining == 0)
                    {
                        // even it if tails we consider the job completed from a status point of view.
                        _completed += batch.Count;
                        string symbols = string.Join(",", batch);
                        try
                        {
                            // this service doesn't want too many calls per second.
                            int ms = _throttle.GetSleep();
                            while (ms > 0 && !_cancelled)
                            {
                                if (ms > 1000)
                                {
                                    int seconds = ms / 1000;
                                    OnError("IEXCloud service needs to sleep for " + seconds + " seconds");
                                }
                                else
                                {
                                    OnError("IEXCloud service needs to sleep for " + ms.ToString() + " ms");
                                }
                                OnSuspended(true);
                                while (!_cancelled && ms > 0)
                                {
                                    Thread.Sleep(1000);
                                    ms -= 1000;
                                }
                                OnSuspended(false);
                                ms = _throttle.GetSleep();
                            }
                            if (_cancelled)
                            {
                                break;
                            }

                            string         uri = string.Format(address, symbols, _settings.ApiKey);
                            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
                            req.UserAgent             = "USER_AGENT=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)";
                            req.Method                = "GET";
                            req.Timeout               = 10000;
                            req.UseDefaultCredentials = false;
                            _current = req;

                            WebResponse resp = req.GetResponse();
                            _throttle.RecordCall();
                            using (Stream stm = resp.GetResponseStream())
                            {
                                using (StreamReader sr = new StreamReader(stm, Encoding.UTF8))
                                {
                                    string            json   = sr.ReadToEnd();
                                    JObject           o      = JObject.Parse(json);
                                    List <StockQuote> result = ParseStockQuotes(o);
                                    // make sure they are all returned, and report errors for any that are not.
                                    foreach (string s in batch)
                                    {
                                        StockQuote q = (from i in result where string.Compare(i.Symbol, s, StringComparison.OrdinalIgnoreCase) == 0 select i).FirstOrDefault();
                                        if (q == null)
                                        {
                                            OnError(string.Format("No quote returned for symbol {0}", s));
                                            OnSymbolNotFound(s);
                                        }
                                        else
                                        {
                                            OnQuoteAvailable(q);
                                        }
                                    }
                                }
                            }

                            Thread.Sleep(1000); // there is also a minimum sleep between requests that we must enforce.

                            symbols = string.Join(", ", batch);
                            OnError(string.Format(Walkabout.Properties.Resources.FetchedStockQuotes, symbols));
                        }
                        catch (System.Net.WebException we)
                        {
                            if (we.Status != WebExceptionStatus.RequestCanceled)
                            {
                                OnError(string.Format(Walkabout.Properties.Resources.ErrorFetchingSymbols, symbols) + "\r\n" + we.Message);
                            }
                            else
                            {
                                // we cancelled, so bail.
                                _cancelled = true;
                                break;
                            }

                            HttpWebResponse http = we.Response as HttpWebResponse;
                            if (http != null)
                            {
                                // certain http error codes are fatal.
                                switch (http.StatusCode)
                                {
                                case HttpStatusCode.ServiceUnavailable:
                                case HttpStatusCode.InternalServerError:
                                case HttpStatusCode.Unauthorized:
                                    OnError(http.StatusDescription);
                                    _cancelled = true;
                                    break;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            // continue
                            OnError(string.Format(Walkabout.Properties.Resources.ErrorFetchingSymbols, symbols) + "\r\n" + e.Message);
                        }
                        batch.Clear();
                    }

                    _current = null;
                }
            }
            catch
            {
            }
            if (PendingCount == 0)
            {
                OnComplete(true, "IEXCloud download complete");
            }
            else
            {
                OnComplete(false, "IEXCloud download cancelled");
            }
            _downloadThread = null;
            _current        = null;
            _completed      = 0;
        }