diff --git a/gnucash/gnome-utils/gnc-tree-view-commodity.c b/gnucash/gnome-utils/gnc-tree-view-commodity.c index a1fe561a22..62d21d9a02 100644 --- a/gnucash/gnome-utils/gnc-tree-view-commodity.c +++ b/gnucash/gnome-utils/gnc-tree-view-commodity.c @@ -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); diff --git a/libgnucash/backend/dbi/test/test-dbi.xml b/libgnucash/backend/dbi/test/test-dbi.xml index 863ae369c6..5ea03f5379 100644 --- a/libgnucash/backend/dbi/test/test-dbi.xml +++ b/libgnucash/backend/dbi/test/test-dbi.xml @@ -51,7 +51,7 @@ 12345 10000 - yahoo + alphavantage Root Account diff --git a/libgnucash/doc/design/top-level.texi b/libgnucash/doc/design/top-level.texi index 2900092bc5..50b52833ad 100644 --- a/libgnucash/doc/design/top-level.texi +++ b/libgnucash/doc/design/top-level.texi @@ -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 diff --git a/libgnucash/engine/gnc-commodity.c b/libgnucash/engine/gnc-commodity.c index c9c28ed123..b31832b994 100644 --- a/libgnucash/engine/gnc-commodity.c +++ b/libgnucash/engine/gnc-commodity.c @@ -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 ¤cy_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"); } /******************************************************************** diff --git a/libgnucash/quotes/Quote_example.pl b/libgnucash/quotes/Quote_example.pl index 82192e05f4..220ee27f15 100755 --- a/libgnucash/quotes/Quote_example.pl +++ b/libgnucash/quotes/Quote_example.pl @@ -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. diff --git a/libgnucash/quotes/gnc-fq-dump b/libgnucash/quotes/gnc-fq-dump index da1c23e635..44e18266d8 100755 --- a/libgnucash/quotes/gnc-fq-dump +++ b/libgnucash/quotes/gnc-fq-dump @@ -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 diff --git a/libgnucash/quotes/gnc-fq-helper.in b/libgnucash/quotes/gnc-fq-helper.in index 75ce57858c..fb6e4e9656 100755 --- a/libgnucash/quotes/gnc-fq-helper.in +++ b/libgnucash/quotes/gnc-fq-helper.in @@ -48,16 +48,14 @@ side :>). ( symbol symbol symbol ...) where 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") diff --git a/libgnucash/quotes/gnc-value-portfolio b/libgnucash/quotes/gnc-value-portfolio deleted file mode 100755 index 7c27f08ee9..0000000000 --- a/libgnucash/quotes/gnc-value-portfolio +++ /dev/null @@ -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, ") { - 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 = ) { -# 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 = ) { - 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 () { - 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 = ) { - ($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 () { - ($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 = ) { - if ($line =~ /Rate: $fromname.*$toname.*:\s*(\d*.\d+)/) { - $rate = $1; - $CURRATE{$toname} = sprintf("%f", $rate); - return; - } - } -} - diff --git a/libgnucash/scm/price-quotes.scm b/libgnucash/scm/price-quotes.scm index 095abd2c9b..c67876b4a6 100644 --- a/libgnucash/scm/price-quotes.scm +++ b/libgnucash/scm/price-quotes.scm @@ -118,7 +118,7 @@ ;; ;; ( 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")