ThinkorSwim Indicators for Basic Fundamental Analysis

ugaotrader

ugaotrader

Member
Share my template for "fundamentals" ,everything is better of course.

Data Labels

Code:
#Chart Label to Provide Trading  Information
#Adaption from Various Sources by zzz 15 Feb 2013

#Open, High, Low, Close for Day
input Show_Label = Yes;
def P = Round(close(period = AggregationPeriod.DAY)[1], 2);
def H = Round(high(period = AggregationPeriod.DAY), 2);
def L = Round(low(period = AggregationPeriod.DAY), 2);
def O = Round(open(period = AggregationPeriod.DAY), 2);

AddLabel(Show_Label, text = Concat("P ", P), if P < O then Color.RED else Color.GREEN);
AddLabel(Show_Label, text = Concat("O ", O), if P > O then Color.RED else Color.GREEN);
AddLabel(Show_Label, "Gap " + AbsValue(P - O), if P > O then Color.RED else if P == O then Color.YELLOW else Color.GREEN);
AddLabel(Show_Label, if P > O and H > P or P <= O and L < P then "Gap Fill" else "Gap Left " + (if P > O and H < P then AbsValue(P - H) else AbsValue(P - L)), if (P > O and H < P) then Color.RED else if P <= O and L > P then Color.GREEN else Color.WHITE);
AddLabel(Show_Label, text = Concat("H ", H), color = Color.WHITE);
AddLabel(Show_Label, text = Concat("L ", L), color = Color.WHITE);
AddLabel(Show_Label, "NC_Open " + Round((close - open(period = AggregationPeriod.DAY)), 2), if open(period = AggregationPeriod.DAY) > close then Color.RED else Color.GREEN);
AddLabel(Show_Label, "NC_Close " + Round((close - close(period = AggregationPeriod.DAY)[1]), 2), if close(period = AggregationPeriod.DAY)[1] > close then Color.RED else Color.GREEN);
AddLabel(Show_Label, Concat(" HH52 " , Highest(high(period = AggregationPeriod.DAY), 252)), Color.GREEN);
AddLabel(Show_Label, "%52W_H: " + AsPercent((close - Highest(high(period = AggregationPeriod.DAY), 252)) / Highest(high(period = AggregationPeriod.DAY), 252)), Color.RED);
AddLabel(Show_Label, Concat( " LL52 ", Lowest(low(period = AggregationPeriod.DAY), 252)), Color.RED);
AddLabel(Show_Label, "%52W_L: " + AsPercent((close - Lowest(low(period = AggregationPeriod.DAY), 252)) / Lowest(low(period = AggregationPeriod.DAY), 252)), Color.GREEN);

#ATR and Daily Range
input atrlength = 5;
def null1 = Double.NaN;
AddLabel(Show_Label, text = Concat("R ", H - L), if O > close then Color.RED else Color.GREEN);
AddLabel(Show_Label, Concat("ADR ",  Round(Average(high(period = AggregationPeriod.DAY) - low(period = AggregationPeriod.DAY), atrlength), 2)), if O > close then Color.RED else Color.GREEN);
AddLabel(Show_Label, text = if (H - L) - Round(Average(high(period = AggregationPeriod.DAY) - low(period = AggregationPeriod.DAY), atrlength), 2) == 0 then "ADR Filled" else "ADR Left " + (if (H - L) - Round(Average(high(period = AggregationPeriod.DAY) - low(period = AggregationPeriod.DAY), atrlength), 2) < 0 then  AbsValue((H - L) - Round(Average(high(period = AggregationPeriod.DAY) - low(period = AggregationPeriod.DAY), atrlength), 2)) else 0) , if (H - L) - Round(Average(high(period = AggregationPeriod.DAY) - low(period = AggregationPeriod.DAY), atrlength), 2) < 0 then Color.GREEN else Color.WHITE);
def ATR2 = Average(TrueRange(high(period = AggregationPeriod.DAY), close(period = AggregationPeriod.DAY), low(period = AggregationPeriod.DAY)), atrlength);
AddLabel(Show_Label, Concat("ATR: D ", Round(ATR2, 2) + Concat(" B " , Round(number = Average(TrueRange(high=high, close=close, low=low), length=atrlength)))), Color.YELLOW);

#Volume
def avgvol = Floor(Average(volume, 10));
AddLabel(Show_Label, "BV " + if volume > 0 then volume else 0, if volume < volume[1] then Color.RED else Color.GREEN);
AddLabel(Show_Label, "DV " + volume(period = AggregationPeriod.DAY), if volume(period = AggregationPeriod.DAY) < Average(volume(period = AggregationPeriod.DAY), 10) then Color.RED else Color.GREEN);

#Current Tick Reading
input u = 0;
input lo = -0;
def it = close ("$tick");
AddLabel(Show_Label, Concat("Tick ", it), if it > u then Color.GREEN else if it < lo then Color.LIGHT_RED else Color.WHITE);

Earning Trend

Code:
#Follow @KRose_TDA on twitter for free updates posted for this and other scripts
#Earnings trend study is used as part of the generating income with dividend stocks webcast presented Monday nights @ 7PM ET   https://events.thinkorswim.com/#/webcast
# I build custom studies like earnings trend as part of my Thursday night thinkscript webinar @ 5:30PM ET 
#     https://events.thinkorswim.com/#/webcast
#This study creates a line chart tracking the trend of a stock's quarterly EPS values(it doesn't work for ETFs).A red square appears when Earnings Per Share(EPS)is lower than the prior quarter's EPS, and a dark green square appears when EPS is higher than the previous quarter's EPS. The arrows represent a comparison of an analyst's estimated EPS for that quarter versus the actual EPS. If the arrow is colored Green, the company's actual EPS was greater than the analyst estimates. If the actual EPS was less than the analyst estimates, the arrow will be Red. The point of the arrow equals analyst estimate value.

declare lower;
declare Hide_on_intraday;

def EPS = if !isNaN(GetActualEarnings()) then GetActualEarnings() else EPS[1];

plot EPS_line_chart = GetActualEarnings();
EPS_line_chart.EnableApproximation();
EPS_line_chart.SetDefaultColor(color.black);

plot earnings_date = GetActualEarnings();
earnings_date.SetPaintingStrategy(PaintingStrategy.squares);

earnings_date.AssignValueColor(if EPS > EPS[1] then color.dark_green else color.red);
earnings_date.SetLineWeight(5);

plot EstEarning = GetEstimatedEarnings();
EstEarning.SetPaintingStrategy(PaintingStrategy.arrow_up );

EstEarning.AssignValueColor (if EstEarning < EPS then color.DARK_GREEN else color.DARK_RED);
EstEarning.SetLineWeight(5);

# end code

Squeeze Bars

Code:
#hint;A WatchList Column (WLC) that shows whether an equity is in a squeeze and if so how many bars it has been in a squeeze. Be sure to set the agg to the chart agg you want to view this on. This is very efficient code.

def Squeeze = if (reference BollingerBands()."UpperBand" - KeltnerChannels()."Upper_Band") < 0 then 1 else 0;
def count = compoundvalue(1, if Squeeze then count[1] + 1 else if !Squeeze then 0 else 0, 1);

#addlabel(1, "Bars into a squeeze = " + count, If squeeze then Color.LIGHT_RED else color.Current);
#if column width is a concern the label below shortens the word length and shows the count value

AddLabel(1, "SQZ= " + count, if Squeeze then Color.LIGHT_RED else Color.CURRENT);
# end

Chris' Enhanced Volume

Code:
#Chris' Enhanced Volume


###############
# Body
###############
input Audible_Alert = yes;
def Deviation_Length = 60;
def Deviate = 2;
def volumestdev = RelativeVolumeStDev(length = Deviation_Length);
def abovedev = volumestdev >= Deviate;
def belowdev = volumestdev <= Deviate;


###############
# Volume Bars
###############
plot volumereplace = volume;
volumereplace.SetPaintingStrategy(paintingStrategy = PaintingStrategy.HISTOGRAM);
def increase = volume > volume[1];
def devincrease = increase and abovedev;
def decrease = volume < volume[1];
def devdecrease = decrease and abovedev;
volumereplace.DefineColor("Increase", Color.DARK_GREEN);
volumereplace.DefineColor("DevIncrease", Color.GREEN);
volumereplace.DefineColor("Decrease", Color.DARK_RED);
volumereplace.DefineColor("DevDecrease", Color.LIGHT_RED);
volumereplace.AssignValueColor(
if devincrease then volumereplace.Color("DevIncrease")
else
if increase then volumereplace.Color("Increase")
else
if devdecrease then volumereplace.Color("DevDecrease")
else
volumereplace.Color("Decrease"));


###############
# Alerts
###############
Alert(devincrease and Audible_Alert, "Support/Resistance Detected", Alert.BAR, Sound.Bell);
Alert(devdecrease and Audible_Alert, "Support/Resistance Detected", Alert.BAR, Sound.Bell);

Vix Labels

Code:
# ------------------------
# Script para Embajadores Shark Trading System
# Gustavo Moyano
# V.1.0 Año 2018
# Creado y Documentado Edwin Londoño
# web: http://www.stsinnova.com/
# Correos:
#  [email protected]
#
# Mostrar en el grafico Diferentes indices
#
# Indicadores_Mercado
# V01.0.2018
# -----------------------------------------------------
#--------------------
declare upper;
input Temporalidad = AggregationPeriod.day;
Input Indicador=  {"SPY", "QQQ", "DIA", default "VIX"};
input Color_del_recuadro = {"magenta", "green", "pink", default "cyan", "orange", "red", "blue", "gray", "violet"};

def Indicador_ = close(Indicador,period = Temporalidad);

AddLabel(yes, Indicador +": " + Indicador_, GetColor(Color_del_recuadro));

Earnings Reaction

Code:
# Script displays earnings and securities reaction to the announcement
#Developed and Coded By Eric Rasmussen
# [email protected]

# 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 "");

Earnings Statistic

Code:
# Archive Name: Earnings Statistics Paris

# Archive Section: Scripts-Earnings

# Suggested Tos Name: EarningsStatistics_Paris

# Archive Date: 5.07.2018

# Archive Notes: 

# Earnings Statisques

# Paris

# 5.6.2018

 

# This study displays the following earnings related info/stats:

#

# ++ Vertical lines that mark each earnings cycle and earnings date

# ++ Bubble that measures the gap and percentage moves post earnings

# ++ Total number of gaps ups versus gap downs

# ++ Average gap ups versus gap downs

# ++ Average percentage moves up versus percentage moves down

# ++ If the next earnings cycle happens within the next "ExpansionBars", 

#    the earnings date is displayed, otherwise it is not displayed

 

declare hide_on_intraday;

 

input ExpansionBars = 11;

input BubbleOffset = 2;

 

def bn = BarNumber();

def Month = GetMonth();

def Day = GetDayOfMonth(GetYYYYMMDD());

 

def isBefore = HasEarnings(EarningTime.BEFORE_MARKET);

def isAfter  = HasEarnings(EarningTime.AFTER_MARKET);

def isToday  = isBefore or isAfter or (HasEarnings() and !isBefore and !isAfter);

 

def EarningsBN  = if HasEarnings(EarningTime.BEFORE_MARKET) then bn[1] 

else if HasEarnings(EarningTime.AFTER_MARKET) then bn 

else EarningsBN[1]; 

def DayAfterBN = if bn - EarningsBN == 1 then bn else Double.NaN;

 

AddVerticalLine(isToday, "        " + Month + "/" + Day + " Earnings", Color.ORANGE, Curve.SHORT_DASH);

 

def EGap = fold y = 0 to 1 

while DayAfterBN do 

if (bn - DayAfterBN) <= 1 then open - close[1]

else Double.NaN;

 

def EPct = fold z = 0 to 1 

while DayAfterBN do 

if (bn - DayAfterBN) <= 1 then (open - close[1]) / close[1]

else Double.NaN;

 

def gapUp = EGap > 0;

def gapDn = EGap < 0;

 

def gapUpTotal = if EGap > 0 then gapUpTotal[1] + EGap else gapUpTotal[1];

def gapDnTotal = if EGap < 0 then gapDnTotal[1] + EGap else gapDnTotal[1];

def pctUpTotal = if EGap > 0 then pctUpTotal[1] + EPct else pctUpTotal[1];

def pctDnTotal = if EGap < 0 then pctDnTotal[1] + EPct else pctDnTotal[1];

 

AddChartBubble(gapUp, high[1] + TickSize() * bubbleOffset, "GapUp: $" + EGap + "\nPctUp: " + AsPercent(EPct), Color.LIGHT_Green);

AddChartBubble(gapDn, low[1] - TickSize() * bubbleOffset, "GapDn: $" + EGap + "\nPctDn: " + AsPercent(EPct), Color.PINK);

 

AddLabel(1, "# Earnings Gap Up: " + TotalSum(gapUp), Color.LIGHT_GREEN);

AddLabel(1, "# Earnings Gap Down: " + TotalSum(gapDn), Color.PINK);

AddLabel(1, "Average Gap Up: " + Round(gapUpTotal/TotalSum(gapUp),2), Color.LIGHT_GREEN);

AddLabel(1, "Average Gap Down: " + Round(gapDnTotal/TotalSum(gapDn),2), Color.PINK);

AddLabel(1, "Average Pct Up: " + AsPercent(pctUpTotal/TotalSum(gapUp)), Color.LIGHT_GREEN);

AddLabel(1, "Average Pct Down: " + AsPercent(pctDnTotal/TotalSum(gapDn)), Color.PINK);

 

###--- Process next earnings date

 

def Earnings = AbsValue(GetEventOffset(Events.Earnings, 0));

def DTE = if isNaN(Earnings) then 0 else Earnings;

def NextEarningsBN = if !isNaN(Earnings) then bn + Earnings else Double.NaN;

def EarningsBNX = bn == HighestAll(NextEarningsBN);

def NextEarningsMth = HighestAll(if EarningsBNX then Month else Double.NaN);

def NextEarningsDay = HighestAll(if EarningsBNX then Day   else Double.NaN);

 

AddLabel(DTE < ExpansionBars and DTE > 0, "Upcoming Earnings Date: " + NextEarningsMth + "/" + NextEarningsDay, Color.YELLOW);

 

# END STUDY

Dividends Return

Code:
#BEST
#Total Return created by [email protected]
#This study shows the total Return: Div + Price Appreciation
#On the chart for the chart period showing

#declare lower;
def close1 = First(close);

rec TotalDiv = totalDiv[1] + if IsNaN(GetDividend()) then 0 else  GetDividend();
def PriceReturn = round((close - close1)/(close1)*100,2);
def DividendReturn = if totaldiv > 0 then round(TotalDiv / close1 * 100,2)else 0 ;

#addlabel(yes,"close1 " + close1 + " Close " + close );

addlabel (yes,"Price Return= "+ PriceReturn +"% " + " Dividend Return= " + DividendReturn +"% " + "Total % Return= " + round(Pricereturn + DividendReturn,2));

Entire collection

https://tos.mx/AV4Tz3k
 
Last edited by a moderator:
C

Craighaber71

Active member
2019 Donor
VIP
How is the bottom indicator used....The TTM one with the bars
 
markos

markos

Well-known member
VIP
@Craighaber71 that is a licensed study. It can be looked up in the Education > Learning Center Tab.

@ugaotrader I really like that chart. Especially the earnings/gap information. Thank you for sharing
 
J

jay2

Member
thanks for this! gap info is exactly what i was looking for.
 
netarchitech

netarchitech

Well-known member
VIP
@ugaotrader Thanks for sharing...

Good Luck and Good Trading :)
 

Similar threads

Top