Remove all references to the now-defunct Yahoo! quote retrieval

And make Alphavantage the default.
This commit is contained in:
John Ralls 2018-01-02 10:43:49 -08:00
parent 320c5211b0
commit c0fd3b3165
9 changed files with 34 additions and 724 deletions

View File

@ -440,7 +440,7 @@ gnc_tree_view_commodity_new (QofBook *book,
sort_by_quote_flag,
NULL);
col = gnc_tree_view_add_text_column (
view, _("Source"), "quote_source", NULL, "yahoo",
view, _("Source"), "quote_source", NULL, "alphavantage",
GNC_TREE_MODEL_COMMODITY_COL_QUOTE_SOURCE,
GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
sort_by_commodity_string);

View File

@ -51,7 +51,7 @@
<cmdty:xcode>12345</cmdty:xcode>
<cmdty:fraction>10000</cmdty:fraction>
<cmdty:get_quotes/>
<cmdty:quote_source>yahoo</cmdty:quote_source>
<cmdty:quote_source>alphavantage</cmdty:quote_source>
</gnc:commodity>
<gnc:account version="2.0.0">
<act:name>Root Account</act:name>

View File

@ -116,9 +116,9 @@ Jon Trowbridge (@url{http://www.gnome.org/guppi}).
The @dfn{Price Quotes} module (@file{src/quotes}) is a Perl system to
fetch stock price data off the Internet and insert it into the GnuCash
Engine. This module requires the functionality of the Finance::Quote
module available at SourceForge. The Finance::Quote module can fetch
price quotes from many different sources including Yahoo, Yahoo Europe,
and some international exchanges.
module available from CPAN. The Finance::Quote module can fetch
price quotes from many different sources including Alphavantage
and several international exchanges.
The Finance::Quote module also supports fetching currency exchange
rates. GnuCash will be extended to allow the fetching and use of

View File

@ -160,6 +160,7 @@ static gnc_quote_source currency_quote_source =
static gnc_quote_source single_quote_sources[] =
{
{ FALSE, 0, 0, "Alphavantage USA", "ALPHAVANTAGE", "alphavantage" },
{ FALSE, 0, 0, "Amsterdam Euronext eXchange, NL", "AEX", "aex" },
{ FALSE, 0, 0, "American International Assurance, HK", "AIAHK", "aiahk" },
{ FALSE, 0, 0, "Association of Mutual Funds in India", "AMFIINDIA", "amfiindia" },
@ -169,20 +170,26 @@ static gnc_quote_source single_quote_sources[] =
{ FALSE, 0, 0, "BMO NesbittBurns, CA", "BMONESBITTBURNS", "bmonesbittburns" },
{ FALSE, 0, 0, "Bucharest Stock Exchange, RO", "BSERO", "bsero" },
{ FALSE, 0, 0, "Budapest Stock Exchange (BET), ex-BUX, HU", "BSE", "bse" },
{ FALSE, 0, 0, "Canada Mutual", "CANADAMUTUAL", "canadamutual" },
{ FALSE, 0, 0, "Citywire Funds, GB", "citywire", "citywire" },
{ FALSE, 0, 0, "Colombo Stock Exchange, LK", "CSE", "cse" },
{ FALSE, 0, 0, "Cominvest, ex-Adig, DE", "COMINVEST", "cominvest" },
{ FALSE, 0, 0, "Deka Investments, DE", "DEKA", "deka" },
{ FALSE, 0, 0, "Dutch", "DUTCH", "dutch" },
{ FALSE, 0, 0, "DWS, DE", "DWS", "dwsfunds" },
{ FALSE, 0, 0, "Equinox Unit Trusts, ZA", "ZA_unittrusts", "za_unittrusts" },
{ FALSE, 0, 0, "Equinox Unit Trusts, ZA", "ZA_unittrusts", "za_unittrusts" },
{ FALSE, 0, 0, "Fidelity", "FIDELITY", "fidelity" },
{ FALSE, 0, 0, "Fidelity Direct", "FIDELITY_DIRECT", "fidelity_direct" },
{ FALSE, 0, 0, "Finance Canada", "FINANCECANADA", "financecanada" },
{ FALSE, 0, 0, "Financial Times Funds service, GB", "FTFUNDS", "ftfunds" },
{ FALSE, 0, 0, "Finanzpartner, DE", "FINANZPARTNER", "finanzpartner" },
{ FALSE, 0, 0, "First Trust Portfolios, US", "FTPORTFOLIOS_DIRECT", "ftportfolios_direct" },
{ FALSE, 0, 0, "First Trust Portfolios, US", "FTPORTFOLIOS", "ftportfolios" },
{ FALSE, 0, 0, "Fund Library, CA", "FUNDLIBRARY", "fundlibrary" },
{ FALSE, 0, 0, "GoldMoney spot rates, JE", "GOLDMONEY", "goldmoney" },
{ FALSE, 0, 0, "HElsinki stock eXchange, FI", "HEX", "hex" },
{ FALSE, 0, 0, "Greece", "GREECE", "greece" },
{ FALSE, 0, 0, "Helsinki stock eXchange, FI", "HEX", "hex" },
{ FALSE, 0, 0, "Hungary", "HU", "hu" },
{ FALSE, 0, 0, "India Mutual", "INDIAMUTUAL", "indiamutual" },
{ FALSE, 0, 0, "Man Investments, AU", "maninv", "maninv" },
{ FALSE, 0, 0, "Morningstar, GB", "MSTARUK", "mstaruk" },
{ FALSE, 0, 0, "Morningstar, JP", "MORNINGSTARJP", "morningstarjp" },
@ -192,6 +199,7 @@ static gnc_quote_source single_quote_sources[] =
{ FALSE, 0, 0, "Paris Stock Exchange/Boursorama, FR", "BOURSO", "bourso" },
{ FALSE, 0, 0, "Paris Stock Exchange/LeRevenu, FR", "LEREVENU", "lerevenu" },
{ FALSE, 0, 0, "Platinum Asset Management, AU", "PLATINUM", "platinum" },
{ FALSE, 0, 0, "Romania", "romania", "romania" },
{ FALSE, 0, 0, "SIX Swiss Exchange funds, CH", "SIXFUNDS", "sixfunds" },
{ FALSE, 0, 0, "SIX Swiss Exchange shares, CH", "SIXSHARES", "sixshares" },
{ FALSE, 0, 0, "Skandinaviska Enskilda Banken, SE", "SEB_FUNDS", "seb_funds" },
@ -201,47 +209,23 @@ static gnc_quote_source single_quote_sources[] =
{ FALSE, 0, 0, "TD Efunds, CA", "TDEFUNDS", "tdefunds" },
{ FALSE, 0, 0, "TIAA-CREF, US", "TIAACREF", "tiaacref" },
{ FALSE, 0, 0, "Toronto Stock eXchange, CA", "TSX", "tsx" },
{ FALSE, 0, 0, "T. Rowe Price", "TRPRICE", "troweprice" },
{ FALSE, 0, 0, "T. Rowe Price, US", "TRPRICE_DIRECT", "troweprice_direct" },
{ FALSE, 0, 0, "Trustnet via tnetuk.pm, GB", "TNETUK", "tnetuk" },
{ FALSE, 0, 0, "Trustnet via trustnet.pm, GB", "TRUSTNET", "trustnet" },
{ FALSE, 0, 0, "U.K. Unit Trusts", "UKUNITTRUSTS", "uk_unit_trusts" },
{ FALSE, 0, 0, "Union Investment, DE", "UNIONFUNDS", "unionfunds" },
{ FALSE, 0, 0, "US Treasury Bonds", "usfedbonds", "usfedbonds" },
{ FALSE, 0, 0, "US Govt. Thrift Savings Plan", "TSP", "tsp" },
{ FALSE, 0, 0, "Vanguard", "VANGUARD", "vanguard" }, /* No module seen in F::Q 1.17. */
{ FALSE, 0, 0, "VWD, DE (unmaintained)", "VWD", "vwd" },
{ FALSE, 0, 0, "Yahoo USA", "YAHOO", "yahoo" },
{ FALSE, 0, 0, "Yahoo Asia", "YAHOO_ASIA", "yahoo_asia" },
{ FALSE, 0, 0, "Yahoo Australia", "YAHOO_AUSTRALIA", "yahoo_australia" },
{ FALSE, 0, 0, "Yahoo Brasil", "YAHOO_BRASIL", "yahoo_brasil" },
{ FALSE, 0, 0, "Yahoo Europe", "YAHOO_EUROPE", "yahoo_europe" },
{ FALSE, 0, 0, "Yahoo New Zealand", "YAHOO_NZ", "yahoo_nz" },
{ FALSE, 0, 0, "Yahoo as JSON", "YAHOO_JSON", "yahoo_json" },
};
static gnc_quote_source multiple_quote_sources[] =
{
{ FALSE, 0, 0, "Asia (Yahoo, ...)", "ASIA", "asia" },
{ FALSE, 0, 0, "Australia (ASX, Yahoo, ...)", "AUSTRALIA", "australia" },
{ FALSE, 0, 0, "Brasil (Yahoo, ...)", "BRASIL", "brasil" },
{ FALSE, 0, 0, "Canada (Yahoo, ...)", "CANADA", "canada" },
{ FALSE, 0, 0, "Canada Mutual (Fund Library, ...)", "CANADAMUTUAL", "canadamutual" },
{ FALSE, 0, 0, "Dutch (AEX, ...)", "DUTCH", "dutch" },
{ FALSE, 0, 0, "Europe (Yahoo, ...)", "EUROPE", "europe" },
{ FALSE, 0, 0, "Greece (ASE, ...)", "GREECE", "greece" },
{ FALSE, 0, 0, "Hungary (Bamosz, BET)", "HU", "hu" },
{ FALSE, 0, 0, "India Mutual (AMFI, ...)", "INDIAMUTUAL", "indiamutual" },
{ FALSE, 0, 0, "Fidelity (Fidelity, ...)", "FIDELITY", "fidelity" },
{ FALSE, 0, 0, "Finland (HEX, ...)", "FINLAND", "finland" },
{ FALSE, 0, 0, "First Trust (First Trust, ...)", "FTPORTFOLIOS", "ftportfolios" },
{ FALSE, 0, 0, "France (Boursorama, ...)", "FRANCE", "france" },
{ FALSE, 0, 0, "Nasdaq (Yahoo, ...)", "NASDAQ", "nasdaq" },
{ FALSE, 0, 0, "New Zealand (Yahoo, ...)", "NZ", "nz" },
{ FALSE, 0, 0, "NYSE (Yahoo, ...)", "NYSE", "nyse" },
/* { FALSE, 0, 0, "South Africa (Sharenet, ...)", "ZA", "za" }, */
{ FALSE, 0, 0, "Romania (BSE-RO, ...)", "romania", "romania" },
{ FALSE, 0, 0, "T. Rowe Price", "TRPRICE", "troweprice" },
{ FALSE, 0, 0, "Europe (Athens, Boursorama, Bucharest)", "EUROPE", "europe" },
{ FALSE, 0, 0, "France (Boursorama, LeRevenue)", "FRANCE", "france" },
{ FALSE, 0, 0, "U.K. Funds (citywire, FTfunds, MStar, tnetuk, ...)", "ukfunds", "ukfunds" },
{ FALSE, 0, 0, "U.K. Unit Trusts (trustnet, ...)", "UKUNITTRUSTS", "uk_unit_trusts" },
{ FALSE, 0, 0, "USA (Yahoo, Fool, ...)", "USA", "usa" },
};
static const int num_single_quote_sources =
@ -1123,7 +1107,7 @@ gnc_commodity_get_default_quote_source(const gnc_commodity *cm)
if (cm && gnc_commodity_is_iso(cm))
return &currency_quote_source;
/* Should make this a user option at some point. */
return gnc_quote_source_lookup_by_internal("yahoo");
return gnc_quote_source_lookup_by_internal("alphavantage");
}
/********************************************************************

View File

@ -22,12 +22,12 @@ my $quoter = Finance::Quote->new();
# -----------------------------------
# get quotes for two stocks ...
%quotes = $quoter->fetch("yahoo","IBM", "SGI");
%quotes = $quoter->fetch("alphavantage","IBM", "SGI");
# print some selected values
print "NYSE by Yahoo: ", $quotes {"IBM", "name"},
print "NYSE by Alphavantage: ", $quotes {"IBM", "name"},
" last price: ", $quotes {"IBM", "last"}, "\n";
print "NYSE by Yahoo: ", $quotes {"SGI", "name"},
print "NYSE by Alphavantage: ", $quotes {"SGI", "name"},
" last price: ", $quotes {"SGI", "last"}, "\n";
# loop over and print all values.

View File

@ -200,8 +200,8 @@ gnc-fq-dump - Print out data from the F::Q module
=head1 SYNOPSIS
gnc-fq-dump yahoo CSCO JNPR
gnc-fq-dump yahoo BAESY.PK
gnc-fq-dump alphavantage CSCO JNPR
gnc-fq-dump alphavantage BAESY.PK
gnc-fq-dump europe 48406.PA 13000.PA
gnc-fq-dump vwd 632034
gnc-fq-dump ftportfolios FKYGTX

View File

@ -48,16 +48,14 @@ side :>).
(<method-name> symbol symbol symbol ...)
where <method-name> indicates the desired Finance::Quote method.
The currently recognized subset is yahoo, yahoo_europe,
fidelity_direct, troweprice_direct, vanguard, asx, tiaacref,
and currency.
One can list the many methods by running gnc-fq-check.
For currency quotes, the symbols alternate between the 'from'
and 'to' currencies.
For example:
(yahoo "IBM" "LNUX")
(alphavantage "IBM" "LNUX")
(fidelity_direct "FBIOX" "FSELX")
(currency "USD" "AUD")
@ -78,7 +76,7 @@ need to convert it to that.
For example:
$ echo '(yahoo "CSCO" "JDSU" "^IXIC")' | ./gnc-fq-helper
$ echo '(alphavantage "CSCO" "JDSU" "^IXIC")' | ./gnc-fq-helper
(("CSCO" (symbol . "CSCO")
(gnc:time-no-zone . "2001-03-13 19:27:00")
(last . 20.375)
@ -95,7 +93,7 @@ For example:
On error, the overall result may be #f, or on individual errors, the
list sub-item for a given symbol may be #f, like this:
$ echo '(yahoo "CSCO" "JDSU")' | ./gnc-fq-helper
$ echo '(alphavantage "CSCO" "JDSU")' | ./gnc-fq-helper
(#f
("JDSU" (symbol . "JDSU")
(gnc:time-no-zone . "2001-03-13 19:27:00")

View File

@ -1,672 +0,0 @@
#!/usr/bin/perl -w
#######################################################################
# $Id$
# Looks up investment prices on the web, and builds a report
# to summarize the results
#######################################################################
$HISTORYFILE="histprices";
$newprices = "NO"; # Haven't found *any* new prices so far...
#######################################################################
# Start by initializing the security list
#######################################################################
# My TSE stocks...
#######################################################################
&add_stock("T", 100, 1670.5, "TSE");
#&add_stock("NVA", 100, 1345.5, "TSE");
&add_stock("NVA", 100, -10.16, "TSE");
&add_stock("TRP", 52, 1345.50, "TSE");
&add_stock("PCA", 100, 1733, "TSE");
&add_stock("TOC", 50, 21.035*50, "TSE");
&add_stock("RY", 50, 32.785*50, "TSE");
#######################################################################
# My Canada Trust Everest funds...
#######################################################################
# Original numbers of units...
#&add_stock("CTMM", 83.951, 839.51, "CTE"); # Not strictly correct..
#&add_stock("CTBOND", 121.747, 1315.17, "CTE");
#&add_stock("CTSTK", 57.177, 832.73, "CTE");
#&add_stock("CTSPEC", 28.263, 504.07, "CTE");
#&add_stock("CTAMER", 177.723, 1983.05, "CTE");
#&add_stock("CTUSEQ", 19.644, 294.91, "CTE");
#&add_stock("CTASIA", 28.224, 251.99, "CTE");
#&add_stock("CTEURO", 60.136, 530.50, "CTE");
#&add_stock("CTEMER", 27.463, 266.67, "CTE");
#&add_stock("CTIBND", 84.879, 907.37, "CTE");
# Units as at Oct 31/98
&add_stock("CTMM", 89.572, 839.51, "CTE");
&add_stock("CTBOND", 137.398, 1315.17, "CTE");
&add_stock("CTSTK", 62.896, 832.73, "CTE");
&add_stock("CTSPEC", 28.263, 504.07, "CTE");
&add_stock("CTAMER", 251.604, 1983.05, "CTE");
&add_stock("CTUSEQ", 20.467, 294.91, "CTE");
&add_stock("CTASIA", 28.238, 251.99, "CTE");
&add_stock("CTEURO", 91.298, 530.50, "CTE");
&add_stock("CTEMER", 27.463, 266.67, "CTE");
&add_stock("CTIBND", 94.264, 907.37, "CTE");
# Stuff on NYSE
&add_stock("MOT", 15, (62+5/8)*15, "NYSE");
#&add_stock("IFMXE", 0.1, 0.1, "NYSE");
&add_stock("TSG", 13.0289, 43.02*5+43.75+44.48, "NYSE");
&add_stock("TSG", 27.619-13.0289, 44.48*8, "NYSE");
# SuperSaver 401(k)... Approximate...
&add_stock("AADBX", 0.3*2115.93/14, 0.3*1604.85, "NYSE");
&add_stock("AADEX", 0.5*2115.93/19, 0.5*1604.85, "NYSE");
&add_stock("AAIEX", 0.2*2115.93/15, 0.2*1604.85, "NYSE");
# SGRP Balances: Approximate...
&add_stock("AADBX", 712.33/14.9, 700, "NYSE"); # Balanced
&add_stock("AADEX", 4556.64/22.5 + (533.94+200.24+183.55)/22.5, 3500+(533.94+200.24+183.55), "NYSE"); # Equity
&add_stock("AAIEX", 1829.63/18.8 + (213.57+80.1+73.41)/18.8, 1700+(213.57+80.1+73.41), "NYSE"); # Int'l Equity
&add_stock("AASPX", 2104.81/15 + (320.37+120.12+110.13)/15, 1900 + (320.37+120.12+110.13), "NYSE"); # Stock Index
#######################################################################
# Working Ventures fund...
#######################################################################
&add_stock("WORKVE", 219.701, 3000, "OTHER");
$PRICE{"WORKVE"} = 3000/219.701; # Hack in a price for Working Ventures
$OLD{"WORKVE"} = "yes"; # Indicate that this is *not* a "new" price...
#######################################################################
# Map CT Everest fund names to the "short" IDs
#######################################################################
# I don't want to get long names; this builds an array that
# shortens the names used in the CT Everest Funds web page to
# the ones used above
#######################################################################
&ct_fund_ids; # Get mapping of CT "long" fund names to "short" names
&load_prices; # Load old prices, so that failure to get a price
# means we fall back to the previously-found
# price
$CURRNAME{"CDN"} = "Canadian";
$CURRNAME{"USD"} = "United States";
$CURRATE{"CDN"} = 1;
$CURRATE{"USD"} = 1.37;
&get_currency("USD");
#######################################################################
# Now, get the current prices by sundry queries of web sites
#######################################################################
&search_web_for_prices(); # Find new closing prices
&calc_variances(); # Calculate variances
#######################################################################
# Run report that details portfolio value based on the prices, costs
# and quantities of shares...
#######################################################################
if ($newprices eq "YES") {
&show_report(); # Display a report summarizing the results...
# &show_variances();
# &hilo_portfolios();
&save_prices(); # Save prices...
}
exit 0; # Done
#######################################################################
#######################################################################
#######################################################################
#######################################################################
#######################################################################
######################## End of the main body #########################
#######################################################################
#######################################################################
#######################################################################
#######################################################################
#######################################################################
#######################################################################
#######################################################################
############################# Subroutines #############################
#######################################################################
#######################################################################
#######################################################################
############### &add_stock("NVA", 100, 1345.5, "TSE"); ################
#######################################################################
# Add a security to the "active list," including the "ticker symbol,"
# quantity of shares, original total cost, and the exchange to look it
# up on.
#######################################################################
sub add_stock {
local($ticker, $num, $cost, $exchange) = @_;
$NUM{$ticker} += $num;
$COST{$ticker} += $cost;
$EXCHANGE{$ticker} = $exchange;
local ($currency) = "CDN";
if ($exchange eq "TSE") {
$currency = "CDN";
}
if ($exchange eq "NYSE") {
$currency = "USD";
}
if ($exchange eq "NY") {
$currency = "USD";
}
$CURRENCY{$ticker} = $currency;
}
#######################################################################
######## &get_url_command("http://www.conline.com/~cbbrowne");#########
#######################################################################
# Build the appropriate command that accesses (in raw form) the
# requested URL. Probably ought to change this to use the w3c
# "line mode" utility, as it's minscule
#######################################################################
sub get_url_command {
local ($url) = @_;
return "lynx -source '$url'";
}
#######################################################################
###################### &search_web_for_prices(); ######################
#######################################################################
# This program searches the %EXCHANGE array, determining how
# the security price should be searched out, and invokes the
# appropriate method.
#######################################################################
sub search_web_for_prices {
local ($ticker);
# Do some per-ticker searching
foreach $ticker (keys EXCHANGE) {
local($exchange) = $EXCHANGE{$ticker};
if ($exchange eq "TSE") {
&get_TSE($ticker);
&get_yahoo($ticker, "TSE");
}
if ($exchange eq "CTE") {
# Do nothing; data is coming
# in en masse via &get_all_everest_rates;
}
if ($exchange eq "NYSE") {
&get_yahoo($ticker, $EXCHANGE{$ticker});
}
}
# search for CT Everest fund data
&get_CT_Everest; # Get Everest mutual fund data
# Search for Working Ventures fund data
&get_WV;
# get all of the TSE stock prices
# foreach $ticker (ord("a")..ord("z")) {
# &get_TSE( chr($ticker) );
# }
}
#######################################################################
########################## &get_TSE ("RY"); ###########################
#######################################################################
# Look up a stock's price on the TSE using the Telenium service
#######################################################################
sub get_TSE {
local ($stock) = @_;
local ($page) = "http://www.telenium.ca/TSE/" .
lc(
substr($stock, 0, 1)
)
. ".html";
if ($OLD{$stock} eq "NO!") { # We've already priced this stock
return;
}
local ($command) = &get_url_command($page) . " | grep ' $stock'";
local ($line);
open(GETPAGE, "$command |");
# open(GETPAGE, "<a:/t~1.htm");
while ($line = <GETPAGE>) {
chop $line;
# print $line, "\n";
if ($line =~ /(\d*\.\d*)\D+\d+\S*\s+\d+\s+\S+\s+\d+\/\d+\s+(\S*)\s*$/) {
local($lp, $ls) = (sprintf("%.4f", $1), $2);
# print "Found $ls @ $lp\n";
#... 21.3 21.35 21.2 21.2 -0.15 142300 193 02/14 T
#... 19.4 19.5 19.2 19.35-0.1 687239 181 02/04 T
#... 51.5 52 50.6 51.4 0 1527378 583 02/05 RY
#... 1.18 1.2 1.1 1.2 0.02 44700 29 02/03 NBX
# ^^^
# Want this "close" value...
if ($lp < 0.001) {
# Do nothing
} elsif ($ls eq $stock) {
if ((($lp * 1.0) != $PRICE{$stock}) && ($price > 0)) {
$newprices = "YES";
$PRICE{$stock} = sprintf("%.4f", $price);
print "NEW PRICE: $stock, $lp\n";
} else {
$price = $PRICE{$stock};
}
$PRICE{$stock} = sprintf("%.4f", $lp);
$OLD{$stock} = "NO!"; # Indicate that this is an update...
}
}
}
close GETPAGE;
}
#######################################################################
############################ &get_yahoo(); ############################
#######################################################################
# Look up a stock via "yahoo"
#######################################################################
sub get_yahoo {
local ($stock, $exchange) = @_;
local ($price);
if (($exchange eq "NY") || ($exchange eq "NYSE")) {
$exchange = "";
}
if ($exchange eq "TSE") {
$exchange = ".TO";
}
local ($page) = "http://quote.yahoo.com/download/quotes.csv?symbols=" .
$stock . $exchange .
"&format=sl1d1t1c1ohgv&ext=.csv";
if ($OLD{$stock} eq "NO!") { # We've already priced this stock
return;
}
local ($command) = &get_url_command($page);
local ($line);
# print $command, "\n";
open(GETPAGE, "$command |");
while ($line = <GETPAGE>) {
# print "$line";
local ($trash, $price)=split(/,/, $line);
# print "$trash, $price\n";
# print "Old price: ", $PRICE{$stock}, "\n";
if ((($price * 1.0) != $PRICE{$stock}) && ($price > 0) ) {
$newprices = "YES";
print "NEW PRICE: $stock, $price\n";
} else {
$price = $PRICE{$stock};
# print "Keep old price: $price\n";
}
$PRICE{$stock} = sprintf("%.4f", $price);
$OLD{$stock} = "NO!"; # Indicate that this is an update...
# print "Done - ", $stock, $PRICE{$stock}, $OLD{$stock}, "\n";
}
}
#######################################################################
########################## &get_CT_Everest(); #########################
#######################################################################
# Look up all of the CT Everest mutual fund prices
#######################################################################
sub get_CT_Everest {
local ($line, $fund, $value);
local ($url) = "http://www.canadatrust.com/test/ctrates/EV.html";
local ($command) = &get_url_command($url);
open(FUNDS, "$command |");
while ($line = <FUNDS>) {
if ($line =~ /.*\s+\d+.\d+\s+\d+.\d+\s+.\d+.\d+/) {
# print "CT: $line";
$fund = substr($line, 0, 15);
# print "fund: [", $fund, "] ID:[", $ID{$fund}, "]\n";
if ($ID{$fund} ne "") {
$value = substr($line, 30, 11);
if (($value*1.0) != $PRICE{$ID{$fund}}) {
$newprices = "YES";
print "NEW PRICE: $fund, $value\n";
}
$PRICE{$ID{$fund}} = $value;
$OLD{$ID{$fund}} = "NO!"; # Indicate that this is an update...
# print "CT Price: $value ", $ID{$fund}, "\n";
}
}
}
close FUNDS;
}
#######################################################################
############################## &get_WV(); #############################
#######################################################################
# Look up Working Ventures fund price
#######################################################################
sub get_WV {
local ($url) = "http://www.workingventures.ca/main_cell.html";
local ($command) = &get_url_command($url) . " | grep 'share price' ";
open(FUNDS, "$command |");
while (<FUNDS>) {
if (/\D+\$(\d+\.\d+)\D+/) {
# matches .... $13.66 ...
if (($1 * 1.0) != $PRICE{"WORKVE"}) {
$newprices = "YES";
print "NEW PRICE: WV, $1\n";
}
$PRICE{"WORKVE"} = sprintf("%.4f", $1);
$OLD{"WORKVE"} = "NO!"; # Indicate that this is an update...
}
}
close FUNDS;
}
#######################################################################
########################### &ct_fund_ids (); ##########################
#######################################################################
# Build an associative array that lets one take the names used in the
# CT mutual fund web page, and associate them with the short forms
# used as "ticker" codes
#######################################################################
sub ct_fund_ids {
%ID = ("MONEY MARKET ", "CTMM",
"PREMIUM MMF ", "CTPMM",
"SHORT TERM BND ", "CTSTB",
"MORTGAGE ", "CTMTG",
"BALANCED ", "CTBAL",
"BOND ", "CTBOND",
"DIV INCOME ", "CTDIV",
"STOCK ", "CTSTK",
"SPECIAL EQUITY ", "CTSPEC",
"INT'L BOND ", "CTIBND",
"NORTH AMERICAN ", "CTNA",
"AMERIGROWTH ", "CTAMER",
"U.S. EQUITY ", "CTUSEQ",
"ASIAGROWTH ", "CTASIA",
"EUROGROWTH ", "CTEURO",
"GLOBALGROWTH ", "CTGLOB",
"INT'L EQUITY ", "CTINTL",
"EMERGING MKTS. ", "CTEMER"
);
}
#######################################################################
############################ &save_prices()############################
#######################################################################
# Dump data out to a file
#######################################################################
sub save_prices {
local ($date) = `date '+%Y/%m/%d-%H:%M:%S'`;
chop $date;
local ($ticker, $price);
open(HISTPRICES, ">>$HISTORYFILE");
while ($ticker = each %PRICE) {
if ($OLD{$ticker} eq "yes") {
# Don't dump it; we didn't get a new price...
} else {
$key = $date . "" . $ticker;
$price = $PRICE{$ticker};
print HISTPRICES $date, "|", $ticker, "|", $price, "\n";;
}
}
close HISTPRICES;
}
#######################################################################
########################### &load_prices();############################
#######################################################################
# Preload prices, thus always keeping around the latest successfully
# located price.
# This means that if the web search process fails, we still do have
# pricing, even if it's somewhat out of date...
#######################################################################
sub load_prices {
local ($date) = `date '+%Y/%m/%d-%H:%M:%S'`;
chop $date;
local ($ticker, $price, $line);
open(HISTPRICES, "<$HISTORYFILE");
while ($line = <HISTPRICES>) {
($date, $ticker, $price) = split(/\|/, $line);
$PRICE{$ticker} = $price;
$OLD{$ticker} = "yes"; # Indicate that this is an old price
# and thus not to be redumped
}
close HISTPRICES;
}
#######################################################################
############################ &show_report();###########################
#######################################################################
# Look up all of the securities, and build a report listing the cost,
# value, and net profit/loss on each security, along with totals.
########################################################################
sub show_report {
local($date) = `date`;
chop $date;
local($ticker, $shares, $price, $value, $cost, $profitloss);
local ($tp, $tv, $tc);
format STDOUT_TOP =
Portfolio Valuation
as at @<<<<<<<<<<<<<<<<<<<<<<<<<<<
$date
Ticker Shares Recent Price Value Cost Profit/Loss
------------------------------------------------------------------------
.
format STDOUT =
@<<<<<<< @>>>>>>> @>>>>>>>> @>>>>>>>>>>> @>>>>>>>>>>> @>>>>>>>>>>>>
$ticker, $shares, $price, $value, $cost, $profitloss
.
foreach $stock (sort keys EXCHANGE) {
if ($stock ne "zPortfolio") {
$ticker = $stock;
$shares = sprintf("%.4f", $NUM{$stock});
$price = sprintf("%.4f", $PRICE{$stock});
$value = sprintf("%.2f", $shares * $price * $CURRATE{$CURRENCY{$stock}});
$cost = sprintf("%.2f", $COST{$stock} * $CURRATE{$CURRENCY{$stock} });
$profitloss = sprintf("%.2f", $value - $cost);
$tv += $value;
$tc += $cost;
$tp += $profitloss;
write;
}
}
($ticker, $shares, $price, $value, $cost, $profitloss) =
("", "", "", "---------------", "---------------", "---------------");
write;
($ticker, $shares, $price, $value, $cost, $profitloss) =
("Total", "", "", sprintf("%.2f", $tv), sprintf("%.2f" ,$tc),
sprintf("%.2f" ,$tp));
write;
($ticker, $shares, $price, $value, $cost, $profitloss) =
("", "", "", "===============", "===============", "===============");
write;
}
#########################################################################=
#####
############################## Find Variances #########################=
#####
#########################################################################=
#####
sub calc_variances {
local ($x);
open(PRICEF, "<$HISTORYFILE");
while (<PRICEF>) {
($date, $id, $price) = split(/\|/, $_);
$XCOUNT{$id} ++;
$quantity = $NUM{$id};
$x = $quantity * $price * $CURRATE{$CURRENCY{$id}};
$XSUM{$id} += $x;
$XSQUARESUM{$id} += ($x * $x);
$DATES{$date} ++;
$PRICES{"$date|$id"} = $price;
# printf "XC: %9.2f XSUM: %9.2f XSQ: %9.2f\n", $XCOUNT{$id}, $XSUM{$id}, $XSQUARESUM{$id};
}
&complete_price_list(); # Get prices for *every* day
&value_portfolios(); # Value the portfolio for every day
}
# Need to make sure that we have prices for each stock for each date
# This is done by (for each stock) going thru all the dates, and
# inserting prices for dates where prices are missing. We use the
# last price present for the stock.
sub complete_price_list {
foreach $stock (keys XCOUNT) {
$current_price = $XSUM{$stock} / $XCOUNT{$stock};
# Move forwards until a price gets found. That price
# is then used for all "empty" price slots up to the first
# actual measurement
FIRSTPRICE:
foreach $date (sort keys DATES) {
if ($PRICES{"$date|$stock"}) {
$current_price = $PRICES{"$date|$stock"};
last FIRSTPRICE;
}
}
# Now, proceed onwards...
foreach $date (sort keys DATES) {
if ($PRICES{"$date|$stock"}) {
# There's a price
$current_price = $PRICES{"$date|$stock"};
} else {
$PRICES{"$date|$stock"} = $current_price;
}
}
}
}
sub value_portfolios {
# &setup_portfolio_quantities();
$NUM{"zPortfolio"}=1;
foreach $date (sort keys DATES) {
$price = 0;
foreach $stock (keys XCOUNT) {
$price += $NUM{$stock} * $PRICES{"$date|$stock"}* $CURRATE{$CURRENCY{$stock}};
}
$XCOUNT{"zPortfolio"} ++;
$XSUM{"zPortfolio"} += $price;
$XSQUARESUM{"zPortfolio"} += ($price * $price);
# printf "Portfolio on %15s valued at %14.2f\n", $date, $price;
}
}
sub hilo_portfolios {
local($date, $hi, $lo, $hival, $loval);
local ($stock, $price, $latest_date);
foreach $stock (keys XCOUNT) {
$LO{$stock} = 99999999;
$HI{$stock} = -99999999;
}
$HI{"zPortfolio"} = -99999999;
$LO{"zPortfolio"} = 99999999;
foreach $date (keys DATES) {
local ($pprice);
local($dt) = split(/-/, $date);
foreach $stock (keys XCOUNT) {
$price = $PRICES{"$date|$stock"};
if ($date >= $latest_date) {
$latest_date = $date;
$CURRENT{$stock} = $price;
}
if ($price > $HI{$stock}) {
($HI{$stock}, $HIDATE{$stock}) = ($price, $dt);
}
if ($price < $LO{$stock}) {
($LO{$stock}, $LODATE{$stock}) = ($price, $dt);
}
$pprice += $NUM{$stock} * $price;
}
if ($date >= $latest_date) {
$latest_date = $date;
$CURRENT{"zPortfolio"} = $pprice;
}
if ($pprice > $HI{"zPortfolio"}) {
($HI{"zPortfolio"}, $HIDATE{"zPortfolio"}) = ($pprice, $dt);
}
if ($pprice > $LO{"zPortfolio"}) {
($LO{"zPortfolio"}, $LODATE{"zPortfolio"}) = ($pprice, $dt);
}
}
# Report results...
print
"-----------------------------------------------------------------------
Highs/Lows
-----------------------------------------------------------------------
";
printf "%10s %10s %10s %10s %10s %10s\n", "Stock", "High Date", "High",
"Low Date", "Low Price", "Current";
print "-----------------------------------------------------------------------";
foreach $stock (sort keys XCOUNT) {
printf "%10s %10s %10.2f %10s %10.2f %10.2f\n", $stock, $HIDATE{$stock},
$HI{$stock}, $LODATE{$stock}, $LO{$stock}, $CURRENT{$stock};
}
print "-----------------------------------------------------------------------";
}
sub show_variances {
print
"-----------------------------------------------------------------------
Variance/Standard Deviations for Portfolio *VALUE*
------------------------------------------------------------------------
Security Mean Variance Std. Dev. % Std.Dev
------------------------------------------------------------------------
";
foreach $i (sort keys XCOUNT) {
if ($XCOUNT{$i} > 2) {
$variance = (($XCOUNT{$i} * $XSQUARESUM{$i})
- ($XSUM{$i} * $XSUM{$i})) /
($XCOUNT{$i} * ($XCOUNT{$i}-1));
}
$variance = -$variance if ($variance < 0);
$deviation = sqrt($variance);
# printf "XC: %5d XSUM: %9.2f XSQ: %9.2f\n", $XCOUNT{$i}, $XSUM{$i}, $XSQUARESUM{$i};
# Divide by mean price to determine volatility of price
if ($XCOUNT{$i} != 0 && $XSUM{$i} != 0) {
$volatility = $deviation / ($XSUM{$i} / $XCOUNT{$i});
printf "%10s %10.2f %14.3f %9.3f %9.3f\n", $i, $XSUM{$i}/$XCOUNT{$i},
$variance, $deviation,
$volatility *100;
($VARIANCE{$i}, $STD{$i}, $VOLATILITY{$i}) = ($variance, $deviation,
$volatility);
}
}
print "------------------------------------------------------------------------";
}
sub get_currency {
local ($to) = @_;
local($url) =
"http://www.dna.lth.se/cgi-bin/kurt/rates/rates?CAD+$to";
local($line, $rate);
local ($command) = &get_url_command($url);
local($fromname, $toname) = ($CURRNAME{"CDN"}, $CURRNAME{$to});
open(CURRS, "$command |");
while ($line = <CURRS>) {
if ($line =~ /Rate: $fromname.*$toname.*:\s*(\d*.\d+)/) {
$rate = $1;
$CURRATE{$toname} = sprintf("%f", $rate);
return;
}
}
}

View File

@ -118,7 +118,7 @@
;;
;; (<fq-method> sym sym ...)
;;
;; i.e. (yahoo "RHAT" "LNUX" "IBM")
;; i.e. (alphavantage "RHAT" "LNUX" "IBM")
;;
;; for currencies, we have
;;
@ -210,7 +210,7 @@
;; gnc-fq-helper. Each item will of the list will be of the
;; form:
;;
;; (("yahoo" (commodity-1 currency-1 tz-1)
;; (("alphavantage" (commodity-1 currency-1 tz-1)
;; (commodity-2 currency-2 tz-2) ...)
;; ("fidelity_direct" (commodity-3 currency-3 tz-3)
;; (commodity-4 currency-4 tz-4) ...)
@ -259,10 +259,10 @@
;; their fq-suitable symbol strings. i.e. turn the former into
;; the latter:
;;
;; ("yahoo" (commodity-1 currency-1 tz-1)
;; ("alphavantage" (commodity-1 currency-1 tz-1)
;; (commodity-2 currency-2 tz-2) ...)
;;
;; ("yahoo" "IBM" "AMD" ...)
;; ("alphavantage" "IBM" "AMD" ...)
;;
(if (equal? (car fq-call-data) "currency")