Ejemplo n.º 1
0
        private static async Task <Stream> GetResponseStreamAsync(string symbol, DateTime?startTime, DateTime?endTime, Period period, string events, CancellationToken token)
        {
            bool reset = false;

            while (true)
            {
                try
                {
                    var(client, crumb) = await YahooClientFactory.GetClientAndCrumbAsync(reset, token).ConfigureAwait(false);

                    return(await _GetResponseStreamAsync(client, crumb, token).ConfigureAwait(false));
                }
                catch (FlurlHttpException ex) when(ex.Call.Response?.StatusCode == (int)HttpStatusCode.NotFound)
                {
                    throw new Exception($"Invalid ticker or endpoint for symbol '{symbol}'.", ex);
                }
                catch (FlurlHttpException ex) when(ex.Call.Response?.StatusCode == (int)HttpStatusCode.Unauthorized)
                {
                    Debug.WriteLine("GetResponseStreamAsync: Unauthorized.");

                    if (reset)
                    {
                        throw;
                    }
                    reset = true; // try again with a new client
                }
            }

            #region Local Functions

            Task <Stream> _GetResponseStreamAsync(IFlurlClient?_client, string?_crumb, CancellationToken _token)
            {
                // Yahoo expects dates to be "Eastern Standard Time"
                startTime = startTime?.FromEstToUtc() ?? new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                endTime   = endTime?  .FromEstToUtc() ?? DateTime.UtcNow;

                var url = "https://query1.finance.yahoo.com/v7/finance/download"
                          .AppendPathSegment(symbol)
                          .SetQueryParam("period1", startTime.Value.ToUnixTimestamp())
                          .SetQueryParam("period2", endTime.Value.ToUnixTimestamp())
                          .SetQueryParam("interval", $"1{period.Name()}")
                          .SetQueryParam("events", events)
                          .SetQueryParam("crumb", _crumb);

                Debug.WriteLine(url);

                return(url
                       .WithClient(_client)
                       .GetAsync(_token)
                       .ReceiveStream());
            }

            #endregion
        }
Ejemplo n.º 2
0
        static async Task <Stream> GetResponseStreamAsync(string symbol, DateTime?startTime, DateTime?endTime, Period period, string events, CancellationToken token)
        {
            var(client, crumb) = await _GetClientAndCrumbAsync();

            try
            {
                return(await _GetResponseStreamAsync(client, crumb).ConfigureAwait(false));
            }
            catch (FlurlHttpException ex) when(ex.Call.Response?.StatusCode == HttpStatusCode.Unauthorized)
            {
                YahooClientFactory.Reset();
                (client, crumb) = await _GetClientAndCrumbAsync().ConfigureAwait(false);

                return(await _GetResponseStreamAsync(client, crumb).ConfigureAwait(false));
            }
            catch (FlurlHttpException ex) when(ex.Call.Response?.StatusCode == HttpStatusCode.NotFound)
            {
                throw new Exception("You may have used an invalid ticker, or the endpoint is invalidated", ex);
            }

            #region Local Functions

            async Task <(IFlurlClient, string)> _GetClientAndCrumbAsync()
            {
                var _client = await YahooClientFactory.GetClientAsync().ConfigureAwait(false);

                var _crumb = await YahooClientFactory.GetCrumbAsync().ConfigureAwait(false);

                return(_client, _crumb);
            }

            Task <Stream> _GetResponseStreamAsync(IFlurlClient _client, string _crumb)
            {
                var url = QueryUrl
                          .AppendPathSegment(symbol)
                          .SetQueryParam(Period1Tag, (startTime ?? new DateTime(1970, 1, 1)).ToUnixTimestamp())
                          .SetQueryParam(Period2Tag, (endTime ?? DateTime.Now).ToUnixTimestamp())
                          .SetQueryParam(IntervalTag, $"1{period.Name()}")
                          .SetQueryParam(EventsTag, events)
                          .SetQueryParam(CrumbTag, _crumb);

                //Debug.WriteLine(url);

                return(url
                       .WithClient(_client)
                       .GetAsync(token)
                       .ReceiveStream());
            }

            #endregion
        }