Difference between revisions of "Stocks/get prices"

From GnuCash
Jump to: navigation, search
m (This document explains how to import historic stock quotes into gnucash)
Line 29: Line 29:
 
  chmod a+x get_quotes
 
  chmod a+x get_quotes
 
  ./get_quotes INTC
 
  ./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!

Revision as of 16:32, 19 January 2011

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

  1. 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!