如何使雅虎财务YQL查询超过1年的股票数据?

时间:2016-11-24 02:12:39

标签: javascript html tableau yql yahoo-finance

我使用tableau网络连接器下载股票价格。源代码如下:

<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将返回null。我试图解决这个问题。如果是python或java,问题并不难,首先检查持续时间是否超过1年,如果是,获得1年结果,并在休息n-1年做同样的事情。但这个画面代码让我坚持下去。我必须使代码可以使用tableau,这使得我无法继续,因为缺乏关于js和tableau的知识。

任何人都可以就此问题提出建议吗?我的目标是使代码可用于像AAPL这样的股票代码> 10年。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我不相信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中的分页模型更灵活,更易于使用。