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.

Capture.jpg
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);
AddLabel(1, num_calendar_days, Color.WHITE);
 

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);
AddLabel(1, num_calendar_days, Color.WHITE);

See if this helps

Capture.jpg
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];
AddLabel(1, "Last Trading Day: " + AsPrice(last_trading_day) + " Trading Date " + daysback + " ago: " + AsPrice(TD_daysback), Color.WHITE);

#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);
 
  • Like
Reactions: bmn

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, "Calendar Days Added: " + days, Color.WHITE);


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

Capture.jpg
Ruby:
input anchor_date     = 20210801;
input to_date         = 20210831;
input show_label      = yes;

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

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

AddLabel(show_label, "TDays: " + num_trading_days  +
              " | CDays: " + num_calendar_days
              , Color.YELLOW );

#X/Y (High/Low)-----------------------------------------
AddLabel(show_label, "H/L", Color.WHITE);
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_trading_days1  = AbsValue(CountTradingDays(Min(Y_Date, X_Date), Max(Y_Date, X_Date)));
def num_calendar_days1 = AbsValue(DaysFromDate(Min(Y_Date, X_Date)) - DaysFromDate(Max(Y_Date, X_Date)) + 1);

AddLabel(show_label, "TDays: " + num_trading_days1  +
              " | 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, "Calendar Days Added: " + days, Color.WHITE);
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);
 

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];
 

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.

Capture.jpg
Code:
input anchor_date     = 20210801;
input to_date         = 20210831;
input show_label      = yes;

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

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

AddLabel(show_label, "TDays: " + num_trading_days  +
              " | CDays: " + num_calendar_days
              , Color.YELLOW );

#X/Y (High/Low)-----------------------------------------
AddLabel(show_label, "H/L", Color.WHITE);
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_trading_days1  = AbsValue(CountTradingDays(Min(Y_Date, X_Date), Max(Y_Date, X_Date)));
def num_calendar_days1 = AbsValue(DaysFromDate(Min(Y_Date, X_Date)) - DaysFromDate(Max(Y_Date, X_Date)) + 1);

AddLabel(show_label, "TDays: " + num_trading_days1  +
              " | 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, "Calendar Days Added: " + days, Color.WHITE);
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);
 

acadiasw

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.
 

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];
AddVerticalLine(newMonth, (GetMonth()), color.black, curve.Short_Dash);
 

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.

Capture.jpg
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);
 
  • Like
Reactions: 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;
AddCloud(up, down, Color.RED);

You see how it has start and end are hardcoded. I'm trying to make that dynamic and paint the cloud for ANY securities (some futures have different start/end RTH e.g. \CL). When I add the following on top "def RTHstart = GetTime() crosses above RegularTradingStart(getYYYYMMDD());" and use that in line #3 "def toPaint = SecondsFromTime(RTHstart) >= 0" it throws an error. Do you know how I can get \CL's "start" so that I can use it in SecondsFromTime?
 

Similar threads

Top