Stocks/get prices
From GnuCash
This document explains how to import historic stock quotes into gnucash
Some knowledge of perl and python is required, adding a sample stock to Gnucash is explained here Add stock to portfolio. The first thing is to get historic stock prices. This is done with the perl module QuoteHist. A sample perl script to get quotes is e.g.:
#!/usr/bin/perl -w
use Finance::QuoteHist;
print "Will get stock quotes of $ARGV[0] and save it into the file $ARGV[0]\n";
$fname = $ARGV[0];
open (MYFILE, ">$fname");
$q = Finance::QuoteHist->new
(
symbols => [($ARGV[0])],
start_date => '01/01/2000',
end_date => 'today',
);
print "name,date, open, high, low, close, volume\n";
foreach $row ($q->quotes()) {
($name,$date, $open, $high, $low, $close, $volume) = @$row;
print MYFILE "$name,$date, $open, $high, $low, $close, $volume\n";
}
close(MYFILE);
On Unix/Linux save the text into a file (e.g. get_quotes) , do a chmod a+x and execute it with the argument INTC to get the Intel prices saved into the file INTC
chmod a+x get_quotes ./get_quotes INTC
from gnucash import Session, Account, Split
import gnucash
import datetime
from fractions import Fraction
- Function definition from Christoph Holtermann
def FindAccount(account,name,account_list=None):
"""Searches full names of account and descendents
returns a list of accounts which contain name."""
if not account_list: account_list=[]
for child in account.get_children():
child=Account(instance=child)
account_list=FindAccount(child,name,account_list)
Account_name=account.GetName()
if name in Account_name:
account_list.append(account)
return account_list
FILE = "./test.gnucash"
url = "xml://"+FILE
# Read data from file
f = open('INTC')
data = []
while 1:
tmp = f.readline()
if(len(tmp)<2):
break
data.append(tmp)
f.close()
stock_date = []
stock_price = []
for i in range(1,len(data)):
year = int(data[i].rsplit(',')[1].rsplit('/')[0])
month = int(data[i].rsplit(',')[1].rsplit('/')[1])
day = int(data[i].rsplit(',')[1].rsplit('/')[2])
stock_date.append(datetime.datetime(year,month,day))
stock_price.append(float(data[i].rsplit(',')[5]))
# Initialize Gnucash session
session = Session(url, True, False, False)
root = session.book.get_root_account()
book = session.book
account = book.get_root_account()
pdb = book.get_price_db()
comm_table = book.get_table()
ac = FindAccount(account,'Intel')[0]
stock = ac.GetCommodity()
# Add the prices
pdb = book.get_price_db()
if len(ac.GetSplitList())<1:
print 'Need at least one Split to get currency info ... '
cur = Split(instance=ac.GetSplitList()[0]).GetParent().GetCurrency()
# Get stock data
pl = pdb.get_prices(stock,cur)
if len(pl)<1:
print 'Need at least one database entry to clone ...'
pl0 = pl[0]
for i in range(1,len(pl)):
pdb.remove_price(pl[i])
for i in range(0,len(stock_date)):
p_new = pl0.clone(book)
p_new = gnucash.GncPrice(instance=p_new)
print 'Adding',i,stock_date[i],stock_price[i]
p_new.set_time(stock_date[i])
v = p_new.get_value()
v.num = int(Fraction.from_float(stock_price[i]).limit_denominator(100000).numerator)
v.denom = int(Fraction.from_float(stock_price[i]).limit_denominator(100000).denominator)
p_new.set_value(v)
pdb.add_price(p_new)
# Clean up
session.save()
session.end()
session.destroy()
You have now a nice stock quotes from Intel in your Gnucash file!