\documentclass[11pt,twoside]{article}
\usepackage{color}
\usepackage{calc}
\usepackage{hyperref}
\usepackage{listings}
\lstset{numbers=left, numberstyle=\tiny, stepnumber=1, numbersep=5pt}
\lstset{% general command to set parameter(s)
basicstyle=\color{red}\scriptsize,
language=perl,
showstringspaces=false,
firstnumber=auto
}
\hypersetup{colorlinks=true, linkcolor=blue, filecolor=blue, pagecolor=blue, urlcolor=blue}
% Text styles
% Outline numbering
\setcounter{secnumdepth}{2}
\renewcommand\thesection{\arabic{section}}
\renewcommand\thesubsection{\arabic{section}.\arabic{subsection}}
% Pages styles (master pages)
\makeatletter
\newcommand\ps@Standard{%
\renewcommand\@oddhead{}%
\renewcommand\@evenhead{}%
\renewcommand\@oddfoot{}%
\renewcommand\@evenfoot{}%
\setlength\paperwidth{8.5in}\setlength\paperheight{11in}\setlength\voffset{-1in}\setlength\hoffset{-1in}\setlength\topmargin{1in}\setlength\headheight{12pt}\setlength\headsep{0cm}\setlength\footskip{12pt+0cm}\setlength\textheight{11in-1in-1in-0cm-12pt-0cm-12pt}\setlength\oddsidemargin{1.25in}\setlength\textwidth{8.5in-1.25in-1.25in}
\renewcommand\thepage{\arabic{page}}
\setlength{\skip\footins}{0.0398in}\renewcommand\footnoterule{\vspace*{-0.0071in}\noindent\textcolor{black}{\rule{0.25\columnwidth}{0.0071in}}\vspace*{0.0398in}}
}
\makeatother
\pagestyle{Standard}
\author{Thomas Weigert, {\tt weigert@mst.edu}}
\title{Writing an Indicator Cookbook}
\date{Last updated: May 2008}
% footnotes configuration
\makeatletter
\renewcommand\thefootnote{\arabic{footnote}}
\makeatother
\title{Writing an Indicator Cookbook}
\begin{document}
%\clearpage\pagestyle{Standard}
\maketitle

\section{Introduction}
This note attempts to summarize lessons learned writing GT indicators,
in the hope that this will be useful to other GT developers.\footnote{The
general techniques discussed here apply equally to the writing of signals,
albeit the name of some of the key functions changes. For example, the main
function to be written for a signal is \lstinline!detect!, which takes the
place of \lstinline!calculate!.}
I shall use the Bollinger Band indicator as a starting point and
annotate its implementation. Subsequent sections will illustrate more
advanced aspects of writing indicators.

With respect to terminology, an indicator defines a time series. In general,
a time series is a sequence of data values, ordered linearly by time. The
prices of a market are also a time series (and also an indicator, see \lstinline!I:Prices!). An indicator is constructed by some or all of the following:
\begin{itemize}
\item one or more time series
\item an application of a transformation to a time series
\item the sequential application of a computation on the individual
values of one or more time series.
\end{itemize}


In the following, code fragments are typeset in red courier font.
Throughout the examples, \lstinline!$self! refers to an
indicator object. Numbered code lines are from the code for the
Bollinger Band indicator; unnumbered code lines are other examples.

\section{Header}
The first section sets up the module and loads the necessary
dependencies.

\subsection{Package definition and object initialization}
Define a package for this indicator. The following use clauses are
standard for all indicators. Then define this package to be an instance
of the indicator object.

\begin{lstlisting}[name=example]
package GT::Indicators::BOL;

use strict;
use vars qw(@ISA @NAMES @DEFAULT_ARGS);
use GT::Indicators;
@ISA = qw(GT::Indicators);
\end{lstlisting}

\subsection{Included packages}
Load all packages this indicator depends on. For example, Bollinger
Bands are moving averages that envelope a securities price. It consists
of three series: A simple moving average of the security, and two
series plotted \textit{n} standard deviation levels above and below the
moving average. Thus, in this particular case, we need three other
indicators: the I:SMA, I:StandardDeviation, and I:Prices.

\begin{lstlisting}[name=example]
use GT::Indicators::SMA;
use GT::Indicators::StandardDeviation;
use GT::Prices;
\end{lstlisting}

\subsection{Input parameters}
The default argument statement defines the default values for the input
parameters of the indicator. These are either constant values or they
depend on the current value of another series. In this example, the
first two parameters are by default given the constant values 20 and 2,
respectively. The third parameter is the result of evaluating the
indicator \lstinline!{I:Prices CLOSE}! at the current period,
yielding the current close of the prices array. 
\begin{lstlisting}[name=example]
@DEFAULT_ARGS = (20, 2, "{I:Prices CLOSE}");
\end{lstlisting}
The arguments of the indicator are accessed via the methods, where
\lstinline!$n! is the number of the argument (starting at 1),
\lstinline!$calc! is a calculator, and \lstinline!$i!
is the current period.
\begin{lstlisting}[numbers=none]
$self->{args}->get_arg_constant($n)
$self->{args}->get_arg_names($n)
$self->{args}->get_arg_values($calc, $i, $n)
\end{lstlisting}

The first form requires that the argument is a constant, which can be
tested by
\begin{lstlisting}[numbers=none]
$self->{args}->get_arg_constant($n).
\end{lstlisting}
The second form will obtain names of the corresponding argument (for
constant arguments, the name is the same as its
value).\footnote{Several indicators use
\lstinline!get_arg_names! in a context where the argument is
not guaranteed to be constant, and thus will fail when a non-constant
parameter is given (e.g., the name of a series).} The final form
obtains both constant and non-constant values for a given period (of
course, constants are the same for all periods).

Most indicators as currently defined perform no type checking on their
parameters, resulting in fatal errors when parameters of the wrong type
are passed. Care must be taken to pass constant parameters when such are
expected, and time series as parameters, where those are required.\footnote{Preoper
run time checking of parameter types is advisable when writing a new
indicator.}

\section[Output values]{\label{bkm:Ref192524690}Output values}
Indicators will produce one or more output series. In other words, for
each period, and indicator will output one or more values. Output
values are defined in the names clause:

\begin{lstlisting}[name=example]
@NAMES = ("BOL[#1,#3]","BOLSup[#1,#2,#3]","BOLInf[#1,#2,#3]");
\end{lstlisting}
In this instance, we define three output series for Bollinger Bands: the
moving average, and the upper and lower bands. These values can be
referred to by the names given in the above clause, where the arguments
(hashed numbers in brackets) are replaced by the corresponding input
parameters of the indicator. The symbol \lstinline!#*! is
replaced by all input parameters of the indicator.

The name of an indicator is the name of the first output series. Therefore,
\lstinline!{I:BOL 12 2}! and \lstinline!{I:BOL 12 3}! have the same name
\lstinline!BOL[12, {I:Prices CLOSE]]!. These two series cannot be distinguished
when they are both used at the same time. Care should be taken to name
the output series wisely so that there are no conflicts between indicators.
The name of an output series can be either used literally as a string, or it
can be obtained by the \lstinline!get_name! method:
\begin{lstlisting}[numbers=none]
$self->get_name
$self->get_name($n)
\end{lstlisting}
where \lstinline!$n! refers to the position of the output series (starting at \lstinline!0!).


The values of the output series are set and read via a calculator
\lstinline!$calc!, where \lstinline!$name! is the
name of the output series and \lstinline!$i! is the period:
\begin{lstlisting}[numbers=none]
$calc->indicators->get($name, $i)
$calc->indicators->set($name, $i, $value)
\end{lstlisting}


\section{Initialization}
If an indicator requires intermediate series to compute its value or
requires data from past periods, these are set up in the initialization
method. This method is passed an indicator object as the single
parameter:

\begin{lstlisting}[name=example]
sub initialize {
    my ($self) = @_;
\end{lstlisting}

\subsection[Intermediate series]{Intermediate series}
Many indicators depend in their computation on other series. For
example, Bollinger bands need the simple moving average of the price of
the security for each period, as well as the standard deviation of the
price of the security for each period. Both of these intermediate
values form a series. Each intermediate series must be created in the
initialization method and be assigned to an attribute of the indicator.
A series is created by calling the new method on its class and passing
the appropriate arguments, or by evaluating the textual representation
of the indicator defining the series. These intermediate series may
rely on output values or on temporary data, see Section 7.2. For
Bollinger Band we define the I:SMA and I:StandardDeviation as
intermediate series, passing both the first (period) and third (data
array the indicator is applied to, typically I:Prices) arguments. If
the indicator was not given any parameters upon creation, the default
values are used.

\begin{lstlisting}[name=example]
    $self->{'sma'} = GT::Indicators::SMA->new([
       $self->{'args'}->get_arg_names(1),$self->{'args'}->get_arg_names(3)]);
    $self->{'sd'} = GT::Indicators::StandardDeviation->new([
       $self->{'args'}->get_arg_names(1),$self->{'args'}->get_arg_names(3)]);
\end{lstlisting}
Note that when such an intermediate series uses other series as its arguments,
these cannot be defined by their constructor functions but must be given
in their textual representation. For example, the following doubly smoothes
the SMA above:
\begin{lstlisting}[numbers=none]
    $self->{'sma'} = GT::Indicators::SMA->new([
       $self->{'args'}->get_arg_names(1), 
       '{I:SMA '.$self->{'args'}->get_arg_names(1).' '
           .$self->{'args'}->get_arg_names(3).'}']);
\end{lstlisting}
An intermediate series can also conveniently be constructed using the \lstinline!GT::Eval::create_standard_! \lstinline!object! method:
\begin{lstlisting}[numbers=none]
$self->{'sma2'} = GT::Eval::create_standard_object("I:SMA", "12 {I:Prices CLOSE}");
\end{lstlisting}


During the computation of the indicator, the intermediate series is
either computed via the dependency mechanism (see Section 4.2) or by
explicitly computing the series via:

\begin{lstlisting}[numbers=none]
$self->{'sma'}->calculate($calc, $i)
$self->{'sma'}->calculate_interval($calc, $i, $j)
\end{lstlisting}
where \lstinline!$calc! is a calculator, and
\lstinline!$i! and \lstinline!$j! are time periods.
The values of these series are obtained via the standard get method,
e.g., the \textit{i}th value of the SMA is obtained via
\begin{lstlisting}[numbers=none]
$calc->indicators->set($self->{'sma'}->get_name, $i)
\end{lstlisting}

\subsection[Dependencies]{\label{bkm:Ref192502803}Dependencies}
Many indicators depend on past data to calculate their current value,
either on past price information, or on the previous values of the
indicator or on the previous value of intermediate series. A key
feature of GT is that the computation of those past values can be
largely driven automatically through a dependency mechanism. We can
declare the current value of an indicator to be dependent on the
previous values of its parameters, or of other series, or of the price
information it is operating on. Such dependencies are declared for
\textit{n} periods of data; when updating dependencies those \textit{n}
values will be ensured to be available. To satisfy dependencies may in
turn require additional data, the computing the dependencies may in
turn depend on other values. The dependency mechanism propagates
automatically until all dependencies are satisfied. 

Determining the correct dependencies is important to be able to compute
the indicator both correctly and efficiently. If too little data is
available, an indicator may not be able to be computed, at best, or may
give incorrect results, at worst. If too much data is required, less
history of an indicator can be computed.

When the dependencies are known at the time the indicator is created,
the dependencies are defined in the initialization section (volatile
dependencies see Section 7.3, allow dependencies to be computed
dynamically during the computation of the values of the indicator). The
following methods can be used to define dependencies:
\begin{lstlisting}[numbers=none]
$self->add_indicator_dependency($indic, $p)
$self->add_arg_dependency($n, $p)
$self->add_prices_dependency($p)
\end{lstlisting}

where \lstinline!$indic! is an indicator,
\lstinline!$n! refers to the \textit{n}-th parameter of the
indicator (counting from 1), and \lstinline!$p! is the number
of periods of data this value depends on. The first form states that
the current value of the indicator depends on \lstinline!$p!
periods of data of indicator \lstinline!$indic!. The second
form states that the indicator depends on \lstinline!$p!
periods of data referenced by parameter \lstinline!$n!. The
third form states that the indicator depends on \lstinline!$p!
periods of data of the input series (this form of dependency is only
needed when the indicator depends on more data periods than is
established by the dependency mechanism).\footnote{While it can be
found in a number of indicators, this dependency is rarely (if ever)
needed.}

For the Bollinger Bands, each value depends on the current value of the
moving average and the standard deviation. However, dependencies
require at least one day of data, and thus the below declare the
current value to be dependent of 1 day of data of the moving average
and the standard deviation. Note that each of these in turn require
data to be computed, but that dependency is declared as part of the
definition of these indicators, and is automatically accounted for by
the dependency mechanism.

\begin{lstlisting}[name=example]
   $self->add_indicator_dependency($self->{'sma'}, 1);
   $self->add_indicator_dependency($self->{'sd'}, 1);
\end{lstlisting}
The Bollinger Band indicator in addition establishes a dependency on the
period passed as the first parameter, assuming that parameter is
constant. However, this declaration is technically not necessary, as
this dependency is already established by the dependencies of the
intermediate series.

\begin{lstlisting}[name=example]
    if ($self->{'args'}->is_constant(1)) {
        $self->add_prices_dependency($self->{'args'}->get_arg_constant(1));
    }

}
\end{lstlisting}
\section{Calculating the value of the indicator}
The GT framework provides two means of calculating the value of an
indicator: we can either compute a single value of the indicator, given
its dependencies, or we can compute the value of the indicator
throughout a given interval. One or the other of these methods must be
defined,\footnote{Note that if the \lstinline!calculate!
method is omitted, the indicator may fail if this method is indirectly
invoked (e.g., when running anashell.pl), as this method is not defined
in the superclass. It is safer to omit the
\lstinline!calculate_interval! method.} albeit often both
methods are given. Typically, calculating the value of the indicator
over the full interval required will be faster, potentially much faster
as calculating the value of the indicator one period at a time may
often repeat much of the computation needlessly.


\subsection{Calculating a single value of the indicator}
The current value of the indicator is computed by the
\lstinline!calculate! method, which takes as arguments a
calculator and the current period. This method typically follows the
following steps:

\begin{lstlisting}[name=example]
sub calculate {
    my ($self, $calc, $i) = @_;
\end{lstlisting}

\paragraph{Define temporary variables.}

Several temporaries are defined for convenience: The distance of the
upper and lower bands from the moving average, as determined by the
second parameter, the names of the intermediate series used, and the
names of the output values.

\begin{lstlisting}[name=example]
    my $nsd = $self->{'args'}->get_arg_values($calc, $i, 2);
    my $sma_name = $self->{'sma'}->get_name;
    my $sd_name = $self->{'sd'}->get_name;
    my $bol_name = $self->get_name(0);
    my $bolsup_name = $self->get_name(1);
    my $bolinf_name = $self->get_name(2);

\end{lstlisting}

\paragraph{Return if the required values of the indicator are already available.} These may have been computed earlier.

\begin{lstlisting}[name=example]
    return if ($calc->indicators->is_available($bol_name, $i) &&
               $calc->indicators->is_available($bolsup_name, $i) &&
               $calc->indicators->is_available($bolinf_name, $i));
\end{lstlisting}

\paragraph{Return if the dependencies required to compute the value of this
indicator are not satisfied.}

This check will attempt to compute the
dependencies but fail when the dependencies cannot be computed. This
triggers the dependency mechanism.

\begin{lstlisting}[name=example]
    return if (! $self->check_dependencies($calc, $i));

\end{lstlisting}

\paragraph{Compute the current value of the indicator.}

For the Bollinger Band indicator, we first obtain the values of the
moving average and the standard deviation. The upper band is obtained
by adding the appropriate factor of the standard deviation to the
moving average; the lower band is calculated similarly.

\begin{lstlisting}[name=example]
    my $sma_value = $calc->indicators->get($sma_name, $i);
    my $sd_value = $calc->indicators->get($sd_name, $i);

    my $bolsup_value = $sma_value + ($nsd * $sd_value);
    my $bolinf_value = $sma_value - ($nsd * $sd_value);

\end{lstlisting}
Note that computing the current value of the indicator may in fact
require iterating over past periods.

\paragraph{Update the output values for the current period.}

For the Bollinger Band store the moving average value into the first
output series, the upper band value into the second output series, and
the lower band value into the last output series.

\begin{lstlisting}[name=example]
    $calc->indicators->set($bol_name, $i, $sma_value);
    $calc->indicators->set($bolsup_name, $i, $bolsup_value);
    $calc->indicators->set($bolinf_name, $i, $bolinf_value);
}

\end{lstlisting}

\subsection[Calculating a the indicator throughout an
interval]{\label{bkm:Ref192603010}Calculating a the indicator
throughout an interval}
The \lstinline!calculate_interval! method computes the value of
the indicator over a given interval. It is passed a calculator as well
as the beginning and end of the interval of interest. This method can
be obtained systematically from the \lstinline!calculate!
method by the following steps:

\begin{enumerate}
\item Change all occurrences of \lstinline!get_arg_values! to the
corresponding \lstinline!get_arg_constant!
\item Change all occurrences of \lstinline!check_dependencies! to
the corresponding \lstinline!check_dependencies_interval!
\item Change all occurrences of \lstinline!is_available! to the
corresponding \lstinline!is_available_interval!
\item Compute the current value of the indicator within a loop from the
beginning of the interval to the end of the interval.
\end{enumerate}

\begin{lstlisting}[name=example]
sub calculate_interval {
    my ($self, $calc, $first, $last) = @_;
    my $nsd = $self->{'args'}->get_arg_constant(2);
    my $sma_name = $self->{'sma'}->get_name;
    my $sd_name = $self->{'sd'}->get_name;
    my $bol_name = $self->get_name(0);
    my $bolsup_name = $self->get_name(1);
    my $bolinf_name = $self->get_name(2);

    return if ($calc->indicators->is_available_interval($bol_name, $first, $last) &&
               $calc->indicators->is_available_interval($bolsup_name, $first, $last) &&
               $calc->indicators->is_available_interval($bolinf_name, $first, $last));
    return if (! $self->check_dependencies_interval($calc, $first, $last));

    for (my $i=$first;$i<=$last;$i++) {
      my $sma_value = $calc->indicators->get($sma_name, $i);
      my $sd_value = $calc->indicators->get($sd_name, $i);

      my $bolsup_value = $sma_value + ($nsd * $sd_value);
      my $bolinf_value = $sma_value - ($nsd * $sd_value);

      $calc->indicators->set($bol_name, $i, $sma_value);
      $calc->indicators->set($bolsup_name, $i, $bolsup_value);
      $calc->indicators->set($bolinf_name, $i, $bolinf_value);
    }
}
\end{lstlisting}
If this method is not provided, it is inherited from the indicator object and
falls back on \lstinline!calculate!. Typically, a provided \lstinline!calculate_interval! method would not invoke calculate.

\section{End of file}
As common practice in Perl modules, conclude the file with a successful
value.

\begin{lstlisting}[name=example]
1;
\end{lstlisting}

\section{Additional capabilities}
There are a number of additional tools provided by GT which are not
leveraged in the Bollinger Bands indicator illustrated above. These are
discussed below.

\subsection[Temporary series]{\label{bkm:Ref192502379}Temporary series}
In addition to storing results in output values, as discussed in Section
3, and indicator may also store data into temporary series that are not
visible outside of the indicator. To create a temporary series, assign
a I:Generic:Container indicator to an attribute of the indicator
object:
\begin{lstlisting}[numbers=none]
my $name = $self->get_name;
$self->{'temp'} = GT::Indicators::Generic::Container->new(["temp($name)"]);
\end{lstlisting}

Above creates a new temporary series with the name
\lstinline!temp($name)!, where \lstinline!$name! is the name of the current indicator. The reason for inserting \lstinline!$name! into the name of the indicator is to ensure its uniqueness. Often this will not matter, but if several instances of this indicator are used at the same time, collisions may occur (for example, when this indicator is used in the long and short signals of a system). This series is an indicator and thus values
can be read and written to this series as to any indicator:
\begin{lstlisting}[numbers=none]
$calc->indicators->get($self->{'temp'}->get_name, $i)
$calc->indicators->set($self->{'temp'}->get_name, $i, $value)
\end{lstlisting}

\subsection[Constructing intermediate series from other
series]{\label{bkm:Ref192502529}Constructing intermediate series from
other series}
An intermediate series may rely on another intermediate series, on a
temporary series, or on an output series. In this situation, when
defining an intermediate series, the dependent series are provided as
parameters.

For example, to define a standard moving average of the upper band of
the Bollinger Band indicator (within the computation of the Bollinger Band indicator) use:
\begin{lstlisting}[numbers=none]
$self->{'upper'} = GT::Indicators::SMA->new([$self->{'args'}->get_arg_names(1),
                           "{I:Generic:ByName " . $self->get_name(1) . "}" ]);
\end{lstlisting}
This constructs an intermediate SMA from the second output series of
the current indicator, with the period taken from the first parameter
of the current indicator and assigns it to an attribute of the
indicator object. The indicator \lstinline!I:Generic:ByName! references
another series by its name (i.e., the name of the first output series, 
see Section~\ref{bkm:Ref192524690}). Care must be taken that the correct
name is used.

Similarly one can construct a series that depends on a temporary series
or an intermediate series. For example, the simple moving average of the
temp indicator from Section 7.1 is defined as follows:
\begin{lstlisting}[numbers=none]
$self->{'sma1'} = GT::Indicators::SMA->new([ $self->{'args'}->get_arg_names(1),
                             "{I:Generic:ByName temp}" ]);
\end{lstlisting}
The further smoothing of the simple moving average of the upper Bollinger
Band (see above) can be defined by\footnote{This requires a correction 
to the I:Generic:ByName indicator available from the mailing list archives 
at http://www.geniustrader.org/lists/devel/msg02362.html.}
\begin{lstlisting}[numbers=none]
$self->{'sma2'} = GT::Indicators::SMA->new([ $self->{'args'}->get_arg_names(1),
                       "{I:Generic:ByName `" . $self->{'upper'}->get_name . "}" ]);
\end{lstlisting}
If the intermediate series has multiple outputs, the proper name must be used
(e.g., use \lstinline!get_name($n)! to construct a series based on the 
{\em n}th output value of the intermediate series.

\subsection[Volatile dependencies]{\label{bkm:Ref192505424}Volatile
dependencies}
It is also possible for indicator dependencies to dynamically change
during the computation of a series, either by the length of the
dependency being computed at each iteration, or by it depending on the
value of a series. Dynamically changing dependencies are referred to as
``volatile''. They are defined analogously to static dependencies using
the following methods, where \lstinline!$indic! is an
indicator, \lstinline!$n! refers to the \textit{n}-th
parameter of the indicator (counting from 1), and
\lstinline!$p! is the number of periods of data this value
depends on:
\begin{lstlisting}[numbers=none]
$self->add_volatile_indicator_dependency($indic, $p)
$self->add_volatile_arg_dependency($n, $p)
$self->add_volatile_prices_dependency($p)
\end{lstlisting}

Before defining volatile dependencies, all volatile dependencies from
the previous period must be removed through calling
\begin{lstlisting}[numbers=none]
$self->remove_volatile_dependencies()
\end{lstlisting}

Volatile dependencies are mostly useful only when indicators are
calculated one period at a time (i.e., in the
\lstinline!calculate! method).\footnote{Note that several
indicators add volatile indicators in the
\lstinline!calculate_interval! method. This will work only if
careful attention is paid to that the dependency period is correctly
obtained. In many such situations, the dependency period is established
correctly only when the corresponding parameter is both constant and
positive. Further, unless the dependencies are updated throughout the
loop, they reduce to static dependencies (in those situations, if
calculate is desired to support volatile dependencies, it is useful to
define the volatile dependencies also in \lstinline!calculate_interval!
to avoid duplicated dependency computation in calculate where static
dependencies defined).}

\section{Styles of calculating indicators}
The value of an indicator in the following three ways: (i) by obtaining
the value of an input data series, (ii) by applying an indicator to a
data series (either an input series or a temporary our output series,
or (iii) by performing some computation on the current or past values
of one or more available data series. These can be combined in
arbitrary ways.

The Bollinger Band indicator above used each of these: It obtains the
value of the input data series, applies two indicators (SMA,
StandardDeviation) to these values, and then performs a calculation on
the current value of these indicators. Other indicators require more
complicated scenarios: For example, an indicator may require smoothing
of the calculated value (as in the stochastic indicator I:STO, the
Fisher indicator I:FISH, or the Volume Oscillator I:VOSC). The
stochastic momentum indicator (I:SMI) first obtains values from an
input series and applies an indicator to these values, then performs
some calculation to produce a temporary series, then applies smoothing
to these temporary series, perform some computation on the results, and
apply a final smoothing. These more complicated calculations can be
constructed in the following manner: Consider the dependencies required
by each of the steps in the calculation and begin the calculation at
the earliest point in the chain of dependencies.

\begin{enumerate}
\item The current or previous value of an indicator can always be obtained
as described above.
\item If an indicator application is not the final step, then calculate the
value of that indicator starting from the earliest period it satisfies
a dependency for subsequent computations up to the current period.
\item If a computation on current or past values of one or more series is
not the final step, then calculate all subsequent values in a loop from
the earliest period the computation satisfies a dependency for
subsequent computations up to the current period.
\end{enumerate}

For example, the following is the \lstinline!calculate! method
for I:VOSC. The oscillator is calculated by first computing the value
of the volume and then smoothing that value with a period given by the
first parameter. The smoothing is performed after the computation of
the volume measure, and thus the indicator first computes sufficient
data values for the smoothing operator in the loop on lines 11-25.
After that the smoothing operator is applied (line 27).

\begin{lstlisting}[numbers=none]
sub calculate {
    my ($self, $calc, $i) = @_;
    my $vosc_name = $self->get_name(0);
    my $volume_name = $self->get_name(1);
    my $volume = 0;

    return if ($calc->indicators->is_available($vosc_name, $i));
    return if (! $self->check_dependencies($calc, $i));

    my $nb_days = $self->{'args'}->get_arg_values($calc, $i, 1);
    for (my $n = 0; $n < $nb_days; $n++) {

    next if $calc->indicators->is_available($volume_name, $i - $n);
    if ($calc->prices->at($i - $n)->[$CLOSE] > $calc->prices->at($i - $n)->[$OPEN]) {
       $volume = $calc->prices->at($i - $n)->[$VOLUME];
    }
    if ($calc->prices->at($i - $n)->[$CLOSE] < $calc->prices->at($i - $n)->[$OPEN]) {
       $volume = -$calc->prices->at($i - $n)->[$VOLUME];
    }
    if ($calc->prices->at($i - $n)->[$CLOSE] eq $calc->prices->at($i - $n)->[$OPEN]) {
       $volume = 0;
    }
    $calc->indicators->set($volume_name, $i - $n, $volume);

    }

    $self->{'sma'}->calculate($calc, $i);
    my $vosc_value = $calc->indicators->get($self->{'sma'}->get_name, $i);
    $calc->indicators->set($vosc_name, $i, $vosc_value);
}
\end{lstlisting}
The transformation to the \lstinline!calculate_interval! method
is similar to as described in Section 5.2, with the exception that the
bounds of any loop used in \lstinline!calculate! will have to
take the required data history in account. For an example of a more
complex indicator as well as for the transformation of the
\lstinline!calculate_interval! method see the Stochastic
Momentum Indicator I:SMI.

\section{Documentation}
Adequate documentation in pod format should be provided for each
indicator.

%\section{Observations and difficulties}
%The following contains a collection of observations I made in writing 
%indicators and difficulties that I encountered. I do not have explanations
%for all of these, so please take them with a grain of salt.



\end{document}
