3 Bar Play - Pattern Scan?

M

mansor

Member
@perig could you guide me in the right direction..which script version are you using? I have applied all 3 versions but wasn't able to generate arrow (potential or confirmed) in the indicators
 
P

perig

New member
@perig could you guide me in the right direction..which script version are you using? I have applied all 3 versions but wasn't able to generate arrow (potential or confirmed) in the indicators
I am using v1.4 as the base code. I modified the script to get it to work for me and added different colors, etc.. I think if you just want to show some patterns, set the parameters as loose as you can to over-dectect and then you can change them as you prefer to detect only the ones you want. I think the script can still be refined, especially for the igniting bar detection as it is all centered around that. Detecting potential 3-bar play is then quite simple. See my suggestions in my previous post for the improvements. Either I can get to it or the OP may still continue development.

Here is what you can try:
  • Show_Only_Above_Prev_High = no
  • Hide_During_Uptrend = no
  • pause_Low_Min_Perc = 40
  • pause_High_Min_Perc = 80
  • pause_High_max_Perc = 110
 
T

Thomas

Active member
Drop to 5 Minute, I have volume on 100K, but a momentum filter for good stocks....I have em all day as long as scan is for 5 minutes....
 
M

mansor

Member
@perig thanks for taking the time to respond & educate me. I am not good in coding at all. I copy pasted the 1st script/indicator from post #8 by Len20 (it reads version 1.4) and applied your settings.

@Thomas you mean to run this indicator at 5m chart instead of 1m? How did you set volume 100k? I couldn't find that section in settings. Or is this setting that you have mentioned above for the scan (2nd script) from post #8 as well?
 
T

Thomas

Active member
@perig thanks for taking the time to respond & educate me. I am not good in coding at all. I copy pasted the 1st script/indicator from post #8 by Len20 (it reads version 1.4) and applied your settings.

@Thomas you mean to run this indicator at 5m chart instead of 1m? How did you set volume 100k? I couldn't find that section in settings. Or is this setting that you have mentioned above for the scan (2nd script) from post #8 as well?
Copy > TOS MAIN CHART> paste=set up>opened shared item... https://tos.mx/4zt7A6W
 
L

Len20

Member
Updated my indicator above (HERE) to v1.5
"Show potential" now includes ignitor bar. Can now color bars. Background color change on signals. Pattern will signal when forming live, disappears if it fails. Uptrend detection lookback now won't overlap pre-market, reg hours, or afterhours time zones. Recoded some logic. Other fixes, tweaks.

@perig Great improvement ideas. I put a few into this update and made some other changes. It's unfortunately beyond my ability to incorporate pivot points and resistance, but I welcome anyone to modify and upgrade my code. The other ideas are great, but I'm probably gonna take a break from updating this for a while. I'm no pro so it's been mentally draining to code lol, but it was worth it and I'm pretty happy with it right now with v1.5. But if you see any bugs or it missed setups it should have signalled, please mention it and I'll try to fix it.
 
Last edited:
BatmansKid

BatmansKid

New member
@Len20 could you expound on how to implement the code you posted. I am pretty sure I got the charts one setup as a study and it is showing so that is good. However, when I put the code into the Scan->Stock Hacker->Study->Custom->Paste your code. I get "Error script execution timeout". Maybe I am putting it in the wrong place? New to thinkscript. Sorry
 
L

Len20

Member
It sounds like your're doing it right. I just tested it again and it worked fine for me. After you click on "Custom", click on the tab "Thinkscript Editor" and delete the default line of code. Then paste in there. Be sure to set the aggregation period that you want also. Another idea is maybe a copy/paste error missed some lines of code?
 
BatmansKid

BatmansKid

New member
That was the issue. My aggregation period was set to default. did not work. I changed it to 10m and it worked. What aggregation do you suggest for optimal performance of this filter?

Edit: 5 minutes seems to work, also a Volume filter of 100k.. thanks Thomas.
Thanks Len for this awesome script, cant wait to mess around with it!
 
Last edited:
P

perig

New member
@Len20 this new version is great, so many new adjustments! Good job. I will play with it more and i'll feedback what I find out.

@BatmansKid I was able to get the scan to work and see some igniting bars for 3BP on all sorts of timescales. I like the 1D view as it is a slower moving trading scale but I was able to get results at other time scales as well.
 
P

perig

New member
Will this work with a Tick chart?
I tried on a chart set for tick and I can see the signals. However I don't think there is a tick setting for the scan, I only see time options (which I believe is from TOS, not this script specifically).
 
T

TCB

New member
Great Study, I've been looking for this setup. Is there a way to change the color of the bars easily, and is there also a study or scan for the Bearish side? Thanks
 
L

Len20

Member
Is there a way to change the color of the bars easily, and is there also a study or scan for the Bearish side? Thanks
Sure, to change the colors of the bars, just search for "createColor" near the bottom. There are 4 occurances of the RGB colors in parentheses. You can find other RGB color codes using google or just replace it with the built in colors code like Color.GREEN
I have't converted it to bearish yet, but I probably will at some point and post here if nobody beats me to it. Could be a while though
 
U

unseen3000

New member
Just updated the 3 and 4 Bar Play above to version 1.2
Changes:
individual lookback customization, ignitor bar height now includes wicks, can now customize pause bars minimum low (was ignitor midpoint),
non-uptrend and no resistance requirements can be disabled, better uptrend detection, inputs more consistent, tweaks, fixes, more comments
Does the script work for when going short?
 
T

TopDog

New member
VIP
@BenTen I tested this on a custom time frame and the results look promising. Is it possible to get a Bearish version of this indicator ? Is it possible to scan for both bullish and bearish version of this pattern on ToS on a custom time frame that is not in the list on the scanner ?
 
BenTen

BenTen

Administrative
Staff
VIP
@TopDog Which script are you referring to specifically?
 
T

TopDog

New member
VIP
Thanks for the idea. I wanted to try to add the 4 bar play too, and tried to follow the criteria that Live Traders mentions in that video. This is my result. It seems to match the pattern pretty well. The only issue is I've found very few matches now in my overnight scans and clicking through stocks. Maybe it'll do better during trading hours, or the criteria is just too strict (it is configurable), though if I loosen up I get results that don't quite match the pattern. Or maybe I made a mistake somewhere. Well here's what I came up with
6/17/20 updated to v1.5



Code:
# Bullish 3 Bar Play & 4 Bar Play v1.5 by Len20
# based on Live Traders video https://www.youtube.com/watch?v=xEjUd82NVVg

# v1.1 fixed small mistake
# v1.2 individual lookback customization, ignitor bar height now includes wicks, can now customize pause bars minimum low (was ignitor midpoint),
#      non-uptrend and no resistance requirements can be disabled, better uptrend detection, inputs more consistent, tweaks, fixes, more comments
# v1.3 trigger bar need not be green = more potential pattern matches
# v1.4 "Show Potential" now includes possible pattern setups during middle ("pause") bars, bug fix, trigger bar min low can now be same as pause bars min low ("Relaxed"), instead of pause bars actual low (official)
# v1.5 "Show potential" now includes ignitor bar. Can now color bars. Background color change on signals. Pattern will signal when forming live, disappears if it fails. Uptrend detection lookback now won't overlap pre-market, reg hours, or afterhours time zones. Recoded some logic. Other fixes, tweaks.

# Magenta arrow = potential pattern forming
# White arrow   = confirmed (trigger bar high broke the high of ignitor and pause bars)

# Official Criteria:
# 1st bar ("ignitor") spike in price, range, maybe volume & 1st or 2nd bar of a move
# 1st bar not in middle of an uptrend
# 1st bar should be above resistance (closes above recent high)
# middle bar/bars ("pause") low is above midpoint of 1st bar
# middle bar/bars high is near 1st bar high
# middle bar/bars can be green or red
# trigger bar (potential) low is greater than low of middle bar/bars
# trigger bar (confirmed) high is above the high of the ingnitor and middle bars

input Show_Arrows_Potential = yes;         # ignitor and pause bars match pattern, trigger has potential
input Show_Arrows_Confirmed = yes;         # trigger bar successfully crossed previous bars high
input Color_Bars_Potential  = yes;         # ignitor and pause bars match pattern, trigger has potential
input Color_Bars_Confirmed  = yes;         # trigger bar successfully crossed previous bars high
input Flash_Background_Start = {default "Off", "Ignitor", "Pause Bars", "Trigger"};   # BG color change starting with selected bar match
input trigger_Bar_Low_Min = {default "Official", "Relaxed"};   # Trigger bar low min based on pause bars low (official), or pause bars minimum
input Show_During_Uptrend = yes;           # Strict pattern not supposed to be in middle of uptrend
input uptrend_Limit_Perc_Inc = 1.0;        # Only used if Show_During_Uptrend = no (Still signal if uptrend is below % entered)
input uptrend_LookBack = 10;               # Only used if Show_During_Uptrend = no
input prev_High_LookBack = 5;              # Ignitor bar must break previous period high
input avg_Vol_LookBack = 10;               # for qualifying ignitor bar
input avg_Range_LookBack = 10;             # for qualifying ignitor bar
input ignitor_Range_Spike_Perc = 200;      # Minimum ignitor range % relative to avg range (200% = 2x avg range)
input ignitor_Vol_Spike_Perc = 100;        # Minimum volume % relative to avg volume
input pause_Low_Min_Perc  = 45;            # Pause bars low min % of ignitor bar range (50% = middle of ingitor bar)
input pause_High_Min_Perc = 80;            # Pause bars high min % of ignitor bar range
input pause_High_max_Perc = 110;           # Pause bars high max % of ignitor bar range

Assert(prev_High_LookBack >= 1, "prev_High_LookBack must be greater than zero");
Assert(uptrend_LookBack >= 1, "uptrend_LookBack must be greater than zero");
Assert(avg_Vol_LookBack >= 1, "avg_Vol_LookBack must be greater than zero");
Assert(avg_Range_LookBack >= 1, "avg_Range_LookBack must be greater than zero");
Assert(ignitor_Range_Spike_Perc >= 110, "ignitor_Range_Spike_Perc must be greater than 110%");
Assert(pause_Low_Min_Perc >= 0, "pause_Low_Min_Perc must be greater than zero");
Assert(pause_High_Min_Perc >= pause_Low_Min_Perc, "pause_High_Min_Perc must be greater than pause_Low_Min_Perc");
Assert(pause_High_max_Perc >= 100, "pause_High_max_Perc must be greater than or equal to 100%");

def triggerMode;
switch (trigger_Bar_Low_Min) {
case "Official": triggerMode = 1;
case "Relaxed": triggerMode = 2; }

def flashBGMode;
switch (Flash_Background_Start) {
case "Off": flashBGMode = 1;
case "Ignitor": flashBGMode = 2;
case "Pause Bars": flashBGMode = 3;
case "Trigger": flashBGMode = 4; }

def start = 0930;
def end = 1600;
def pre = secondsTillTime(start) > 0;
def regHrs = secondsfromtime(start) >= 0 and secondsTillTime(end) > 0;
def AH =  secondsfromtime(end) >= 0;
def utLookback = max(1, rounddown(uptrend_LookBack / 2, 0));
def utLookbackRecent = max(1, rounddown(uptrend_LookBack / 4, 0));
def uptrendLimMult = 1 + (uptrend_Limit_Perc_Inc * .01);
def h = high;
def l = low;
def o = open;
def c = close;
def v = volume;
def liveBar = isNaN(c[-1]);
def upBar = o < c;
def range = h - l;
def avgRange = ATR(avg_Range_LookBack);
def avgVol = Average(v, avg_Vol_LookBack);
def hh = Highest(h, prev_High_LookBack);

def movAvg = MovingAverage(AverageType.SIMPLE, c, utLookback);
def movAvgRecent = MovingAverage(AverageType.SIMPLE, c, utLookbackRecent);

def diffTimeZone1 = (pre and !pre[utLookback * 2]) or (regHrs and !regHrs[utLookback * 2]) or (AH and !AH[utLookback * 2]);
def diffTimeZone2 = (pre and !pre[utLookbackRecent * 2]) or (regHrs and !regHrs[utLookbackRecent * 2]) or (AH and !AH[utLookbackRecent * 2]);

def notUptrend1 = diffTimeZone1 or (movAvg <= movAvg[utLookback] * uptrendLimMult);
def notUptrend2 = diffTimeZone2 or (movAvgRecent <= movAvgRecent[utLookbackRecent] * uptrendLimMult);
def notUptrend = Show_During_Uptrend or (notUptrend1 and notUptrend2);

def ignitorMinHigh = max(hh[1] , h[1] + (range[1] * (ignitor_Range_Spike_Perc - 100) * .01 * .7));
def ignitor_bar = upBar and notUptrend[1] and h >= ignitorMinHigh and range > range[1] and range >= avgRange[1] * ignitor_Range_Spike_Perc * .01 and v >= avgVol[1] * ignitor_Vol_Spike_Perc *.01;

def pauseLowMin = l + (range * pause_Low_Min_Perc * .01);
def pauseHighMin = l + (range * pause_High_Min_Perc * .01);
def pauseHighMax = l + (range * pause_High_max_Perc * .01);
def pause_bar1 = ignitor_bar[1] and l >= pauseLowMin[1] and h <= pauseHighMax[1] and h >= pauseHighMin[1];
def pause_bar2 =  pause_bar1[1] and l >= pauseLowMin[2] and h <= pauseHighMax[2] and h >= pauseHighMin[2];

def potential_3BP = pause_bar1[1] and range > 0 and if triggerMode == 1 then l >= l[1] else l >= pauseLowMin[2];
def confirmed_3BP = potential_3BP and h > Max(h[1], h[2]);
def potential_4BP = pause_bar2[1] and range > 0 and if triggerMode == 1 then l >= min(l[1], l[2]) else l >= pauseLowMin[3];
def confirmed_4BP = potential_4BP and h > Max(Max(h[1], h[2]), h[3]);

# The 3rd bar can be both pause_bar2 and 3BP trigger bar at same time

def show_confirmed = confirmed_3BP or confirmed_4BP;
def show_potential = (potential_3BP or potential_4BP) and liveBar;
#def show_pause2  = pause_bar2 and !potential_3BP and !confirmed_3BP and (if liveBar then 1 else (potential_4BP[-1] and liveBar[-1]) or confirmed_4BP[-1]);
def show_pause2  = pause_bar2 and (if liveBar then 1 else (potential_4BP[-1] and liveBar[-1]) or confirmed_4BP[-1]);
def show_pause1  = pause_bar1 and (if liveBar then 1 else show_pause2[-1] or (potential_3BP[-1] and liveBar[-1]) or confirmed_3BP[-1]);
def show_ignitor = ignitor_bar and (if liveBar then 1 else show_pause1[-1]);

plot confirmed_arrows = Show_Arrows_Confirmed and show_confirmed;
plot potential_arrows = Show_Arrows_Potential and (show_ignitor or show_pause1 or show_pause2 or show_potential);

def paintPotential = Color_Bars_Potential and (show_ignitor or show_pause1 or show_pause2 or show_potential);
def paintConfirmed = Color_Bars_Confirmed and show_confirmed;

def flashBG = if flashBGMode == 2 then (show_ignitor or show_pause1 or show_pause2 or show_potential or show_confirmed) else
              if flashBGMode == 3 then (show_pause1 or show_pause2 or show_potential or show_confirmed) else
              if flashBGMode == 4 then (show_potential or show_confirmed) else 0;

# STYLE #
confirmed_arrows.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
confirmed_arrows.SetDefaultColor(Color.WHITE);
confirmed_arrows.SetLineWeight(3);

potential_arrows.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
potential_arrows.SetDefaultColor(Color.MAGENTA);
potential_arrows.SetLineWeight(3);

assignPriceColor(if paintPotential then if c < o then createColor(255,0,20) else createColor(200,255,20) else color.CURRENT);
assignPriceColor(if paintConfirmed then if c < o then createColor(255,0,20) else createColor(200,255,20) else color.CURRENT);

assignBackgroundColor(if flashBG then color.LIGHT_GRAY else color.current);
and here is the scan
Code:
# Bullish 3 Bar Play & 4 Bar Play SCAN v1.5 by Len20
# based on Live Traders video https://www.youtube.com/watch?v=xEjUd82NVVg

# v1.1 fixed small mistake
# v1.2 individual lookback customization, ignitor bar height now includes wicks, can now customize pause bars minimum low (was ignitor midpoint),
#      non-uptrend and no resistance requirements can be disabled, better uptrend detection, inputs more consistent, tweaks, fixes, more comments
# v1.3 trigger bar need not be green = more potential pattern matches
# v1.4 "Show Potential" now includes possible pattern setups during middle ("pause") bars, bug fix, trigger bar min low can now be same as pause bars min low ("Relaxed"), instead of pause bars actual low (official)
# v1.5 "Show potential" now includes ignitor bar. Can now color bars. Background color change on signals. Pattern will signal when forming live, disappears if it fails. Uptrend detection lookback now won't overlap pre-market, reg hours, or afterhours time zones. Recoded some logic. Other fixes, tweaks.

# Magenta arrow = potential pattern forming
# White arrow   = confirmed (trigger bar high broke the high of ignitor and pause bars)

# Official Criteria:
# 1st bar ("ignitor") spike in price, range, maybe volume & 1st or 2nd bar of a move
# 1st bar not in middle of an uptrend
# 1st bar should be above resistance (closes above recent high)
# middle bar/bars ("pause") low is above midpoint of 1st bar
# middle bar/bars high is near 1st bar high
# middle bar/bars can be green or red
# trigger bar (potential) low is greater than low of middle bar/bars
# trigger bar (confirmed) high is above the high of the ingnitor and middle bars

input Show_Arrows_Potential = yes;         # ignitor and pause bars match pattern, trigger has potential
input Show_Arrows_Confirmed = yes;         # trigger bar successfully crossed previous bars high
input Color_Bars_Potential  = yes;         # ignitor and pause bars match pattern, trigger has potential
input Color_Bars_Confirmed  = yes;         # trigger bar successfully crossed previous bars high
input Flash_Background_Start = {default "Off", "Ignitor", "Pause Bars", "Trigger"};   # BG color change starting with selected bar match
input trigger_Bar_Low_Min = {default "Official", "Relaxed"};   # Trigger bar low min based on pause bars low (official), or pause bars minimum
input Show_During_Uptrend = yes;           # Strict pattern not supposed to be in middle of uptrend
input uptrend_Limit_Perc_Inc = 1.0;        # Only used if Show_During_Uptrend = no (Still signal if uptrend is below % entered)
input uptrend_LookBack = 10;               # Only used if Show_During_Uptrend = no
input prev_High_LookBack = 5;              # Ignitor bar must break previous period high
input avg_Vol_LookBack = 10;               # for qualifying ignitor bar
input avg_Range_LookBack = 10;             # for qualifying ignitor bar
input ignitor_Range_Spike_Perc = 200;      # Minimum ignitor range % relative to avg range (200% = 2x avg range)
input ignitor_Vol_Spike_Perc = 100;        # Minimum volume % relative to avg volume
input pause_Low_Min_Perc  = 45;            # Pause bars low min % of ignitor bar range (50% = middle of ingitor bar)
input pause_High_Min_Perc = 80;            # Pause bars high min % of ignitor bar range
input pause_High_max_Perc = 110;           # Pause bars high max % of ignitor bar range

Assert(prev_High_LookBack >= 1, "prev_High_LookBack must be greater than zero");
Assert(uptrend_LookBack >= 1, "uptrend_LookBack must be greater than zero");
Assert(avg_Vol_LookBack >= 1, "avg_Vol_LookBack must be greater than zero");
Assert(avg_Range_LookBack >= 1, "avg_Range_LookBack must be greater than zero");
Assert(ignitor_Range_Spike_Perc >= 110, "ignitor_Range_Spike_Perc must be greater than 110%");
Assert(pause_Low_Min_Perc >= 0, "pause_Low_Min_Perc must be greater than zero");
Assert(pause_High_Min_Perc >= pause_Low_Min_Perc, "pause_High_Min_Perc must be greater than pause_Low_Min_Perc");
Assert(pause_High_max_Perc >= 100, "pause_High_max_Perc must be greater than or equal to 100%");

def triggerMode;
switch (trigger_Bar_Low_Min) {
case "Official": triggerMode = 1;
case "Relaxed": triggerMode = 2; }

def flashBGMode;
switch (Flash_Background_Start) {
case "Off": flashBGMode = 1;
case "Ignitor": flashBGMode = 2;
case "Pause Bars": flashBGMode = 3;
case "Trigger": flashBGMode = 4; }

def start = 0930;
def end = 1600;
def pre = secondsTillTime(start) > 0;
def regHrs = secondsfromtime(start) >= 0 and secondsTillTime(end) > 0;
def AH =  secondsfromtime(end) >= 0;
def utLookback = max(1, rounddown(uptrend_LookBack / 2, 0));
def utLookbackRecent = max(1, rounddown(uptrend_LookBack / 4, 0));
def uptrendLimMult = 1 + (uptrend_Limit_Perc_Inc * .01);
def h = high;
def l = low;
def o = open;
def c = close;
def v = volume;
def liveBar = isNaN(c[-1]);
def upBar = o < c;
def range = h - l;
def avgRange = ATR(avg_Range_LookBack);
def avgVol = Average(v, avg_Vol_LookBack);
def hh = Highest(h, prev_High_LookBack);

def movAvg = MovingAverage(AverageType.SIMPLE, c, utLookback);
def movAvgRecent = MovingAverage(AverageType.SIMPLE, c, utLookbackRecent);

def diffTimeZone1 = (pre and !pre[utLookback * 2]) or (regHrs and !regHrs[utLookback * 2]) or (AH and !AH[utLookback * 2]);
def diffTimeZone2 = (pre and !pre[utLookbackRecent * 2]) or (regHrs and !regHrs[utLookbackRecent * 2]) or (AH and !AH[utLookbackRecent * 2]);

def notUptrend1 = diffTimeZone1 or (movAvg <= movAvg[utLookback] * uptrendLimMult);
def notUptrend2 = diffTimeZone2 or (movAvgRecent <= movAvgRecent[utLookbackRecent] * uptrendLimMult);
def notUptrend = Show_During_Uptrend or (notUptrend1 and notUptrend2);

def ignitorMinHigh = max(hh[1] , h[1] + (range[1] * (ignitor_Range_Spike_Perc - 100) * .01 * .7));
def ignitor_bar = upBar and notUptrend[1] and h >= ignitorMinHigh and range > range[1] and range >= avgRange[1] * ignitor_Range_Spike_Perc * .01 and v >= avgVol[1] * ignitor_Vol_Spike_Perc *.01;

def pauseLowMin = l + (range * pause_Low_Min_Perc * .01);
def pauseHighMin = l + (range * pause_High_Min_Perc * .01);
def pauseHighMax = l + (range * pause_High_max_Perc * .01);
def pause_bar1 = ignitor_bar[1] and l >= pauseLowMin[1] and h <= pauseHighMax[1] and h >= pauseHighMin[1];
def pause_bar2 =  pause_bar1[1] and l >= pauseLowMin[2] and h <= pauseHighMax[2] and h >= pauseHighMin[2];

def potential_3BP = pause_bar1[1] and range > 0 and if triggerMode == 1 then l >= l[1] else l >= pauseLowMin[2];
def confirmed_3BP = potential_3BP and h > Max(h[1], h[2]);
def potential_4BP = pause_bar2[1] and range > 0 and if triggerMode == 1 then l >= min(l[1], l[2]) else l >= pauseLowMin[3];
def confirmed_4BP = potential_4BP and h > Max(Max(h[1], h[2]), h[3]);

# The 3rd bar can be both pause_bar2 and 3BP trigger bar at same time

def show_confirmed = confirmed_3BP or confirmed_4BP;
def show_potential = (potential_3BP or potential_4BP) and liveBar;
#def show_pause2  = pause_bar2 and !potential_3BP and !confirmed_3BP and (if liveBar then 1 else (potential_4BP[-1] and liveBar[-1]) or confirmed_4BP[-1]);
def show_pause2  = pause_bar2 and (if liveBar then 1 else (potential_4BP[-1] and liveBar[-1]) or confirmed_4BP[-1]);
def show_pause1  = pause_bar1 and (if liveBar then 1 else show_pause2[-1] or (potential_3BP[-1] and liveBar[-1]) or confirmed_3BP[-1]);
def show_ignitor = ignitor_bar and (if liveBar then 1 else show_pause1[-1]);

def confirmed_arrows = Show_Arrows_Confirmed and show_confirmed;
def potential_arrows = Show_Arrows_Potential and (show_ignitor or show_pause1 or show_pause2 or show_potential);

plot scan = (confirmed_arrows or potential_arrows) within 3 bars;
@BenTen This one
 

Similar threads

Top