How to I query price at a particular date and time using Alphavantage API.
For eg: I tried this:
https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=^INFY&interval=1min&outputsize=compact&apikey=***********
However I want to pass both Date and Time and need the HIGH for that particular minute for that symbol.
I am using the Excel 365 Add-On but I can use Google Sheets as well.
Possible?
The url will give you a json. You have then to parse it and then apply a formula to retrieve the max value and date/hour/minute it occurs. To parse the json, try with your own api key :
function getAllDataJSON(code) {
var url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol='+code+'&interval=1min&apikey='+YOURAPIKEY
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())['Time Series (1min)']
var resultat = []
for (var elem in eval(data)){
resultat.push([elem,eval(data[elem]['1. open']),eval(data[elem]['2. high']),eval(data[elem]['3. low']),eval(data[elem]['4. close']),eval(data[elem]['5. volume'])])
}
return resultat
}
If you want extended period, the answer will be a csv file
function getAllDataCSV(code){
// last month : slice=year1month1 (by default) ... until slice=year2month12 (farthest month from today)
// interval : 1min
var url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY_EXTENDED&slice=year1month1&symbol='+code+'&interval=1min&apikey='+apikey
var csv = UrlFetchApp.fetch(url).getContentText();
return Utilities.parseCsv(csv)
}
Related
I have a google sheet form response data where column B is a time duration value. But it shows time in AM or PM. I tried different app script but still unable to get the value a time Delta( difference) format
The form response data itself gives time in AM or PM. Help me in this matter.
This is my latest code.
function timeFormat() {
var cell = SpreadsheetApp.getActive().getSheetByName('Sheet4').getRange('B1:B');
cell.setNumberFormat('hh:mm');
}
Is your issue basically with the AM / PM part popping up when you click into the cells formatted as 'hh:mm'? You can fix that by applying the duration format for hours to the entire range (e.g. B2:B)
GAS:
range.setNumberFormat('[hh]:mm');
Or manually under Format -> Number -> More Formats -> Custom number format (a lot easier)
And here's how the end result looks like. Note that you get the 'AM/PM' part popping up when you click into cells formatted as 'hh:mm' but not with the ones formatted as [hh]:mm:
You could use this function as a cell function and then format the cells as a duration and you will get hours:minutes:seconds.
function days(Start,End) {
if(Start && End)
{
var second=1000;
var minute=60*second;
var hour=minute*60;
var day=hour*24;
var t1=new Date(Start).valueOf();
var t2=new Date(End).valueOf();
var d=t2-t1;
return d/day;
}
else
{
return 'Invalid Inputs';
}
}
This essentially returns the date number in the form that the spreadsheet understands as days and fraction of days.
In a Google spreadsheet I pull some numbers from Google Analytics via Apps script and the Analytics API.
One of the numbers is the bounce rate, which is returned in the format 42.380071394743425. I want to display this with two digits after the decimal point (and I need to add a percentage sign). I would like to do this via setNumberFormat.
However a format token like "0.00", "#,##" etc result in output like "4.238.007.139.4743.425" which is not at all what I want. I somewhat suspect a part of the problem might be that my document is in German, with a comma as decimal delimiter, and the number from the API returned has a decimal point (or I might be overlooking something simple, wich is just as likely).
So, can I use setNumberFormat, and what format token do I have to use to turn "42.380071394743425" into "42,38%" ?
I am using the build-in App service. I do not have problems with other types of KPIs, just percentage values like bounceRate.
var viewId = "<myViewId>"
var options = {};
options['max-results'] = 1;
metric = "ga:bounceRate"; // actually this is passed in as a function parameter
// formatDate is a wrapper that calls Utilities.formatDate
var startDate = formatDate(pDate, 'yyyy-MM-dd');
var endDate = formatDate(pDate, 'yyyy-MM-dd');
var report = Analytics.Data.Ga.get(viewId, startDate, endDate, metric, options);
.....
token = [];
// format is passed in as a function parameter to fit the metric
switch(format) {
case("percentage"):
token.push(["0.00%"]);
break;
default:
token.push(["0.00"]); // tried different options to no avail
break;
}
sheet.getRange(<row>,<col>).setValue(report.rows).setNumberFormats(token);
As I said the code itself is working fine if the API returns unformatted numbers (so I don't think the problem is in the code), but I can't get the bounceRate to display the way I want.
Thank you for your time.
Select Format > Number > More Formats > Custom number formats... and type ##.##"%".
Or you can set the number format by GAS the same way.
var range = sheet.getActiveRange();
range.setNumberFormat('##.##"%"');
This is US locale based. You may change the format string according to your spreadsheet's locale(File > Spreadsheet settings...). As you can see in this documentation, the format is dependant on the spreadsheet's locale.
I have a column contain a date in "Sep -13" format.
When I access it from code, it gives integer value. How can I get a date object?
If I use "dd/mm/yyyy" format in sheet, it gives me date object.
function check()
{
var source = SpreadsheetApp.openById('sheet id');
var sourcesheet = source.getSheetByName('sheet name');
var tt = sourcesheet.getRange('F700').getValue();
debugger;
}
Result:
That cells original value might be an integer. That could be happen if you copy and paste values only for a date. so .getValue() will give you that number.
You can use that number to create a date object. JavaScript dates can be constructed by passing milliseconds
//base date 01/01/1970 integer value :25569
//excelDate your date in integer
var myDate = new Date((excelDate - 25569)*86400*1000);
In the Google reference documentation I found a short function to convert RFC3339 date string to a valid Date object. The code is very simple and goes like this :
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
The problem is that it does not work.(I'm surprised they publish a code that doesn't work... am I missing something ?)
I also had an issue while using JSON to stringify and parse dates because the JSON method returns a UTC value (a Z at the end) and because of that I lose the Time zone information. Google's code does not handle that issue either (even if it worked).
Below is a demo code I used to test it and a solution I wrote to get what I want. Not sure it's very efficient nor well written but at least I get the result I want (I'm executing this code in a script set to GMT+2, Belgium summer time).
I'm open to any suggestion to improve this code.(and that would be the subject of this question)
I added a lot of logs and comments in the code to make it as clear as possible :
function testJSONDate() {
Logger.log('starting value : "2016/3/31 12:00:00"');
var jsDate = JSON.stringify(new Date("2016/3/31 12:00:00"));// time is 12:00 I'm in GMT+2
Logger.log('JSON.stringify value : '+jsDate);
Logger.log('JSON parse jsDate : '+JSON.parse(jsDate)); // time is 10:00, UTC
var jsDateWithoutQuotes = jsDate.replace(/"/,'');
var date = parseDate(jsDateWithoutQuotes);
Logger.log('parsed RFC3339 date using Google\'s code : '+date); // does not return a valid date
var otherFunction = parseDate2(jsDateWithoutQuotes);
Logger.log('parsed RFC3339 date using other code : '+otherFunction); // does return a valid date in my TZ
}
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
function parseDate2(string) {
var refStr = new Date().toString();
var fus = Number(refStr.substr(refStr.indexOf('GMT')+4,2));
Logger.log('TZ offset = '+fus);
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
var t = parts[1].split(':');
return new Date(new Date(parts[0]).setHours(+t[0]+fus,+t[1],0));
}
Logger results :
EDIT following first answer
After a small change in the code I managed to get Google's snippet to work but the problem of time zone being lost still remains because of the way JSON converts JS date objects.
new code and logger result below:
function testJSONDate() {
Logger.log('starting value : 2016/3/31 12:00:00');
var jsDate = JSON.stringify(new Date("2016/3/31 12:00:00"));// time is 12:00 I'm in GMT+2
Logger.log('JSON.stringify value : '+jsDate);
Logger.log('JSON parse jsDate : '+JSON.parse(jsDate)); // time is 10:00, UTC
var jsDateWithoutQuotesAndMillisecAndZ = jsDate.replace(/"/g,'').split('.')[0];
Logger.log('jsDateWithoutQuotesAndMillisecAndZ = '+jsDateWithoutQuotesAndMillisecAndZ);
var date = parseDate(jsDateWithoutQuotesAndMillisecAndZ);
Logger.log('parsed RFC3339 date using Google\'s code : '+date); // does not return a valid date
var otherFunction = parseDate2(jsDateWithoutQuotesAndMillisecAndZ);
Logger.log('parsed RFC3339 date using other code : '+otherFunction); // does return a valid date in the right tz
}
You have taken a little helper function out of context. It was only meant as a stopgap device to get the strings returned by a particular API (Google Calendar API) to parse correctly in Apps Script. It is not any kind of universal date converter. A project member threw it together when filing an issue, and a follow-up message in that thread points out another detail that the function doesn't handle.
As of now, the date parser in Apps Script correctly parses the following formats:
function testdate() {
Logger.log(new Date("2016/03/31 10:00:00")); // local time
Logger.log(new Date("2016/03/31 10:00:00 +2:00")); // with given offset
Logger.log(new Date("2016-03-31T08:00:00.000Z")); // in UTC
}
Note that milliseconds are required for UTC timestamp, but are not allowed for the others.
What you do with a datetime string that needs to be parsed but is not one of the above, depends on its format. If you have 2016-03-31T10:00:00 (apparently, this is what Google Calendar API returns) and this is meant to be in local time, then you need exactly what the quoted parse function does: replace T by space and - by /. If the same string represents UTC time, one needs to add .000Z at the end. And so on.
Using Google Apps script, I'm trying to take a date written in a spreadsheet and add it as a date field to a Contact. Specifically, I cannot seem to convert the month of the javascript date read from the spreadsheet into a month enum that the contact.addDate method can use.
var months = ContactsApp.Month.values;
var birthdate = new Date( spreadsheet_date );
var month = months[ birthdate.getMonth() ];
contact.addDate(ContactsApp.Field.BIRTHDAY,
month, birthdate.getDate(), birthdate.getFullYear() );
There are lots of ways to approach, as I see a switch is the easiest, there's no one-liner though, as there's no month name built into Javascript:
var month = birthdate.getMonth();
switch(month){
case 0:
month = ContactsApp.Month.JANUARY;
break;
case 1:
month = ContactsApp.Month.FEBRUARY;
break;
[...]
case 11:
month = ContactsApp.Month.DECEMBER
break;
}
another pattern...
var arr = [
CalendarApp.Month.JANUARY,
CalendarApp.Month.FEBRUARY,
CalendarApp.Month.MARCH,
...
];
var month = arr[birthdate.getMonth()];
See how I'm doing it in this post of a different question I have, here
Google Contact "Birthday" field not showing when set from Apps Script.
You need a mapping from the enum to the month name. This will avoid the long switch statement. This solution was initially provided to me by #tehhowch.
var month = months[ birthdate.getMonth() ];
var monthAsInt={JANUARY:1,FEBRUARY:2,MARCH:3,APRIL:4,MAY:5,JUNE:6,JULY:7
,AUGUST:8,SEPTEMBER:9,OCTOBER:10,NOVEMBER:11,DECEMBER:12}[month];
as a function;
function monthToInt(month) {
return {JANUARY:1,FEBRUARY:2,MARCH:3,APRIL:4,MAY:5,JUNE:6,JULY:7
,AUGUST:8,SEPTEMBER:9,OCTOBER:10,NOVEMBER:11,DECEMBER:12}[month];
}