# Date Math and display the date on the chart

#### gravity2726

##### Member
VIP
For example :

to_date=20211008
X=10 days
Need to add 10 days to to_date and display the date on the chart;
If possible ; Even if the date is in the future

Solution
If I wanted to get get the date X-Trading Days in the past from today (excluding today), how can I go about doing that? I tried messing around with +/- etc, but no luck.

e.g. for today (20210910), I want to get the trading date 5 trading days ago (20210902 - due to 3 non-trading days in between), how would I achieve that?

This looks for the last trading day for the days you input the prior trading date.

Ruby:
``````def ymd      = GetYYYYMMDD();
def candles  = !isnan(close);
def capture  = candles and ymd != ymd[1];
def dayCount = CompoundValue(1, if capture then dayCount[1] + 1 else dayCount[1], 0);
def thisDay  = (HighestAll(dayCount) - dayCount) ;

input daysback  = 5;
def today =...``````

#### bmn

##### Member
This looks for the last trading day for the days you input the prior trading date.
THANK YOU!

One last thing, I'm then trying to calculate CALENDAR days between that date and last_trading_day (most recent trading day) but am not getting the label to show up. Can you please check what I'm doing wrong?

Ruby:
``````def num_calendar_days = DaysFromDate(TD_daysback);

#### SleepyZ

##### Well-known member
THANK YOU!

One last thing, I'm then trying to calculate CALENDAR days between that date and last_trading_day (most recent trading day) but am not getting the label to show up. Can you please check what I'm doing wrong?

Ruby:
``````def num_calendar_days = DaysFromDate(TD_daysback);

See if this helps

Code:
``````def ymd      = GetYYYYMMDD();
def candles  = !IsNaN(close);
def capture  = candles and ymd != ymd[1];
def dayCount = CompoundValue(1, if capture then dayCount[1] + 1 else dayCount[1], 0);
def thisDay  = (HighestAll(dayCount) - dayCount) ;

input daysback  = 5;
def today = 1;
def last_trading_day = HighestAll(if !IsNaN(close) and IsNaN(close[-1]) then GetYYYYMMDD() else Double.NaN);
def TD_daysback = if thisDay == daysback then GetYYYYMMDD() else TD_daysback[1];

#Calendar Days between the above dates----------------------
def cdays =  DaysFromDate(HighestAll(TD_daysback)) - DaysFromDate(last_trading_day);
AddLabel(1, "Calendar Days from " + AsPrice(TD_daysback) + " to " + AsPrice(last_trading_day) + " = " + AbsValue(cdays + 1), Color.yellow);``````

bmn

#### bmn

##### Member
See if this helps
This works, thank you! Not a big deal, but why does it show 37 cdays when I set daysback = 0?

#### gravity2726

##### Member
VIP
Thank you Sleepz that is what I am looking for ; For some reason it is not working for the X_Date (instead of date) which we used in the previous code.
@SleepyZ Here is the code with the X_date ;
Code:
``````input anchor_date = 20210801;

input to_date = 20210831;

input show_label = yes;

def Xamt = if GetYYYYMMDD()[1] < anchor_date and GetYYYYMMDD() >= anchor_date

then high

else if Between(GetYYYYMMDD(), anchor_date, to_date)

then Max(high, Xamt[1])

else double.nan;

def X = highestall(Xamt);

def X_Date = if high == X then GetYYYYMMDD() else X_Date[1];

input days = 10;

def yymmdd = X_date; /*THIS IS THE STEP DOESNT WORK/

def year = Round(date / 10000, 0);

def Month = AbsValue(year - Round(date / 100, 0) / 100) * 100;

def Day = GetDayOfMonth(date);

def daysinmonth = if Month == 2

then 28

else if Month == 4 or Month == 6 or Month == 9 or Month == 11

then 30

else 31;

def newdays = if Month then (Day + days) else newdays[1];

def month_ = if Between(newdays, 1, daysinmonth)

then Month

else if Between(newdays, 1, daysinmonth * 2)

then Month + 1

else if Between(newdays, 1, daysinmonth * 3)

then Month + 2

else if Between(newdays, 1, daysinmonth * 4)

then Month + 3

else month_[1];

def newmonth = if month_ <= 13

then month_

else if month_ <= 25

then month_ - 12

else if month_ > 25

then month_ - 24

else newmonth[1];

def daysinmonth_ = if month_ == 2

then 28

else if month_ == 4 or month_ == 6 or month_ == 9 or month_ == 11

then 30

else 31;

def newyear = if month_ < 13

then year

else if month_ < 24

then year + 1

else if month_ > 24

then year + 2

else newyear[1];

def newday = if (newdays - daysinmonth) == 1

then 1

else if (newdays - daysinmonth) <= 0

then newdays

else if (newdays - daysinmonth * 2) <= 0

then newdays - (daysinmonth * 1)

else if (newdays - daysinmonth * 3) <= 0

then newdays - (daysinmonth * 2)

else if (newdays - daysinmonth * 4) <= 0

then newdays - (daysinmonth * 3)

else newday[1];

AddLabel(1, "Date Input: " + Month + "/" + Day + "/" + AsPrice(year), Color.YELLOW);

AddLabel(1, "New Calendar Date: " + (if daysinmonth_ == 2 and newday[1] == 29

then 31 else newmonth) + "/"

+ newday + "/"

+ AsPrice(newyear), Color.YELLOW);

input debug = no;

AddLabel(debug, " " + month_ + " " + newdays + " " + daysinmonth + " " + newyear, Color.WHITE);``````

Last edited by a moderator:

#### SleepyZ

##### Well-known member
gravity2726 said:
Thank you Sleepz that is what I am looking for ; For some reason it is not working for the X_Date (instead of date) which we used in the previous code.

This works for X_Date. Changed from an Input date to a Def date = X_Datee

Ruby:
``````input anchor_date     = 20210801;
input to_date         = 20210831;
input show_label      = yes;

AddLabel(show_label, AsPrice(anchor_date) + " to " + AsPrice(to_date), Color.YELLOW);

def num_calendar_days = AbsValue(DaysFromDate(anchor_date) - DaysFromDate(to_date) + 1);

" | CDays: " + num_calendar_days
, Color.YELLOW );

#X/Y (High/Low)-----------------------------------------
def Xamt    = if GetYYYYMMDD()[1] < anchor_date and GetYYYYMMDD() >= anchor_date
then high(period=aggregationPeriod.DAY)
else if Between(GetYYYYMMDD(), anchor_date, to_date)
then Max(high(period=aggregationPeriod.DAY), Xamt[1])
else Double.NaN;
def X       = HighestAll(Xamt);
def X_Date  = HighestAll(if high(period=aggregationPeriod.DAY) == X then GetYYYYMMDD() else 0);

def Yamt    = if GetYYYYMMDD()[1] < anchor_date and GetYYYYMMDD() >= anchor_date
then low(period=aggregationPeriod.DAY)
else if Between(GetYYYYMMDD(), anchor_date, to_date)
then Min(low(period=aggregationPeriod.DAY), Yamt[1])
else Double.NaN;
def Y       = LowestAll(Yamt);
def Y_Date  = highestAll(if low(period=aggregationPeriod.DAY)  == Y then GetYYYYMMDD() else double.nan);

def min_date =  X_date==Min(Y_Date, X_Date);
AddLabel(show_label, if min_date==0 then "L: " + AsText(Y) + "  Y_Date: " + AsPrice(Y_Date) else "H: " + AsText(X) + "  H_Date: " + AsPrice(X_Date), Color.WHITE);
AddLabel(show_label, if min_date==0 then "H: " + AsText(X) + "  X_Date: " + AsPrice(X_Date) else "L: " + AsText(Y) + "  L_Date: " + AsPrice(Y_Date), Color.WHITE);

def num_calendar_days1 = AbsValue(DaysFromDate(Min(Y_Date, X_Date)) - DaysFromDate(Max(Y_Date, X_Date)) + 1);

" | CDays: " + num_calendar_days1
, Color.WHITE );

# Calendar Days From Date Input
input days = 10;
def date = X_Date;
def yymmdd = date;
def year   = Round(date / 10000, 0);
def Month  = AbsValue(year - Round(date / 100, 0) / 100) * 100;
def Day    = GetDayOfMonth(date);

def daysinmonth  = if Month == 2
then 28
else if Month == 4 or Month == 6 or Month == 9 or Month == 11
then 30
else 31;

def newdays      = if Month then (Day + days) else newdays[1];

def month_       = if Between(newdays, 1, daysinmonth)
then Month
else if Between(newdays, 1, daysinmonth * 2)
then Month + 1
else if Between(newdays, 1, daysinmonth * 3)
then Month + 2
else if Between(newdays, 1, daysinmonth * 4)
then Month + 3
else month_[1];

def newmonth     = if month_ <= 13
then month_
else if month_ <= 25
then month_ - 12
else if month_ > 25
then month_ - 24
else newmonth[1];

def daysinmonth_ = if month_ == 2
then 28
else if month_ == 4 or month_ == 6 or month_ == 9 or month_ == 11
then 30
else 31;

def newyear      = if month_ < 13
then year
else if month_ < 24
then year + 1
else if month_ > 24
then year + 2
else newyear[1];
def newday       = if (newdays - daysinmonth) == 1
then 1
else if (newdays - daysinmonth) <= 0
then newdays
else if (newdays - daysinmonth * 2) <= 0
then newdays - (daysinmonth * 1)
else if (newdays - daysinmonth * 3) <= 0
then newdays - (daysinmonth * 2)
else if (newdays - daysinmonth * 4) <= 0
then newdays - (daysinmonth * 3)
else newday[1];

AddLabel(1, "Date Input: " + Month + "/" + Day + "/" + AsPrice(year), Color.YELLOW);
AddLabel(1, "New Calendar Date: " +  (if daysinmonth_ == 2 and newday[1] == 29
then 31 else newmonth) + "/"
+ newday + "/"
+ AsPrice(newyear), Color.YELLOW);

input debug = no;
AddLabel(debug, " " + month_ + " " + newdays + " " + daysinmonth + " " + newyear, Color.WHITE);``````

#### SleepyZ

##### Well-known member
This works, thank you! Not a big deal, but why does it show 37 cdays when I set daysback = 0?

Probably because that is not logical, the code for which I did not make an error routine in it, cannot handle it.

bmn

#### gravity2726

##### Member
VIP
This works for X_Date. Changed from an Input date to a Def date = X_Datee
Great It is working Sleepz...Is it possible to add the X_date in the calculation; I mean if days= 3 and X_Date=20210912.....It is showing the calendar date 15SEP2021; Instead it should add the current day and provide me 14SEP2021....Where I can change in the code to do it.

#### SleepyZ

##### Well-known member
Great It is working Sleepz...Is it possible to add the X_date in the calculation; I mean if days= 3 and X_Date=20210912.....It is showing the calendar date 15SEP2021; Instead it should add the current day and provide me 14SEP2021....Where I can change in the code to do it.

Replace this line

Ruby:
``def newdays      = if Month then (Day + days - 1) else newdays[1];``

#### gravity2726

##### Member
VIP
Replace this line

Ruby:
``def newdays      = if Month then (Day + days - 1) else newdays[1];``
Thank you @SleepyZ ; It worked. Instead of label can I plot the date on the chart....

#### SleepyZ

##### Well-known member
Thank you @SleepyZ ; It worked. Instead of label can I plot the date on the chart....

This may not always work as TOS only plots trading days. Moreover, the way the X_date had to be deconstructed to add days, provides no easy way to construct a date from that code. So this workaround code finds the first date of the year and month and constructs a yyyyymmdd that can be used to reconstruct the new calendar date.

You can choose to display an arrow and/or verticalline() on this date if it is a trading day or the nearest trading day to it.

As you can see in the picture below, it will plot into the right expansion, even though are no candles currently plotted there.

Code:
``````input anchor_date     = 20210801;
input to_date         = 20210831;
input show_label      = yes;

AddLabel(show_label, AsPrice(anchor_date) + " to " + AsPrice(to_date), Color.YELLOW);

def num_calendar_days = AbsValue(DaysFromDate(anchor_date) - DaysFromDate(to_date) + 1);

" | CDays: " + num_calendar_days
, Color.YELLOW );

#X/Y (High/Low)-----------------------------------------
def Xamt    = if GetYYYYMMDD()[1] < anchor_date and GetYYYYMMDD() >= anchor_date
then high(period = AggregationPeriod.DAY)
else if Between(GetYYYYMMDD(), anchor_date, to_date)
then Max(high(period = AggregationPeriod.DAY), Xamt[1])
else Double.NaN;
def X       = HighestAll(Xamt);
def X_Date  = HighestAll(if high(period = AggregationPeriod.DAY) == X then GetYYYYMMDD() else 0);

def Yamt    = if GetYYYYMMDD()[1] < anchor_date and GetYYYYMMDD() >= anchor_date
then low(period = AggregationPeriod.DAY)
else if Between(GetYYYYMMDD(), anchor_date, to_date)
then Min(low(period = AggregationPeriod.DAY), Yamt[1])
else Double.NaN;
def Y       = LowestAll(Yamt);
def Y_Date  = HighestAll(if low(period = AggregationPeriod.DAY)  == Y then GetYYYYMMDD() else Double.NaN);

def min_date =  X_Date == Min(Y_Date, X_Date);
AddLabel(show_label, if min_date == 0 then "L: " + AsText(Y) + "  Y_Date: " + AsPrice(Y_Date) else "H: " + AsText(X) + "  H_Date: " + AsPrice(X_Date), Color.WHITE);
AddLabel(show_label, if min_date == 0 then "H: " + AsText(X) + "  X_Date: " + AsPrice(X_Date) else "L: " + AsText(Y) + "  L_Date: " + AsPrice(Y_Date), Color.WHITE);

def num_calendar_days1 = AbsValue(DaysFromDate(Min(Y_Date, X_Date)) - DaysFromDate(Max(Y_Date, X_Date)) + 1);

" | CDays: " + num_calendar_days1
, Color.WHITE );

# Calendar Days From Date Input----------------------------------
input days = 6;
def date = X_Date;
def yymmdd = date;
def year   = Round(date / 10000, 0);
def Month  = AbsValue(year - Round(date / 100, 0) / 100) * 100;
def Day    = GetDayOfMonth(date);

def daysinmonth  = if Month == 2
then 28
else if Month == 4 or Month == 6 or Month == 9 or Month == 11
then 30
else 31;

def newdays      = if Month then (Day + days - 1) else newdays[1];

def month_       = if Between(newdays, 1, daysinmonth)
then Month
else if Between(newdays, 1, daysinmonth * 2)
then Month + 1
else if Between(newdays, 1, daysinmonth * 3)
then Month + 2
else if Between(newdays, 1, daysinmonth * 4)
then Month + 3
else month_[1];

def newmonth     = if month_ <= 13
then month_
else if month_ <= 25
then month_ - 12
else if month_ > 25
then month_ - 24
else newmonth[1];

def daysinmonth_ = if month_ == 2
then 28
else if month_ == 4 or month_ == 6 or month_ == 9 or month_ == 11
then 30
else 31;

def newyear      = if month_ < 13
then year
else if month_ < 24
then year + 1
else if month_ > 24
then year + 2
else newyear[1];
def newday       = if (newdays - daysinmonth) == 1
then 1
else if (newdays - daysinmonth) <= 0
then newdays
else if (newdays - daysinmonth * 2) <= 0
then newdays - (daysinmonth * 1)
else if (newdays - daysinmonth * 3) <= 0
then newdays - (daysinmonth * 2)
else if (newdays - daysinmonth * 4) <= 0
then newdays - (daysinmonth * 3)
else newday[1];

AddLabel(1, "Date Input: " + Month + "/" + Day + "/" + AsPrice(year), Color.YELLOW);
AddLabel(1, "New Calendar Date: " +  (if daysinmonth_ == 2 and newday[1] == 29
then 31 else newmonth) + "/"
+ newday + "/"
+ AsPrice(newyear), Color.YELLOW);

input debug = no;
AddLabel(debug, " " + month_ + " " + newdays + " " + daysinmonth + " " + newyear, Color.WHITE);

#New Calendar Date or Nearest Trading Date to it ------------------------------------
def count   = if count[1] == 0 and GetYear() == newyear and GetMonth() == month_
then 1
else if GetMonth() == month_ and count[1] >= 1
then count[1] + 1 else 0;
def cdbegin = HighestAll(if count == 1 then GetYYYYMMDD() else 0) ;
def cdday   = getdayofmonth(cdbegin);
def newcd   = cdbegin + newday - cdday;

input showarrow_new_calendar_date = yes;

plot newcdarrow = if !showarrow_new_calendar_date
then double.nan
else GetYYYYMMDD()[1] < newcd and getyyyYMMDD()>=newcd;
newcdarrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
newcdarrow.setdefaultColor(color.cyan);
newcdarrow.setlineWeight(3);

input showvertical = yes;
addverticalLine(showvertical and newcdarrow,"                                New Calendar Date or Closest Trading Date  " + asprice(newcd), color = Color.YELLOW, stroke = Curve.FIRM);

addlabel(debug, asprice(cdbegin + newday - cdday) ,color.white);``````

##### New member
how can I have thinkscript pull a closing price for specific date and trade based of that price. for example lets say i want to buy if the price is above closing price of june 1 and sell if the price is below the closing price of june 1.

#### MerryDay

Staff member
Staff
VIP
@acadiasw The ToS does not allow auto-trading. And this type of complex date math would be beyond what is allowed to us in conditional orders.

#### pmettler

##### New member
Hello all,
I'd like to get the price of the first trading day of a month? How does it work? Is anybody able to help? Thanks in advance

#### MerryDay

Staff member
Staff
VIP
@pmettler if you want to display the date on a chart, read through the above posts. But these scripts will be too complex to use in scans or conditional orders.

#### pmettler

##### New member
@pmettler if you want to display the date on a chart, read through the above posts. But these scripts will be too complex to use in scans or conditional orders.
Hello MerryDay, now I was looking for the close of the first trading day of a month in order to calculate the performance since the beginning of the month.

I figured it out:

declare lower;

plot zero = 0;

#Defines Start of the Year
def yearstart = GetYear() * 10000 + 101;

#Defines Start of the Month
def monthstart = GetYear()*10000 + Getmonth()*100 +1;

def closeOnDate = if GetYYYYMMDD()[1] < monthstart and GetYYYYMMDD() >= monthstart then close else closeOnDate[1];

plot PercentChg = 100 * (close - closeOnDate) / closeOnDate;
PercentChg.AssignValueColor(if PercentChg > 0 then Color.GREEN else if PercentChg == 0 then color.light_GRAY else Color.RED);
PercentChg.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);

def newMonth = GetMonth() != GetMonth()[1];

#### bmn

##### Member
@SleepyZ , various studies have start/end RTH inputs (e.g. input start = 0930; input end = 1600; ). Is it possible to get those values dynamically for the current selected ticker?

#### SleepyZ

##### Well-known member
@SleepyZ , various studies have start/end RTH inputs (e.g. input start = 0930; input end = 1600; ). Is it possible to get those values dynamically for the current selected ticker?

Here is a study by Mobius that uses gettime to do that. These generally work if there is activity in post/pre market as it requires gettime() to cross some form of regulartradinghours(). If there is none of that activity, then especially the regular trading hour start will not work.

Ruby:
``````# GetTime() and Regular Trading Start / End Functions
# Mobius
# 4.27.2018

# TOS could write 4 functions or 2 and allow a different cross
# case to determine which to plot
#
# Here are the 3 RegularTradingStart() functions as you'd expect.
# Whether you use cross, cross above or cross below, it's all
# the same
#
# RegularTradingEnd() can be the RTH end or Extended Hours End
# depending on the cross selection. Cross by itself will get both

def RTHstart = GetTime() crosses above RegularTradingStart(getYYYYMMDD());
def RTHEnd   = GetTime() crosses above RegularTradingEnd(getYYYYMMDD());
def ExtEnd   = GetTime() crosses below RegularTradingEnd(getYYYYMMDD());
plot x=rthstart;
x.setpaintingStrategy(paintingStrategy.BOOLEAN_ARROW_UP);
addVerticalLine(RTHStart, "RTH Hours Begin", color.cyan, curve.firm);
addVerticalLine(RTHEnd, "RTH Hours End", color.cyan, curve.firm);
addVerticalLine(ExtEnd, "Extended Hours End", color.cyan, curve.firm);
# End``````

#### bmn

##### Member
Here is a study by Mobius that uses gettime to do that. These generally work if there is activity in post/pre market as it requires gettime() to cross some form of regulartradinghours(). If there is none of that activity, then especially the regular trading hour start will not work.
THANK YOU!!

If there's no activity, would there be a way to set a fallback time to 0930-1600? Would it return NaN or something that can be used in if condition to set the default in that scenario?

Edit: was actually playing around with this. Is there a way to save the values themselves (not boolean outcome) in a variable?

Last edited:

#### SleepyZ

##### Well-known member
THANK YOU!!

If there's no activity, would there be a way to set a fallback time to 0930-1600? Would it return NaN or something that can be used in if condition to set the default in that scenario?

Edit: was actually playing around with this. Is there a way to save the values themselves (not boolean outcome) in a variable?

This seems to work for regulartradingstart.. AFL did not have premarket on numerous days on the top chart in the picture below with the original code. The lower chart is the same set up as the upper, but with the code below.

I did not find any examples of the other regulartradingend applications, but something similar to the regulartradingstart fix should work. I included a 1600 possible fix, but was unsure what you may run into if you even use the extended application.

Ruby:
``````def RTHstart = GetTime() crosses above RegularTradingStart(GetYYYYMMDD());
def RTHEnd   = GetTime() crosses above RegularTradingEnd(GetYYYYMMDD());
def ExtEnd   = GetTime() crosses below RegularTradingEnd(GetYYYYMMDD());
plot x =  RTHstart or SecondsFromTime(0930) == 0;
x.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
AddVerticalLine(RTHstart or SecondsFromTime(0930) == 0, "RTH Hours Begin", Color.CYAN, Curve.FIRM);
AddVerticalLine(RTHEnd   or SecondsFromTime(1600) == 0, "RTH Hours End", Color.CYAN, Curve.FIRM);
addVerticalLine(ExtEnd , "Extended Hours End", color.cyan, curve.firm);``````

bmn

#### bmn

##### Member
This seems to work for regulartradingstart.. AFL did not have premarket on numerous days on the top chart in the picture below with the original code. The lower chart is the same set up as the upper, but with the code below.

I did not find any examples of the other regulartradingend applications, but something similar to the regulartradingstart fix should work. I included a 1600 possible fix, but was unsure what you may run into if you even use the extended application.
Thank you for the update.

I'm trying to run the following example from jshingler.

Code:
``````input start = 0930; #Start of RTH for most securities
input end = 1600; #End of RTH for most securities
def toPaint = SecondsFromTime(start) >= 0 and SecondsTillTime(end) > 0;
def up = if toPaint then Double.POSITIVE_INFINITY else Double.NaN;
def down = if toPaint then LowestAll(low) else Double.NaN;