In Search of
the Holy Grail
by Howard Arrington
In literature, the 'Holy Grail' is generally considered
to be the cup from which Christ drank at the Last Supper and
the one used by Joseph of Arimathea to catch his blood as he
hung on the cross. The term 'holy grail' has been used
among traders to represent the ultimate mechanical trading
system that would return unlimited wealth. Though many
seasoned traders say the Holy Grail does not exist, it is a
never ending pursuit of many traders to find a Holy Grail.
Armed with a computer as a research tool, thousands of
traders have tested their ideas against historical data sets
in search of the ultimate trading system. Many ideas are
marketed, surrounded by claims of phenomenal success with
graphs showing the hypothetical accumulation of wealth
if the system had been used to trade financial
markets over the past few years. Many of these mechanical
systems are promoted with 'rags-to-riches' testimonials in
the advertising literature which arrives unsolicited in my
mail box each week.
Perhaps it has been my luck to just be unlucky. The
$3000 systems I am familiar with have ended up being more
phony than legitimate. Thus, my bias is more likely to
embrace the philosophy that the Holy Grail does not exist.
I consider the following are very valid questions to ask
about any system being offered.
- Why does an author bother to sell a trading system
if it does all that the author claims?
- Why doesn't the author acquire unlimited wealth by
using his Holy Grail, instead of being bothered with
advertising, marketing, trade shows, customer support,
and criticism?
- Has the system withstood the test of time? If it
was 'holy' a decade ago, shouldn't it still be highly
sought after now?
- What happened to the 'rags-to-riches' folks who had
their testimonials published a year ago?
Sorry I do not have the answers to these questions.
However, the real purpose of this article is to discuss the
challenges of designing mechanical trading systems.
Consideration of these principles in one's design should be
helpful to those who engage in a search for the Holy Grail.
1) Type of Market
We all realize that there are different types of markets,
namely: trending, swing, and choppy. Different systems try
to take advantage of a particular type of market, and their
results look great when applied to the type of market they
were designed for. These systems have poor results in the
wrong type of market. System designers feel they have a
great system if they can put money in the bank when the
market is the right type, and break even when the market is
the wrong type.
Studies serve as a basis for the design of many trading
system, or are used as either a filter or a signal in the
system design. The following common studies have been
categorized by the type of market they work best with.
- Trending - Moving Averages, Parabolic Stop,
Volatility Stop, Trailing Stop, Directional Movement
Index, Channels
- Swing - Stochastics, Relative Strength Index,
MACD, Commodity Channel Index, Pesavento Patterns,
Fibonacci, Divergence
- Choppy - can't think of anything that works
well with choppy. Most traders prefer to stand aside in
choppy markets.
Traders often try to label the Elliot wave counts so they
can anticipate the type of market unfolding, whether the
market is in a consolidating wave 4 triangle, or whether a
wave 3 breakout thrust is underway. They can then adjust
their trading strategy for the type of market.
2) Slippage
Some systems suffer from trading too frequently.
Commissions and slippage costs become a high percentage of
the expected gain. For example, if two systems both
generate a profit of $4000, would you prefer system A
that did so with 10 trades or system B that did so
with 100 trades? The average trade in system A is
$400 while the average trade in system B is $40. For
example, if the fills in real life are one tick worse in the
E-mini markets, $25 has evaporated from the average trade
results, and the penalty on 100 trades is more severe than
on 10 trades. Thus, a big factor to consider in evaluating
a system's success record is the number of trades. Too few
trades may not be statistically sound, and too many trades
may suffer from commissions and slippage losses, not to
mention the constant wear it is on one's emotions.
3) Emotion
Emotion is one of the hardest areas to design for. The
whole reason traders seek a Holy Grail is because they have
had a few bad experiences in the markets, and no longer
trust themselves to trade well.. They assume that the
computer can analyze the facts more logically and pull the
trigger more mechanically, which are areas they feel they
need help with. The results look good on paper, up $60,000
for the year with the system, and the maximum draw down
looks tolerable compared to the benefit. So, courage is
mustered and commitment to faithfully follow the system's
signals is expressed to one's friends.
But what happens over the next couple weeks. Our
emotions want instant success. We are unwilling to tolerate
a series of losing trades. All systems eventually have a
string of losing trades and a draw down in equity. Such is
part of the statistical results buried somewhere in those
beautiful graphs of wealth accumulation. However, a graph
of past performance is emotionless. The real thing, with my
money on the line, is 100% emotion. When I am ahead I am
elated at how easy it is. When I am behind, I start to
second guess every signal and think I am smarter than the
system, and I can improve on the trading system by applying
my experience. Surely I am aware of intangibles the system
failed to consider. For example, does the trading system
know what is the correct thing to do when the news is
showing horrifying pictures of planes flying into tall
buildings, or war has broken out in the Middle East, or the
dock workers have decided to go on strike, or Greenspan is
speaking before Congress? Suddenly we convince ourselves we
know more than the Holy Grail system, and we abandon it as
we seek a place of greater personal comfort.
It is easier to design a mechanical system than it is to
actually trade it! I know... I have been there and done
that.
4) Now you see it, now you don't
One problem when doing analysis on a daily data set is
the urge to jump the gun and execute a new signal during the
day. For example, you may see study lines cross during the
day, which would constitute a signal, and you want to
execute the trade now before the market runs away from you.
However, signals based on a daily data set only know the
four prices of Open, High, Low and Close. During the day
the Open is known. However, the High and Low are moving
targets. And the Close in not known until the market
closes. To execute any trade based on a signal during the
day is to jump the gun.
Though you see the signal intra-day, the signal
conditions will often undo themselves. For example, a
simple signal might be when the Close is above the Open.
When the market is putting in new highs, the signal
condition is True. However, the market can turn around and
put in new lows wherein the signal condition has reversed to
being False. Signals which incorporate the Close price
either directly or indirectly through studies should analyze
through the last completed bar on the chart, and avoid
giving a signal during the time period the current bar is
under construction. Otherwise they will suffer from the
"'now you see it, now you don't" challenge.
5) Moving target
One of the unique studies in Ensign Windows is the
Pesavento Patterns tool. The program uses its set of
proprietary rules to identify swings and label them with
their percentage of retracement when compared to other
swing. The problem with using a study like this for a
signal is that the target can move, as illustrated by this
sequence of 3 charts.
Here the price has dipped to a swing low of
992.50, and the swing ratios are favored 1.128 and .841.
One might think there is a Buy signal in effect because of
the ratios and the pattern. If the markets were to rally,
buying the apparent signal would look like a stroke of
genius. Now consider what happened.
The market dribbled higher in sideways chop
between 12:30 and 14:00, then fell to a new low at 991.50.
The Pesavento Pattern tool adjusted to used the new swing
low. At 991.50 we have another favored ratio of 1.0 for a
double bottom. Do we have a buy signal at this double
bottom? Well consider what happened next.
The market traded lower into the close and
the Pesavento Patterns tool adjusted again to this new swing
low. None of the bounces off of the prior swing low points
were of sufficient amplitude to qualify as a new up trend
because our minimum swing size parameter was set for 5
points. Fluctuations under 5 points in size are being
ignored by the Pesavento Patterns tool.
The tool illustrates a general problem where
it is easier to see things with the benefit hindsight.
This can be said about most divergence patterns. It is easy
to see the last divergence where the market finally turned.
It is easy to overlook other divergence patterns that
existed at the time, but were not the ones to be traded once
additional bars were added to the chart and they became
obscured by a subsequent pattern. Often the patterns we
seek to identify, the divergences, the study lines crossing,
are a moving target. In hindsight it is easy to say, "Of
course, there it is, I see it" yet in real-time we are
frustrated by seeing similar patterns and signals
prematurely in the moving target. If we wait for the signal
to be confirmed we are often late in our execution. For
example, it will be 5 points after the fact before we know
for sure the current Pesavento Pattern is not going to
adjust again to a new lower low.
6) Interior sequence
Another
challenge in back testing a signal idea is the loss of
detail in looking at historical bars versus knowing a real
time tick sequence. Consider a signal where we want to buy
when the market rises 1 full point. In this bar example we
do not know whether the High was put in before or after the
Low.
So in back testing, is the buy signal at 994.50, which
would be the case if the market opened, and then went to the
low of 993.50 and then rallied back to 994.50? Or is the
signal at the high of 995.50, which would be the case if it
rallied from the 994.50 open to put in the high first? We
cannot tell. We simply lack the detail of knowing the
interior sequence of how the bar came to be. The only thing
known about the bar are the four fixed prices of its Open,
High, Low and Close.
Another illustration of the interior sequence challenge
is this. Let's assume the Buy signal was one tick higher
than the high of the bar on the left. The buy trigger would
be a known price of 995.50, and since the bar traded at that
price, we can assume the position was filled. Now suppose
our protective stop is an automatic 2 points below our fill
price. Are we in or out of this trade on this bar? The
answer all depends on the sequence. If the Low was put in
prior to the High, then we have not been stopped out. If
the Low was put in after the order was executed, then the
position is stopped out for a loss. What happened is
uncertain because the detail of how the bar was constructed
is unknown in the historical data set.
7) Execution price
I often find fault with the price chosen for execution.
A trading system I recently looked at used for its Sell
price the High of the bar following the signal. What a
phony deal! Using the High of any bar is biasing the sell
statistics to be executed as a most favorable and unlikely
price. Likewise, using the Low of any bar as the execution
price is biasing the buy statistics with a favorable and
unlikely price.
My opinion is that the execution price should be the Open
of the bar following the signal. A second choice could be
the Close of the bar that generated the signal. While this
is a fixed price in your historical data set, it is a moving
target in real-time and leads you to anticipate the price or
the signal just prior to the close of the bar. We have
already talked about this challenge in our "Now you see it,
now you don't" discussion.
Another consideration is whether the execution price is a
study value, such as a Parabolic Stop value, or a bar price
such as its Close. When a bar touches the Parabolic Stop,
did you have a buy or sell stop in place to execute your
trade? That is fine if your system was designed for the
trigger to be the Low or High of the bar touching the stop,
as opposed to the bar closing across the stop. If your
signal is based on where the bar closes, then the execution
price should be the bar's Close price and not the study
value. Also, the study value might be unrealistic if the
bar gapped across the line, in which case the Open price of
the gap bar should be used as the execution price.
8) Time of day
Many day traders want a system that incorporates the time
of day in its consideration. Some systems are designed to
avoid the choppiness of the market open. Others may want to
consider avoiding new trades near the close of the day.
Some systems will want to exit all positions ahead of the
market close.
I find fault with scalping systems that establish trades
just prior to market close, are blind to all Globex
activity, and then exit at an excessive profit objective at
the following day's favorable gap open. My opinion is that
scalping systems are day trading systems and their
statistical results should not include holding positions
overnight, nor be blind to the Globex trading if a position
is held past the day session close.
9) Optimization
The computer lends itself to endless number crunching.
System designers adjust parameters endlessly in an effort to
tweak more performance out of their idea. They will adjust
study parameters such as the number of bars in a moving
average, adjust trigger thresholds such as CCI crossing 100,
adjust entry and exit rules, and adjust slack parameters
such as a stop offset from a bar high or low. The number of
possibilities is mind boggling. The billions of
calculations, permutations and combinations are
unfathomable.
When it is all said and done, the author announces the
greatness of his work, expounds on the difficulty of the
project and the cleverness of his creativity. A price tag
is picked, advertising hype assembled, and marketing efforts
directed at would be buyers.
The problem is that the system performance is often over
optimized in an effort to tweak great performance out of the
historical data set used to design the system. When I
started Ensign Software 22 years ago, one of my first
products was the CAT program (Computer Analyzed Trading).
It basically was a High/Low stop concept with an optimized
slack value for each futures symbol. CAT had an optimized
slack value for Japanese Yen, a different slack value for
Gold, and a different slack value for Live Cattle. The idea
was to put the good trends in the bank, and hold its own in
choppy markets. A really good trend came along in each
market a couple times each year, and the impressive wealth
accumulation was to catch those trends and put them in the
bank. The other 9 or 10 months of the year, the small
winners would balance out the small losers.
The downfall of the system was over optimization.
Trading the program signals in real-time did not amass the
same results as the back tested results. Why? It took a
long time for me to admit to what the problem was because of
my ego. The system was being optimized to find a slack
value for each market such that the stops would be far
enough away to optimally avoid whip lash. This meant we
back tested tighter stops (enter and exit the trade sooner
for more profit per trade) and wider stops (try to avoid
whip-lash). Somewhere between these conflicting objectives
would be some slack values that would show positive returns
in the back testing results. The finely tuned slack values
that generated 80+% winning trades, were valid for the
historical data set the analysis was done on, but were not
necessarily the best values to use for the immediate
future. The hope was, and it was definitely just a hope,
that the past would repeat itself in the future and so the
optimized parameters should continue to work. Sometimes
they did, often they did not.
When you see advertisements showing stellar results,
please realize that the graphs and reports show Optimized
settings, optimized for the past. And wisely the small
print says, "Past performance is no guarantee of future
performance." Trust me... future performance will be worse
than the past performance because the past was optimized.
10) Just one more rule
The dilemma with every system designer is that their work
is never done. They are plagued with the perpetual need to
add just one more rule to handle just one more situation
that just came up in today's market that was not handled as
profitably as it should. If only we had one more rule too
keep us out of that losing trade today, then the system
would be perfect. So one more rule, one more exception is
incorporated into the system. But the process is repeated
over and over again as the original pure idea evolves into a
different beast.
One more rule is just another form of on-going
optimization. Often this type of optimization is based on
what happened today, and not on thorough back testing. I
have seen systems that worked in general and were
statistically proven through back testing, become
specialized and cease to work at all because of the addition
of rules to handle special situations. Rules get added to
avoid opening gaps that exceed a certain threshold, or to
avoid trading during certain windows of time during the day,
or to increase the trade size if a particular formation is
seen, etc. Too often the rules use specific hard coded
values instead of being generalized so they auto adapt to
different instruments or auto adapt to calmer or more
volatile markets.
I guess the lure to harvest more money from the field of
opportunity will keep the Holy Grail seekers forever
employed. Not all will agree on the ideas on which
different mechanical system are founded. One trader
shooting for the moon might be confident even when a big
position is against him 20 thousand dollars, while other
traders would be financially and emotionally wiped out. We
each have a different 'risk avoidance' threshold and comfort
zone. May each of you find a methodology that fits your
personality and pocket book, and helps you be successful in
your trading.
Research:
Back Testing
by Howard Arrington
Ensign Windows has a powerful programming language called
ESPL. This Delphi (Pascal) like language can be used to
implement proprietary studies, draw tools, alerts, reports,
and program control. This article will demonstrate using
ESPL to develop a trading system and back test its
performance. Consult the Ensign web site for information
about ESPL and for the ESPL programming manual,
http://www.ensignsoftware.com/espl/espl.htm
Our trading system must be kept simple for the sake of
being a teaching example. Yet, it will demonstrate many of
the design principles that would be used in designing any
trading system and back testing its performance. Let's
begin by outlining the characteristics of the example
trading system.
- It must trade in the direction of the trend. Trade
'short' in a downtrend and 'long' in an uptrend.
- It must have specific, mathematical rules that
define the 'signals' for buying, selling, and exiting a
position.
- Parameters should be flexible so that different
settings can be tried and tested.
- The profitability of the trading system needs to be
measured and reported.
The structure of the ESPL program will be like this.
Each section will be developed, and then the program will be
shown in its entirety.
{define global variables}
{define procedures and functions}
{main program}
begin
Initialize;
Calculate;
Report;
end;
Initialize
The Initialize procedure will be where variables are
initialized prior to calculating the trades and accumulating
the results for the report. ESPL has the ability to trade
our trades and generate a report. The ResetTrades
statement is used to define specific Trading System values.
The statement is used in conjunction with the Trade, and
TradeReport commands. ResetTrades is used to initialize a
Trading System. The statement prepares a file to receive
the Buy and Sell trades specified by the Trade command.
The Commission per contract or per share is specified.
The style of the Arrows (marking the trades on a chart) is
also specified.
procedure Initialize;
var
Commission: real;
BuyArrow: integer;
SellArrow: integer;
OutArrow: integer;
ShowBoxes: boolean;
begin
Commission:=10; {deduct $10 round trip for each
trade}
BuyArrow:=8; {show Up arrow and the word 'Long'}
SellArrow:=13; {show Down arrow and the word
'Short'}
OutArrow:=7; {show Right arrow and the word
'Out'}
ShowBoxes:=true; {mark trade with a square box on
the bar}
ResetTrades(Commission,BuyArrow,SellArrow,OutArrow,ShowBoxes);
Position:=0; {0 = out, -1 = short, 1 = long}
ScalpSize:=100; {scalp objective, IQFeed users
enter 1.00}
StopSize:=250; {protective stop, IQFeed users
enter 2.50}
BuySignal:=false; {flag to indicate Buy setup}
SellSignal:=false; {flag to indicate Sell setup}
end;
Calculate
The Calculate procedure will find the chart, clear it of
all studies and markers, put on the Parabolic stop, and loop
through all bars in the chart file and make trades based on
the rules for the Buy and Sell signals.
procedure Calculate;
var
w: integer;
study: integer;
stop: integer;
begin
FindWindow(eChart); {locate the window with
the chart}
Remove(eAll); {clear off studies and
markers}
study:=AddStudy(ePar); {put on Parabolic stop
for trend}
for w:=1 to BarEnd do begin {calculate across all
chart bars}
stop:=GetStudy(study,3,w); {read the Parabolic
position flag}
if stop>0 then begin {determine trend}
TrendUp:=(stop=1);
TrendDn:=(stop=2);
HH:=High(w); {start new swing high
search}
LL:=Low(w); {start new swing low
search}
end;
TestExit(w); {did this bar trigger an
exit}
TestTrade(w); {did this bar trigger a
trade}
end;
end;
Report
The Report procedure will close out the current position,
and print a report in the Output window on the ESPL editor
form.
procedure Report;
begin
Trade(eOut); {close-out the last open trade}
TradeReport(True); {print the results in the output
window}
end;
Exit Rules
For this simple trade system, a position will be exited
when it has hit the protective stop or when it has achieved
the scalp objective.
procedure TestExit(w: integer);
var
bExit: boolean;
begin
bExit:=false;
if Position=1 then begin
{currently long}
if Low(w)<=ExitStop then begin
{test for stopped out}
if Open(w)<ExitStop then ExitPrice:=Open(w)
{check for gap across stop}
else ExitPrice:=ExitStop;
bExit:=true;
{set exit flag}
end
else if High(w)>ExitPrice then begin
{test for scalp objective}
if Open(w)>ExitPrice then ExitPrice:=Open(w);
{check for gap across goal}
bExit:=true; {set exit flag}
end;
end
else if Position=-1 then begin
{currently short}
if High(w)>=ExitStop then begin
{test for stopped out}
if Open(w)>ExitStop then ExitPrice:=Open(w)
{check for gap across stop}
else ExitPrice:=ExitStop;
bExit:=true;
{set exit flag}
end
else if Low(w)<ExitPrice then begin
{test for scalp objective}
if Open(w)<ExitPrice then ExitPrice:=Open(w);
{check for gap across goal}
bExit:=true;
{set exit flag}
end;
end;
if bExit then begin
Trade(eOut,w,ExitPrice,1);
{exit the position}
Position:=0;
{position goes to neutral}
BuySignal:=false;
{clear any pending signals}
SellSignal:=false;
HH:=High(w);
{start new swing high search}
LL:=Low(w);
{start new swing low search}
end;
end;
Signal Logic
This trading system will watch for higher highs and lower
lows to determine swing points. The Parabolic stop will be
used to determine the trend. When in an up trend,
the signal will be a bar whose High is lower than the swing
high. When in a downtrend, the signal will be a bar whose
Low is above the swing low. Execution will use the Open of
the bar following the signal bar. The Exit Price objective
will be the entry price plus a scalp size. The protective
stop price will be the entry price minus the stop size.
The scalp size and the stop size were variables set in the
Initialize procedure and can be adjusted to test the
profitability of different settings.
procedure TestTrade(w: integer);
begin
if Position=0 then begin {do not trade
if already in a position}
if TrendUp then begin {consider
'long' trade}
if BuySignal then begin {did prior bar
give buy signal}
EntryPrice:=Open(w); {trade at open
price}
Trade(eBuy,w,EntryPrice,1);
ExitPrice:=EntryPrice+ScalpSize; {set scalp
objective}
ExitStop:=EntryPrice-StopSize; {set
protective stop}
Position:=1; {new position
long}
end;
if High(w)>HH then HH:=High(w); {find swing
high}
BuySignal:=(High(w)<HH); {signal is 1st
bar below swing high}
end;
if TrendDn then begin {consider
'short' trade}
if SellSignal then begin {did prior bar
give sell signal}
EntryPrice:=Open(w); {trade at open
price}
Trade(eSell,w,EntryPrice,1);
ExitPrice:=EntryPrice-ScalpSize; {set scalp
objective}
ExitStop:=EntryPrice+StopSize; {set
protective stop}
Position:=-1; {new position
short}
end;
if Low(w)<LL then LL:=Low(w); {find swing
low}
SellSignal:=(Low(w)>LL); {signal is 1st
bar above swing low}
end;
end;
end;
Full Program
Cut and the text from this newsletter and paste it into
the ESPL editor form in Ensign Windows, or use the Internet
Services form to download the script file from the Ensign
web site. Open a chart, such as 3-min ES #F, and apply the
Parabolic Stop study. For my tests, I have reduced the
Acceleration rate and Maximum limit on the Parabolic
parameters so the study indicates the bigger trends and has
less whip lash. The Parabolic Stop will be used as the
indicator for the trend. The trading system only takes
Long trades when the Parabolic stop is rising, and Short
trades when the Parabolic Stop is falling. After changing
the Parabolic Stop properties, check the Use as Default
check box so these parameters are used as the default
settings.
{define global variables}
var
Position: integer;
EntryPrice: real;
ExitPrice: real;
ExitStop: real;
ScalpSize: real;
StopSize: real;
HH: real;
LL: real;
BuySignal: boolean;
SellSignal: boolean;
TrendUp: boolean;
TrendDn: boolean;
{define procedures and functions}
procedure Initialize;
var
Commission: real;
BuyArrow: integer;
SellArrow: integer;
OutArrow: integer;
ShowBoxes: boolean;
begin
Commission:=10; {deduct $10 round trip for each
trade}
BuyArrow:=8; {show Up arrow and the word 'Long'}
SellArrow:=13; {show Down arrow and the word
'Short'}
OutArrow:=7; {show Right arrow and the word
'Out'}
ShowBoxes:=true; {mark trade with a square box on
the bar}
ResetTrades(Commission,BuyArrow,SellArrow,OutArrow,ShowBoxes);
Position:=0; {0 = out, -1 = short, 1 = long}
ScalpSize:=100; {scalp objective, IQFeed users
enter 1.00}
StopSize:=250; {protective stop, IQFeed users
enter 2.50}
BuySignal:=false; {flag to indicate Buy setup}
SellSignal:=false; {flag to indicate Sell setup}
end;
procedure TestExit(w: integer);
var
bExit: boolean;
begin
bExit:=false;
if Position=1 then begin
{currently long}
if Low(w)<=ExitStop then begin
{test for stopped out}
if Open(w)<ExitStop then ExitPrice:=Open(w)
{check for gap across stop}
else ExitPrice:=ExitStop;
bExit:=true;
{set exit flag}
end
else if High(w)>ExitPrice then begin
{test for scalp objective}
if Open(w)>ExitPrice then ExitPrice:=Open(w);
{check for gap across goal}
bExit:=true; {set exit flag}
end;
end
else if Position=-1 then begin
{currently short}
if High(w)>=ExitStop then begin
{test for stopped out}
if Open(w)>ExitStop then ExitPrice:=Open(w)
{check for gap across stop}
else ExitPrice:=ExitStop;
bExit:=true;
{set exit flag}
end
else if Low(w)<ExitPrice then begin
{test for scalp objective}
if Open(w)<ExitPrice then ExitPrice:=Open(w);
{check for gap across goal}
bExit:=true;
{set exit flag}
end;
end;
if bExit then begin
Trade(eOut,w,ExitPrice,1);
{exit the position}
Position:=0;
{position goes to neutral}
BuySignal:=false;
{clear any pending signals}
SellSignal:=false;
HH:=High(w);
{start new swing high search}
LL:=Low(w);
{start new swing low search}
end;
end;
procedure TestTrade(w: integer);
begin
if Position=0 then begin {do not trade
if already in a position}
if TrendUp then begin {consider
'long' trade}
if BuySignal then begin {did prior bar
give buy signal}
EntryPrice:=Open(w); {trade at open
price}
Trade(eBuy,w,EntryPrice,1);
ExitPrice:=EntryPrice+ScalpSize; {set scalp
objective}
ExitStop:=EntryPrice-StopSize; {set
protective stop}
Position:=1; {new position
long}
end;
if High(w)>HH then HH:=High(w); {find swing
high}
BuySignal:=(High(w)<HH); {signal is 1st
bar below swing high}
end;
if TrendDn then begin {consider
'short' trade}
if SellSignal then begin {did prior bar
give sell signal}
EntryPrice:=Open(w); {trade at open
price}
Trade(eSell,w,EntryPrice,1);
ExitPrice:=EntryPrice-ScalpSize; {set scalp
objective}
ExitStop:=EntryPrice+StopSize; {set
protective stop}
Position:=-1; {new position
short}
end;
if Low(w)<LL then LL:=Low(w); {find swing
low}
SellSignal:=(Low(w)>LL); {signal is 1st
bar above swing low}
end;
end;
end;
procedure Calculate;
var
w: integer;
study: integer;
stop: integer;
begin
FindWindow(eChart); {locate the window with
the chart}
Remove(eAll); {clear off studies and
markers}
study:=AddStudy(ePar); {put on Parabolic stop
for trend}
for w:=1 to BarEnd do begin {calculate across all
chart bars}
stop:=GetStudy(study,3,w); {read the Parabolic
position flag}
if stop>0 then begin {determine trend}
TrendUp:=(stop=1);
TrendDn:=(stop=2);
HH:=High(w); {start new swing high
search}
LL:=Low(w); {start new swing low
search}
end;
TestExit(w); {did this bar trigger an
exit}
TestTrade(w); {did this bar trigger a
trade}
end;
end;
procedure Report;
begin
Trade(eOut); {close-out the last open trade}
TradeReport(True); {print the results in the output
window}
end;
{main program}
begin
Initialize;
Calculate;
Report;
end;
Back Test Results
For all tests, a $10 round trip commission will be used.
The chart being tested is the 3 minute ES #F. The data set
has been limited to Day Session Only data for the three
dates of June 20th, 23rd, and 24th.
For the first test, let's try a small scalp objective of
one full point, and a generous stop size of 2.50 points.
The following are the back test results, and the chart shows
some of the trades.
ES #F Profit Trades Average Ratio
Wins 1435.00 34 42.21 79.07
Loss 1215.00 9 135.00 20.93
Total 220.00 43 5.12 1.18
79% of the trades were profitable scalps,
but the Net Profit is only $220 after paying commissions on
43 trades. Let's try a bigger scalp objective, knowing in
advance a lower percentage of winning trades will be
achieved. The following results are for a scale objective
of 2.50 points.
ES #F Profit Trades Average Ratio
Wins 1675.00 15 111.67 62.50
Loss 1215.00 9 135.00 37.50
Total 460.00 24 19.17 1.38
The larger scalp objective generates more
profit, on fewer trades, which is good on both points.
Further testing could be done with this
trade system to determine whether one should use a tight or
a generous stop, and whether the scalp objective should be
large or small. The parameters for the Parabolic stop
should also be adjusted to see the impact it has on the
trade system. Finally, the system should be tested using
more data to simulate a wider variety of market
conditions. Some may wish to modify the logic for the Buy
and Sell signals to test other ideas. The tools are
available in Ensign Windows for designing trade systems and
the effort can be both rewarding and fun |