NAME
Finance::Shares::Momentum - functions dealing with rates of change
SYNOPSIS
use Finance::Shares::Sample;
use Finance::Shares::Momentum;
my $s = new Finance::Shares::Sample(...);
my $id1 = $s->momentum(
graph => 'prices',
line => 'close',
period => 10,
strict => 0,
scaled => 1,
shown => 1,
style => {...}, # PostScript::Graph::Style
key => 'My Momentum Line',
);
my $id2 = $s->ratio(...);
my $id3 = $s->gradient(...);
my $id4 = $s->rising(
...
style => {...}, # PostScript::Graph::Style
key => 'Rising Trends',
weight => 50,
decay => 0.66,
ramp => 0,
cutoff => {...}, # PostScript::Graph::Style
gradient => {...}, # PostScript::Graph::Style
smallest => 10,
);
my $id5 = $s->falling(...);
my $id6 = $s->oversold(
...
gradient => {...}, # PostScript::Graph::Style
sd => 2.5,
);
my $id7 = $s->undersold(...);
DESCRIPTION
This package provides additional methods for Finance::Shares::Sample objects. Some functions analyse how another line changes over time and produce lines on the cycles graph. Others are pseudo-tests producing digital output on the tests graph, although they don't trigger signals (use the test test for that, see "Tests" in Finance::Shares::Models).
Once a line has been constructed it may be referred to by a text identifier returned by the function. The functions may also be referred to by their text names in a model specification (short or full version):
mom momentum
roc ratio (Rate of Change)
grad gradient
obv on_balance_volume
adx direction
rise rising
fall falling
over oversold
under undersold
ext extend
Common options
They all take the following parameters in hash key/value format. All of these keys are optional.
- graph
-
A string indicating the graph for display: one of prices, volumes, cycles or signals. (Default: 'prices')
- line
-
A string indicating the data/function to be analysed - normally the closing prices. (Default: 'close')
- period
-
The number of readings used in the analysis. The actual time spanned depends on how the sample was configured.
- strict
-
Where appropriate, setting this to 0 might produce a better looking line by including some (possibly dubious) guesses. Set as 1 to ensure the line is accurate and reliable. (Default: 1)
- scaled
-
Set this to 1 to make comparison easier. It ensures the values all lie within +/- 100. Particularly useful for
ratio
which normally produces values of +/-1. - shown
-
A flag controlling whether the function is graphed. 0 to not show it, 1 to add the line to the named
graph
. (Default: 1) - style
-
A hash ref holding settings suitable for the PostScript::Graph::Style object used when drawing the line. By default lines and points are plotted, with each line in a slightly different style. (Default: undef)
- key
-
If given this becomes the visual identifier, shown on the Chart key panel.
Pseudo-test options
In addition, the pseudo-tests rising
, falling
, oversold
and undersold
also recognize these keys.
- smallest
-
[
rising
andfalling
only.] This is the smallest daily change that will be considered. For example,$s->falling( line => 'close', period => 10, smallest => 5, );
This will only produce 'true' if the closing price was 5p or more lower than the day before, according to the 10 day smoothed gradient.
- sd
-
[
oversold
andundersold
only.] Short for standard deviation, this defines the point beyond which stock is deemed oversold or undersold. The following table gives some idea how standard deviation relates to the number of quotes within the normal area or in the under/oversold region.sd within above or below 3.00 99.74% 0.13% 2.58 99% 0.5% 2.33 98% 1% 2.06 96% 2% 2.00 95.46% 2.27% 1.65 90% 5% 1.29 80% 10% 1.15 75% 12.5% 1.00 68.26% 15.87% 0.85 60% 20% 0.68 50% 25%
- weight
-
How important the test should appear. Most tests implement this as the height of the results line.
- decay
-
If the condition is met over a continuous period, the results line can be made to decay. This factor is multiplied by the previous line value, so 0.95 would produce a slow decay while 0 signals only the first date in the period.
- ramp
-
An alternative method for conditioning the test line. This amount is added to the test value with each period.
- gradient
-
Determine whether, and how, the gradient line will be shown. It can be '0' for hide or '1' for show but the most useful is a PostScript::Graph::Style object or a hash ref holding style settings.
- cutoff
-
Determine whether, and how, the boundary line will be shown. It can be '0' for hide or '1' for show but the most useful is a PostScript::Graph::Style object or a hash ref holding style settings.
Example script
Sometimes it is useful to see how the parts fit within the whole. Here is a fairly minimal script that marks suitable buy points on a chart. Signals are triggered when the volume rises in an undersold period. Or more explicitly:
if
the sample has been undersold
(prices lower than 1 std dev)
in the last 5 days
and
the 10 day 'on balance volume'
is rising
then
a buy signal highlights the low price
The Sample needs a MySQL object to provide the quotes, so that must be constucted first. Both Chart and Model need the Sample in turn, and before a signal is used, the Model needs to know all about it. We are then in a position to build all the functions (all from this module as it happens). Finally the test produces the signals and the chart is saved as 'output.ps'.
#!/usr/bin/perl
use strict;
use warnings;
use Finance::Shares::MySQL;
use Finance::Shares::Sample;
use Finance::Shares::Momentum;
use Finance::Shares::Model;
use Finance::Shares::Chart;
my $sql = new Finance::Shares::MySQL(
user => 'test',
password => 'test',
database => 'test',
mode => 'offline',
);
my $sample = new Finance::Shares::Sample(
source => $sql,
symbol => 'AV.L',
start_date => '2003-01-01',
end_date => '2003-06-30',
);
my $chart = new Finance::Shares::Chart(
sample => $sample,
);
my $model = new Finance::Shares::Model;
$model->add_sample($sample);
$model->add_signal('buysig', 'mark_buy', undef, {
graph => 'prices',
line => 'low',
});
my $usold = $sample->undersold(
sd => 1,
shown => 0,
);
my $usold_ex = $sample->extend(
graph => 'tests',
line => $usold,
period => 5,
key => 'undersold (ext)',
weight => 75,
);
my $obv = $sample->on_balance_volume(
period => 10,
key => 'obv',
);
my $vup = $sample->rising(
graph => 'cycles',
line => $obv,
key => 'rising OBV',
weight => 50,
);
my $both = $model->test(
graph1 => 'tests',
line1 => $usold_ex,
graph2 => 'tests',
line2 => $vup,
test => 'and',
signals => ['buysig'],
shown => 1,
key => 'oversold & rising vol',
);
$chart->output('example');
Key strings were declared throughout to stop too much space being wasted by the Key panels. The weights have just been given to make the tests graph clearer. See the tests for examples of how to make the chart look better using PostScript::File, PostScript::Graph::Style and Finance::Shares::Chart options.
This test can be found in fs_model format in the distribution as models/momentum_ex. The following command will apply this model to all the stocks listed in the file stock/FTSE-retail.
fs_model -m models/momentum -s -c stock/FTSE-retail
The resulting PostScript file FTSE-retail.ps has a page showing how each stock fared under the test.
MOMENTUM METHODS
momentum
Movement is calculated by subtracting the value period
days/weeks/months ago.
ratio
This calculates the rate of change by dividing the current value with a correspnding one period
days/weeks/months previously.
The line centers around 1 normally, but can be made to center around zero by setting strict
to 0. scaled
should probably be used.
gradient
This is an attempt to provide a function which performs differentiation, smoothing out abberations as it goes.
A period
of 1 just produces the slope of the line to the next point. Larger values, however, take a wider spread of neighbours into account. E.g. a 10 day gradient will calculate each gradient from the weighted average of the differences from the previous 5 and subsiquent 5 days, where they exist.
on_balance_volume
This function produces a line on the cycles graph, showing how the volume varies. It presents a running total, adding the days volume if the price closed higher than the previous date or subtracting it if the price closed lower.
Being a specialized function, there are fewer options. See "DESCRIPTION" for explanation of the keys available:
shown scaled
style key
strict gradient
period
The direction of movement is more significant than the raw numbers. So it is usually scaled or passed to rising or falling.
direction
This is really three function in one. The lines are drawn on the cycles graph, indicating the direction prices are moving. Option keys include:
- direction
-
Standing for 'direction', this determines the type of line produced. (Default: 0)
+1 Upward movement 0 Average of up and down -1 Downward movement
- period
-
If 0, the direction line is unsmoothed. Otherwise a moving average of this period is used for smoothing. (Default: 0)
- average
-
This should be the name (short or long) of a moving average function. It should be one of the following. (Default: 'avg')
avg simple_average wgt weighted_average exp exponential_average
The following keys are also supported. See "DESCRIPTION" for details.
shown scaled
style key
PSEUDO-TEST METHODS
rising
A pseudo-test producing a true/false output on the tests graph depending on whether the gradient of the specified line is sufficiently positive.
falling
A pseudo-test producing a true/false output on the tests graph depending on whether the gradient of the specified line is sufficiently negative.
oversold
A pseudo-test producing a true/false output on the tests graph depending on whether the gradient rises above a certain level. The level depends on the data sampled, so it is controlled using sd
.
undersold
A pseudo-test producing a true/false output on the tests graph depending on whether the gradient falls below a certain level. The level depends on the data sampled, so it is controlled using sd
.
extend
This produces a logic line on the tests graph like the other pseudo-tests, but unlike the others it doesn't really test anything. It provides a fixed period following some event on the line passed to it. It is level triggered, with the period beginning when the line moves above the value of smallest
.
Example
BUGS
The complexity of this software has seriously outstripped the testing, so there will be unfortunate interactions. Please do let me know when you suspect something isn't right. A short script working from a CSV file demonstrating the problem would be very helpful.
AUTHOR
Chris Willmot, chris@willmot.org.uk
SEE ALSO
Finances::Shares::Sample, Finance::Shares::Chart and Finances::Shares::Model.
There is also an introduction, Finance::Shares::Overview and a tutorial beginning with Finance::Shares::Lesson1.
2 POD Errors
The following errors were encountered while parsing the POD:
- Around line 223:
You forgot a '=back' before '=head2'
- Around line 327:
=back without =over