thinkScript
User Manual
Need more help? Email us at support@thinkorswim.com
You may also find it helpful to join this online discussion group started by existing thinkScript users. thinkScript discussion group
thinkScript Introduction

Basic Commands NEW! - Constants
thinkScript Functions

Function Definitions
thinkScript Advanced & Saving

Limiting input data (ENUM & SWITCH)
Accessing Data From Another Symbol
Using Historical Data
Referencing Pre-Defined Studies
Choosing Colors
Saving Your Study
thinkScript and Strategies

Adding Strategies
Editing Strategies Saving Your Strategy

Introduction
thinkScript is a basic editing tool used for fine-tuning an existing study or implementing your own study on the Charts tab. Put simply, thinkScript is a way to manipulate the closing, opening, high and low price of a stock or index, as well as the trading volume and volatility of a stock or index with a formula and then display the results on a chart. One or all of those data types (open, high, low, close, volume and imp_volatility) in conjunction with some basic functions will constitute the building blocks of your thinkScript studies. Like building blocks, each element of thinkScript is, in itself, fairly simple but combining them together can yield some complex and powerful results.

To begin using the thinkScript editor for studies, go to the Charts tab, click 'Studies' in the upper right corner of the page and select 'Edit Studies'. This will open the 'Edit Studies' window. To use thinkScript to make a study of your own you now have two choices:
PLEASE NOTE: Every line of thinkScript code must end with a semi-colon(;). Also, thinkScript code is not case-sensitive.


Basic Commands
thinkScript supports five simple commands: DECLARE, PLOT, DEF, INPUT and REC. These commands control the basic behavior of your thinkScript study.


Basic Command - DECLARE
The DECLARE keyword is a method for telling the chart something basic about the appearance of the study you are creating. There are three current uses for declare:
declare upper;
This command places your study in the main chart window on top of the pricing bars. You want an upper study if your study plot falls more or less within the same range as pricing. 'SimpleMovingAverage', for instance. By default, all studies created with thinkScript are upper studies and you don't have to make this declaration.
declare lower;
This statement places your study on a separate graph under the pricing bars. You want a lower study if your study is some complex value in the range of 0-100, i.e. not directly related to the market values.
declare hide_on_intraday;
This command obscures your study for pre- or post-market (non-regular market hours) data on intraday graphs. This is useful if you use IMP_VOLATILITY where there is no implied volatility outside of regular market hours because options do not trade then even though a stock may.


Basic Command - Study Declarations
all_for_one (applicable to strategies) Keeps the "volume" value in all price inputs or in none of them. This function is used to prevent visualizing irrelevant data in case the "volume" value does not combine with other price input values.

Syntax
declare all_for_one;
Example (Price Envelopes)
declare all_for_one;

input HighPrice = high;
input LowPrice = low;

plot UpperBand = Average(HighPrice) * 1.1;
plot LowerBand = Average(LowPrice) * 0.9;
This example plots the "high" and "low" price envelopes at 10 percent above and below for the 12-day simple moving average. If you change the inputs in this code to "close" and "volume", the "all_for_one" declaration will automatically change the "HighPrice" and the "LowPrice" inputs to the two "volumes" because the "close" and "volume" in combination lead to irrelevant data. As a result, the two "volume" values will be plotted.


fullrange (Highest Price) Changes the study recalculation mode. By default, only the last study values are recalculated when a new tick arrives. This declaration forces the study to recalculate values for all bars when a new bar appears. The "fullrange" declaration should be used to provide the correct work of the "HighestAll", "LowestAll", and "InertiaAll" functions.

Syntax
declare fullrange;
Example
declare fullrange;
input price = close;

plot HighestPrice = HighestAll(price);
This example plots the highest price for all bars. The "fullrange" declaration is used to recalculate the chart values from the beginning. If you do not use the declaration, only the last values will be recalculated.


hide_on_intraday Hides the study on intraday charts.

Syntax
declare hide_on_intraday;
Example (Implied Volatility)
declare hide_on_intraday;
declare lower;

plot ImpVol = IMP_VOLATILITY();
Data for the implied volatility is not available for intraday charts. Therefore you can use the declaration to automatically hide the study on this type of charts.


lower Places a study on the lower subgraph. This declaration is used when your study uses values that are considerably lower or higher than the price history or volume values.

Syntax
declare lower;
Example (Price Oscillator)
declare lower;

input price = close;
input fastLength = 9;
input slowLength = 18;
plot PriceOsc = Average(price, fastLength) - Average(price, slowLength);
The example plots the difference between the two average values calculated on 9 and 18-bar intervals. The result value is lower compared to the "price" value. It is reasonable to put the plot on the lower subgraph to avoid scaling the main chart.


on_volume Places the plot on the volume subgraph. By default, the application automatically defines where to place a study. If the study contains "volume" values and values not related to the base subgraph, then this study is displayed on the volume subgraph, otherwise it is displayed on the base subgraph. However, it may be required to forcibly place the study on the volume subgraph regardless of the values you are using.

Syntax
declare on_volume;
Example (Volume Accumulation on the Volume subgraph)
declare on_volume;
plot VolumeAccumulation = (close - (high + low) / 2) * volume;
The code in the example contains both volume and base subgraph related values. In order to place the study on the volume subgraph, the code uses the "on_volume" declaration. To study the example that uses only non-volume values, see the "real_size" declaration section.


real_size Forces the study to use axis of either base subgraph or volume subgraph. Note that the axis of the volume subgraph can be used in case you use only "volume" values in your study.

Studies always use the axis of the subgraph on which you plot them except for the following two cases when the native plot axis are used: For the described two cases it may be required to use the axis of the volume or base subgraph, instead of the native plot axis.

Syntax
declare real_size;
Example (Open Interest)
declare real_size;
declare on_volume;
declare hide_on_intraday;

plot Data = open_interest();
In the code above, in order to use the axis of the volume subgraph, you specify the "real_size" declaration


upper Places the study on the base subgraph or on the volume subgraph. Note that the study is placed on the volume subgraph in case only "volume" values are used in the study. This declaration is applied by default to all studies that do not contain the "lower" and "on_volume" declarations.

Syntax
declare upper;
Example (Price Oscillator)
declare upper;

input price = close;
input length = 9;

plot AvgWtd = wma(price, length);
In this example, the "upper" declaration places the weighted moving average plot on the main chart.


weak_volume_dependency Places the study on the volume subgraph when at least one "volume" value is used.

Syntax
declare weak_volume_dependency;
Example (Keltner Channels)
declare weak_volume_dependency;

input factor = 1.5;
input length = 20;
input price = close;

def shift = factor * AvgTrueRange(high, close, low, length);
def average = Average(price, length);

plot Avg = average;
plot Upper_Band = average + shift;
plot Lower_Band = average - shift;
Consider you are analyzing data that contains both volume and base subgraph related values using the code provided above. You want to display the plot on the base subgraph except for cases when you use at least one volume value. For the latter case, you would like to use the volume subgraph. In order to implement the logics, you use the "weak_volume_declaration". If you use the "close" price input in the code, the study is displayed on the base subgraph. If you use the "volume" price input, then there is a "weak volume dependency" and the study is displayed on the volume subgraph.


zerobase Sets the minimal value on the study axis to zero if there are no negative values in the study.

Syntax
declare zerobase;
Example
declare zerobase;
declare lower;

plot Vol = Volume;
In this example, the Vol plot does not contain any negative values. It is reasonable to set the minimum value on the study axis to zero using the "zerobase" declaration.


Strategy Declarations
LONG_ENTRY Defines a buying strategy for entering a new long position. This function can also used to define a buying strategy for closing a short position. Note that you can switch this function to the SHORT_EXIT. To switch to the SHORT_EXIT, select the "Exit only" option in the Strategy mode list box.

Syntax
declare LONG_ENTRY;
declare ENTRY;
Example (Key Reversal LE)
declare LONG_ENTRY;

input length = 1;

addOrder(Low < Lowest(Low[1], Length) and Close > Close[1]);
The strategy generates a long position entry signal on the open price of the next bar when the Key Reversal Up condition is satisfied: the close value is higher that the previous close and the low value is lower than the lowest low for the last period ("length") .


LONG_EXIT Defines a selling strategy for closing a long position. Note that this function should not be used to define a selling strategy for entering a new short position.

Syntax
declare LONG_EXIT;
declare EXIT;
Example (Key Reversal LX)
declare LONG_EXIT;

input length = 1;

addOrder(High > Highest(High[1], Length) and Close < Close[1]);
The strategy generates a long position exit signal on the open price of the next bar when the Key Reversal Down condition is satisfied: the close value is lower that the previous close and the high value is higher than the highest high for the last period ("length").


SHORT_ENTRY Defines a selling strategy for entering a new short position. This function can also used to define a selling strategy for closing a long position. You can switch this function to the LONG_EXIT. To switch to the LONG_EXIT, select the "Exit only" option in the Strategy mode list box.

Syntax
declare SHORT_ENTRY;
Example (Key Reversal SE)
declare SHORT_ENTRY;

input length = 1;

addOrder(High > Highest(High[1], Length) and Close < Close[1]);
The strategy generates a short position entry signal on the open price of the next bar when the Key Reversal Down condition is satisfied: the close value is lower that the previous close and the high value is higher than the highest high for the last period ("length").


SHORT_EXIT Defines a buying strategy for closing a short position. Note that this function should not be used to define a buying strategy for entering a new long position.

Syntax
declare SHORT_EXIT;
Example (Key Reversal SX)
declare SHORT_EXIT;

input length = 1;

addOrder(Low < Lowest(Low[1], Length) and Close > Close[1]);
The strategy generates a short position exit signal on the open price of the next bar when the Key Reversal Up condition is satisfied: the close value is higher that the previous close and the low value is lower than the lowest low for the last period ("length").


Basic Command - PLOT
The PLOT command actually renders the data you are working with on the chart. Every study contains at least on plot declaration (without one, nothing would be displayed on the chart). For it to work, you must give the data you are trying to plot a name and then define what that data will represent. For example, if you want to plot the closing price of a stock, you can't simply write
plot close;
That won't work. You have to provide both the name and the data:
plot price = close;
The name for what you are plotting can be anything that makes sense to you, such as
plot median = (open + close) / 2;
This script will display a line that adds the opening and closing price of each bar of data and divides the sum by two.

You can make multiple plot declarations to show more than one line on the chart, such as
plot median = (open + close) / 2;
plot ohlc = (open + high + low + close) / 4;
As you can see, the plot command uses the basic information of open, high, low, close, volume and implied volatility in mathematical formulas and displays the result on the chart.


Basic Command - DEF
The DEF command defines a variable you'd like to work with. For example, you can define something called "MyClosingPrice" as
def MyClosingPrice = Close;
By using the def command, you can create a variable that can be used in another formula in the study. This let's you construct complex formulas from simpler elements. For example, if you wanted to divide the range of a stock price by the closing price, you could create a variable for the range:
def range = high - low;
then create another variable
def percentrange = range / close;

Doing it this way lets you re-use variables and gives you the power to combine complex variables in your formulas more easily. By defining a variable such as
def SMA = average(close, 20);
you can use that variable "sma" in your code as part of another calculation. For instance,
plot doubleSMA = SMA * 2;
plot tripleSMA = SMA * 3;
This will display lines that are 2 and 3 times the SMA variable. In this case, SMA itself is not displayed on the chart because there is no plot declaration to do so.


Basic Command - INPUT
Most studies are adjustable in terms of length, bounds or levels. You can create an adjustable parameter for your thinkScript study using the INPUT command. An input is like a def that can be adjusted in the 'Edit Studies' window or in the 'Format Study' dialog found by right-clicking on a study line right on the graph. For instance,
input length = 12;
input price = close;

plot SMA = average(data = price, length = length);
Here '12' and 'close' are default values which you can override on the preferences panel the way you adjust any pre-defined studies.


Basic Command - REC
The REC command lets you reference a historical value of a variable that you are calculating in the study itself. Rec is short for "recursion". For example,
def mystudy = mystudy[1] + 5;
won't work because you are trying to use a previous value of the variable "mystudy" in the formula.
rec mystudy = mystudy[1] + 5;
will work because the rec command allows you to use previous values of the variable in the formula.


Constants
Aggregation Period Defines the aggregation period in milliseconds.

Example

Syntax Value
AggregationPeriod.MIN 60,000
AggregationPeriod.HOUR 3,600,000
AggregationPeriod.DAY 86,400,000
AggregationPeriod.WEEK 604,800,000
AggregationPeriod.MONTH 2,592,000,000


Color Defines the color.

Example
See the setDefaultColor function in the Look & Feel functions section.

Syntax Sample RGB Code
Color.BLACK   (0,0,0)
Color.BLUE   (0,0,255)
Color.CYAN   (0,255,255)
Color.DARK_GRAY   (64,64,64)
Color.DARK_GREEN   (0,100,0)
Color.DARK_ORANGE   (255,127,0)
Color.DARK_RED   (128,0,0)
Color.DOWNTICK   (204,0,0)
Syntax Sample RGB Code
Color.GRAY   (128,128,128)
Color.GREEN   (0,255,0)
Color.LIGHT_GRAY   (192,192,192)
Color.LIGHT_GREEN   (144,238,144)
Color.LIGHT_ORANGE   (255,165,0)
Color.LIGHT_RED   (255,63,0)
Color.LIME   (191,255,0)
Color.MAGENTA   (255,0,255)
Syntax Sample RGB Code
Color.ORANGE   (255,200,0)
Color.PINK   (255,175,175)
Color.RED   (255,0,0)
Color.UPTICK   (3,128,0)
Color.VIOLET   (153,153,255)
Color.WHITE   (255,255,255)
Color.YELLOW   (255,255,0)
     


Curve Style Defines the curve style.

Example
See the SetStyle function in the Look & Feel section.

Syntax Example
Curve.FIRM
Curve.INEDITABLE
Curve.LONG_DASH
Curve.POINTS
Curve.SHORT_DASH

Note that the Curve.INEDITABLE constant is used to disable the style of the chart on the UI. If you specify this constant, the corresponding UI field will become inactive and the solid line style will be applied for your chart.

Double.E Returns the value of the exponent constant.

Example
See the exp function in the Mathematical and Logical section.

Double.NaN Returns the value that indicates that the result of an operation is not a number.

Example
See the isNaN function in the Mathematical and Trigonometrical section.

Double.Pi Returns the value of the pi constant.

Example
See the Asin, Acos, Sin, and Cos functions in the Mathematical and Trigonometrical section.

Painting Strategy Defines the painting strategy of a study.

Example
See the SetPaintingStrategy in the Look & Feel section.

Syntax Example
PaintingStrategy.HISTOGRAM
PaintingStrategy.LINE_VS_POINTS
PaintingStrategy.LINE_VS_SQUARES
PaintingStrategy.LINE_VS_TRIANGLES
PaintingStrategy.POINTS



Functions
thinkScript has 12 mathematical and logic functions (AbsValue, average, between, ceil, if, isNaN, log, max, min, sqrt, sum and totalsum) that can be performed on the price data to generate the desired study. For example,
plot CloseAvg = average(close, 12);
displays an average of the last 12 days' closing prices.

Each function has required parameters. 'Average', for example, requires data (open, close, etc.) and length (number of bars). You can specify these parameters in any order. For example,
plot SMA = average(data = close, length = 50);
and
plot SMA = average(length = 50, data = close);
will show the same result on the chart.


Function Definitions - Date and Time
daysFromDate Returns the number of days from the specified date. Note that the "fromDate" argument is specified in the EST timeszone and has the "yyyymmdd" format.

Syntax
daysFromDate(int fromDate);
Example
input BeginDate = 20090101;
plot Price = if daysFromDate(BeginDate) >= 0 and daysFromDate(BeginDate) <= 50 then close else double.NaN;
The example draws a plot of the "close" values for 50 days starting 50 days before the year 2009 and through the beginning of the year 2009.


daysTillDate Returns the number of days till the specified date. Note that the "tillDate" argument is specified in the EST timeszone and has the "yyyymmdd" format.

Syntax
daysTillDate(int tillDate);
Example
input EndDate = 20090101;
plot price = if daysTillDate(EndDate) >= 0 and daysTillDate(EndDate) <= 50 then close else double.NaN;
The example draws a plot of the "close" values for 50 days starting 50 days before the year 2009 and through the beginning of the year 2009.


getDay Returns the number of the current bar day. The output is returned in the range from 1 through 365.

Syntax
getDay();
Example
plot Price = if getDay() <= 100 then close else Double.NaN;
The code draws a plot for the "close" value for the first 100 days of each year.


getLastDay Returns the number of the last bar day. The output is returned in the range from 1 through 365.

Syntax
getLastDay();
Example
plot Price = if getLastDay() == getDay() and getLastYear() == getYear() then close else Double.NaN;
This example draws a "close" plot for the last bar day of the current year.


getLastMonth Returns the number of the last bar month. The output is returned in the range from 1 through 12.

Syntax
getLastMonth();
Example 1
plot Price = if getLastMonth() == getMonth() and getLastYear() == getYear() then close else Double.NaN;
The example draws a "close" plot for the last month of the current year.
Example 2
plot Price = if getLastMonth() == getMonth() then open else Double.NaN;
This code draws an "open" plot for the last month of each year.


getLastWeek Returns the number of the last bar week. The output is returned in the range from 1 through 52.

Syntax
getLastWeek();
Example
plot Price = if getLastWeek() == getWeek() and getLastYear() == getYear() then high else Double.NaN;
This example draws a "high" plot for the last week of the current year.


getLastYear Returns the number of the last bar year.

Syntax
getLastYear();
Example
plot Price = if getLastYear() == getYear() then close else Double.NaN;
The code draws a "close" plot for the current year.


getMonth Returns the number of the current bar month. The output is returned in the range from 1 through 12.

Syntax
getMonth();
Example
plot Price = if getMonth() <= 6 then close else Double.NaN;
The example draws a "close" plot for the first half of each year.


getWeek Returns the number of the current bar week.The output is returned in the range from 1 through 52.

Syntax
getWeek();
Example
plot Price = if getWeek() % 2 == 1 then close else Double.NaN;
The example draws a "close" plot for odd weeks of each year.


getYear Returns the number of the current bar year.

Syntax
getYear();
Example
plot Price = if getYear() > getLastYear() - 3 then open else Double.NaN;
The example draws an "open" plot for the last three years.


secondsFromTime Returns the number of seconds from the specified time in the EST timezone. Note that the international time notation should be used: for instance, the NYSE opens at 0930 and closes at 1600.

Syntax
secondsFromTime(int fromTime);
Example
input OpenTime = 0930;
input DurationHours = 1;
def durationSec = 1 * 60 * 60;
def secondsPassed = secondsFromTime(OpenTime);
plot Price = if secondsPassed >= 0 and secondsPassed <= durationSec then close else double.NaN;
The plot displays the "close" value based on on the specified duration and the beginning in the EST timezone format.


secondsTillTime Returns the number of seconds till the specified time in the EST timezone. Note that the international time notation should be used: for instance, the NYSE opens at 0930 and closes at 1600.

Syntax
secondsTillTime(int tillTime);
Example
input CloseTime = 1600;
input DurationHours = 1;
def durationSec = 1 * 60 * 60;
def secondsRemained = secondsTillTime(closeTime);
plot Price = if secondsRemained >= 0 and secondsRemained <= durationSec then close else double.NaN;
This example draws a "close" plot based on the defined duration and through the specified time in EST.


Function Definitions - Logic
between is a logic function that gives a value of 1 (true) if the data is between two parameter values, and 0 (false) if the data is outside of the two parameter values. The first parameter is the data type to compare on. For example,
plot center = between(close, 140, 160);
will display a 1 if the closing price is between 140 and 160, and 0 if the closing price is below 140 or above 160. "Between" is mainly used as part of a test within a larger study.


if can be used in two ways. First, it can be used on the right side of an equation bu using 3 parameters: a condition, a true value and a false value. For example,
plot resistance = if(close > 150, 150, 100);
will draw a line that is at a value of 150 if the closing price is 150 or higher, and a value of 100 if the closing price is less than 150.

Secondly, 'if' can be used in conjunction with 'else' to create more complex conditions:
rec upper;
if open == close then {
    upper = upper[1] + 2;
} else {
    upper = upper[1] + 1;
}
Obviously, this example could be extended to perform even more calculations for each condition simply by adding additional lines inside each. Please note the placement of the '{}' brackets in this example. Also note that when evaluating equality in an 'if' statement, two equal signs must be used ('==').

Like between, the 'if' function will most likely be used as a test for a larger study.


Function Definitions - Look And Feel
AddCloud Fills the space between the two plots with a translucent background. The function enables visualizing the difference between the two plots.

Syntax
AddCloud(plot1, plot2);
Example 1
plot LowPrice = low;
plot HighPrice = high;
AddCloud(LowPrice, HighPrice);
In this example, the "AddCloud" function draws a translucent "cloud" that highlights the difference between the "LowPrice" and the "HighPrice" plots.

Example 2
plot CurrentPrice = close;
plot PastPrice = close[10];
AddCloud(CurrentPrice, PastPrice);
In this example, the "AddCloud" draws the translucent cloud and paints it according to the following rule: Note that the order in which the arguments appear in the "AddCloud" function affects the logics. For example, if you change the "PastPrice" and the "CurrentPrice":

Example
plot CurrentPrice = close;
plot PastPrice = close[10];
AddCloud(PastPrice, CurrentPrice);
the rule will be: Note that yellow and red are hardcoded values.



AssignValueColor Paints intervals of the plot with desired colors depending on a condition. The specified colors override the default color set for the plot.

Example
plot Diff = close - close[1];
Diff.assignValueColor(if Diff >= 0 then Color.UPTICK else Color.DOWNTICK);
In this example, if the difference between the current closing value and the closing value on the previous date is positive, the Diff plot is painted green, otherwise it is painted red.

Colors can be specified in the following ways:

CreateColor Generates a color based on its rgb code.

Syntax
CreateColor(double red, double green, double blue);
Example
plot Price = close;
Price.SetDefaultColor(CreateColor(255, 220, 210));
This example paints the Price chart in color that has (255, 220, 210) rgb code.



GetColor (applicable to strategy) Gets the color from the color palette. Note that colors in color palettes are different depending on the current Look & Feel you are using. Despite different Look & Feels, the colors in the color palettes are chosen in a way that your data is visualized in an optimal way.

Syntax
GetColor(int index);
Example
plot Price = close;
Price.SetDefaultColor(GetColor(1));
This example sets the default color for the Price plot. The color is taken from the color palette using the "GetColor" function.



hide Makes the plot hidden by default. This function may be required to hide plot data that is not used in the analysis at the moment.

Syntax
hide();
Example
plot PriceClose = close;
plot PriceOpen = open;
PriceOpen.hide();
This example sets the PriceOpen plot invisible by default.



HideBubble Makes the plot's last value bubble invisible.

Syntax
HideBubble();
Example
plot Data = volume;
Data.HideBubble();
The example hides the last value bubble for the "Data" plot.



SetDefaultColor Sets the default color of the plot. This setting affects the color of the plot when the study is first initialized or added to the chart.

Syntax
SetDefaultColor(CustomColor color);
Example
plot Data = close;
Data.SetDefaultColor(color.RED);
The example sets the default color of the Data plot to red.



setHiding Controls the visibility of the plot depending on a condition. If the condition is true, then makes the plot invisible, otherwise visible.

Syntax
setHiding(double condition);
Example
plot DailyClose = close(period="DAY");
plot WeeklyClose = close(period="WEEK");
plot Monthly = close(period="MONTH");


DailyClose.SetHiding(getAggregationPeriod() > AggregationPeriod.DAY);
WeeklyClose.SetHiding(getAggregationPeriod() > AggregationPeriod.WEEK);
In this example, the daily plot is hidden if the aggregation period is greater than a day. The weekly plot is hidden if the aggregation period is greater than a week.



SetLineWeight Sets the line weight.

Syntax
SetLineWeight(int lineWeight);
Example
plot Price = close;
Price.SetLineWeight(5);
This code sets the weight of the line to 5. The value is measured in pixels and ranges from 1 to 5 inclusively.



SetPaintingStrategy Controls the line painting style. Valid parameters are: For more information about the values, see the constants section.

Syntax
SetPaintingStrategy(int paintingStrategy);
Example
plot Data = open;
Data.setPaintingStrategy(PaintingStrategy.HISTOGRAM);
In this example, the painting style of the "Data" plot is a histogram.



SetStyle Controls the line style. Valid parameters are: For more information about the values, see the constants section.

Syntax
SetPaintingStrategy(int paintingStrategy);
Example
plot Data = low;
Data.setStyle(Curve.SHORT_DASH);
In this example, the line style of the "Data" plot is a short dash.


Function Definitions - Mathematical and Trigonometrical
AbsValue Returns the absolute value of the argument. If the argument is positive, the argument is returned. If the argument is negative, the negation of the argument is returned.

Syntax
AbsValue(double value);
Example
declare lower;
plot Absolute = AbsValue(open - close);
The example plots the absolute value of the difference between the open and close price which can be either positive, or negative.


ACos Returns the arc cosine of the angle in the range from 0 through pi.

Syntax
ACos(double value);
Example
declare lower;
plot Data = Acos(0.5) == Double.Pi / 3;
The expression in the second line of code compares two values and draws a plot. If the two values are equal, it draws a unit(true) plot . Otherwise, it draws a zero(false) plot. The arc cosine of 0.5 equals pi/3. So the example draws a unit plot.


ASin Returns the arc sine of the angle in the range from -pi/2 through pi/2.

Syntax
ASin(double value);
Example 1
declare lower;
plot Data = Asin(0.5) == Double.Pi / 3;
Similar to the example for the Acos function, the code above compares two values and draws a unit(true) plot if they are equal. In case the values are not equal, zero(false) plot is drawn. The arc sine of 0.5 is not equal pi/3. The example draws a zero plot.
Example 2
declare lower;
input length = 3;
def height = close - close[length];
def hypotenuse = sqrt( sqr(length) + sqr(height) );
plot "Angle, deg" = Asin(height/hypotenuse) * 180 / Double.Pi;
The code draws a line that connects the current close value with the close value on the desired bar in the past. The Asin function is used to calculate the angle of slope of the line.


Ceil Rounds a value up to the nearest integer.

Syntax
Ceil(double value);
Example
plot data = ceil(close);
The example returns an integer that is equal to or next higher than the close price.


Cos Returns the trigonometric cosine of an angle.

Syntax
Cos(double angle);
Example
declare lower;
input a = 0;
input b = 10;
input periodBars = 20;
def w = 2 * Double.Pi / periodBars;
rec x = compoundValue(1, x[1] + 1, 0);
plot F = a + b * Cos(w * x);
The code draws a cosine function depending on the x variable which starts from one and increments by one on each bar. The cyclic frequency(w) is calculated based on the periodBars input.


exp Returns the exponential value of a number.

Syntax
exp(double value);
Example 1
declare lower;
input x = 3;
plot Calculate1 = exp(x);
plot Calculate2 = power(Double.E, x);
The example calculates the value of the exponent raised to the power of x using two different approaches. The results of calculation using the approaches are equal.
Example 2
declare lower;
def temp = 0.1 * (RSIWilder() - 50);
def x = wma(temp, 9);
plot IFT_RSI = (exp(2 * x) - 1) / (exp(2 * x) + 1);
The code plots the Inversed Fisher Transform indicator based on a smoothed RSI value. Initially, the code subtracts a standart RSIWilder by 50 and multiplies the result by 0.1 to get values starting from -5 and through 5. Then it smoothes the values using the wma function. Finally, it calculates the IFT for the values.


isNaN Returns true if the specified parameter is not a number, returns false otherwise.

Syntax
isNaN(double value);
Example 1
declare fullrange;
def onExpansion = if isNaN(close) then yes else no;
plot HighestClose = if onExpansion then HighestAll(close) else double.NaN;
plot LowestClose = if onExpansion then LowestAll(close) else double.NaN;
The example draws the highest close and open on the right expansion of the subgraph.
Example 2
declare lower;
input symbol = "IBM";
def closeSymbol = close(symbol);
rec closeSymbolWithOutNaN = CompoundValue(1, if isNaN(closeSymbol) then closeSymbolWithOutNan[1] else closeSymbol, closeSymbol);
plot Data = closeSymbolWithOutNaN;
The code draws a comparison close chart replacing gaps that contain no data with lines. If the plot contains a NaN value then the last available non-NaN value is used.


lg Returns the base-10 logarithm of an argument.

Syntax
lg(double value);
Example
declare lower;
plot data = lg(close);
The example draws a base-10 logarithm plot of the close values.


log Returns the natural logarithm of an argument.

Syntax
log(double value);
Example
declare lower;
plot data = log(close);
The code draws a plot of the logarithm of the closing price of a stock.


Max Returns the greater of two values.

Syntax
Max(double value1, double value2);
Example
def SMA = SimpleMovingAvg();
plot data = Max(close, SMA);
This example displays the higher value of either the closing price or the simple moving average.


Min Returns the smaller of two values.

Syntax
Min(double value1, double value2);
Example
plot data = Min(close, open);
The code draws the smaller value of the close and open values.


Power Returns the value of the first argument raised to the power of the second argument.

Syntax
Power(double number, double power);
Example
declare lower;
plot Close1_5 = power(close, 1.5);
The example draws a plot of the close value raised to the power of 1.5.


Random Returns a value with a positive sign, greater than or equal to 0.0 and less than 1.0.

Syntax
Random();
Example
declare lower;
input limit = 10;
plot Noise = Random() * limit;
The code draws a plot of random values ranging from 0 to 10.


Round100 Rounds a number to two decimal places.

Syntax
Round100(double number);
Example
plot PriceRounded = Round100(close);
The example rounds the close value to two decimal places.


Sin Returns the trigonometric sine of an angle.

Syntax
Sin(double angle);
Example
declare lower;
input a = 0;
input b = 10;
input periodBars = 20;
def w = 2 * Double.Pi / periodBars;
rec x = compoundValue(1, x[1] + 1, 0);
plot F = a + b * Sin(w * x);
The code draws a sine function depending on the x variable which starts from one and increments by one on each bar. The cyclic frequency(w) is calculated based on the periodBars constant.


Sqr Returns the square of a value.

Syntax
Sqr(double number);
Example
declare lower;
plot Data = Sqr(stdev(close, 10));
The example draws a variance of the close for the last 10 bars. Variance by definition is a square of a standard deviation.


Sqrt Calculates the square root of the argument.

Syntax
Sqrt(double number);
Example
declare lower;
plot data = Sqrt(close);
The draws a plot of the square root of the closing price of a stock.


sum Returns the sum of values for the specified number of bars. The default value of length is 12.

Syntax
sum(IDataHolder data, int length);
Example 1
declare lower;
plot data = sum(close, 20);
The example displays a line that is the sum of the last 20 days' closing prices.
Example 2
plot data = sum(close, 20)/20;
This example returns the sum of the last 20 days' closing prices divided by 20. This value is called "20 day moving average".


totalSum Returns the sum of all values from the first bar to the current.

Syntax
TotalSum(IDataHolder data);
Example
declare lower;
plot data = TotalSum(volume);
The example returns the total accumulated volume for the time frame of the current chart.


Function Definitions - Strategy
SetColor Sets the color of the strategy signal.

Syntax
SetColor(CustomColor color)
Example
declare LONG_ENTRY;
setColor(GetColor(2))
addOrder(close > close[1]);
In this example, the strategy signal is colored with the second color from the color palette.


Limiting Input Data (ENUM & SWITCH)
Let's say you wanted to create an input editable from the 'Edit Studies' window but, for ease of use, you wanted to limit the possible answers for that input to a predetermined set (for instance, the trading days of the week). In an application or software such an input is called a 'select box'. You can create a select box in thinkScript by using a construction known as an 'enum'. This is simply a predefined set of data and the code looks like this:
input day = {default Mon,Tue,Wed,Thu,Fri};
Please notice that one of the elements in the set must be defined as the default value. In this case it's 'Mon'. The value generated for 'Mon' by the select box is actually 0 and each succeeding value is 1 greater ('Tue' = 1, 'Wed' = 2 ... 'Fri' = 4).

In order to do something more powerful with the results of your select box rather than simply operate on the numeric value (0,1,2...), you can use a SWITCH statement. A SWITCH allows you to define a discreet action for each 'case'. For example,
input day = {default Mon,Tue,Wed,Thu,Fri};
plot vertical_line;
switch(day) {
  case Mon:
    vertical_line = average(close, length = 8);
  case Tue:
    vertical_line = average(close, length = 13);
  default:
    vertical_line = average(high);
}
In this case, specific plots will be drawn if you input 'Mon' or 'Tue' and a third drawn if you input 'Wed', 'Thu' or 'Fri' as defined by the default case. At this point, you should begin to see how you could use ENUM and SWITCH to use predefined data sets like the months of the year, etc.


Accessing Data From Another Symbol
To access data from another symbol in your code, append the name of the symbol in quotes and parentheses to the data type you want to use. For instance,
plot data = close - close("GOOG");
will give you a line that is the difference between the closing price for the symbol that you have in the chart and the closing price for Google (GOOG).


Using Historical Data
To access a value from a previous bar of data, you can use what is called [offset] syntax. For example, close[1] will give you the closing price from one day ago; close[2] will give you the close 2 days ago, etc.
plot data = close - close[5];
will display a line that is the difference between the current closing price and the closing price 5 days ago. Please note: in thinkScript, a positive number is used to refer to data in the past. Negative numbers will give you bars in the future when working from historical data.


Referencing Pre-Defined Studies
thinkScript allows you to reference studies that are already available on the Charts tab in your code. You use the reference keyword to do this.
plot SMA = reference simplemovingavg;
or
plot SMA = simplemovingavg();
will plot a simple moving average with the default parameters of that study. So long as the study name is followed by parentheses, you don't need to include the word 'reference'. You can change the parameters of the study within reference by inputting them between parentheses.
plot SMA = simplemovingavg(price = volume, length = 20);
will plot a 20 day moving average of the volume. To see the input parameters of a particular study, click on that study in the 'Edit Studies' section of the Charts tab. You will see the available parameters listed in the study properties section.

By default, the first plot of a study is always referenced. However, you can specify the plot you want to reference, as well.
plot bear = reference ElderRay."BearPower"

plot bear = ElderRay(length = 6)."BearPower"


Choosing Colors
Each plot has its main color which you can change using the setDefaultColor function:
plot diff = close - close[1];
diff.setDefaultColor(getcolor(5));
In this example, the 5th color of a dynamic 'look & feel' palette was used. These colors will always be part of the Color Scheme you chose to run thinkDesktop with - Black, White or Metal. You can also choose explicit colors:
plot diff = close - close[1];
diff.setDefaultColor(Color.Red);
Below the 'Functions' section in the right sidebar you will see that the definitions of some Constants are also provided. There you will find all of the standard colors you can use in conjunction with the 'Look & Feel' functions.

Lastly, you can override plot main color using assignValueColor function:
plot diff = close - close[1];
diff.assignValueColor(if diff >=0 then Color.UPTICK else Color.DOWNTICK);


Saving Your Study
When you are done with your code, you can save it and apply it to your chart. At the top of the "New Study" editor is a field where you can name your study. Once you've provided the name, click the "Save" button and your new study can be applied to any chart like any of the pre-programmed studies.

If you want to change the code in your custom study, return to the "Edit Studies" window by clicking the "Studies" button in the upper right hand corner of the Charts tab, then clicking on "Edit Studies". Locate your study in the "Available Studies" list. Custom studies are marked with the icon. Click the blue bullet to the left of the name of the study and select "Edit source". That will return you to the study editor to make any changes.



thinkScript and Strategies
Just like with studies, thinkScript can be used for fine-tuning pre-defined strategies or creating strategies of your own in the TOS Charts charting package. When strategies are drawn on a chart, buy and sell triggers appear in response to the conditions defined in the strategy. To begin using the thinkScript editor for strategies, go to the TOS Charts tab, click 'Studies' in the upper right corner of the page and select 'Edit Strategies'. This will open the 'Edit Strategies' window.


Adding Strategies
On the 'Edit Strategies' window you'll see a list of predefined strategies under 'Available Strategies'. These strategies are actually based on studies and render buy and sell triggers when their underlying study meets a certain condition. If you simply want to draw predefined strategies on the chart, right click the Blue Bullet and select 'Add Strategy'. This will cause the strategy to appear in the 'Added strategies' box and any of its customizable inputs to appear under 'Strategy properties'. PLEASE NOTE: in order to render strategies on your chart, you must select BOTH the buy and sell ends. These are indicated by the letters SE (Short End) and LE (Long End) in the strategy name. Once you've added your strategies and adjusted their properties click 'OK' (or 'Apply' to keep working in the window) to draw them on your chart.


Editing Stategies
More than likely, you will want to create strategies of your own rather than use predefined strategies. To do so, you have two choices: It is important to remember that most strategies are based on movement in an underlying study. If you haven't done so, it might be good to familiarize yourself with how thinkScript handles studies above.


Editing Stategies - A Simple Example
Here are examples of the buy and sell sides of a very simple strategy. In this example, the user simply wants to be able to set a buy (entry) trigger when the closing price drops below 50 and a sell (exit) trigger when the price exceeds 70:
BUY SIDE -
Name: myEntry
Body:
  declare ENTRY;
  addOrder(close < 50);

SELL SIDE -
Name: myExit
Body:
  declare EXIT;
  addOrder(close > 70);
For now, let's just take a look at the body of these definitions - the name has more to do with how you save the strategy. As you can see, the script involved here is very simple. First, the strategy needs to declare if it is BUY (entry) or SELL (exit) side. Then, it uses a simple function, addOrder, which indicates that we want to set a trigger when the condition inside the parentheses is met. In this case, that condition is either 'close < 50' or 'close >70'.


Editing Stategies - Using Functions
In the previous example, we used a simple function, addOrder. AddOrder takes one required parameter, 'condition' (e.g. 'close < 50'), and one optional parameter, 'price'. Price can be set using a variable like 'open' or a value like '52'. Definitions for all of the available functions can be found by holding your mouse over the function name in the edit page or in the sidebar on the right side of the 'New strategy' editor. There you'll find functions grouped by category - 'Technical analysis', 'Mathematical' and 'Look & Feel'. Click on a function name to see details of how that function works in the lower box on the right-hand sidebar. Clicking on 'Mathematical' > 'average', for instance, reveals that this function returns the average value of a dataset. No surprise there.

In every respect using functions in strategies behaves the same as using them when editing studies. See 'Using Functions' for details.


Editing Stategies - Creating Input Parameters
Most of the time you'll want to create strategies that allow you to easily adjust the boundaries of the strategy. You can do this by creating an input and its default value in the thinkScript definition. These inputs can be adjusted in the 'Edit Strategies' window (HINT: You can also open the 'Edit Strategies' window by left-clicking on the strategy from a chart). If you want to create an adjustable parameter for your thinkScript strategy, you use the input keyword:
input parameter_name = default_value;
for instance,
input length = 12;
input price = close;

def delta = price - price[length]
Here 12 and close are default values which you can override on the preferences panel the way you adjust pre-defined strategies.


Editing Stategies - Referencing Historical Bars
In the example above you see a construct that looks like this:
price[length]
Given our default values for price and length, this would actually resolve to 'close[12]'. What you see here is a reference to a bar other than current bar using [offset] syntax. In this case, 'close[12]' would give you the close price on the bar 12 bars in the past. It's important to remember that positive values are bars BACK and negative numbers are bars FORWARD:
def diff = close - close[-1];
In this example, diff equals the difference in the current and the next value.


Editing Stategies - Accessing External Price Data
For comparison strategies, you can access 'external' symbol market data like this:
def diffGoog = close - close("GOOG");


Editing Stategies - Choosing Colors
Each strategy can be assigned a color using the setColor function:
setColor(getColor(4));
In this example, the 4th color of a dynamic 'look & feel' palette was used. These colors will always be part of the Color Scheme you chose to run thinkDesktop with, Black, White or Metal. You can also choose explicit colors:
setColor(Color.Red);
Below the 'Functions' section in the right sidebar you will see that the definitions of some Constants are also provided. There you will find all of the standard colors you can use in conjunction with the 'Look & Feel' functions.


Saving Your Strategy
Once you are done editing the strategy, you can save it so that it will be available to add to the charting package from the 'Edit Strategies' window. At the top of the 'New Strategy' editor is a field where you can name the strategy. You can name your new strategy the way you like it or leave the pre-defined 'NewStrategyXX' name. Once you've provided the name, click 'Save' and your new strategy will be available for drawing over any chart. To do so, add it to the list of 'Added strategies' from the 'Edit Strategies' window and click 'OK' (or 'Apply' to keep working in the window).

If you need to make changes to your custom strategy, return to the 'Edit Strategies' window by clicking 'Studies' in the upper right corner of the TOS Charts tab. Locate your strategy in the 'Available strategies' list. Custom strategies are marked with the icon. Double-click the strategy or click the Blue Bullet to the left of the strategy and select 'Edit source...'. This will return you to the strategy editor to make any necessary changes.