<< . .

. 4
( : 30)

. . >>

0 M A: 960228
960228 -1 724.750 722.900 0 M A: 7 925 Bl25 2525 -12925
0 N B: 960305
960308 725.900 0 M 8: 4l500 4475 1275 -11425
960305 1 722.900 0 H A:
960308 -1 725.900 716.150 0 M A: 4 4875 4075 1300 -6550
0 t4 E.: 960311

on the trade? Has the trading been fairly consistent? Are recent trades worse than
those of the past? Or are they better? How might some of the worst trades be char-
acterized in a way to improve the trading system? These are the kinds of questions
that cannOt be answered by a distant panoramic view of the forest (a summary
report), but they can be answered with a good trade-by-trade or detail report. In addi-
tion, a properly formatted detail report can be loaded into a spreadsheet for further
analysis. Spreadsheets are convenient for sorting and displaying data. They make it
easy, for instance, to draw histograms. Histograms can be very useful in decisions
regarding the placement of stops (Sweeney, 1993). Histograms can show how much
of the potential profit in the trades is being captured by the system™s exit strategy and
is also helpful in designing profit targets. Finally, a detailed examination of the worst
and best trades may generate ideas for improving the system under study.

Trading simulators vary dramatically in such aspects of performance as speed,
capacity, and power. Speed is important when there is a need to carry out many
tests or perform complex optimizations, genetic or otherwise. It is also essential
when developing systems on complete portfolios or using long, intraday data
series involving thousands of trades and hundreds of thousands of data points. In
some instances, speed may determine whether certain explorations can even be
attempted. Some problems are simply not practical to study unless the analyses
can be accomplished in a reasonable length of time. Simulator capacity involves
problem size restrictions regarding the number of bars on which a simulation may
be performed and the quantity of system code the simulator can handle. Finally,
the power a simulator gives the user to express and test complex trading ideas, and
to run tests and even system optimizations on complete portfolios, can be signifi-
cant to the serious, professional trader. A fairly powerful simulator is required, for
example, to run many of the trading models examined in this book.

The most significant determinant of simulation processing speed is the nature of
the scripting or programming language used by the simulator, that is, whether
the language is compiled or interpreted. Modern optimizing compilers for gener-
ic languages, such as Cf f, FORTRAN, and Pascal/Delphi, translate the user-
written source code into highly efficient machine code that the processor can
execute directly at full bore; this makes simulator toolkits that use such lan-
guages and compilers remarkably fast. On the other hand, proprietary, interpret-
ed languages, such as Microsoft™s Visual Basic for Applications and Omega™s
Easy Language, must be translated and fed to the processor line by line.
Simulators that employ interpreted languages can be quite sluggish, especially

when executing complex or “loopy” source code. Just how much speed can be
gained using a compiled language over an interpreted one? We have heard
claims of systems running about 50 times faster since they were converted from
proprietary languages to C+ + !

While speed is primarily a function of language handling (interpreted versus com-
piled), capacity is mostly determined by whether 16-bit or 32-bit software is used.
Older, 16-bit software is often subject to the dreaded 64K limit. In practical terms,
this means that only about 15,000 bars of data (about 4 days of ticks, or 7 weeks of
l-minute bars on the S&P 500) can be loaded for system testing. In addition, as the
system code is embellished, expect to receive a message to the effect that the sys-
tem is too large to verify. Modem C+ + or FORTRAN products, on the other hand,
work with standard 32.bit C+ + or FORTRAN compilers. Consequently, they have
a much greater problem size capacity: With continuous-contract data on a machine
with sufficient memory, every single tick of the S&P 500 since its inception in 1983
can easily be loaded and studied! In addition, there are virtually no limits on the
number of trades a system can take, or on the system™s size and complexity. All
modern Cf +, FORTRAN, and Pascal/Delphi compilers are now full 32.bit pro-
grams that generate code for, and run under, 32-bit operating systems, such as
Windows 95, Windows NT, or LINUXAJNIX. Any simulator that works with such
a compiler should be able to handle large problems and enormous data sets with
ease. Since most software packages are upgrading to 32-bit status, the issue of
problem size capacity is rapidly becoming less significant than it once was.

Differences in simulator power are attributable mostly to language and to design.
Consider language first: In this case, it is not whether the language is compiled or
interpreted, as was the case for speed, but rather its expressive power. Can the most
elaborate and unusual trading ideas be expressed with precision and grace? In
some languages they can; in others they cannot. It is unfortunate that the most
powerful languages have steep learning curves. However, if one can climb the
curve, a language like Cf + makes it possible to do almost anything imaginable.
Your word processor, spreadsheet, web browser, and even operating system were
all probably written in C++ or its predecessor, C. Languages like C++ and
Object Pascal (the basis of Borland™s Delphi) are also extensible and can easily be
customized for the purpose of trading system development by the use of appro-
priate libraries and add-on components. Visual Basic and Easy Language,
although not as powerful as general-purpose, object-oriented languages like Cf +
or Object Pascal, have gentler learning curves and are still quite capable as lan-
guages go. Much less powerful, and not really adequate for the advanced system
developer, are the macro-like languages embedded in popular charting packages,
e.g., Bquis International™s MetaStock. The rule of thumb is the more powerful the
language, the more powerful the simulator.
Design issues are also a consideration in a simulator™s power. Extendability
and modularity are especially important. Simulators that employ C+ + or Object
Pascal (Borland™s Delphi) as their native language are incredibly extensible and
can be highly modular, because such general-purpose, object-oriented languages
are themselves highly extensible and modular; they were designed to be so from
the ground up. Class libraries permit the definition of new data types and opera-
tors. Components can provide encapsulated functionality, such as charting and
database management. Even old-fashioned function libraries (like the Numerical
Algorithms Group library, the International Mathematics and Statistics Library
and the Numerical Recipes library) are available to satisfy a variety of needs. Easy
Language, too, is highly extensible and modular: Modules called User Functions
can be created in Easy Language, and jimcrions written in other languages
(including C+ +) can be called (if they are placed in a dynamic link library, or
DLL). Macrolike languages, on the other hand, are not as flexible, greatly limit-
ing their usefulness to the advanced system developer. In our view, the ability to
access modules written in other languages is absolutely crucial: Different lan-
guages have different expressive foci, and even with a powerful language like
C+ +, it sometimes makes sense to write one or more modules in another lan
guage such as Prolog (a language designed for writing expert systems).
One additional design issue, unrelated to the language employed, is relevant
when discussing simulator power: whether a simulator can work with whole portfo-
lios as well as with individual tradables. Many products are not designed to perform
simulations and optimizations on whole portfolios at once, although sometimes add-
ons are available that make it possible to generate portfolio performance analyses
after the fact. On the other hand, an appropriately designed simulator can make mul-
tiple-account or portfolio simulations and system optimizations straightforward.

Trading simulators vary in their reliability and trustworthiness. No complex soft-
ware, and that includes trading simulation software, is completely bug-free. This
is true even for reputable vendors with great products. Other problems pertain to
the assumptions made regarding ambiguous situations in which any of several
orders could be executed in any of several sequences during a bar. Some of these
items, e.g., the so-called bouncing tick (Ruggiero, 1998), can make it seem like the
best system ever had been discovered when, in fact, it could bankrupt any trader.
It seems better that a simulator makes worst-case assumptions in ambiguous situ-
ations: this way, when actual trading begins, there is greater likelihood of having

a pleasant, rather than an unpleasant, surprise. All of this boils down to the fact
that when choosing a simulator, select one that has been carefully debugged, that
has a proven track record of reliability, and in which the assumptions and handling
of ambiguous situations are explicitly stated. In addition, learn the simulator™s
quirks and how to work around them.

If you are serious about developing sophisticated trading systems, need to work
with large portfolios, or wish to perform tests using individual contracts or
options, then buckle down, climb the learning curve, and go for an advanced sim-
ulator that employs a generic programming language such as the C++ or Object
Pascal. Such a simulator will have an open architecture that provides access to an
incredible selection of add-ons and libraries: technical analysis libraries, such as
those from PM Labs (609-261-7357) and Scientific Consultant Services (516-696-
3333); and general numerical algorithm libraries, such as Numerical Recipes
(800.872-7423), Numerical Algorithms Group (NAG) (44-1865.511.245), and
International Mathematics and Statistics Library (IMSL), which cover statistics,
linear algebra, spectral analysis, differential equations, and other mathematics.
Even neural network and genetic algorithm libraries are readily available.
Advanced simulators that employ generic programming languages also open up a
world of third-party components and graphical controls which cover everything
from sophisticated charting and data display to advanced database management,
and which are compatible with Borland™s C++ Builder and Delphi, as well as
with Microsoft™s Visual Basic and Visual C+ +.
If your needs are somewhat less stringent, choose a complete, integrated solu-
tion Make sure the simulation language permits procedures residing in DLLs to be
called when necessary. Be wary of products that are primarily charting tools with
limited programming capabilities if your intention is to develop, back-test, and trade
mechanical systems that go significantly beyond traditional or “canned” indicators.

We personally prefer simulators built using modern, object-oriented programming
practices. One reason for our choice is that an object-oriented simulator makes it
easy to create as many simulation instances or simulated accounts as might be
desired. This is especially useful when simulating the behavior of a trading system
on an entire portfolio of tradables (as is done in most tests in this book), rather than
on a single instrument. An object-oriented simulator also comes in handy when
building adaptive, self-optimizing systems where it is sometimes necessary to
implement internal simulations. In addition, such software makes the construction
of merasysrems (systems that trade in or out of the equity curves of other systems)
a simple matter. Asset allocation models, for instance, may be treated as metasys-
terns that dynamically allocate capital to individual trading systems or accounts. A
good object-oriented simulator can generate the portfolio equity curves and other
information needed to create and back-test asset allocation models operating on
top of multiple trading systems. For these reasons, and such others as familiarity,
most tests carried out in this book have been performed using the C-Trader toolk-
it. Do not be alarmed. It is not necessary to have any expertise in C+ + or mod-
em software practices to benefit from this book. The logic of every system or
system element examined will be explained in great detail in the text.

Optimizers and Optimization

I t would be nice to develop trading systems without giving a thought to opti-
mization. Realistically, however, the development of a profitable trading strategy
is a trial-and-error activity in which some form of optimization always plays a
role. There is always an optimizer around somewhere-if not visible on the table,
then lurking in the shadows.
An @mizer is simply an entity or algorithm that attempts to find the best
possible solution to a problem; optimization is the search process by which that
solution is discovered. An optimizer may be a self-contained software component,
perhaps implemented as a C++ class, Delphi object, or ActiveX control.
Powerful, sophisticated optimizers often take the form of software components
designed to be integrated into user-written programs. Less sophisticated opti-
mizers, such as those found in high-end simulation and charting packages, are usu-
ally simple algorithms implemented with a few lines of programming code. Since
any entity or algorithm that performs optimization is an optimizer, optimizers need
not be associated with computers or machines at all; an optimizer may be a per-
son engaged in problem-solving activities. The human brain is one of the most
powerful heuristic optimizers on earth!

Optimizers exist to find the best possible solution to a problem. What is meant by
the best possible solution to a problem? Before attempting to define that phrase,
let us first consider what constitutes a solution. In trading, a solution is a particu-
lar set of trading rules and perhaps system parameters,
All trading systems have at least two mles (an entry rule and an exit rule), and
most have one or more parameters. Rules express the logic of the trading system,
and generally appear as “if-then” clauses in whatever language the trading system has
been written. Parameters determine the behavior of the logic expressed in the rules;
they can include lengths of moving averages, connection weights in neural networks,
thresholds used in comparisons, values that determine placements for stops and prof-
it targets, and other similar items. The simple moving-average crossover system,
used in the previous chapter to illustrate various trading simulators, had two rules:
one for the buy order and one for the sell order. It also had a single parameter, the
length of the moving average. Rules and parameters completely define a trading sys-
tem and determine its performance. To obtain the best performance from a trading
system, parameters may need to be adjusted and rules juggled.
There is no doubt that some rule and parameter combinations define systems
that trade well, just as others specify systems that trade poorly; i.e., solutions dif-
fer in their quality. The goodness of a solution or trading model, in terms of how
well it performs when measured against some. standard, is often calledjfitness. The
converse of fitness, the inadequacy of a solution, is frequently referred to as coot.
In practice, fitness is evaluated by a@ness function, a block of programming
code that calculates a single number that reflects the relative desirability of any
solution. A fitness function can be written to appraise fitness howsoever the trader
desires. For example, fitness might be interpreted as net profit penalized for exces-
sive drawdown. A costfuncrion works in exactly the same way, but higher numbers
signify worse solutions. The sum of the squared errors, commonly computed when
working with linear regression or neural network models, is a cost function.
The best possible solution to a problem can now be defined: It is that partic-
ular solution that has the greatest fitness or the least cost. Optimizers endeavor to
find the best possible solution to a problem by maximizing fitness, as measured by
a titness function, or minimizing cost, as computed by a cost function.
The best possible solution to a problem may be discovered in any number of
ways. Sometimes problems can be solved by simple trial-and-error, especially when
guided by human insight into the problem being worked. Alternatively, sophisticated
procedures and algorithms may be necessary. For example, simulating the process of
evolution (as genetic optimizers do) is a very powerful way to discover or evolve
high-quality solutions to complex problems. In some cases, the best problem solver
is an analytic (calculus-based) procedure, such as a conjugate gradient. Analytic opti-
mization is an efficient approach for problems with smooth (differentiable) fitness
surfaces, such as those encountered in training neural networks, developing multiple
linear regression models, or computing simple-structure factor rotations.

Optimizers are wonderful tools that can be used in a myriad of ways. They help
shape the aircraft we fly, design the cars we drive, and even select delivery routes
CHMTER 3 Optimizers and Optimization

for our mail. Traders sometimes use optimizers to discover rule combinations that
trade profitably. In Part II, we will demonstrate how a genetic optimizer can evolve
profitable rule-based entry models. More commonly, traders call upon optimizers
to determine the most appropriate values for system parameters; almost any kind
of optimizer, except perhaps an analytic optimizer, may be employed for this pur-
pose. Various kinds of optimizers, including powerful genetic algorithms, are
effective for training or evolving neural or fuzzy logic networks. Asset allocation
problems yield to appropriate optimization strategies. Sometimes it seems as if the
only limit on how optimizers may be employed is the user™s imagination, and
therein lies a danger: It is easy to be seduced into “optimizer abuse” by the great
and alluring power of this tool. The correct and incorrect applications of opti-
mizers are discussed later in this chapter.

There are many kinds of optimizers, each with its own special strengths and weak
nesses, advantages and disadvantages. Optimizers can be classified along such
dimensions as human versus machine, complex versus simple, special purpose
versus general purpose, and analytic versus stochastic. All optimizers-regardless
of kind, efficiency, or reliability-execute a search for the best of many potential
solutions to a formally specified problem.

lmpllcit Optimizers
A mouse cannot be used to click on a button that says “optimize.” There is no spe-
cial command to enter. In fact, there is no special software or even machine in
sight. Does this mean there is no optimizer? No. Even when there is no optimizer
apparent, and it seems as though no optimization is going on, there is. It is known
as implicit optimization and works as follows: The trader tests a set of rules based
upon some ideas regarding the market. Performance of the system is poor, and so
the trader reworks the ideas, modifies the system™s rules, and runs another simu-
lation Better performance is observed. The trader repeats this process a few
times, each time making changes based on what has been learned along the way.
Eventually, the trader builds a system worthy of being traded with real money.
Was this system an optimized one? Since no parameters were ever explicitly
adjusted and no rules were ever rearranged by the software, it appears as if the
trader has succeeded in creating an unoptimized system. However, more than one
solution from a set of many possible solutions was tested and the best solution was
selected for use in trading or further study. This means that the system was opti-
mized after all! Any form of problem solving in which more than one solution is
examined and the best is chosen constitutes de facto optimization. The trader has
a powerful brain that employed mental problem-solving algorithms, e.g., heuris-
tically guided trial-and-error ones, which are exceptionally potent optimizers.

This means that optimization is always present: optimizers are always at work.
There is no escape!

Brute Force Optimizers
A brute force optimizer searches for the best possible solution by systematically
testing all potential solutions, i.e., all definable combinations of rules, parameters,
or both. Because every possible combination must be tested, brute force opti-
mization can be very slow. Lack of speed becomes a serious issue as the number
of combinations to be examined grows. Consequently, brute force optimization is
subject to the law of “combinatorial explosion.” Just how slow is brute force opti-
mization? Consider a case where there are four parameters to optimize and where
each parameter can take on any of 50 values. Brute force optimization would
require that 504 (about 6 million) tests or simulations be conducted before the
optimal parameter set could be determined: if one simulation was executed every
1.62 seconds (typical for TradeStation), the optimization process would take about
4 months to complete. This approach is not very practical, especially when many
systems need to be tested and optimized, when there are many parameters, when
the parameters can take on many values, or when you have a life. Nevertheless,
brute force optimization is useful and effective. If properly done, it will always
find the best possible solution. Brute force is a good choice for small problems
where combinatorial explosion is not an issue and solutions can be found in min-
utes, rather than days or years.
Only a small amount of programming code is needed to implement brute
force optimization. Simple loop constructs are commonly employed. Parameters
to be optimized are stepped from a start value to a stop value by some increment
using a For loop (C, C+ +, Basic, Pascal/Delphi) or a Do loop (FORTRAN). A
brute force optimizer for two parameters, when coded in a modem dialect of
Basic, might appear as follows:
Because brute force optimizers are conceptually simple and easy to program,
they are often built into the more advanced software packages that arc available
for traders.
As a practical illustration of bmte force optimization, TradeStation was used
to optimize the moving averages in a dual moving-average crossover system.
Optimization was for net profit, the only trading system characteristic that Trade-
Station can optimize without the aid of add-on products, The Easy Language code
for the dual moving-average trading model appears below:

The system was optimized by stepping the length of the first moving average
(LenA) from 2 to 10 in increments of 2. The length of the second moving average
(LenB) was advanced from 2 to 50 with the same increments. Increments were set
greater than 1 so that fewer than 200 combinations would need to be tested
(TradeStation can only save data on a maximum of 200 optimization runs). Since
not all possible combinations of values for the two parameters were explored, the
optimization was less thorough than it could have been; the best solution may have
been missed in the search. Notwithstanding, the optimization required 125 tests,
which took 3 minutes and 24 seconds to complete on 5 years of historical, end-of-
day data, using an Intel 486 machine running at 66 megahertz. The results gener-
ated by the optimization were loaded into an Excel spreadsheet and sorted for net
profit. Table 3-l presents various performance measures for the top 25 solutions.
In the table, LENA represents the period of the shorter moving average,
LENB the period of the longer moving average, NetPrft the total net profit,
LtNerPlft the net profit for long positions, S:NefPrji the net profit for short posi-
tions, PFact the profit factor, ROA the total (unannualized) return-on-account,
MaxDD the maximum drawdown, #Trds the total number of trades taken, and
%Prji the percentage of profitable trades.
Since optimization is a problem-solving search procedure, it frequently
results in surprising discoveries. The optimization performed on the dual moving-
average crossover system was no exception to the rule. Conventional trading wis-
dom says that “the trend is your friend.” However, having a second moving average
that is faster than the first, the most profitable solutions in Table 3. I trade against
the trend. These profitable countertrend solutions might not have been discovered
without the search performed by the optimization procedure.

Successful user-guided optimization calls for skill, domain knowledge, or
both, on the part of the person guiding the optimization process. Given adequate
skill and experience, not to mention a tractable problem, user-guided optimization
can be extremely efficient and dramatically faster than brute force methods. ˜Ibe
speed and efficiency derive from the addition of intelligence to the search process:
Zones with a high probability of paying off can be recognized and carefully exam-
ined, while time-consuming investigations of regions unlikely to yield good
results can be avoided.
User-guided optimization is most appropriate when ballpark results have
already been established by other means, when the problem is familiar or well
understood, or when only a small number of parameters need to be manipulated.
As a means of “polishing” an existing solution, user guided-optimization is an
excellent choice. It is also useful for studying model sensitivity to changes in rules
or parameter values.

Genetic Optimizers
Imagine something powerful enough to solve all the problems inherent in the
creation of a human being. That something surely represents the ultimate in
problem solving and optimization. What is it? It is the familiar process of evo-

<< . .

. 4
( : 30)

. . >>