ThinkorSwim Earnings Date Indicator and Watchlist Column

Status
Not open for further replies.

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

thats a prebuilt scan already defined in TOS
I am using the prebuilt scanner but its not ideal I am hoping to refine it further. I want to build a scan that shows yesterdays AMO earnings and this mornings BMO earnings. I am trying to play earnings gaps.

One issue with the prebuilt scanner is that the previous days AMO earnings disappear as soon as the market opens.
 
Found this indicator created by Mobius while I was browsing the thinkScript Lounge. It adds two labels to your chart. One shows the next earning date for the stock. If the upcoming earning date is within five days, it will also add a bright red warning. It sort of acts as an attention grabber to let you know.

YWi7ai4.png


thinkScript Code

Code:
# Next Earnings Label
# Mobius

def Earnings = AbsValue(GetEventOffset(Events.Earnings, 0));
def NextEarnings = if isNaN(Earnings)
                   then 0
                   else Earnings;
def Month = getMonth();
def year = getYear();
def DOW = getDayOfWeek(getYYYYMMDD());
def today = getDayOfMonth(getYYYYMMDD());
def EarningDay = if NextEarnings + DOW <= 5
                 then NextEarnings + today
                 else if NextEarnings + DOw > 5
                 then NextEarnings + today + 2
                 else NextEarnings;
AddLabel(1, "Next " + getSymbol() + " earnings " + Month + "/" + EarningDay + "/" + AsPrice(year), color.white);
AddLabel(NextEarnings < 30 and NextEarnings > 0,
        "Earnings in " + NextEarnings +
       " trading days", if NextEarnings <= 4
                then Color.Red
                else Color.White);

Shareable Link

https://tos.mx/FDrNKR

Warning: Some users have pointed out that this indicator and the data it provides may be inconsistent. An alternative script has been posted here.
This is EXACTLY what I wanted.
Is there a way to get the data directly and not from the chart? I don't normally use the daily aggregation so my dates are wrong.
can we not get the date via EarningTime function (the https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Corporate-Actions/HasEarnings) and then using the DaysFromDate function (https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Date---Time/DaysFromDate) to show the earnings date. and also ex-div date, regardless of what aggregation period I use, or regardless of how many bars expansion I have??
 
@Sonima Ah! Now we are getting somewhere. I immediately see where the problem is. When this code was released in the ThinkScript Lounge months ago, several people pointed out that that code is FUBAR. Do not use that as it is inaccurate. Let me give you an example. Load the study that was posted in post #1 of this thread. Set your aggregation to DAILY and load up ticker symbol C. Just to be sure I have my expansion space set to 44.

What happens? Notice that that particular study reports that the next C earnings is on 12/33/2019. That is clearly wrong.

@BenTen Please take note and either DELETE or TAG that study as being inconsistent.

As a workaround, I have a study that I obtained from a long standing contributor in the ThinkScript Lounge. That study works much better and is an improved version over the original release that was created 4-5 years ago. It correctly reports that ticker C will report earnings in 25 days, on 1/14/2020.

Here is the code

Code:
# Next Earnings Date
# Paris
# 10.15.2019

# You have to have enough expansion area on your chart available to reach the actual Earnings date, so if you have 0 expansion area, an inconsistent date will be displayed

#HINT: watchlist label that shows days-to-earnings and next earnings date (if next earnings date is available).  Includes a visual alert if "EARNINGS TODAY"

#def allows you to teach ThinkScript new "words" to save time and typing by using your new "words" later in the code
def bn = BarNumber();
def na = Double.NaN;
def getNextEarnings = AbsValue(GetEventOffset(Events.EARNINGS, 0));
def findDay = GetDayOfMonth(GetYYYYMMDD());
def findMonth = GetMonth();
def findYear = GetYear();

#ThinkScript thinks in numbers, including converting dates into numbers and viewing each bar on the chart as a number.  Therefore you can use BarNumber to tell ThinkScript which bar, and use lines in ThinkScript code to 'trick' ThinkScript into displaying that daily bar in date format
def getNextEarningsBarNumber = if !isNaN(getNextEarnings) then bn + getNextEarnings else na;
def NextEarnings = bn == HighestAll(getNextEarningsBarNumber);
def getNextEarningsMonth = HighestAll(if NextEarnings then findMonth else na);
def getNextEarningsDay = HighestAll(if NextEarnings then findDay else na);
def getNextEarningsYear = HighestAll(if NextEarnings then findYear else na);

#plot tells ThinkScript what data you want displayed.  Hide() is used in this case because desired display is the label and not the numberic equivalent of the data
plot DaysToEarnings = getNextEarningsBarNumber;
DaysToEarnings.Hide();

AddLabel(getNextEarnings > 0, "Next Earnings: (" + getNextEarnings + (if getNextEarnings == 1 then " Day): " else " Days): ") + getNextEarningsMonth + "/" + getNextEarningsDay + "/" + AsPrice(getNextEarningsYear), Color.Pink);
AddLabel(getNextEarnings == 0, "  EARNINGS TODAY ", Color.Yellow);
# End Next Earnings Date
Hi, I used the above code, but I still get inconsistent data, I used expansion area of 10 to 30 days.
 
@majidg I rely heavily on the earnings date labels and do not have inconsistent data at all. My expansion area is 44. Adjust your expansion area and if still having issues, post a screenshot of your chart and label.
Below is a link of how to insert images into your post:
https://usethinkscript.com/threads/answers-to-commonly-asked-questions.6006/#post-58714

IdRCb2h.png

AlyuT91.png

Ruby:
# Next Earnings Date
# Paris
# 10.15.2019

## IMPORTANT!!!! 44 EXPANSION You have to have enough expansion area on your chart available to reach the actual Earnings date, so if you have 0 expansion area, an inconsistent date will be displayed

#HINT: watchlist label that shows days-to-earnings and next earnings date (if next earnings date is available).  Includes a visual alert if "EARNINGS TODAY"

#def allows you to teach ThinkScript new "words" to save time and typing by using your new "words" later in the code
def bn = BarNumber();
def na = Double.NaN;
def getNextEarnings = AbsValue(GetEventOffset(Events.EARNINGS, 0));
def findDay = GetDayOfMonth(GetYYYYMMDD());
def findMonth = GetMonth();
def findYear = GetYear();

#ThinkScript thinks in numbers, including converting dates into numbers and viewing each bar on the chart as a number.  Therefore you can use BarNumber to tell ThinkScript which bar, and use lines in ThinkScript code to 'trick' ThinkScript into displaying that daily bar in date format
def getNextEarningsBarNumber = if !isNaN(getNextEarnings) then bn + getNextEarnings else na;
def NextEarnings = bn == HighestAll(getNextEarningsBarNumber);
def getNextEarningsMonth = HighestAll(if NextEarnings then findMonth else na);
def getNextEarningsDay = HighestAll(if NextEarnings then findDay else na);
def getNextEarningsYear = HighestAll(if NextEarnings then findYear else na);

#plot tells ThinkScript what data you want displayed.  Hide() is used in this case because desired display is the label and not the numberic equivalent of the data
plot DaysToEarnings = getNextEarningsBarNumber;
DaysToEarnings.Hide();

DefineGlobalColor("Pre_Cyan", CreateColor(50, 200, 255)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("LabelGreen",  CreateColor(0, 165, 0)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("Label2Green",  CreateColor(0, 200, 0)) ;
DefineGlobalColor("Violet", CreateColor (200, 125, 255)) ;
AddLabel(getNextEarnings > 0, "Next Earnings: (" + getNextEarnings + (if getNextEarnings == 1 then " Day): " else " Days): ") + getNextEarningsMonth + "/" + getNextEarningsDay + "/" + AsPrice(getNextEarningsYear),
if getNextEarnings > 5 then GlobalColor("Violet") else GlobalColor("LabelGreen"));
AddLabel(getNextEarnings == 0, "  EARNINGS TODAY ", GlobalColor("Pre_Cyan"));
# End Next Earnings Date
Ruby:
# Script displays earnings and securities reaction to the announcement
#Developed and Coded By Eric Rasmussen
# [email protected]
# IMPORTANT 44 EXPANSION
# Finding the Earnings Dates
def isBefore = HasEarnings(EarningTime.BEFORE_MARKET);
def isAfter = HasEarnings(EarningTime.AFTER_MARKET);

# Earnings Move Up or Down
def afterCalc = AbsValue(Round(close[-1] - close));
def beforeCalc = AbsValue(Round(close - close[1]));

def afterAbs = if isAfter then Round(AbsValue(((close[-1] - close) / close) * 100)) else 0;
def beforeAbs =  if isBefore then Round(AbsValue(((close - close[1]) / close) * 100)) else 0;

def earningsPrice = if isAfter then afterCalc else if isBefore then beforeCalc else 0;

# Price Percent Calculations
def afterPercent = if isAfter then Round(((close[-1] - close) / close) * 100) else 0;
def beforePercent = if isBefore then Round(((close - close[1]) / close) * 100) else 0;

def earningsPercent = if isAfter then afterPercent else if isBefore then beforePercent else 0;

def absPercent = if isAfter then afterAbs else if isBefore then beforeAbs else 0;

# Records Number of Earnings Periods
def aMove = if HasEarnings(EarningTime.AFTER_MARKET) then TotalSum(earningsPrice) else aMove[1];

def bMove = if HasEarnings(EarningTime.BEFORE_MARKET) then TotalSum(earningsPrice) else bMove[1];

def earningsPeriods = if HasEarnings() then 1 else 0;

# Average Earnings Move calculation
def periodSum = Sum(earningsPeriods, length = 252);
def Sum = Sum(earningsPrice, length = 252);
def averageMove = Sum / periodSum;
def percentSum = Sum(absPercent, length = 252);
def percentAvg = percentSum / periodSum;
def avgMove = if !IsNaN(averageMove) then averageMove else avgMove[1];
def percentAvgMove = if !IsNaN(averageMove) then percentAvg else percentAvgMove[1];

# Actual Earnings and Estimates Info
def AECont = if HasEarnings() then GetActualEarnings() else AECont[1];
def EECont = if HasEarnings() then GetEstimatedEarnings() else EECont[1];

def actualEarnings = if !IsNaN(AECont) then AECont else actualEarnings[1];
def estimatedEarnings = if !IsNaN(EECont) then EECont else estimatedEarnings[1];

def EarningsBeat =  !IsNaN(GetActualEarnings()) and HasEarnings() and actualEarnings > estimatedEarnings;
def EarningsMiss =  !IsNaN(GetActualEarnings()) and HasEarnings() and actualEarnings < estimatedEarnings;

# Earnings Move Calculations
def aCalc =  Round(close[-1] - close);
def bCalc = Round(close - close[1]);

def ePrice = if isAfter then aCalc else if isBefore then bCalc else ePrice[1];

def earningsNaN = if HasEarnings() and IsNaN(GetEstimatedEarnings()) then 1 else earningsNaN[1];
def earningsSum = TotalSum(HasEarnings()) - earningsNaN;
def earningsMove =  if HasEarnings() then ePrice else earningsMove[1];

def uM = HasEarnings() and earningsMove > 0;
def dM = HasEarnings() and earningsMove < 0;

def beatRatio =  Round((TotalSum(EarningsBeat) / earningsSum) * 100);

# Look And Feel
 
# Average Move Label (Percentage)
input percentLabel = yes;
AddLabel(percentLabel, Concat(Concat("Average Earnings Move: ", Round(percentAvgMove, 2)), "%"), if earningsPrice[1] > avgMove[1] then Color.MAGENTA else Color.plum);

# Percentage of Earnings Beats Label
DefineGlobalColor("Pre_Cyan", CreateColor(50, 200, 255)) ;
DefineGlobalColor("LabelGreen",  CreateColor(0, 165, 0)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("Label2Green",  CreateColor(0, 200, 0)) ;

input beatRatioLabel = yes;
AddLabel(beatRatioLabel, Concat(Concat("Earnings Beats: ", beatRatio), "%"), color =
if beatRatio >= 100 then GlobalColor("Pre_Cyan")  else
if beatRatio >= 80 then GlobalColor("LabelGreen") else
if beatRatio >= 55 then color.gray else
GlobalColor("LabelRed"));
 
@majidg I rely heavily on the earnings date labels and do not have inconsistent data at all. My expansion area is 44. Adjust your expansion area and if still having issues, post a screenshot of your chart and label.
Below is a link of how to insert images into your post:
https://usethinkscript.com/threads/answers-to-commonly-asked-questions.6006/#post-58714

IdRCb2h.png

AlyuT91.png

Ruby:
# Next Earnings Date
# Paris
# 10.15.2019

## IMPORTANT!!!! 44 EXPANSION You have to have enough expansion area on your chart available to reach the actual Earnings date, so if you have 0 expansion area, an inconsistent date will be displayed

#HINT: watchlist label that shows days-to-earnings and next earnings date (if next earnings date is available).  Includes a visual alert if "EARNINGS TODAY"

#def allows you to teach ThinkScript new "words" to save time and typing by using your new "words" later in the code
def bn = BarNumber();
def na = Double.NaN;
def getNextEarnings = AbsValue(GetEventOffset(Events.EARNINGS, 0));
def findDay = GetDayOfMonth(GetYYYYMMDD());
def findMonth = GetMonth();
def findYear = GetYear();

#ThinkScript thinks in numbers, including converting dates into numbers and viewing each bar on the chart as a number.  Therefore you can use BarNumber to tell ThinkScript which bar, and use lines in ThinkScript code to 'trick' ThinkScript into displaying that daily bar in date format
def getNextEarningsBarNumber = if !isNaN(getNextEarnings) then bn + getNextEarnings else na;
def NextEarnings = bn == HighestAll(getNextEarningsBarNumber);
def getNextEarningsMonth = HighestAll(if NextEarnings then findMonth else na);
def getNextEarningsDay = HighestAll(if NextEarnings then findDay else na);
def getNextEarningsYear = HighestAll(if NextEarnings then findYear else na);

#plot tells ThinkScript what data you want displayed.  Hide() is used in this case because desired display is the label and not the numberic equivalent of the data
plot DaysToEarnings = getNextEarningsBarNumber;
DaysToEarnings.Hide();

DefineGlobalColor("Pre_Cyan", CreateColor(50, 200, 255)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("LabelGreen",  CreateColor(0, 165, 0)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("Label2Green",  CreateColor(0, 200, 0)) ;
DefineGlobalColor("Violet", CreateColor (200, 125, 255)) ;
AddLabel(getNextEarnings > 0, "Next Earnings: (" + getNextEarnings + (if getNextEarnings == 1 then " Day): " else " Days): ") + getNextEarningsMonth + "/" + getNextEarningsDay + "/" + AsPrice(getNextEarningsYear),
if getNextEarnings > 5 then GlobalColor("Violet") else GlobalColor("LabelGreen"));
AddLabel(getNextEarnings == 0, "  EARNINGS TODAY ", GlobalColor("Pre_Cyan"));
# End Next Earnings Date
Ruby:
# Script displays earnings and securities reaction to the announcement
#Developed and Coded By Eric Rasmussen
# [email protected]
# IMPORTANT 44 EXPANSION
# Finding the Earnings Dates
def isBefore = HasEarnings(EarningTime.BEFORE_MARKET);
def isAfter = HasEarnings(EarningTime.AFTER_MARKET);

# Earnings Move Up or Down
def afterCalc = AbsValue(Round(close[-1] - close));
def beforeCalc = AbsValue(Round(close - close[1]));

def afterAbs = if isAfter then Round(AbsValue(((close[-1] - close) / close) * 100)) else 0;
def beforeAbs =  if isBefore then Round(AbsValue(((close - close[1]) / close) * 100)) else 0;

def earningsPrice = if isAfter then afterCalc else if isBefore then beforeCalc else 0;

# Price Percent Calculations
def afterPercent = if isAfter then Round(((close[-1] - close) / close) * 100) else 0;
def beforePercent = if isBefore then Round(((close - close[1]) / close) * 100) else 0;

def earningsPercent = if isAfter then afterPercent else if isBefore then beforePercent else 0;

def absPercent = if isAfter then afterAbs else if isBefore then beforeAbs else 0;

# Records Number of Earnings Periods
def aMove = if HasEarnings(EarningTime.AFTER_MARKET) then TotalSum(earningsPrice) else aMove[1];

def bMove = if HasEarnings(EarningTime.BEFORE_MARKET) then TotalSum(earningsPrice) else bMove[1];

def earningsPeriods = if HasEarnings() then 1 else 0;

# Average Earnings Move calculation
def periodSum = Sum(earningsPeriods, length = 252);
def Sum = Sum(earningsPrice, length = 252);
def averageMove = Sum / periodSum;
def percentSum = Sum(absPercent, length = 252);
def percentAvg = percentSum / periodSum;
def avgMove = if !IsNaN(averageMove) then averageMove else avgMove[1];
def percentAvgMove = if !IsNaN(averageMove) then percentAvg else percentAvgMove[1];

# Actual Earnings and Estimates Info
def AECont = if HasEarnings() then GetActualEarnings() else AECont[1];
def EECont = if HasEarnings() then GetEstimatedEarnings() else EECont[1];

def actualEarnings = if !IsNaN(AECont) then AECont else actualEarnings[1];
def estimatedEarnings = if !IsNaN(EECont) then EECont else estimatedEarnings[1];

def EarningsBeat =  !IsNaN(GetActualEarnings()) and HasEarnings() and actualEarnings > estimatedEarnings;
def EarningsMiss =  !IsNaN(GetActualEarnings()) and HasEarnings() and actualEarnings < estimatedEarnings;

# Earnings Move Calculations
def aCalc =  Round(close[-1] - close);
def bCalc = Round(close - close[1]);

def ePrice = if isAfter then aCalc else if isBefore then bCalc else ePrice[1];

def earningsNaN = if HasEarnings() and IsNaN(GetEstimatedEarnings()) then 1 else earningsNaN[1];
def earningsSum = TotalSum(HasEarnings()) - earningsNaN;
def earningsMove =  if HasEarnings() then ePrice else earningsMove[1];

def uM = HasEarnings() and earningsMove > 0;
def dM = HasEarnings() and earningsMove < 0;

def beatRatio =  Round((TotalSum(EarningsBeat) / earningsSum) * 100);

# Look And Feel
 
# Average Move Label (Percentage)
input percentLabel = yes;
AddLabel(percentLabel, Concat(Concat("Average Earnings Move: ", Round(percentAvgMove, 2)), "%"), if earningsPrice[1] > avgMove[1] then Color.MAGENTA else Color.plum);

# Percentage of Earnings Beats Label
DefineGlobalColor("Pre_Cyan", CreateColor(50, 200, 255)) ;
DefineGlobalColor("LabelGreen",  CreateColor(0, 165, 0)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("Label2Green",  CreateColor(0, 200, 0)) ;

input beatRatioLabel = yes;
AddLabel(beatRatioLabel, Concat(Concat("Earnings Beats: ", beatRatio), "%"), color =
if beatRatio >= 100 then GlobalColor("Pre_Cyan")  else
if beatRatio >= 80 then GlobalColor("LabelGreen") else
if beatRatio >= 55 then color.gray else
GlobalColor("LabelRed"));

@majidg I rely heavily on the earnings date labels and do not have inconsistent data at all. My expansion area is 44. Adjust your expansion area and if still having issues, post a screenshot of your chart and label.
Below is a link of how to insert images into your post:
https://usethinkscript.com/threads/answers-to-commonly-asked-questions.6006/#post-58714

IdRCb2h.png

AlyuT91.png

Ruby:
# Next Earnings Date
# Paris
# 10.15.2019

## IMPORTANT!!!! 44 EXPANSION You have to have enough expansion area on your chart available to reach the actual Earnings date, so if you have 0 expansion area, an inconsistent date will be displayed

#HINT: watchlist label that shows days-to-earnings and next earnings date (if next earnings date is available).  Includes a visual alert if "EARNINGS TODAY"

#def allows you to teach ThinkScript new "words" to save time and typing by using your new "words" later in the code
def bn = BarNumber();
def na = Double.NaN;
def getNextEarnings = AbsValue(GetEventOffset(Events.EARNINGS, 0));
def findDay = GetDayOfMonth(GetYYYYMMDD());
def findMonth = GetMonth();
def findYear = GetYear();

#ThinkScript thinks in numbers, including converting dates into numbers and viewing each bar on the chart as a number.  Therefore you can use BarNumber to tell ThinkScript which bar, and use lines in ThinkScript code to 'trick' ThinkScript into displaying that daily bar in date format
def getNextEarningsBarNumber = if !isNaN(getNextEarnings) then bn + getNextEarnings else na;
def NextEarnings = bn == HighestAll(getNextEarningsBarNumber);
def getNextEarningsMonth = HighestAll(if NextEarnings then findMonth else na);
def getNextEarningsDay = HighestAll(if NextEarnings then findDay else na);
def getNextEarningsYear = HighestAll(if NextEarnings then findYear else na);

#plot tells ThinkScript what data you want displayed.  Hide() is used in this case because desired display is the label and not the numberic equivalent of the data
plot DaysToEarnings = getNextEarningsBarNumber;
DaysToEarnings.Hide();

DefineGlobalColor("Pre_Cyan", CreateColor(50, 200, 255)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("LabelGreen",  CreateColor(0, 165, 0)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("Label2Green",  CreateColor(0, 200, 0)) ;
DefineGlobalColor("Violet", CreateColor (200, 125, 255)) ;
AddLabel(getNextEarnings > 0, "Next Earnings: (" + getNextEarnings + (if getNextEarnings == 1 then " Day): " else " Days): ") + getNextEarningsMonth + "/" + getNextEarningsDay + "/" + AsPrice(getNextEarningsYear),
if getNextEarnings > 5 then GlobalColor("Violet") else GlobalColor("LabelGreen"));
AddLabel(getNextEarnings == 0, "  EARNINGS TODAY ", GlobalColor("Pre_Cyan"));
# End Next Earnings Date
Ruby:
# Script displays earnings and securities reaction to the announcement
#Developed and Coded By Eric Rasmussen
# [email protected]
# IMPORTANT 44 EXPANSION
# Finding the Earnings Dates
def isBefore = HasEarnings(EarningTime.BEFORE_MARKET);
def isAfter = HasEarnings(EarningTime.AFTER_MARKET);

# Earnings Move Up or Down
def afterCalc = AbsValue(Round(close[-1] - close));
def beforeCalc = AbsValue(Round(close - close[1]));

def afterAbs = if isAfter then Round(AbsValue(((close[-1] - close) / close) * 100)) else 0;
def beforeAbs =  if isBefore then Round(AbsValue(((close - close[1]) / close) * 100)) else 0;

def earningsPrice = if isAfter then afterCalc else if isBefore then beforeCalc else 0;

# Price Percent Calculations
def afterPercent = if isAfter then Round(((close[-1] - close) / close) * 100) else 0;
def beforePercent = if isBefore then Round(((close - close[1]) / close) * 100) else 0;

def earningsPercent = if isAfter then afterPercent else if isBefore then beforePercent else 0;

def absPercent = if isAfter then afterAbs else if isBefore then beforeAbs else 0;

# Records Number of Earnings Periods
def aMove = if HasEarnings(EarningTime.AFTER_MARKET) then TotalSum(earningsPrice) else aMove[1];

def bMove = if HasEarnings(EarningTime.BEFORE_MARKET) then TotalSum(earningsPrice) else bMove[1];

def earningsPeriods = if HasEarnings() then 1 else 0;

# Average Earnings Move calculation
def periodSum = Sum(earningsPeriods, length = 252);
def Sum = Sum(earningsPrice, length = 252);
def averageMove = Sum / periodSum;
def percentSum = Sum(absPercent, length = 252);
def percentAvg = percentSum / periodSum;
def avgMove = if !IsNaN(averageMove) then averageMove else avgMove[1];
def percentAvgMove = if !IsNaN(averageMove) then percentAvg else percentAvgMove[1];

# Actual Earnings and Estimates Info
def AECont = if HasEarnings() then GetActualEarnings() else AECont[1];
def EECont = if HasEarnings() then GetEstimatedEarnings() else EECont[1];

def actualEarnings = if !IsNaN(AECont) then AECont else actualEarnings[1];
def estimatedEarnings = if !IsNaN(EECont) then EECont else estimatedEarnings[1];

def EarningsBeat =  !IsNaN(GetActualEarnings()) and HasEarnings() and actualEarnings > estimatedEarnings;
def EarningsMiss =  !IsNaN(GetActualEarnings()) and HasEarnings() and actualEarnings < estimatedEarnings;

# Earnings Move Calculations
def aCalc =  Round(close[-1] - close);
def bCalc = Round(close - close[1]);

def ePrice = if isAfter then aCalc else if isBefore then bCalc else ePrice[1];

def earningsNaN = if HasEarnings() and IsNaN(GetEstimatedEarnings()) then 1 else earningsNaN[1];
def earningsSum = TotalSum(HasEarnings()) - earningsNaN;
def earningsMove =  if HasEarnings() then ePrice else earningsMove[1];

def uM = HasEarnings() and earningsMove > 0;
def dM = HasEarnings() and earningsMove < 0;

def beatRatio =  Round((TotalSum(EarningsBeat) / earningsSum) * 100);

# Look And Feel
 
# Average Move Label (Percentage)
input percentLabel = yes;
AddLabel(percentLabel, Concat(Concat("Average Earnings Move: ", Round(percentAvgMove, 2)), "%"), if earningsPrice[1] > avgMove[1] then Color.MAGENTA else Color.plum);

# Percentage of Earnings Beats Label
DefineGlobalColor("Pre_Cyan", CreateColor(50, 200, 255)) ;
DefineGlobalColor("LabelGreen",  CreateColor(0, 165, 0)) ;
DefineGlobalColor("LabelRed",  CreateColor(225, 0, 0)) ;
DefineGlobalColor("Label2Green",  CreateColor(0, 200, 0)) ;

input beatRatioLabel = yes;
AddLabel(beatRatioLabel, Concat(Concat("Earnings Beats: ", beatRatio), "%"), color =
if beatRatio >= 100 then GlobalColor("Pre_Cyan")  else
if beatRatio >= 80 then GlobalColor("LabelGreen") else
if beatRatio >= 55 then color.gray else
GlobalColor("LabelRed"));
Thanks a lot, by changing the expansion time, I can consistently obtain the next earrings date
 
If someone could please help, i would greatly appreciate it.
I'm only seeing one of the labels and date is wrong.
l2EvU4q.gif
 
https%3A//i.imgur.com/kwRAKGo.jpg[/img]']
kwRAKGo.jpg


https%3A//i.imgur.com/P7LSrZg.jpg[/img]']
P7LSrZg.jpg


@MerryDay I like the earnings labels very much as it gives me a quick check on the company growth. For strong stocks, I like to see consistent rising EPS growth for at least 3 qtr and Sales growth as well. Like to clarify if my interpretation of the earnings label is correct.

Background, PTON missed their earnings last week but the label shows beats earnings 75% (used on 1year Daily) and 50%(used on 6mths daily)

# Actual Earnings and Estimates Info
def AECont = if HasEarnings() then GetActualEarnings() else AECont[1];
def EECont = if HasEarnings() then GetEstimatedEarnings() else EECont[1];

def actualEarnings = if !IsNaN(AECont) then AECont else actualEarnings[1];
def estimatedEarnings = if !IsNaN(EECont) then EECont else estimatedEarnings[1];

def EarningsBeat = !IsNaN(GetActualEarnings()) and HasEarnings() and actualEarnings > estimatedEarnings;
def EarningsMiss = !IsNaN(GetActualEarnings()) and HasEarnings() and actualEarnings < estimatedEarnings;

# Earnings Move Calculations
def aCalc = Round(close[-1] - close);
def bCalc = Round(close - close[1]);

def ePrice = if isAfter then aCalc else if isBefore then bCalc else ePrice[1];

def earningsNaN = if HasEarnings() and IsNaN(GetEstimatedEarnings()) then 1 else earningsNaN[1];
def earningsSum = TotalSum(HasEarnings()) - earningsNaN;
def earningsMove = if HasEarnings() then ePrice else earningsMove[1];

def uM = HasEarnings() and earningsMove > 0;
def dM = HasEarnings() and earningsMove < 0;

def beatRatio = Round((TotalSum(EarningsBeat) / earningsSum) * 100);

May I know if the beatRatio is calculated based on the number of times in beats earnings for 1yr or 6mths respectively? Does it count the latest earning result? Is that the correct way of interpreting??

If I want to show how many times in 1yr the stock has missed earnings, I just need to change the condition here
def beatRatio = Round((TotalSum(EarningsMiss) / earningsSum) * 100); and it will show how many times it missed earnings

Is there a way to compare and show a label the difference between the current qtr earnings and the previous qtr ?

Thanks
 
@Sonima Ah! Now we are getting somewhere. I immediately see where the problem is. When this code was released in the ThinkScript Lounge months ago, several people pointed out that that code is FUBAR. Do not use that as it is inaccurate. Let me give you an example. Load the study that was posted in post #1 of this thread. Set your aggregation to DAILY and load up ticker symbol C. Just to be sure I have my expansion space set to 44.

What happens? Notice that that particular study reports that the next C earnings is on 12/33/2019. That is clearly wrong.

@BenTen Please take note and either DELETE or TAG that study as being inconsistent.

As a workaround, I have a study that I obtained from a long standing contributor in the ThinkScript Lounge. That study works much better and is an improved version over the original release that was created 4-5 years ago. It correctly reports that ticker C will report earnings in 25 days, on 1/14/2020.

Here is the code

Code:
# Next Earnings Date
# Paris
# 10.15.2019

# You have to have enough expansion area on your chart available to reach the actual Earnings date, so if you have 0 expansion area, an inconsistent date will be displayed

#HINT: watchlist label that shows days-to-earnings and next earnings date (if next earnings date is available).  Includes a visual alert if "EARNINGS TODAY"

#def allows you to teach ThinkScript new "words" to save time and typing by using your new "words" later in the code
def bn = BarNumber();
def na = Double.NaN;
def getNextEarnings = AbsValue(GetEventOffset(Events.EARNINGS, 0));
def findDay = GetDayOfMonth(GetYYYYMMDD());
def findMonth = GetMonth();
def findYear = GetYear();

#ThinkScript thinks in numbers, including converting dates into numbers and viewing each bar on the chart as a number.  Therefore you can use BarNumber to tell ThinkScript which bar, and use lines in ThinkScript code to 'trick' ThinkScript into displaying that daily bar in date format
def getNextEarningsBarNumber = if !isNaN(getNextEarnings) then bn + getNextEarnings else na;
def NextEarnings = bn == HighestAll(getNextEarningsBarNumber);
def getNextEarningsMonth = HighestAll(if NextEarnings then findMonth else na);
def getNextEarningsDay = HighestAll(if NextEarnings then findDay else na);
def getNextEarningsYear = HighestAll(if NextEarnings then findYear else na);

#plot tells ThinkScript what data you want displayed.  Hide() is used in this case because desired display is the label and not the numberic equivalent of the data
plot DaysToEarnings = getNextEarningsBarNumber;
DaysToEarnings.Hide();

AddLabel(getNextEarnings > 0, "Next Earnings: (" + getNextEarnings + (if getNextEarnings == 1 then " Day): " else " Days): ") + getNextEarningsMonth + "/" + getNextEarningsDay + "/" + AsPrice(getNextEarningsYear), Color.Pink);
AddLabel(getNextEarnings == 0, "  EARNINGS TODAY ", Color.Yellow);
# End Next Earnings Date
This flashes back and forth with 2 different dates and doesn't come up as a study I can use in a watchlist? Thanks and I am brand new here.
 
This flashes back and forth with 2 different dates and doesn't come up as a study I can use in a watchlist? Thanks and I am brand new here.
I changed the expansion area and now it does not flash back and forth on charts. Still cannot see this as a study I can use in watchlists. Any ideas. Thank you.
 
I changed the expansion area and now it does not flash back and forth on charts. Still cannot see this as a study I can use in watchlists. Any ideas. Thank you.
So.... Got the study to come up in a watchlist but now it almost everything is 30 days!
 
Status
Not open for further replies.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
511 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top