# Pinbar Scan
# tomsk
# 11.23.2019
# https://usethinkscript.com/threads/create-your-own-candlestick-pattern-in-thinkorswim.1103/#post-10213
# This scans for a bullish/bearish pinbar that closes within the body
# of the previous candle. The conditions for the logic for the pinbar
# conditions were extracted from the following study as posted by BenTen
# in May 2019
#
# https://usethinkscript.com/threads/pin-bar-reversal-indicator-for-thinkorswim.156/
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;
# Scan specific logic. Look for a close within previous bar's body
# Add this to the original scan condition from a user request
def condition = between(close, min(open[1],close[1]),max(open[1],close[1]));
# Comment out (#) the ONE not needed
plot bullish_signal = BullSignalup and condition;
# plot bearish_signal = BearSignalDown and condition;
# End Pinbar Scan