% Percentage Change for ThinkorSwim

Branch

Member
Can someone create a label that will tell me how much the current product (symbol) is up or down? TOS has it in the Symbol Menu but I would like to have it on the chart as a label also.

Code:
# =============================================================================
#Hint: <b>PM Percent Change</b>\nCalculates the percent change in value from now and N periods ago where<li>value: any data type enumerated by FundamentalData such as CLOSE, IV, etc.</li><li>N: user specified look back length</li><li>period: user or chart selected aggregation period such as FIVE_MIN, DAY, WEEK, etc.</li>
#
# PM Percent Change
#
# @author: Patrick Menard, @dranem05, [email protected]
#
# This script calculates the percent change in value from now and N periods ago
# where:
#
#     value: data type enumerated by FundamentalData := CLOSE, IV, VOLUME, etc.
#         N: user specified look back length
#    period: user or chart selected aggregation period := MIN, DAY, WEEK, etc.
#
# This script can be used as a plot and as a label. If displayed on a lower
# subgraph, the % chg and its hi and lo alert triggered instances will be
# shown as it occurred over time. If 'show_label' is enabled, the most recent
# % chg will be displayed on the chart. To use this script purely as a label
# on the main price chart, set 'label_only' to YES in the script settings window
#
# This script utilized ThinkOrSwim's built-in PercentChg script and the
# customizability provided in the PM_Rank script as inspiration.
#
# LICENSE ---------------------------------------------------------------------
#
# This PM_PercentChg script is free software distributed under the terms of the
# MIT license reproduced here:
#
# The MIT License (MIT)
#
# Copyright (c) 2013 Patrick Menard, http://www.dranem05.com, http://dranem05.blogspot.com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# =============================================================================


input label_only       = YES; #Hint label_only: use this script only as a label (supercedes 'show_label')
input show_label       = YES; #Hint show_label: Toggle display of a label to display the % chg value (superceded by 'label_only')
input data_type        = FundamentalType.CLOSE; #Hint data_type: Data on which to compute a % chg
input length           = 10; #Hint length: 252 ~= 12 mth<br>189 ~= 9 mth<br>126 ~= 6 mth<br>63 ~= 3 mth
input period           = AggregationPeriod.DAY; #Hint period: Must be DAY or greater for IV computations
input use_chart_ap     = NO; #Hint use_chart_ap: Set to YES to utilize the chart's aggregation period
input high_alert       =  5.0; #Hint high_alert: Percent equal to or above which to change % chg display color
input low_alert        = -5.0; #Hint low_alert: Percent equal to or below which to change % chg display color
input multiplier       = 100; #Hint multiplier: 100 turns the % chg into a percentage, 1 leaves it as a decimal
input rounding         = 2; #Hint rounding: Number of decimal digits to which % chg value shall round
input no_nans          = YES; #Hint no_nans: If YES, return the previous % chg if current data is NaN

# -------------------------------------------------------------------------
# Ensure Aggregation Period is supported per the Fundamental Type specified
# -------------------------------------------------------------------------
#
# IMP_VOLATILITY does not support Aggregration periods less than 1 day.
# So, display at least the daily IV value

def ap_choice = if use_chart_ap then GetAggregationPeriod() else period;
def ap        = If( ap_choice < AggregationPeriod.DAY && FundamentalType.IMP_VOLATILITY == data_type, AggregationPeriod.DAY, ap_choice );

# -------------------------------------------------------------------------
# Adjust high and low alert thresholds to account for % chg multiplier
# -------------------------------------------------------------------------

plot pct_chg; # declare here so it appears first in strategy settings box on TOS
plot hi_alert = high_alert * multiplier / 100.0;
plot lo_alert = low_alert  * multiplier / 100.0;

# -------------------------------------------------------------------------
# Compute the percent change
# -------------------------------------------------------------------------

# If 'no_nans' is enabled, the previously computed % chg is returned when
# the fundamental data is NaN. If there is no previously computed % chg,
# the value returned will be what TOS uses to initialize variables:
#
#    0 as of 11/4/2013.
#
# Otherwise, NaN will be returned when a gap is encountered.
#
# TODO: may need to distinguish between gap meaning no data period vs. a temporary hole in the data (like a halt)

#def data      = Fundamental(data_type, period=ap); #TODO: creates an array or maps 'data' to this fundamental array?
#def data      = close(period=ap); #TODO: creates an array or maps 'data' to this fundamental array?
#def pct_chg_v = if   no_nans && (IsNaN(data) or IsNaN(data[length]))
#                then pct_chg_v[1]
#                else Round(multiplier * (data / data[length] - 1), rounding);

# Using 'data', whether def or plot, to reference Fundamental() does not
# work as one would assume. During market hours (OnDemand or Live), the
# result returned for data[N] is the same as data[0]. Whereas explicitly
# doing Fundamental(dt,pd)[N] returns the actual value for N periods ago.
# The same is true if we reference directly 'close', 'open', etc.
#
# So, we have to be explicit in code until this ThinkScript error is fixed.

def pct_chg_v = if   no_nans && (IsNaN(Fundamental(data_type, period=ap)) or IsNaN(Fundamental(data_type, period=ap)[length]))
                then pct_chg_v[1]
                else Round(multiplier * (Fundamental(data_type, period=ap) / Fundamental(data_type, period=ap)[length] - 1), rounding);
pct_chg       = pct_chg_v;

# DEBUGGING TOOLS
#AddLabel(1, Concat("d[0]: ", data[0]), Color.CYAN);
#AddLabel(1, Concat("d[" + length + "]: ", data[length]), Color.CYAN);
#AddLabel(1, Concat("c[0]: ", close(period=ap)[0]), Color.CYAN);
#AddLabel(1, Concat("c[" + length + "]: ", close(period=ap)[length]), Color.CYAN);
#AddLabel(1, Concat("f[0]: ", Fundamental(data_type, period=ap)[0]), Color.CYAN);
#AddLabel(1, Concat("f[" + length + "]: ", Fundamental(data_type, period=ap)[length]), Color.CYAN);

# -------------------------------------------------------------------------
# Create visual effects, display label if requested
# -------------------------------------------------------------------------

# set colors based on hi and lo alert thresholds --------------------------

pct_chg.DefineColor("HiAlert", Color.UPTICK);
pct_chg.DefineColor("Normal" , Color.GRAY);
pct_chg.DefineColor("LoAlert", Color.DOWNTICK);
pct_chg.AssignValueColor( if pct_chg >= hi_alert then pct_chg.Color("HiAlert") else if pct_chg <= lo_alert then pct_chg.Color("LoAlert") else pct_chg.Color("Normal") );
hi_alert.SetDefaultColor( Color.YELLOW );
lo_alert.SetDefaultColor( Color.YELLOW );

# select the label's prefix based on the fundamental type -----------------

# cannot use switch/case as ThinkScript's fundamental types are not enums

AddLabel(show_label or label_only,
              Concat( if data_type == FundamentalType.IMP_VOLATILITY then "IV "
         else if data_type == FundamentalType.OPEN           then "$O "
         else if data_type == FundamentalType.HIGH           then "$H "
         else if data_type == FundamentalType.LOW            then "$L "
         else if data_type == FundamentalType.CLOSE          then "PRICE "
         else if data_type == FundamentalType.HL2            then "$HL2 "
         else if data_type == FundamentalType.HLC3           then "$HLC3 "
         else if data_type == FundamentalType.OHLC4          then "$OHLC4 "
         else if data_type == FundamentalType.VWAP           then "VWAP "
         else if data_type == FundamentalType.VOLUME         then "VOLUME "
         else if data_type == FundamentalType.OPEN_INTEREST  then "OI "
         else                                                     "",
         "%CHG("+length+") " + pct_chg),
         pct_chg.TakeValueColor() );

# hide plots if user wants labels only ------------------------------------

hi_alert.SetHiding( label_only );
lo_alert.SetHiding( label_only );
pct_chg.SetHiding( label_only );
 
Solution
I have updated the Percent Change Label (from Previous Day's Close) that should work both on a daily as well as intraday aggregations. Since the equities market is currently closed I have tested this against /ES. It seems to work fine as far as I can tell.

Code:
# Percent Change Label (from Yesterday's Close)
# tomsk
# 1.9.2020

# V1.0 - 01.08.2020 - tomsk - Initial release of Percent Change Label, to be used for daily aggregation
# V1.1 - 01.09.2020 - tomsk - Updated to work on intraday aggregation as well as daily

def PC = close(period = AggregationPeriod.DAY)[1];
def PctChange = (close - PC) / PC;
AddLabel(1, "Percent Change = " + AsPercent(PctChange), if PctChange > 0 then Color.Green else if PctChange < 0 then Color.Red else...
The code above works perfect to match percent change on the TOS platform for stocks, but when you load a futures symbol it don't match. I realized futures market have different open/close times then stock for most likely this is the issue. Is there a code or can this be modified to show the correct percent change to match what TOS has for FUTURES ?
VIP_TOS thanks for the code. It works great. But how do you use it with multiple labels without all of them displaying the same net and percentage change?
 

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

is it possible to run a SCAN that would look at 1/3/6 month % change summarize those totals aka
if 1 month was 3.6%
if 3 month was -4.5%
and 6 month was 15.6% a total of 14.7 (3.6-4.5+15.6=14.7)

so if i run scan on a watch list of say 40 stocks it will tell me which of those end up with a positive vs a negative score?
or if it wont generate score, at very least have the columns so that i can visually scan the scan results

is this a possible scan? i'm sure there is a way, i have not been able to do myself, nor find a youtube that explains how. i might not be searching correct title

any help is greatly appreciated

thanks in advance
 
is it possible to run a SCAN that would look at 1/3/6 month % change summarize those totals aka
if 1 month was 3.6%
if 3 month was -4.5%
and 6 month was 15.6% a total of 14.7 (3.6-4.5+15.6=14.7)

so if i run scan on a watch list of say 40 stocks it will tell me which of those end up with a positive vs a negative score?
or if it wont generate score, at very least have the columns so that i can visually scan the scan results

is this a possible scan? i'm sure there is a way, i have not been able to do myself, nor find a youtube that explains how. i might not be searching correct title

any help is greatly appreciated

thanks in advance

try this,

set time to month (each bar is a month)

Code:
input period1 = 1;
input period2 = 3;
input period3 = 6;

def per1 = 100 * (close - close[period1] )/ close[period1];
def per2 = 100 * (close - close[period2] )/ close[period2];
def per3 = 100 * (close - close[period3] )/ close[period3];

def per = per1 + per2 + per3;

#------------------------------
#  choose what the study does, by enabling just 1 of the following plots, by removing the #

# scan,  for positive numbers
# plot z1 = if per > 0 then 1 else 0;

# scan,  for negative numbers
# plot z2 = if per < 0 then 1 else 0;

# column ,  show total %
# plot z3 = per;
 
try this,

set time to month (each bar is a month)

Code:
input period1 = 1;
input period2 = 3;
input period3 = 6;

def per1 = 100 * (close - close[period1] )/ close[period1];
def per2 = 100 * (close - close[period2] )/ close[period2];
def per3 = 100 * (close - close[period3] )/ close[period3];

def per = per1 + per2 + per3;

#------------------------------
#  choose what the study does, by enabling just 1 of the following plots, by removing the #

# scan,  for positive numbers
# plot z1 = if per > 0 then 1 else 0;

# scan,  for negative numbers
# plot z2 = if per < 0 then 1 else 0;

# column ,  show total %
# plot z3 = per;
you rock, i appreciate the help here, but there is something not coming through correctly when it runs monthly data, is doing a true month. for example when i run the scan a few stocks come up that should not first example i run scan today and ASAN came up as passing, but when i calculate the time frames its 1 month =(-10.61) 3 month = 2.55 and 6 month = (-46.59) that is not a positive # so am i under the assumption this scan will only work correctly on the first of the month. or actually last day of the month. so instead of it running 8/9-9/9 for 1 month, it is actually just looking at current monthly bar aka 9/1-9/9? the 3 month is pulling data for 7-1 through today instead of 6/9-9/9 do you follow me, its pulling Bars, not actual months????? thoughts input? what do you think?


other examples in this set that are coming up incorrectly
the following are coming up Positive when they should be negative
EA
ETHE
GDDY
KLAC
the following coming up Negative when they should be Positive
BTAI
HIVE
PANW
 
you rock, i appreciate the help here, but there is something not coming through correctly when it runs monthly data, is doing a true month. for example when i run the scan a few stocks come up that should not first example i run scan today and ASAN came up as passing, but when i calculate the time frames its 1 month =(-10.61) 3 month = 2.55 and 6 month = (-46.59) that is not a positive # so am i under the assumption this scan will only work correctly on the first of the month. or actually last day of the month. so instead of it running 8/9-9/9 for 1 month, it is actually just looking at current monthly bar aka 9/1-9/9? the 3 month is pulling data for 7-1 through today instead of 6/9-9/9 do you follow me, its pulling Bars, not actual months????? thoughts input? what do you think?


other examples in this set that are coming up incorrectly
the following are coming up Positive when they should be negative
EA
ETHE
GDDY
KLAC
the following coming up Negative when they should be Positive
BTAI
HIVE
PANW

yes, month data reads from 1st day of month to end, or current day. not back 30 days.

if you want to look back 30 , 90, 180 days from current bar, then use 2nd agg of days

To help debugging copy and change the study to a lower study than add labels and bubbles

addchartbubble(0, 1,
per1 + " 1\n" +
per2 + " 2\n" +
per3 + " 3\n" +
per + " sum"
, color.yellow, yes);
 
Last edited:

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
490 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