I'm working to fill an array with High/Low pivot points of the "Previous Trading Day", but I'm facing an issue in terms of the time series (second section below!). I'm not sure if that PineScript's bug or my misunderstanding of how are the time-series functions working!! Please Help, very organize details.
Calling for current Trading Day, then selected the regular session ( No issues in this part )
//------------------ Selected Day of Trading
//Start Day
Start_Period= timestamp(syminfo.timezone, 2020, 12, 09, 00, 00, 00)
//End Day
End_Period = timestamp(syminfo.timezone, 2020, 12, 09, 23, 59, 59)
//------------------ Filtring Session
// Regular Session
t_reg = time("1440", session.regular)
The issue only in this coding box.
Pine script would not recognize the result of Change_Time
// Detect the change of time between selected day trading and most recent day trading (t-t[1])
Change_Time = security(syminfo.tickerid, "1440", change(time))
FunYesterday()=>
if time >= Start_Period-Change_Time and time <= End_Period-Change_Time and t_reg
[pivothigh(close, 3, 2), pivotlow(close, 3, 2)]
However, if I substitute the security function of Change_time= 60*60*24*1000will work fine!!, but I tried to avoid this method because of time deference on weekends, and other holidays.
Final Section find Pivot and Create Array ( No issues in this part )
//------------------ Pivot point at 15 min.
[ph2, pl2] = security(syminfo.tickerid, "15", FunYesterday(), lookahead = barmerge.lookahead_off)
ph2_filter= ph2 == ph2[1]?na:ph2
pl2_filter= pl2 == pl2[1]?na:pl2
//------------------ Array Part
var a = array.new_float()
if (not na(ph2_filter))
array.push(a,ph2_filter)
else if (not na(pl2_filter))
array.push(a,pl2_filter)
if barstate.islast and array.size(a)>0
y=label.new(bar_index, close, "Initial\na: " + tostring(a))
label.delete(y[1])
I'm very open if you have any other idea to import data from the most recent trading day only!!. Thank you
Related
**DATE FROM:**
def format=new java.text.SimpleDateFormat("yyyyMMdd")
def cal=Calendar.getInstance()
cal.get(Calendar.YEAR);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 31);
[format.format(cal.getTime())]
**DATE TO:**
def format=new java.text.SimpleDateFormat("yyyyMMdd")
def cal=Calendar.getInstance()
cal.add(Calendar.DAY_OF_MONTH,-cal.get(Calendar.DAY_OF_MONTH))
[format.format(cal.getTime())]
when year changes (2020 - 2021) - it confuses January of previous year with January of this year
I have to correct so that in January (December reporting) it extracts data for period 31.01 - 31.12. of previous year.
The job was wrong because it extracted data from 31.01.2021 to 31.12.2020
// retrieve details of the current date
def cal = Calendar.instance;
def currentYear = cal.get(Calendar.YEAR);
def currentMonth = cal.get(Calendar.MONTH);
// set the instance to the start of the previous month
if ( currentMonth == 0 ) {
cal.set(currentYear-1, 11, 1);
} else {
cal.set(currentYear, (currentMonth-1), 1);
}
// extract the date, and format to a string
Date previousMonthStart = cal.time;
String previousMonthStartFormatted = previousMonthStart.format('yyyy-MM-dd');
If all you are looking for is the start of the previous year as in your title then the following code:
import java.time.*
def startOfPreviousYear = LocalDate.now()
.withDayOfMonth(1)
.withMonth(1)
.minusYears(1)
println startOfPreviousYear
def againStartingFromJanuary = LocalDate.of(2021, 1, 15)
.withDayOfMonth(1)
.withMonth(1)
.minusYears(1)
println againStartingFromJanuary
demonstrates one way to accomplish this. When run, this prints (with now being today's date of 2021.Mar.10):
─➤ groovy solution.groovy
2020-01-01
2020-01-01
updated after comments
You can get the end of previous and current months with something like this:
import java.time.*
def endOfPreviousMonth = LocalDate.now()
.withDayOfMonth(1)
.minusDays(1)
def endOfCurrentMonth = LocalDate.now()
.withDayOfMonth(1)
.plusMonths(1)
.minusDays(1)
println "end of last month: ${endOfPreviousMonth}"
println "end of current month: ${endOfCurrentMonth}"
which with current date prints:
end of last month: 2021-02-28
end of current month: 2021-03-31
or if we are in january:
def endOfPreviousMonth = LocalDate.of(2021, 1, 15)
.withDayOfMonth(1)
.minusDays(1)
def endOfCurrentMonth = LocalDate.of(2021, 1, 15)
.withDayOfMonth(1)
.plusMonths(1)
.minusDays(1)
println "end of last month: ${endOfPreviousMonth}"
println "end of current month: ${endOfCurrentMonth}"
which prints:
─➤ groovy solution.groovy
end of last month: 2020-12-31
end of current month: 2021-01-31
In general you should try to, when possible, stay away from using manual date arithmetic when dealing with dates if your target is based on the current date (as in, previous month, next month, three months ago, etc). Use the api:s handed to you by java. The date classes take care of rolling years, rolling months, rolling days, leap years, etc, all that stuff that you really do not want to spend time solving yourself.
I am having a weird issue with dates formatting in Google Sheets and Google Script.
I am developing a script that reads a list of dates in a Google sheet and then sends automatic emails to a list of recipients. I have a cell in the spreadsheet with a date formatted as "dd/mm/yyyy" and then I use the following formulas (cell + 7, cell + 14, cell + 21, cell + 28, etc...) to generate all the other dates in the spreadsheet.
I use the following code to read the dates in the spreadsheet:
var sheet = SpreadsheetApp.getActiveSheet();
var drng = sheet.getDataRange();
var rng = sheet.getRange(4, 2, drng.getLastRow()-3, drng.getLastColumn());
var rngData = rng.getValues();
var todayDate = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy");
// CYCLE THROUGH DATA
for (var i = 0; i < rngData.length; i++) { // cycle through the rows in the spreadsheet
var ptLastName = rngData[i][0]; // fixed patient data used to email customization
var ptFirstName = rngData[i][1];
var ptDoB = Utilities.formatDate(rngData[i][2], "GMT+1", "dd/MM/yyyy");
var ptSex = rngData[i][3];
var ptEmail = rngData[i][4];
var ptDoS = Utilities.formatDate(rngData[i][5], "GMT+1", "dd/MM/yyyy");
var ptDoD = Utilities.formatDate(rngData[i][6], "GMT+1", "dd/MM/yyyy");
for (var j = 7; j <= 14; j++) { // cycle through follow-up data for the current patient
var currentDate = Utilities.formatDate(rngData[i][j], "GMT+1", "dd/MM/yyyy");
if (currentDate == todayDate) { // send email with the questionnaire
writeEmail(ptFirstName, ptLastName, ptSex, ptDoD, ptEmail);
rng.getCell(i+1, j+1).setBackground("yellow");
}
}
}
The issue is that when I try for read and format some of the dates they are not corresponding to the ones listed in the spreadsheet. I have noted that the wrong dates in the code are systematically 1 day earlier than the ones listed in the spreadsheet. On a closer look I have noted that some of the dates read from the spreadsheet at GMT+2 while others are GMT+1.
That's weird because I have checked my system settings (it GMT+1) as well as the spreadsheet settings (GMT+1). So I don't understand why some dates are automatically converted to GMT+2.
I tried it this way and it works okay:
function dattest() {
const ss=SpreadsheetApp.getActive();
const sh=ss.getActiveSheet();
const rg=sh.getDataRange();
const vs=rg.getValues()[0];
vs.forEach(function(d){
Logger.log(Utilities.formatDate(new Date(d),Session.getScriptTimeZone(),"dd/MM/yyyy"));
});
}
Display Values:
8/1/2020,8/8/2020,8/15/2020,8/22/2020
Formulas:
,=A1+7,=A1+14,=a1+21
The output from view Executions:
Aug 1, 2020, 2:52:37 PM Info 01/08/2020
Aug 1, 2020, 2:52:37 PM Info 08/08/2020
Aug 1, 2020, 2:52:37 PM Info 15/08/2020
Aug 1, 2020, 2:52:37 PM Info 22/08/2020
Seems correct to me
thank you for your help.
I finally found out what the problem was.
The dates in the spreadsheet were stored as dd/mm/yyyy, and the system automatically added 00.00.00 as time to them. As a result, when I was trying to read some of the dates with the code some of them were converted as the day before because of the daylight saving time adjustment. I have managed to solve the issue adding 1/3 of a day to all the dates. This way they are stored as dd/mm/yyyy 8.00.000 am and they remain the same day all year long.
I have pattern namely QUARTERDATE and FILENAME inside the file.
Both will have some value as in below eg.
My requirement is, I should rename the file like FILENAME_QUARTERDATE.
My file(myfile.txt) will be as below:
QUARTERDATE: 03/31/14 - 06/29/14
FILENAME : LEAD
field1 field2
34567
20.0 5,678
20.0 5,678
20.0 5,678
20.0 5,678
20.0 5,678
I want the the file name to be as LEAD_201402.txt
Date range in the file is for Quarter 2, so i given as 201402.
Thanks in advance for the replies.
newname=$(awk '/QUARTERDATE/ { split($4, d, "/");
quarter=sprintf("%04d%02d", 2000+d[3], int((d[1]-1)/3)+1); }
/FILENAME/ { fn = $3; print fn "_" quarter; exit; }' "$file")
mv "$file" "$newname"
How is a quarter defined?
As noted in comments to the main question, the problem is as yet ill-defined.
What data would appear in the previous quarter's QUARTERDATE line? Could Q1 ever start with a date in December of the previous year? Could the end date of Q2 ever be in July (or Q1 in April, or Q3 in October, or Q4 in January)? Since the first date of Q2 is in March, these alternatives need to be understood. Could a quarter ever start early and end late simultaneously (a 14 week quarter)?
To which the response was:
QUARTERDATE of Q2 will start as 1st Monday of April and end as last Sunday of June.
Which triggered a counter-response:
2014-03-31 is a Monday, but hardly a Monday in April. What this mainly means is that your definition of a quarter is, as yet, not clear. For example, next year, 2015-03-30 is a Monday, but 'the first Monday in April' is 2015-04-06. The last Sunday in March 2015 is 2015-03-29. So which quarter does the week (Mon) 2015-03-30 to (Sun) 2015-04-05 belong to, and why? If you don't know (both how and why), we can't help you reliably.
Plausible working hypothesis
The lessons of Y2K have been forgotten already (why else are two digits used for the year, dammit!).
Quarters run for an integral number of weeks.
Quarters start on a Monday and end on a Sunday.
Quarters remain aligned with the calendar quarters, rather than drifting around the year. (There are 13 weeks in 91 days, and 4 such quarters in a year, but there's a single extra day in an ordinary year and two extra in a leap year, which mean that occasionally you will get a 14-week quarter, to ensure things stay aligned.)
The date for the first date in a quarter will be near 1st January, 1st April, 1st July or 1st October, but the month might be December, March (as in the question), June or September.
The date for the last date in a quarter will be near 31st March, 30th June, 30th September, 31st December, but the month might be April, July, October or January.
By adding 1 modulo 12 (values in the range 1..12, not 0..11) to the start month, you should end up with a month firmly in the calendar quarter.
By subtracting 1 modulo 12 (values in the range 1..12 again) to the end month, you should end up with a month firmly in calendar quarter.
If the data is valid, the 'start + 1' and 'end - 1' months should be in the same quarter.
The early year might be off-by-one if the start date is in December (but that indicates Q1 of the next year).
The end year might be off-by-one if the end date is in January (but that indicates Q4 of the prior year).
More resilient code
Despite the description above, it is possible to write code that detects the quarter despite any or all of the idiosyncrasies of the quarter start and end dates. This code borrows a little from Barmar's answer, but the algorithm is more resilient to the vagaries of the calendar and the quarter start and end dates.
#!/bin/sh
awk '/QUARTERDATE/ {
split($2, b, "/")
split($4, e, "/")
if (b[1] == 12) { q = 1; y = e[3] }
else if (e[1] == 1) { q = 4; y = b[3] }
else
{
if (b[3] != e[3]) {
print "Year mismatch (" $2 " vs " $4 ") in file " FILENAME
exit 1
}
m = int((b[1] + e[1]) / 2)
q = int((m - 1) / 3) + 1
y = e[3]
}
quarter = sprintf("%.4d%.2d", y + 2000, q)
}
/FILENAME/ {
print $3 "_" quarter
# exit
}' "$#"
The calculation for m adds the start month plus one to the end month minus one and then does integer division by two. With the extreme cases already taken care of, this always yields a month number that is in the correct quarter.
The comment in front of the exit associated with FILENAME allows testing more easily. When processing each file separately, as in Barmar's example, that exit is an important optimization. Note that the error message gives an empty file name if the input comes from standard input. (Offhand, I'm not sure how to print the error message to standard error rather than standard output, other than by a platform-specific technique such as print "message" > "/dev/stderr" or print "message" > "/dev/fd/2".)
Given this sample input data (semi-plausible start and end dates for 6 quarters from 2014Q1 through 2015Q2):
QUARTERDATE: 12/30/13 - 03/30/14
FILENAME : LEAD
QUARTERDATE: 03/31/14 - 06/29/14
FILENAME : LEAD
QUARTERDATE: 06/30/14 - 09/28/14
FILENAME : LEAD
QUARTERDATE: 09/29/14 - 12/28/14
FILENAME : LEAD
QUARTERDATE: 12/29/14 - 03/29/15
FILENAME : LEAD
QUARTERDATE: 03/30/15 - 06/29/15
FILENAME : LEAD
The output from this script is:
LEAD_201401
LEAD_201402
LEAD_201403
LEAD_201404
LEAD_201501
LEAD_201502
You can juggle the start and end dates of the quarters within reason and you should still get the required output. But always be wary of calendrical calculations; they are almost invariably harder than you expect.
I'm trying to get the difference between 2 dates in days, hours, and seconds:
import groovy.time.*
Date now = new Date()
// Using deprecated constructor just for this example
Date newYearsDay2000 = new Date(2000, 0, 1)
use (TimeCategory) {
now - newYearsDay2000
}
This prints:
-690023 days, -14 hours, -38 minutes, -27.182 seconds
Which is obviously nothing like the difference between today's date and 2000/1/1, where am I going wrong?
Thanks,
Don
Could be an issue with the deprecated constructor?
If you use Calendar (and the Groovy updated method) to create the newYearsDay2000 var, you get:
import groovy.time.*
import static java.util.Calendar.*
Date now = new Date()
// Use the static imported Calendar class
Date newYearsDay2000 = instance.updated( year:2000, month:JANUARY, day:1 ).time
use( TimeCategory ) {
now - newYearsDay2000
}
which gives the result:
3925 days, 23 hours, 59 minutes, 59.999 seconds
Edit
Yeah, the JavaDoc for Date shows that constructor with the comment:
Date(int year, int month, int date)
Deprecated. As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date) or GregorianCalendar(year + 1900, month, date).
Which leads me to believe that:
Date newYearsDay2000 = new Date(2000, 0, 1)
Is actualy creating the Date for new Years Day in the year 3900
Date
Parameters:
year - the year minus 1900.
Flex is driving me CRAZY and I think it's some weird gotcha with how it handles leap years and none leap years. So here's my example. I have the below dateDiff method that finds the number of days or milliseconds between two dates. If I run the following three statements I get some weird issues.
dateDiff("date", new Date(2010, 0,1), new Date(2010, 0, 31));
dateDiff("date", new Date(2010, 1,1), new Date(2010, 1, 28));
dateDiff("date", new Date(2010, 2,1), new Date(2010, 2, 31));
dateDiff("date", new Date(2010, 3,1), new Date(2010, 3, 30));
If you were to look at the date comparisons above you would expect to get 30, 27, 30, 29 as the number of days between the dates. There weird part is that I get 29 when comparing March 1 to March 31. Why is that? Is it something to do with February only having 28 days? If anyone has ANY input on this that would be greatly appreciated.
public static function dateDiff( datePart:String, startDate:Date, endDate:Date ):Number
{
var _returnValue:Number = 0;
switch (datePart) {
case "milliseconds":
_returnValue = endDate.time - startDate.time;
break;
case "date":
// TODO: Need to figure out DST problem i.e. 23 hours at DST start, 25 at end.
// Math.floor causes rounding down error with DST start at dayOfYear
_returnValue = Math.floor(dateDiff("milliseconds", startDate, endDate)/(1000 * 60 * 60 * 24));
break;
}
return _returnValue;
}
This is not a leap year problem, but rather a daylight savings time problem.
To correct the code to account for DST, you need to look at the timezoneOffset of both dates to determine if the date range is spanning a DST boundary.
var adjustment:Number = ( startDate.timezoneOffset - endDate.timezoneOffset ) * 60 * 1000;
_returnValue = endDate.time - startDate.time + adjustment;
This will get the difference between the two time zones (in minutes), convert that value to milliseconds, and then apply the timezone difference to the millisecond difference to "cancel out" the DST boundary.
Naturally, when both numbers are in the same time zone, the adjustment value becomes 0 and the time values are not adjusted.
You have part of the answer in your comment: 2010-Mar-01 0:00 until 2010-Mar-31 0:00 is thirty (!) days minus one hour (because Mar 14 is DST start in 2010). Since you floor the result of your division, you get 29.
Edit: This answer is of course based on the assumption that the time property of Date takes DST into account. This would explain your problem; I didn't check it, however.