NAME
Finance::Shares::Sample - Price data on a single share
SYNOPSIS
use Finance::Shares::Simple;
Simplest
Obtain a series of stock quotes from a CSV file.
my $ss = new Finance::Shares::Sample(
source => 'gsk,csv',
symbol => 'GSK.L',
);
Typical
Get a series of stock quotes and graph them using specific settings. Calculate some trend lines from the Finance::Shares::Sample data and superimpose them on the graph.
my $s = new Finance::Shares::Sample(
source => {
user => 'guest',
password => 'a94Hq',
database => 'London',
},
dates_by => 'weeks',
symbol => 'GSK.L',
start_date => '2001-09-01',
end_date => '2002-08-31'
);
# construct data for lines, and then...
$s->add_line( 'prices', 'one', $line1, 'Support' );
$s->add_line( 'volumes', 'two', 'Average' );
$s->add_line( 'cycles', 'three', $line3, 'RSI' );
DESCRIPTION
This module is principally a data structure holding stock quotes. Price and volume data are held for a particular share over a specified period. This data can be read from a CSV file or from an array, but more usually it is fetched from Finance::Shares::MySQL which in turn handles getting the data from the internet.
The Data
This object is used as a data structure common to a number of modules. Therefore, unusually, most of the internal data is made available directly. Those documented here can be relied upon to exist as soon as the object has been constructed.
open, high, low, close, volume
These hashes are indexed by date and return the appropriate value for that date. The volume hash is not used when dates_by
is set to months.
lx
This hash, indexed by date, returns the logical x coordinate for that date.
dates
This array is a list of known dates indexed by the logical x coordinate. It is the inverse to lx, where
$x = $s->{lx}{$date};
$date = $s->{dates}[$x];
lines
Function data is stored in this hash, first keyed by the chart where the function belongs - one of prices, volumes, cycles or tests. Each of these are in turn sub-hashes keyed by a line id. See <add_line> for details of the data stored.
Example
A function line with two points on the prices graph would be entered thus.
my $s = new Finance::Shares::Sample(...);
my $data = {
'2002-01-11' => 850,
'2002-03-28' => 991,
};
$s->add_line('prices', 'my_trend', $data, 'My Trend');
It would be held within the Sample object thus.
$s->{lines}{prices}{my_trend}{data}{2002-01-11} = 850;
{2002-03-28} = 991;
Functions
A number of other modules provide functions which work on the data held here. The 'functions' provided in this module are principally the source data, but they can be identified with the following text names when building model specifications.
open
close
high
low
volume
value
CONSTRUCTOR
new( [options] )
options
can be a hash ref or a list of hash keys and values.
source
and symbol
must be specified, with start_date
and end_date
also required if the source is a mysql database.
Recognized keys are:
source
This can be a Finances::Shares::MySQL object or a hash ref holding options suitable for creating one. Alternatively it may be the name of a CSV file or an array ref holding similar data.
Example 1
Using an existing MySQL object.
my $db = new Finance::Shares::MySQL;
my $ss = new Finance::Shares::Sample (
source => $db,
);
Example 2
Creating our own MySQL connection.
my $ss = new Finance::Shares::Sample (
source => {
user => 'wally',
password => '123jiM',
database => 'London',
},
);
Several attempts (see tries
below) are made to fetch the data from the internet. Then the data is extracted from the MySQL database, filtered according to dates_by
and stored as date, price and volume data.
The CSV file is read and converted to price and/or volume data, as appropriate. Files downloaded from !Yahoo Finance need filtering to change the dates into the YYYY-MM-DD format. Alternatively, a script, fetch_csv is provided in the Finance::Shares directory. The comma seperated values are interpreted by Text::CSV_XS and so are currently unable to tolerate white space. See the array
option for how the field contents are handled. Optionally, the directory may be specified seperately.
Example 3
my $ss = new Finance::Shares::Sample (
source => 'quotes.csv',
directory => '~/shares',
);
If source
is an array ref it should point to a list of arrays with fields date, open, high, low, close and volume.
Example 4
my $data = [
['2002-08-01',645.13,645.13,586.00,606.36,33606236],
['2002-08-02',574.75,620.88,558.00,573.00,59618288],
['2002-08-05',589.88,589.88,560.11,572.42,20300730],
['2002-08-06',571.89,599.00,545.30,585.92,26890880],
['2002-08-07',565.11,611.00,560.11,567.11,24977940] ];
my $ss = new Finance::Shares::Sample (
source => $data,
);
Three formats are recognized:
Date, Open, High, Low, Close, Volume
Date, Open, High, Low, Close
Date, Volume
Examples
[2001-04-26,345,400,300,321,12345678],
[2001-04-27,234.56,240.00,230.00,239.99],
[2001-04-28, 987654],
The four price values are typically decimals and the volume is usually an integer in the millions.
dates_by
Control how the data are stored and displayed on a chart. Suitable values:
- quotes
-
By default, the prices are displayed just as they are received.
- days
-
Every day is recognized, though only trading days (Monday to Friday) will have quotes, and some of those may be missing.
- weekdays
-
Entries are made for every day except weekends. So the data mostly appears as for
quotes
except that missing data is visible. - weeks
-
One entry shows the average data for each week. Holes in the data are visible as blank weeks.
- months
-
Entries show the average data for each month.
end_date
The last day of price data, in YYYY-MM-DD format. Only used if the data is fetched using Finance::Shares::MySQL. See fetch.
symbol
The market abbreviation for the stock as used by Yahoo. Non-US codes should have a suffix indicating the stock exchange (e.g. BSY.L for BSkyB on the London Stock Exchange).
mode
Determines how the stock quotes are obtained if Finance::Shares::MySQL is used. Suitable values are 'online', 'offline', 'fetch' and 'cache'. (Default: 'cache')
start_date
The first day of price data, in YYYY-MM-DD format. Only used if the data is fetched using Finance::Shares::MySQL. See fetch.
add_line( graph, lineid, data, key [, style [, shown ]] )
- graph
-
The graph where the line should appear, one of 'prices', 'volumes', 'cycles' or 'tests'.
- lineid
-
A string uniquely identifying the line.
- data
-
A hash ref of values indexed by date.
- key
-
The text to be shown next with the style in the Price Key box to the right of the chart.
- style
-
This can either be a PostScript::Graph::Style object or a hash ref holding options for one.
- shown
-
True if to be drawn, false otherwise.
Add a line to the price chart to be drawn in the style specified identified by some key text. The data is stored as a hash with the following keys:
data A hash of numbers keyed by YYYY-MM-DD dates.
shown True if the line is to be drawn on a chart.
style A hash or PostScript::Graph::Style object.
key A string associated with the style in the Key.
id Unique internal identifier
order Integer indicating when the line was added.
min The lowest data value
max The highest data value
Example
my $s = new Finance::Shares::Sample(...);
$s->add_line('cycles', 'my_line', $data, 'My Line');
then
$s->{lines}{cycles}{my_line}{key} == 'My Line';
value( options )
Produce a comparison line for a fixed y value.
options
are in key/value format using the following keys.
- strict
-
If 1, return undef if the average period is incomplete. If 0, return the best value so far. (Default: 0)
- 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) - graph
-
A string indicating the graph for display: one of prices, volumes, cycles or tests. (Default: 'prices')
- value
-
The Y value indicating the line.
Like all function methods, this returns the line identifier.
ACCESS METHODS
See DESCRIPTION for the data items that are directly available.
id()
Return a string used to identify the sample.
start_date()
Returns date of first quote in YYYY-MM-DD format.
symbol()
Returns the !Yahoo stock code as given to new().
end_date()
Returns date of last quote in YYYY-MM0DD format.
dates_by()
Return a string indicating how the dates are spread. One of 'data', 'days', 'workdays', 'weeks', 'months'.
chart( [chart] )
Either set or get the Finance::Shares::Chart displaying this data.
line_order( graph )
Return an array ref holding the ids of all the lines known to the sample so that the display order can be changed. Reassigning the new order to the returned array ref has the effect of altering the order displayed.
The lines will be displayed by Finance::Shares::Chart in this order (as they were added) unless shuffling this array moves lines forward or backward. See add_lines for the structure of the line data.
Note that changing this does not affect the key order, which will still show the order they were added.
SUPPORT METHODS
known_lines( [ graph(s) ] )
Returns a list of line identifiers valid for the specified graphs, zero or more of prices, volumes, cycles or tests. If none are specified, all known lines are returned.
line_by_key( identifier )
identifier
must be a concatention of the graph name, '::' and the line key (the visible one, NOT the line id), as given to add_line.
Returns the internal data structure for that line. See "add_line" for details.
min_value( graph )
Return the lowest value used on the given graph, which should be one of prices, volumes, cycles or tests.
max_value( graph )
Return the highest value used on the given graph, which should be one of prices, volumes, cycles or tests.
choose_line( graph, line [, nocopy ] )
Return the data for the identified line. The data may be checked and any missing values interpolated.
- graph
-
One of prices, volumes, cycles or tests.
- line
-
A string identifying the line.
- nocopy
-
If true, interpolation is prevented.
Returns undef if there is no such line. choose_line therefore indicates whether the line exists or not (best called with original=1 for this).
SUPPORT FUNCTIONS
line_id( arg1, arg2, ... )
Builds an identifier from the list of strings passed as arguments.
Note that this is NOT a method.
call_function ( hashref, name, args... )
Call a known function by name. The hashref
must map names to coderefs like \%function here or Finance::Shares::Model's \%testfunc. name
must be one of the names recognised by that hash. args
is the argument list passed to the function. If a method is being called, an object must be the first argument in the args
list.
Example
use Finance::Shares::Sample
qw(call_function %function);
use Finance::Shares::Averages;
my $fss = new Finance::Shares::Sample(...);
my $res = call_function( \%function, 'simple_a',
$fss, period => 3, key => 'Simple average' );
Note this is NOT a method.
DATE FUNCTIONS
There are three types of dates here. A 'days' value is the number of days from some arbitrary day zero. A 'date' is a string in YYYY-MM-DD format while 'ymd' refers to an array holding a year, month and day such as (2002, 12, 31). See SYNOPSIS for all the functions.
today_as_string
Return today's date in YYYY-MM-DD format.
string_from_ymd( year, month, day )
Convert the numeric representation of year, month and day into a YYYY-MM-DD date.
ymd_from_string( date )
Convert a YYYY-MM-DD date into an array of numeric values in the form:
(year, month, day)
increment_days( year, month, day, inc_days )
Add inc_days
to the date and return as a year-month-day array.
increment_date( date, days )
Add the number of days given to the YYYY-MM-DD date and return the new date in YYYY-MM-DD format.
days_difference( year1, month1, day1, year2, month2, day2 )
Return the number of days between the two dates
day_of_week( year, month, day )
Returns 1=Monday, ... 7=Sunday.
BUGS
Where data is missing from a function or test, it is filled by interpolating. I don't think this is the right behaviour, but haven't got around to changing it yet. If something looks a bit odd and you suspect this, a work-round would be to use 'quotes' for the Sample dates_by
value.
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
Finance::Shares::MySQL, Finance::Shares::Chart and Finance::Shares::Model.
There is also an introduction, Finance::Shares::Overview and a tutorial beginning with Finance::Shares::Lesson1.