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 中的分页模型更加灵活易用。
我正在使用 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 中的分页模型更加灵活易用。