Pin Bar Reversal Indicator for ThinkorSwim

BenTen

BenTen

Administrative
Staff
VIP
Here is an indicator that detects bullish and bearish Pin Bar candlestick patterns on your ThinkorSwim chart. I'll also include the version with RSI which takes overbought and oversold values into consideration.



thinkScript Code

Rich (BB code):
input LastBars = 0;
input MaxNoseBodySize = 0.33; #(default = 0.33) — maximum allowed body/length ratio for the Nose bar.
input NoseBodyPosition = 0.4; #(default = 0.4) — Nose body should be position in top (bottom for bearish pattern) part of the Nose bar.
input LeftEyeOppositeDirection = yes; #(default = true) — tells the indicator that the Left Eye bar should be bearish for bullish Pinbar, and bullish for bearish Pinbar.
input NoseSameDirection = yes; #(default = true) — tells the indicator that the Nose bar should be of the same direction as the pattern itself.
input NoseBodyInsideLeftEyeBody = no; #(default = false) — tells the indicator that the Nose body should be inside the Left Eye body.
input LeftEyeMinBodySize = 0.1; #(default = 0.1) — minimum size of the Left Eye body relative to the bar length.
input NoseProtruding = 0.5; #(default = 0.5) — minimum protrusion of the Nose bar relative to the bar length.
input NoseBodyToLeftEyeBody = 1; #(default = 1) — maximum size of the Nose body relative to the Left eye body.
input NoseLengthToLeftEyeLength = 0; #(default = 0) — minimum Nose length relative to the Left Eye length.
input LeftEyeDepth = 0.2; #(default = 0.2) — minimum depth of the Left Eye relative to its length. Depth is length of the part of the bar behind the Nose.

# Left Eye and Nose bars's paramaters
def NoseLength = High - Low;
def LeftEyeLength = High[1] - Low[1];
def NoseBody = Absvalue(Open - Close);
def LeftEyeBody = Absvalue(Open[1] - Close[1]);

# Bearish Pinbar

def BearSignalDown = if  (High - High[1] >= NoseLength * NoseProtruding) and
                     (NoseBody / NoseLength <= MaxNoseBodySize) and
                     (1 - (High - Max(Open, Close)) / NoseLength < NoseBodyPosition) and
                     if LeftEyeOppositeDirection then (Close[1] > Open[1]) else 1 and
                     if NoseSameDirection then (Close < Open) else 1  and
                     (LeftEyeBody / LeftEyeLength  >= LeftEyeMinBodySize) and
                     ((Max(Open, Close) <= High[1]) && (Min(Open, Close) >= Low[1]))  and
                     (NoseBody / LeftEyeBody <= NoseBodyToLeftEyeBody) and
                     (NoseLength / LeftEyeLength >= NoseLengthToLeftEyeLength) and
                     (Low - Low[1] >= LeftEyeLength * LeftEyeDepth) and
                     if NoseBodyInsideLeftEyeBody then ((Max(Open, Close) <= Max(Open[1], Close[1]))
                     && (Min(Open,  Close) >= Min(Open[1],  Close[1]))) else 1                   
                     then yes
                     else no ;

def BullSignalUp   = if (Low[1] - Low >= NoseLength * NoseProtruding) and
                     (NoseBody / NoseLength <= MaxNoseBodySize) and
                     (1 - (Min(Open, Close) - Low) / NoseLength < NoseBodyPosition) and
                     if LeftEyeOppositeDirection then (Close[1] < Open[1]) else 1 and
                     if NoseSameDirection then (Close > Open) else 1 and
                     (LeftEyeBody / LeftEyeLength >= LeftEyeMinBodySize) and
                     ((Max(Open, Close) <= High[1]) && (Min(Open, Close) >= Low[1])) and
                     (NoseBody / LeftEyeBody <= NoseBodyToLeftEyeBody) and
                     (NoseLength / LeftEyeLength >= NoseLengthToLeftEyeLength) and
                     (High[1] - High >= LeftEyeLength * LeftEyeDepth) and
                     if NoseBodyInsideLeftEyeBody then ((Max(Open, Close) <= Max(Open[1], Close[1]))
                     && (Min(Open, Close) >= Min(Open[1], Close[1]))) else 1
                     then yes
                     else no;

#defining the bullish / bearish signals

def bullish_signal = BullSignalup;

def bearish_signal = BearSignalDown;

#plotting the bullish / bearish signals
plot bullish = bullish_signal;
bullish.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);

plot bearish = bearish_signal;
bearish.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);

Shareable Link

https://tos.mx/l2rtkP

Similar to the Engulfing candles with RSI, we added the overbought input to bearish and oversold input to bullish Pin Bar candles. That means a Pin Bar candle will only be generated when a stock is oversold or overbought according to the default RSI indicator. You can also set each value to your liking.

Hopefully that will help to reduce false signals.

Pin Bars with RSI

Rich (BB code):
input length = 14;
input over_Bought = 75;
input over_Sold = 25;
input price = close;
input averageType = AverageType.WEIGHTED;

input LastBars = 0;
input MaxNoseBodySize = 0.33; #(default = 0.33) — maximum allowed body/length ratio for the Nose bar.
input NoseBodyPosition = 0.4; #(default = 0.4) — Nose body should be position in top (bottom for bearish pattern) part of the Nose bar.
input LeftEyeOppositeDirection = yes; #(default = true) — tells the indicator that the Left Eye bar should be bearish for bullish Pinbar, and bullish for bearish Pinbar.
input NoseSameDirection = yes; #(default = true) — tells the indicator that the Nose bar should be of the same direction as the pattern itself.
input NoseBodyInsideLeftEyeBody = no; #(default = false) — tells the indicator that the Nose body should be inside the Left Eye body.
input LeftEyeMinBodySize = 0.1; #(default = 0.1) — minimum size of the Left Eye body relative to the bar length.
input NoseProtruding = 0.5; #(default = 0.5) — minimum protrusion of the Nose bar relative to the bar length.
input NoseBodyToLeftEyeBody = 1; #(default = 1) — maximum size of the Nose body relative to the Left eye body.
input NoseLengthToLeftEyeLength = 0; #(default = 0) — minimum Nose length relative to the Left Eye length.
input LeftEyeDepth = 0.2; #(default = 0.2) — minimum depth of the Left Eye relative to its length. Depth is length of the part of the bar behind the Nose.

# Left Eye and Nose bars's paramaters
def NoseLength = High - Low;
def LeftEyeLength = High[1] - Low[1];
def NoseBody = Absvalue(Open - Close);
def LeftEyeBody = Absvalue(Open[1] - Close[1]);

# Bearish Pinbar

def BearSignalDown = if  (High - High[1] >= NoseLength * NoseProtruding) and
                     (NoseBody / NoseLength <= MaxNoseBodySize) and
                     (1 - (High - Max(Open, Close)) / NoseLength < NoseBodyPosition) and
                     if LeftEyeOppositeDirection then (Close[1] > Open[1]) else 1 and
                     if NoseSameDirection then (Close < Open) else 1  and
                     (LeftEyeBody / LeftEyeLength  >= LeftEyeMinBodySize) and
                     ((Max(Open, Close) <= High[1]) && (Min(Open, Close) >= Low[1]))  and
                     (NoseBody / LeftEyeBody <= NoseBodyToLeftEyeBody) and
                     (NoseLength / LeftEyeLength >= NoseLengthToLeftEyeLength) and
                     (Low - Low[1] >= LeftEyeLength * LeftEyeDepth) and
                     if NoseBodyInsideLeftEyeBody then ((Max(Open, Close) <= Max(Open[1], Close[1]))
                     && (Min(Open,  Close) >= Min(Open[1],  Close[1]))) else 1                   
                     then yes
                     else no ;

def BullSignalUp   = if (Low[1] - Low >= NoseLength * NoseProtruding) and
                     (NoseBody / NoseLength <= MaxNoseBodySize) and
                     (1 - (Min(Open, Close) - Low) / NoseLength < NoseBodyPosition) and
                     if LeftEyeOppositeDirection then (Close[1] < Open[1]) else 1 and
                     if NoseSameDirection then (Close > Open) else 1 and
                     (LeftEyeBody / LeftEyeLength >= LeftEyeMinBodySize) and
                     ((Max(Open, Close) <= High[1]) && (Min(Open, Close) >= Low[1])) and
                     (NoseBody / LeftEyeBody <= NoseBodyToLeftEyeBody) and
                     (NoseLength / LeftEyeLength >= NoseLengthToLeftEyeLength) and
                     (High[1] - High >= LeftEyeLength * LeftEyeDepth) and
                     if NoseBodyInsideLeftEyeBody then ((Max(Open, Close) <= Max(Open[1], Close[1]))
                     && (Min(Open, Close) >= Min(Open[1], Close[1]))) else 1
                     then yes
                     else no;

#defining the bullish / bearish signals

def bullish_signal = RSI(length = length, averageType = averageType) < over_Sold and BullSignalup;

def bearish_signal = RSI(length = length, averageType = averageType) > over_Bought and BearSignalDown;

#plotting the bullish / bearish signals
plot bullish = bullish_signal;
bullish.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);

plot bearish = bearish_signal;
bearish.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
P.S: I found the original code without any header on it so I can't give credit to the developer. If you know who created it please let me know.
 
Last edited:
E

ecpipo

New member
Hi. Is there a way to use this indicator in a scan? Thinkorswim throws an error : "too complex"
I can't seem to find any built-in pinbar pattern finder on the platform..

Thanks in advance
 
T

tomsk

Well-known member
VIP
@BenTen Since you asked, it appears like your version of the first pinbar study you posted in this thread is based on a study called KMS_PINBAR_V2 that was posted by madhu_kms in the Yahoo TOS_ThinkScript group in 2016. The version you have has very minor edits from madhu's version. I happened to find this when I was reviewing my files.

Here is some commentary from Madhu's post you may be interested in reading

This indcator is based of Pinbar Detector (MetaTrader indicator)

https://www.earnforex.com/forex-strategy/pinbar-trading-system/https://www.earnforex.com/metatrader-indicators/Pinbar-Detector/
I have seen people using pin bar at support and resistance to identify trend reversals. As a matter of fact I was looking for some indicator to identify PinBar on chart came across PinBar Detector and converted it to TOS.

Experienced traders can verify if the MT5 to TOS conversion is correct. I tried on couple of charts identifies the Pinbars correctly. If anyone has MT5 just compare it if matches.

Just passing to you for info sharing, I don't use this indicator.
 
H

hellocucen

New member
VIP
I am very new to these scripts and do excuse if this is a naive question. Is it possible to replace the arrow with cloud green for buy and red for sell. Similar to the white oval highlights in the above diagram.

Thanks in advance.
 
T

tomsk

Well-known member
VIP
I am very new to these scripts and do excuse if this is a naive question. Is it possible to replace the arrow with cloud green for buy and red for sell. Similar to the white oval highlights in the above diagram.

Thanks in advance.
The original version of the code that I mentioned in post#3 is a study that has up/down arrows for identification of bullish/bearish pinbars. The version that @BenTen has essentially has the same definitions and can be used for both a scan as well as a study.

To replace the color of the arrows with GREEN for buy and RED for sell replace the plot specific statements in the code as follows:

Code:
#plotting the bullish / bearish signals
plot bullish = bullish_signal;
bullish.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
bullish.SetDefaultColor(Color.GREEN);

plot bearish = bearish_signal;
bearish.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
bearish.SetDefaultColor(Color.RED);
As far as a white oval highlight as you've detailed, that is not a feature available from ThinkScript
To use as a scan you would first install the study, and then you can simply make reference to that study in the scanner

EDITED: Just tested it out
 
Last edited:
R

Rowing109

New member
Hi there, does anyone know how to add an alert to the Pin Bar study on this thread to give an alert on ThinkorSwim when a Pin Bar Boolean arrow is printed? I am familiar with price alerts, but I haven't quite figured out the steps I need to take to have ThinkorSwim give me an email alert when a Boolean arrow up/down is printed. I have the study on my ThinkorSwim and it is very good, but an alert would be even better. Thanks, Jarrod
 
BenTen

BenTen

Administrative
Staff
VIP
@Rowing109 Add this to the end of your script:

Code:
# Alerts
Alert(bullish, " ", Alert.Bar, Sound.Chimes);
Alert(bearish, " ", Alert.Bar, Sound.Bell);
 
R

Rowing109

New member
Will this script give me the alert after the arrow is printed after the close of the candle? I notice an arrow will appear sometimes while the candle is still forming and I would like it to give an alert after a real pin is printed, not one that may be forming, then end up not being a pin. Thank you so much. Jarrod
 
R

Rowing109

New member
Okay, great. Let me see if I can take this code one step further, is it possible to have written in the code what timeframe the pin was identified on as well as what market it was identified on?

Also, for the alert, is there a way to have it send to me via email too?

Maybe another way to look at this is from the beginning of the script, to have the Boolean arrow form only after the candle closes and meets the parameters set forth in the script. Is this possible?
 
Last edited by a moderator:
lukeskywalker

lukeskywalker

New member
"Pin Bar" Candlestick Pattern Indicator
The "Pin Bar" indicator shows with arrows on the chart the situation when "Pin Bar" is drawn after a certain trend (the most probable signal for reversal).
Settings. Inputs: The ratio of the total length of a candlestick to the candlestick body (i ratio: 2.5) and the number of bars - trends before the PinBar (i-bars: 2).
________
Code:
#thinkscript indicator: Pin_Bar.
#Draws the Pinbars on the chart following the trend.
#by thetrader.top
input iRatio = 2.5; #candle length-to-body ratio
input iBars = 2; #trend number of bars
def iTelo=absValue (close-open);
def bPinUp = (((high - low)/(iTelo)) >iRatio) and high > high[1] and low>low[1] and max(open,close)<high-((high-low)/2);
def bPinDown =(((high - low)/(iTelo)) >iRatio) and high < high[1] and low<low[1] and min(open,close)>low+((high-low)/2);
def bTrendUp = fold TUbar = 1 to iBars+1 with TUsumm=1 do if (close[TUbar]-open[TUbar]>0) then TUsumm*1 else TUsumm*0;
def bTrendUp2 = fold TUbar2 = 1 to iBars with TUsumm2=1 do if (high[TUbar2]==highest(high[TUbar2],iBars)) then TUsumm2*1 else TUsumm2*0;
def bTrendDown = fold TDbar = 1 to iBars+1 with TDsumm=1 do if (open[TDbar]-close[TDbar]>0) then TDsumm*1 else TDsumm*0;
def bTrendDown2 = fold TDbar2 = 1 to iBars with TDsumm2=1 do if (low[TDbar2]==lowest(low[TDbar2],iBars)) then TDsumm2*1 else TDsumm2*0;
def bSignalUp = bPinUp and bTrendUp and bTrendUp2;
def bSignalDown = bPinDown and bTrendDown and bTrendDown2;
plot up = if bSignalUp  then high else double.NaN;
plot down = if bSignalDown then high else double.NaN;
up.SetPaintingStrategy(paintingStrategy.BOOLEAN_ARROW_down);
down.SetPaintingStrategy(paintingStrategy.BOOLEAN_ARROW_up);
up.setDefaultColor(color.LIGHT_red);
down.setDefaultColor(color.LIGHT_green);
 
Last edited by a moderator:
mc01439

mc01439

Well-known member
2019 Donor
VIP
@lukeskywalker - Thank You for posting.


A few key points for the Pin Bar Indicator.

A Pin Bar must have:

– Open and close within previous candle

– Candle wick minimum 3 times the length of the candle body

– Long nose protruding from all other candles (must stick out from all other candles)
 

Similar threads

Top