/// <summary>
        /// Gets a series of Historical Market Data from the starting date
        /// to the end date.
        /// </summary>
        /// <param name="mdq">
        /// A <see cref="MarketDataQuery"/> with the data request.
        /// </param>
        /// <param name="end">
        /// A <see cref="DateTime"/> with the ending date of the period to fetch data from.
        /// </param>
        /// <param name="dates">
        /// In case of success, a list of the dates data was fetched from in the requested period.
        /// </param>
        /// <param name="marketData">
        /// In case of success, a list of the fetched market data day
        /// by day corresponding to <see cref="dates"/>.
        /// </param>
        /// <returns>
        /// A <see cref="RefreshStatus"/> indicating if the query was successful.
        /// </returns>
        public RefreshStatus GetTimeSeries(MarketDataQuery mdq, DateTime end, out DateTime[] dates, out IMarketData[] marketData)
        {
            RefreshStatus status = new RefreshStatus();

            // Check if close value was requested.
            switch (mdq.Field)
            {
            case "close":
            {
                break;
            }

            default:
            {
                // In case the request is not close return an error.
                marketData           = null;
                dates                = null;
                status.HasErrors     = true;
                status.ErrorMessage += "GetTimeSeries: Market data not available (only " +
                                       "close values are available, " +
                                       mdq.Field + " was requested).";
                return(status);
            }
            }

            // For now only Scalar requests are handled.
            if (mdq.MarketDataType == typeof(Scalar).ToString())
            {
                List <MEFFHistoricalQuote> quotes = null;

                try
                {
                    // Request the data to the Market Data Provider.
                    quotes = MEFFAPI.GetHistoricalQuotes(TickerUtility.PreparseSymbol(mdq.Ticker), mdq.Date, end);
                }
                catch (Exception e)
                {
                    // There can be conversion, server availability
                    // and other exceptions during this request.
                    marketData           = null;
                    dates                = null;
                    status.HasErrors     = true;
                    status.ErrorMessage += "GetTimeSeries: Market data not available due " +
                                           "to problems with MEFF service: " + e.Message;
                    return(status);
                }

                // Check if there is at least one result.
                if (quotes.Count >= 1)
                {
                    // Allocate the structures for the output.
                    marketData = new Scalar[quotes.Count];
                    dates      = new DateTime[quotes.Count];

                    // Scan the list of quotes to prepare the data for Fairmat.
                    for (int i = 0; i < quotes.Count; i++)
                    {
                        // Fill the dates array from the date field of each quote.
                        dates[i] = quotes[i].SessionDate;

                        // Prepare the single scalar data.
                        Scalar val = new Scalar();
                        val.TimeStamp = quotes[i].SessionDate;
                        val.Value     = quotes[i].SettlPrice;

                        // Put it in the output structure.
                        marketData[i] = val;
                    }

                    return(status);
                }
                else
                {
                    // If there isn't at least one result return an error.
                    marketData           = null;
                    dates                = null;
                    status.HasErrors     = true;
                    status.ErrorMessage += "GetTimeSeries: Market data not available: " +
                                           "empty data set for the request.";
                    return(status);
                }
            }
            else
            {
                // If control falls through here it means the request type was not supported.
                marketData           = null;
                dates                = null;
                status.HasErrors     = true;
                status.ErrorMessage += "GetTimeSeries: Market data request type (" +
                                       mdq.MarketDataType +
                                       ") not supported by the Market Data Provider.";
                return(status);
            }
        }
        /// <summary>
        /// Gets a series of Historical Market Data from the starting date
        /// to the end date.
        /// </summary>
        /// <param name="mdq">
        /// A <see cref="MarketDataQuery"/> with the data request.
        /// </param>
        /// <param name="end">
        /// A <see cref="DateTime"/> with the ending date of the period to fetch data from.
        /// </param>
        /// <param name="dates">
        /// In case of success, a list of the dates data was fetched from in the requested period.
        /// </param>
        /// <param name="marketData">
        /// In case of success, a list of the fetched market data day
        /// by day corresponding to <see cref="dates"/>.
        /// </param>
        /// <returns>
        /// A <see cref="RefreshStatus"/> indicating if the query was successful.
        /// </returns>
        public RefreshStatus GetTimeSeries(MarketDataQuery mdq, DateTime end, out DateTime[] dates, out IMarketData[] marketData)
        {
            RefreshStatus status = new RefreshStatus();

            // Holds whathever we should take market close or market open values.
            bool closeRequest;

            // Holds the currency conversion target in case a market different than
            // US is choosen. This handles conversion from USD values provided by yahoo.
            string targetMarket = null;

            string ticker = TickerUtility.PreparseSymbol(mdq.Ticker);
            bool   divisionTransformation = false;
            bool   inverseTransformation  = false;

            // Check if open or close value was requested.
            switch (mdq.Field)
            {
            case "open":
            {
                closeRequest = false;
                break;
            }

            case "close":
            {
                closeRequest = true;
                break;
            }

            default:
            {
                // In case the request is neither open or close return an error.
                marketData           = null;
                dates                = null;
                status.HasErrors     = true;
                status.ErrorMessage += "GetTimeSeries: Market data not available (only " +
                                       "open and close values are available, " +
                                       mdq.Field + " was requested).";
                return(status);
            }
            }

            // Gather in which currency to get the data, this will require
            // an additional data fetching for the target currency for the same time period.
            if (mdq.Market.Length > 0 && mdq.Market != "US")
            {
                // Try to convert the entries in the Fairmat drop down box,
                // for the rest rely on the user.
                switch (mdq.Market)
                {
                case "EU":
                {
                    targetMarket = "EUR";
                    break;
                }

                case "GB":
                {
                    targetMarket = "GBP";
                    break;
                }

                case "JP":
                {
                    targetMarket = "JPY";
                    break;
                }

                case "CH":
                {
                    targetMarket = "CHF";
                    break;
                }

                case "HK":
                {
                    targetMarket = "HKD";
                    break;
                }

                default:
                {
                    // In the fallback scenario just use directly the provided string.
                    targetMarket = mdq.Market;
                    break;
                }
                }
            }

            // Check for currencies and handle them in a special way.
            // Check the single currency only (eg: EUR for USDEUR).
            if (GetCurrencyList().Contains(ticker))
            {
                ticker += "=X";

                // Disable the feature for this for now.
                targetMarket = null;
            }
            else
            {
                // Attempt a more throughout parsing. Check for <currency><currency> formats.
                foreach (string currency in GetCurrencyList())
                {
                    if (ticker.StartsWith(currency))
                    {
                        if (currency == "USD")
                        {
                            // If usd is in the ticker name it's a special case due to the way
                            // Yahoo! Finance keeps currencies.
                            ticker       = ticker.Remove(0, 3) + "=X";
                            targetMarket = null;
                        }
                        else if (ticker.Remove(0, 3) == "USD")
                        {
                            // This is the inverse of the previous case.
                            // From other currency to USD. Similarly to above it's a special case.
                            ticker                = currency + "=X";
                            targetMarket          = null;
                            inverseTransformation = true;
                        }
                        else
                        {
                            // Normal not USD to not USD currency conversions.
                            targetMarket           = currency;
                            ticker                 = ticker.Remove(0, 3) + "=X";
                            divisionTransformation = true;
                        }

                        break;
                    }
                }
            }

            // For now only Scalar requests are handled.
            if (mdq.MarketDataType == typeof(Scalar).ToString())
            {
                List <YahooHistoricalQuote> quotes = null;
                Dictionary <DateTime, YahooHistoricalQuote> currencyQuotes = new Dictionary <DateTime, YahooHistoricalQuote>();

                try
                {
                    // Request the data to the Market Data Provider.
                    quotes = YahooFinanceAPI.GetHistoricalQuotes(ticker, mdq.Date, end);

                    if (targetMarket != null)
                    {
                        // If we need currency quotes in order to handle currency conversions
                        // fetch them now.
                        List <YahooHistoricalQuote> fetchedCurrencyQuotes = YahooFinanceAPI.GetHistoricalQuotes(targetMarket + "=X", mdq.Date, end);

                        // Put all items in a dictionary for easy fetching.
                        fetchedCurrencyQuotes.ForEach(x => currencyQuotes.Add(x.Date, x));
                    }
                }
                catch (Exception e)
                {
                    // There can be conversion, server availability
                    // and other exceptions during this request.
                    marketData           = null;
                    dates                = null;
                    status.HasErrors     = true;
                    status.ErrorMessage += "GetTimeSeries: Market data not available due " +
                                           "to problems with Yahoo! Finance: " + e.Message;
                    return(status);
                }

                // Check if there is at least one result.
                if (quotes.Count >= 1)
                {
                    // Allocate the structures for the output.
                    List <Scalar>   readyMarketData = new List <Scalar>();
                    List <DateTime> readyDates      = new List <DateTime>();

                    // Scan the list of quotes to prepare the data for Fairmat.
                    for (int i = 0; i < quotes.Count; i++)
                    {
                        // Prepare the single scalar data.
                        Scalar val = new Scalar();
                        val.TimeStamp = quotes[i].Date;
                        val.Value     = (closeRequest == true) ? quotes[i].Close : quotes[i].Open;

                        // Handle currency conversions if needed.
                        if (currencyQuotes != null)
                        {
                            // Check if the entry in a date exists also for the
                            // currency conversion, if not discard the data.
                            if (!currencyQuotes.ContainsKey(quotes[i].Date))
                            {
                                // We skip this entry.
                                continue;
                            }

                            YahooHistoricalQuote currencyQuote = currencyQuotes[quotes[i].Date];

                            //if (divisionTransformation)
                            //{
                            //    val.Value /= (closeRequest == true) ? currencyQuote.Close : currencyQuote.Open;
                            //}
                            //else
                            //{
                            //    val.Value *= (closeRequest == true) ? currencyQuote.Close : currencyQuote.Open;
                            //}
                        }

                        // Apply an inverse transformation, used for currency values when going
                        // from a not USD currency to USD.
                        //if (inverseTransformation)
                        //{
                        //    val.Value = 1 / val.Value;
                        //}

                        // Put it in the output structure.
                        readyMarketData.Add(val);

                        // Fill the dates array from the date field of each quote.
                        readyDates.Add(quotes[i].Date);
                    }

                    // Put in the output data.
                    marketData = readyMarketData.ToArray();
                    dates      = readyDates.ToArray();

                    return(status);
                }
                else
                {
                    // If there isn't at least one result return an error.
                    marketData           = null;
                    dates                = null;
                    status.HasErrors     = true;
                    status.ErrorMessage += "GetTimeSeries: Market data not available: " +
                                           "empty data set for the request.";
                    return(status);
                }
            }
            else
            {
                // If control falls through here it means the request type was not supported.
                marketData           = null;
                dates                = null;
                status.HasErrors     = true;
                status.ErrorMessage += "GetTimeSeries: Market data request type (" +
                                       mdq.MarketDataType +
                                       ") not supported by the Market Data Provider.";
                return(status);
            }
        }