yahoo finance YQL如何查询1年以上的股票数据?

How to make yahoo finance YQL query more than 1 year stock data?

我正在使用 Tableau Web 连接器下载股票价格。源代码如下:

<html>
<meta http-equiv="Cache-Control" content="no-store" />
<head>
  <title>Stock Quote Connector-Tutorial</title>
  <script src="https://connectors.tableau.com/libs/tableauwdc-1.1.1.js" type="text/javascript"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>

  <script type="text/javascript">
  (function() {

    function buildUri(tickerSymbol, startDate, endDate) {
      var startDateStr = getFormattedDate(startDate);
      var endDateStr   = getFormattedDate(endDate);
      var queryStatement = 'select * from yahoo.finance.historicaldata where symbol = "' +
                            tickerSymbol +
                           '" and startDate = "' + startDateStr +
                           '" and endDate = "' + endDateStr + '"';
      var uri = 'http://query.yahooapis.com/v1/public/yql?q=' +
                encodeURIComponent(queryStatement) +
                "&env=http%3A%2F%2Fdatatables.org%2Falltables.env&format=json";
      return uri;
    }

    function getFormattedDate(date) {
        // Return a date in the format YYYY-MM-DD
        return date.getUTCFullYear()  +
               '-' +
               makeTwoDigits(date.getUTCMonth() + 1) +
               '-' +
               makeTwoDigits(date.getUTCDate());
    }

    function makeTwoDigits(num) {
       // Pad a digit to be two digits with leading zero
       return num <= 9 ? "0" + num.toString() : num.toString();
    }

    var myConnector = tableau.makeConnector();

    myConnector.getColumnHeaders = function() {
        var fieldNames = ['Ticker', 'Day', 'Close'];
        var fieldTypes = ['string', 'date', 'float'];
        tableau.headersCallback(fieldNames, fieldTypes);
    }

    myConnector.getTableData = function(lastRecordToken) {
        var dataToReturn = [];
        var hasMoreData = false;

        // Get parameter values and build YQL query
        var ticker = tableau.connectionData;
        var endDate = new Date();
        var startDate = new Date();
        startDate.setYear(endDate.getFullYear() - 1);
        //startDate.setYear(startDate.getFullYear() - 1);
        //startDate.setYear(startDate.getFullYear() - 1);
        //startDate.setYear(startDate.getFullYear() - 1);
        var connectionUri = buildUri(ticker, startDate, endDate);

        var xhr = $.ajax({
          url: connectionUri,
          dataType: 'json',
          success: function (data) {
              if (data.query.results) {
                var quotes = data.query.results.quote;
                var ii;
                for (ii = 0; ii < quotes.length; ++ii) {
                    var entry = {'Ticker': quotes[ii].Symbol,
                                 'Day': quotes[ii].Date,
                                 'Close': quotes[ii].Close};
                    dataToReturn.push(entry);
                }
                tableau.dataCallback(dataToReturn, lastRecordToken, false);
              }
              else {
                  tableau.abortWithError("No results found for ticker symbol: " + ticker);
              }
          },
          error: function (xhr, ajaxOptions, thrownError) {
              tableau.log("Connection error: " + xhr.responseText + "\n" + thrownError);
              tableau.abortWithError("Error while trying to connect to the Yahoo stock data source.");
          }
        });
      }
      tableau.registerConnector(myConnector);
  })();

  $(document).ready(function() {
    $("#submitButton").click(function() {
      var tickerSymbol = $('#ticker').val().trim();
      if (tickerSymbol) {
        tableau.connectionName = "Stock Data for " + tickerSymbol;
        tableau.connectionData = tickerSymbol;
        tableau.submit();
      }
    });
  });
</script>
</head>
<body>
  <p>Enter a stock ticker symbol: <input type="text" id="ticker" /></p>
  <p><button type="button" id="submitButton">Get the Data</button></p>
  </body>
</html>

当我们只是想下载1年的数据时,代码是可行的,但是如果我们改变时间超过1年(enddate.year - startdate.year > 1),它就不行了。 调试代码后发现问题出在YQL查询:

http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.historicaldata where symbol = "AAPL" and startDate = "2014-08-24" and endDate = "2016-11-23"&env=http%3A%2F%2Fdatatables.org%2Falltables.env&format=json

startDate = "2014-08-24" and endDate = "2016-11-23"超过15个月时,YQL会return无效。我正在尝试解决此问题。如果是python或者java,问题不难,先看duration是否超过1年,如果是,取1年的结果,其余n-1年也一样。但是这个画面代码让我坚持下去。我必须使代码适用于 tableau,由于缺乏对 js 和 tableau 的了解,这使我无法继续。

任何人都可以就此问题提出建议吗?我的 objective 是为了使代码对于 AAPL 这样的股票代码可以工作 >10 年。

提前致谢。

我认为 YQL 不支持超过 15 个月左右的查询。在使用 API 时,像这样的限制是相当普遍的。从 Web 数据连接器的角度来看,您要做的是实现分页。

高层次的想法是您的 WDC 的 getTableData 函数将执行多次,每次都会收集一页数据,然后将其传递给 Tableau。例如,在您的示例中,您可以通过以下方式获取多年的数据:

myConnector.getTableData = function(lastRecordToken) {
    var dataToReturn = [];
    var hasMoreData = false;

    // Get parameter values and build YQL query
    var ticker = tableau.connectionData;
    var endDate = new Date();
    var startDate = new Date();

    var maxYear = 5;        
    var yearOffset = lastRecordToken || 0;
    endDate.setYear(endDate.getFullYear() - (yearOffset));
    startDate.setYear(endDate.getFullYear() - 1);

    var connectionUri = buildUri(ticker, startDate, endDate);

    var xhr = $.ajax({
      url: connectionUri,
      dataType: 'json',
      success: function (data) {
          if (data.query.results) {
            var quotes = data.query.results.quote;
            var ii;
            for (ii = 0; ii < quotes.length; ++ii) {
                var entry = {'Ticker': quotes[ii].Symbol,
                             'Day': quotes[ii].Date,
                             'Close': quotes[ii].Close};
                dataToReturn.push(entry);
            }

            var hasMoreData = !(yearOffset == maxYear);
            tableau.dataCallback(dataToReturn, yearOffset + 1, hasMoreData)
          }
          else {
              tableau.abortWithError("No results found for ticker symbol: " + ticker);
          }
      },
      error: function (xhr, ajaxOptions, thrownError) {
          tableau.log("Connection error: " + xhr.responseText + "\n" + thrownError);
          tableau.abortWithError("Error while trying to connect to the Yahoo stock data source.");
      }
    });
  }
  tableau.registerConnector(myConnector);
  })();

本例使用dataCallback函数的两个额外参数实现分页。可以在此处找到 Web 数据连接器 API v1 中的分页文档:http://onlinehelp.tableau.com/current/api/wdc/en-us/help.htm#WDC/wdc_paging.htm%3FTocPath%3DAdditional%2520Concepts%7C_____2

此外,如果您能够使用 v2 of the WDC API(可在 Tableau 10 及更高版本中使用),我强烈推荐它。 V2 中的分页模型更加灵活易用。