Testing Keith Fitschen’s Bar Scoring with Pattern Smasher

Keith’s Book

Thanks to MJ for planting the seed for this post.  If you were one of the lucky ones to get Keith’s “Building Reliable Trading SystemsTradable Strategies that Perform as They Backtest and Meet Your Risk-Reward Goals”  book by John Wiley 2013 at the list price of $75 count yourself lucky.  The book sells for a multiple of that on Amazon.com.  Is there anything earth shattering in the book you might ask?  I wouldn’t necessarily say that, but there are some very well thought out and researched topics that most traders would find of interest.

Bar Scoring

In his book Keith discusses the concept of bar-scoring.  In Keith’s words, “Bar-scoring is an objective way to classify an instrument’s movement potential every bar.  The two parts of the bar-scoring are the criterion and the resultant profit X days hence.”  Keith provides several bar scoring techniques, but I highlight just one.

Keith broke these patterns down into the relationship of the close to the open, and close in the upper half of the range; close greater than the open and close in the lower half of the range.  He extended the total number of types to 8 by adding the relationship of the close of the bar to yesterdays bar.

The PatternSmasher code can run through a binary representation

for each pattern and test holding the position for an optimizable number of days.  It can also check for long and short positions.  The original Pattern Smasher code used a for-loop to create patterns that were then compared to the real life facsimile.  In this code it was easier to just manually define the patterns and assign them the binary string.

if c[0]> c[1] and c[0] > o[0] and c[0] > (h[0] + l[0])/2  then patternString = "----";
if c[0]> c[1] and c[0] > o[0] and c[0] < (h[0] + l[0])/2 then patternString = "---+";
if c[0]> c[1] and c[0] < o[0] and c[0] > (h[0] + l[0])/2 then patternString = "--+-";
if c[0]> c[1] and c[0] < o[0] and c[0] < (h[0] + l[0])/2 then patternString = "--++";
if c[0]< c[1] and c[0] > o[0] and c[0] > (h[0] + l[0])/2 then patternString = "-+--";
if c[0]< c[1] and c[0] > o[0] and c[0] < (h[0] + l[0])/2 then patternString = "-+-+";
if c[0]< c[1] and c[0] < o[0] and c[0] > (h[0] + l[0])/2 then patternString = "-++-";
if c[0]< c[1] and c[0] < o[0] and c[0] < (h[0] + l[0])/2 then patternString = "-+++";
Manual Pattern Designations

Please check my code for any errors.  Here I go through the 8 different relationships and assign them to a Patter String.  “-+++”  represents pattern number (7 ) or type (7 + 1 = 8 – my strings start out at 0).  You can then optimize the test pattern and if the test pattern matches the actual pattern, then the Pattern Smasher takes the trade  on the opening of the next bar and holds it for the number of days you specify.  You an also designate long and short positions in the code.  Here I optimized the 8 patterns going long and short and holding from 1-4 days.

Here is the equity curve!  Remember these are Hypothetical Results with $0 commission/slippage and historic performance is not necessarily indicative of future results.  Educational purposes only!  This is tested on ES.D

Play around with the code and let me know if you find any errors or any improvements.

input: patternTests(8),orbAmount(0.20),LorS(1),holdDays(0),atrAvgLen(10),enterNextBarAtOpen(true);

var: patternTest(""),patternString(""),tempString("");
var: iCnt(0),jCnt(0);
array: patternBitChanger[4](0);

{written by George Pruitt -- copyright 2019 by George Pruitt
This will test a 4 day pattern based on the open to close
relationship. A plus represents a close greater than its
open, whereas a minus represents a close less than its open.
The default pattern is set to pattern 14 +++- (1110 binary).
You can optimize the different patterns by optimizing the
patternTests input from 1 to 16 and the orbAmount from .01 to
whatever you like. Same goes for the hold days, but in this
case you optimize start at zero. The LorS input can be
optimized from 1 to 2 with 1 being buy and 2 being sellshort.}

patternString = "";
patternTest = "";

patternBitChanger[0] = 0;
patternBitChanger[1] = 0;
patternBitChanger[2] = 0;
patternBitChanger[3] = 0;

value1 = patternTests - 1;


//example patternTests = 0 -- > 0000
//example patternTests = 1 -- > 0001
//example patternTests = 2 -- > 0010
//example patternTests = 3 -- > 0011
//example patternTests = 4 -- > 0100
//example patternTests = 5 -- > 0101
//example patternTests = 6 -- > 0110
//example patternTests = 7 -- > 0111

if(value1 >= 0) then
begin

if(mod(value1,2) = 1) or value1 = 1 then patternBitChanger[0] = 1;
value2 = value1 - patternBitChanger[0] * 1;

if(value2 >= 7) then begin
patternBitChanger[3] = 1;
value2 = value2 - 8;
end;

if(value2 >= 4) then begin
patternBitChanger[2] = 1;
value2 = value2 - 4;
end;
if(value2 = 2) then patternBitChanger[1] = 1;
end;

for iCnt = 3 downto 0 begin
if(patternBitChanger[iCnt] = 1) then
begin
patternTest = patternTest + "+";
end
else
begin
patternTest = patternTest + "-";
end;
end;

patternString = "";

if c[0]> c[1] and c[0] > o[0] and c[0] > (h[0] + l[0])/2 then patternString = "----";
if c[0]> c[1] and c[0] > o[0] and c[0] < (h[0] + l[0])/2 then patternString = "---+";
if c[0]> c[1] and c[0] < o[0] and c[0] > (h[0] + l[0])/2 then patternString = "--+-";
if c[0]> c[1] and c[0] < o[0] and c[0] < (h[0] + l[0])/2 then patternString = "--++";
if c[0]< c[1] and c[0] > o[0] and c[0] > (h[0] + l[0])/2 then patternString = "-+--";
if c[0]< c[1] and c[0] > o[0] and c[0] < (h[0] + l[0])/2 then patternString = "-+-+";
if c[0]< c[1] and c[0] < o[0] and c[0] > (h[0] + l[0])/2 then patternString = "-++-";
if c[0]< c[1] and c[0] < o[0] and c[0] < (h[0] + l[0])/2 then patternString = "-+++";


if(barNumber = 1) then print(elDateToString(date)," pattern ",patternTest," ",patternTests-1);
if(patternString = patternTest) then
begin

// print(date," ",patternString," ",patternTest); //uncomment this and you can print out the pattern
if (enterNextBarAtOpen) then
begin
if(LorS = 2) then SellShort("PatternSell") next bar on open;
if(LorS = 1) then buy("PatternBuy") next bar at open;
end
else
begin
if(LorS = 2) then SellShort("PatternSellBO") next bar at open of tomorrow - avgTrueRange(atrAvgLen) * orbAmount stop;
if(LorS = 1) then buy("PatternBuyBO") next bar at open of tomorrow + avgTrueRange(atrAvgLen) * orbAmount stop;
end;


end;

if(holdDays = 0 ) then setExitonClose;
if(holdDays > 0) then
begin
if(barsSinceEntry = holdDays and LorS = 2) then BuyToCover("xbarLExit") next bar at open;
if(barsSinceEntry = holdDays and LorS = 1) then Sell("xbarSExit") next bar at open;
end;
Bar Scoring Testing Template

Discover more from George Pruitt

Subscribe to get the latest posts sent to your email.

Leave a Reply