Earnings, Dividend and P/E Labels for ThinkorSwim

markos

Well-known member
VIP
Posted via the thinkScript lounge by Nube.

22:40 Nube: Price to Earnings lines have come up a few times without a good answer. This isn't a good answer either, but it shows one way to do it. This will draw lines for 5 input PE values at the 2 most recent earnings releases. If someone desires the lines going further back, they can expand the script using more of the same logic

Here's the code:

Code:
``````# Earnings, Dividend and P/E Labels
# Nube
# v01 7.3.18
# http://tos.mx/ieYc5f#
#hint: Displays the previous annual earnings for the 2 most recent quarters and the previous 4 dividends in labels as well as 5 user selectable P/E values for two most recent quarters. Method can be duplicated to draw PE lines for previous quarters.

input PEOne   = 9;
input PETwo   = 13;
input PEThree = 15;
input PEFour  = 16;
input PEFive  = 18;

def c  = close;
def na = Double.NaN;
def bn = BarNumber();
def Earnings = GetActualEarnings();
def Dividend = GetDividend();

def currentBar = if   !IsNaN(c) and IsNaN(c[-1])
then bn
else currentBar[1];
# section below identifies the bars at which earnings were released
def earningsBar = if   !IsNaN(Earnings)
then bn
else earningsBar[1];
def prevEarningsBar1 = if   earningsBar != earningsBar[1]
then earningsBar[1]
else prevEarningsBar1[1];
def prevEarningsBar2 = if   prevEarningsBar1 != prevEarningsBar1[1]
then prevEarningsBar1[1]
else prevEarningsBar2[1];
def prevEarningsBar3 = if   prevEarningsBar2 != prevEarningsBar2[1]
then prevEarningsBar2[1]
else prevEarningsBar3[1];
def prevEarningsBar4 = if   prevEarningsBar3 != prevEarningsBar3[1]
then prevEarningsBar3[1]
else prevEarningsBar4[1];
# identifies the which bars are the previous 1,2,3 etc earnings bars as of the current time
def hEB   = HighestAll(earningsBar);
def hpEB1 = HighestAll(prevEarningsBar1);
def hpEB2 = HighestAll(prevEarningsBar2);
def hpEB3 = HighestAll(prevEarningsBar3);
def hpEB4 = HighestAll(prevEarningsBar4);
# getting the four most recent earnings values
def currentEarnings = if   bn == hEB
then Earnings
else currentEarnings[1];
def secondEarnings  = if   bn == hEB
then GetValue(Earnings, hEB - prevEarningsBar1)
else secondEarnings[1];
def thirdEarnings   = if   bn == hEB
then GetValue(Earnings, hEB - prevEarningsBar2)
else thirdEarnings[1];
def fourthEarnings  = if   bn == hEB
then GetValue(Earnings, hEB - prevEarningsBar3)
else fourthEarnings[1];
# getting 4 earnings values up until second most recent earnings bar
def lQfirstEarnings   = if   bn == hpEB1
then Earnings
else lQfirstEarnings[1];
def lQsecondEarnings   = if   bn == hpEB1
then GetValue(Earnings, hpEB1 - hpEB2)
else lQsecondEarnings[1];
def lQthirdEarnings = if   bn == hpEB1
then GetValue(Earnings, hpEB1 - hpEB3)
else lQthirdEarnings[1];
def lQfourthEarnings  = if   bn == hpEB1
then GetValue(Earnings, hpEB1 - hpEB4)
else lQfourthEarnings[1];

def currentAnnualEarnings = currentEarnings + secondEarnings + thirdEarnings + fourthEarnings;
def lastQannualEarning = lQfirstEarnings + lQsecondEarnings + lQthirdEarnings + lQfourthEarnings;
def cAE  = currentAnnualEarnings;
def lQaE = lastQannualEarning;
def annualEarnings = if   bn == hpEB1
then lQaE
else if bn == hEB
then cAE
else annualEarnings[1];
def AE = annualEarnings;
def PE = c / AE;

# same process for getting the dividend bars
def dividendBar      = if   !IsNaN(Dividend)
then bn
else dividendBar[1];
def prevDividendBar1 = if   DividendBar != DividendBar[1]
then DividendBar[1]
else prevDividendBar1[1];
def prevDividendBar2 = if   prevDividendBar1 != prevDividendBar1[1]
then prevDividendBar1[1]
else prevDividendBar2[1];
def prevDividendBar3 = if   prevDividendBar2 != prevDividendBar2[1]
then prevDividendBar2[1]
else prevDividendBar3[1];
# again, same process for getting the dividend values
def currentDividend  = if   bn == DividendBar
then Dividend
else currentDividend[1];
def secondDividend = GetValue(Dividend, currentBar - prevDividendBar1);
def thirdDividend  = GetValue(Dividend, currentBar - prevDividendBar2);
def fourthDividend = GetValue(Dividend, currentBar - prevDividendBar3);
def annualDividend = currentDividend + secondDividend + thirdDividend + fourthDividend;
def yield = AD / c;

plot
"P/E 1" = AE * PEOne;
"P/E 1".  SetDefaultColor(CreateColor(100,225,100));
"P/E 1".  SetPaintingStrategy(PaintingStrategy.DASHES);

plot
"P/E 2" = AE * PETwo;
"P/E 2".  SetDefaultColor(CreateColor(75,175,225));
"P/E 2".  SetPaintingStrategy(PaintingStrategy.DASHES);

plot
"P/E 3" = AE * PEThree;
"P/E 3".  SetDefaultColor(CreateColor(250,175,50));
"P/E 3".  SetPaintingStrategy(PaintingStrategy.DASHES);

plot
"P/E 4" = AE * PEFour;
"P/E 4".  SetDefaultColor(CreateColor(200,100,200));
"P/E 4".  SetPaintingStrategy(PaintingStrategy.DASHES);

plot
"P/E 5" = AE * PEFive;
"P/E 5".  SetDefaultColor(CreateColor(225,100,100));
"P/E 5".  SetPaintingStrategy(PaintingStrategy.DASHES);

def locate = !IsNaN(c[3]) && IsNaN(c[2]);
AddChartBubble(locate, "P/E 1", "P/E: "+PEOne+ "\n\$"+"P/E 1",
CreateColor(100,225,100));
AddChartBubble(locate, "P/E 2", "P/E: "+PETwo+ "\n\$"+"P/E 2",
CreateColor(75,175,225));
AddChartBubble(locate, "P/E 3", "P/E: "+PEThree+ "\n\$"+"P/E 3",
CreateColor(250,175,50));
AddChartBubble(locate, "P/E 4", "P/E: "+PEFour+ "\n\$"+"P/E 4",
CreateColor(200,100,200));
AddChartBubble(locate, "P/E 5", "P/E: "+PEFive+ "\n\$"+"P/E 5",
CreateColor(225,100,100));
Addlabel(1, "Earnings 1: \$" +currentEarnings+" Earnings 2: \$" +secondEarnings+" Earnings 3: \$" +thirdEarnings+" Earnings 4: \$" +fourthEarnings, CreateColor(200,200,100));
Addlabel(1, " Last Q Earnings 1: \$" +lQfirstEarnings+" Last Q Earnings 2: \$" +lQsecondEarnings+" Last Q Earnings 3: \$" +lQthirdEarnings+" Last Q Earnings 4: \$" +lQfourthEarnings, CreateColor(225,175,75));
Addlabel(1, "Dividend 1: \$" +currentDividend+" Dividend 2: \$"      +secondDividend+" Dividend 3: \$" +thirdDividend+" Dividend 4: \$" +fourthDividend, CreateColor(250,150,0));
AddLabel(1," Annual Earnings Last Q: \$"+lQaE, CreateColor(100,225,100));
AddLabel(yes, "P/E Ratio: " + Round(PE,2),
CreateColor(200,200,200));
CreateColor(200,200,200));

# f/ Earnings, Dividend and P/E Labels``````

Ex-dividend Days Label
Code:
``````# WatchList of Label Days Till X Dividend
# If over 30 days away shows 30
# Mobius
input DaysTillXdiv = 30;

def LastDividendBar = AbsValue(GetEventOffset(Events.DIVIDEND, 0));
def NextDividend = if isNaN(LastDividendBar) then 0 else LastDividendBar;
AddLabel(NextDividend == DaysTillXdiv, "Dividend More than 30 days out", color.white);
AddLabel(NextDividend <= DaysTillXdiv-1 and NextDividend > 0, "Dividend in " + NextDividend + " days", Color.Red);``````

Last edited by a moderator:

2019 Donor

tomsk

Well-known member
VIP
@J007RMC Make sure you have sufficient bars defined in your expansion area. If you do not do this, you won't see the data.

Go to Settings > Time Axis > Expansion area

Miket

Member
Can you have this column in your watchlist and see how long you must wait for the dividend?

BenTen

Staff member
Staff
VIP
@Miket You can easily find this out by searching through the existing watchlist columns that ThinkorSwim provided.

Miket

Member
Doesn't exist. It would be great to know when the date of record is to try to scalp some dividends.

BenTen

Staff member
Staff
VIP
@Miket The TD app has it. You can try that or their webapp as well.

Praful005

Member
Hello friends,

Can anyone please watch the following webinar and create the Earning Hotzone indicator. It is looking cool and very helpful for trading earnings.

Thank you,

jtay2002

New member
Will be good if someone can indeed came up with the Earning Hotzone indicator. Possible to share if you have the thinkscript as I am interested to try it out as it looks promising.

Thank You

1HugoValencia

New member
Hello All,

I am new on this great community. I added the code to create the hotzones and labels on the one developed by Eric Rasmussen some time ago; is the first little script I do for TOS so feel free to improve the code or do some recommendations:

Ruby:
``````# Script displays earnings and securities reaction to the announcement, it displays a counter and hotzones

# HotZones added by Hugo Valencia

# 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.LIME);

# Percentage of Earnings Beats Label

input beatRatioLabel = yes;

AddLabel(beatRatioLabel, Concat(Concat("Earnings Beats: ", beatRatio), "%"), color = if beatRatio >= 80 then Color.GREEN else Color.RED);

# Bubbles Showing Percent Moves After Earnings

input percentBubbles = yes;

AddChartBubble("price location" = high, text = Concat(earningsPercent, "%"), "time condition" =  if percentBubbles == yes then earningsPercent else 0, color = if isAfter and close[-1] > close then Color.MAGENTA else if isAfter and close[-1] < close then Color.LIME else if isBefore and close > close[1] then Color.MAGENTA else if isBefore and close < close[1] then Color.LIME else Color.BLACK);

# Date Line for Earnings

input text = no;

AddVerticalLine(HasEarnings() and EarningsBeat and uM, color = Color.CYAN, stroke = Curve.FIRM, text = if text == yes then Concat(if isBefore then "(Before) " else "(After) ", Concat("\$", Concat(EECont, Concat(" Actual", Concat("  \$", Concat(AECont, " Estimated")))))) else "");

AddVerticalLine(HasEarnings() and EarningsBeat and dM, color = Color.MAGENTA, stroke = Curve.FIRM, text = if text == yes then Concat(if isBefore then "(Before) " else "(After) ", Concat("\$", Concat(EECont, Concat(" Actual", Concat("  \$", Concat(AECont, " Estimated")))))) else "");

AddVerticalLine(HasEarnings() and EarningsMiss and uM, color = Color.LIME, stroke = Curve.FIRM, text = if text == yes then Concat(if isBefore then "(Before) " else "(After) ", Concat("\$", Concat(EECont, Concat(" Actual", Concat("  \$", Concat(AECont, " Estimated")))))) else "");

AddVerticalLine(HasEarnings() and EarningsMiss and dM, color = Color.RED, stroke = Curve.FIRM, text = if text == yes then Concat(if isBefore then "(Before) " else "(After) ", Concat("\$", Concat(EECont, Concat(" Actual", Concat("  \$", Concat(AECont, " Estimated")))))) else "");

#Hotzones: Days before earnings

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;

input Hotzone1 = 14;

input Hotzone2 = 21;

def HotZone1def = if Earnings <= Hotzone1 then Double.POSITIVE_INFINITY else Double.NaN;

def HotZone2def = if Earnings <= Hotzone2 and Earnings >= Hotzone1 then Double.POSITIVE_INFINITY else Double.NaN;

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);``````
- Make sure the Autoexpand to fix Corporate actions is set (under the Time axis tab)

Last edited:

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
• Exclusive indicators
• Proven strategies & setups
• Private Discord community
• Exclusive members-only content
• 1 full year of unlimited support

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?