Posted on

Porting the Visualizing Displacement indicator from TradingView PineScript to Thinkorswim ThinkScript

porting an indicator from tradingview to thinkorswim

Today I had a customer request a port of the “Visualizing Displacement” indicator from Tradingview Pine Script over to Thinkorswim, so I made a video of the translation/porting process here to teach people ThinkScript and provide a free indicator.

The original indicator is found here:

https://www.tradingview.com/script/n6djFgQH-Visualizing-Displacement-TFO/

The original PineScript code is as follows:

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © tradeforopp

//@version=5
indicator("Visualizing Displacement [TFO]", "Displacement [TFO]", true)

require_fvg = input.bool(true, "Require FVG")
disp_type = input.string("Open to Close", "Displacement Type", options = ['Open to Close', 'High to Low'])
std_len = input.int(100, minval = 1, title = "Displacement Length", tooltip = "How far back the script will look to determine the candle range standard deviation")
std_x = input.int(4, minval = 0, title = "Displacement Strength")
disp_color = input.color(color.yellow, "Bar Color")

candle_range = disp_type == "Open to Close" ? math.abs(open - close) : high - low
std = ta.stdev(candle_range, std_len) * std_x
fvg = close[1] > open[1] ? high[2] < low[0] : low[2] > high[0]

displacement = require_fvg ? candle_range[1] > std[1] and fvg : candle_range > std

barcolor(displacement ? disp_color : na, offset = require_fvg ? -1 : na)

The modified ThinkScript code, line by line, is as follows (import here: http://tos.mx/uI1jVGJ ):

#require_fvg = input.bool(true, "Require FVG")
input requireFvg = yes;

#disp_type = input.string("Open to Close", "Displacement Type", options = ['Open to Close', 'High to Low'])
input displayType = {default OpenToClose, HighToLow};

#std_len = input.int(100, minval = 1, title = "Displacement Length", tooltip = "How far back the script will look to determine the candle range standard deviation")
input stdDevLength = 100;

#std_x = input.int(4, minval = 0, title = "Displacement Strength")
input displacementStrength = 4;

#candle_range = disp_type == "Open to Close" ? math.abs(open - close) : high - low
def candleRange = if displayType == displayType.OpenToClose then bodyHeight() else high - low; # absValue(open - close)

#std = ta.stdev(candle_range, std_len) * std_x
def std = standardDeviation(candleRange, stdDevLength) * displacementStrength;

#fvg = close[1] > open[1] ? high[2] < low : low[2] > high
def fvg = if close[1] > open[1] then high[2] < low else low[2] > high;

#displacement = require_fvg ? candle_range[1] > std[1] and fvg : candle_range > std
def displacement = if requireFvg then candleRange[1] > std[1] and fvg else candleRange > std;

# disp_color = input.color(color.yellow, "Bar Color")
defineGlobalColor("Bar Color", color.yellow);

# barcolor(displacement ? disp_color : na, offset = require_fvg ? -1 : na)
def offset = if requireFvg then -1 else 0;

assignPriceColor(if displacement[offset] then globalColor("Bar Color") else color.current);

The final code without comments is below:

input requireFvg = yes;
input displayType = {default OpenToClose, HighToLow};
input stdDevLength = 100;
input displacementStrength = 4;

def candleRange = if displayType == displayType.OpenToClose then bodyHeight() else high - low; # absValue(open - close)
def std = standardDeviation(candleRange, stdDevLength) * displacementStrength;
def fvg = if close[1] > open[1] then high[2] < low else low[2] > high;
def displacement = if requireFvg then candleRange[1] > std[1] and fvg else candleRange > std;
def offset = if requireFvg then -1 else 0;

defineGlobalColor("Bar Color", color.yellow);
assignPriceColor(if displacement[offset] then globalColor("Bar Color") else color.current);
Posted on

How to Program a ThinkScript Bollinger Band Squeeze Scanner in Thinkorswim Tutorial

thinkorswim tutorial bollinger band squeeze scanner

I recently had a question from a client on how to program and port a scanner from a video they’d seen from another platform and use it in Thinkorswim. So I decided to make a video and share the process and a couple of things I would do to improve the scan.

Here’s the video:

And the Thinkorswim sharing link:

http://tos.mx/Dt4pyna

And the code:

input maxWidthPct = 1.0;
input minWidthSqueeze = .5;
input withinBarsSqueeze = 5;

input minWidthPct = 2.0;
input withinBarsVolatile = 200;

def bbh = reference BollingerBands().UpperBand;
def bbl = reference BollingerBands().LowerBand;
def bbm = reference BollingerBands().Midline;
def width = bbh - bbl;
def widthPct = width / bbm * 100;

plot scan = 
highest(widthPct, withinBarsVolatile) >= minWidthPct AND
highest(widthPct, withinBarsSqueeze) <= maxWidthPct AND
highest(widthPct, withinBarsSqueeze) >= minWidthSqueeze;

And a screenshot:

thinkorswim tutorial bollinger band squeeze scanner

Posted on

New All In One Gap Scan + Columns

Today I’ve released updated versions of the All-In-One Gap Scan and the % and $ Gap Columns.

The improvements to the columns were just to fix a small error I found. But for the scan, several big improvements have been implemented …

  1. Choose both min/max gap % size
  2. Choose both min/max gap $ size
  3. Choose whether you only want to scan for gaps that haven’t filled yet
  4. Choose whether the gap needs to be “significant” — i.e., gapping above the prior high, or below the prior low (completely outside the range of the prior day’s candle)
  5. Choose whether the gap needs to be a “pro” or “tier 1” or “shock” gap — i.e., gapping over a prior day red candle, or gapping under a prior day green candle, adding “shock value” to the gap

This single all-in-one scan works during the extended hours / premarket / aftermarket, and continues working as the regular trading hours begin, so you only need to use one scan all day long.

The other change is that the $ and % values are now all calculated from the prior close instead of the high/low, just for consistency, and whether the gap is over/under the prior day’s candle is specified as a separate criterion in settings, which can be turned on/off at will. This will help keep things consistent and logical no matter what type of trading you do.