Set the desired line-ending style to the correct value on the server side.

Without the svn:eol-style property, SVN checkouts on windows tend to appear
with varying line endings. The only possible way around this in svn is to
set the expected line endings as svn properties.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18959 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Christian Stimming 2010-03-24 19:18:08 +00:00
parent 3fdbb0a412
commit c172bc7ee4
18 changed files with 8496 additions and 8496 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +1,51 @@
GnuCash is een vrij, open source boekhoudprogramma, uitgegeven
onder de GNU General Public License (GPL) en is beschikbaar voor
GNU/Linux, *BSD, Solaris, Mac OSX, en Microsoft Windows.
Het is een eenvoudig te gebruiken, en tegelijkertijd krachtig en flexibel
programma dat je helpt om je bankrekeningen, aandelen, inkomsten en uitgaven
te beheren. Zo vlot en intuïtief te gebruiken als een dagboek enerzijds, en
anderzijds gebaseerd op professionele boekhoudkundige principes om boeken in
balans en nauwkeurige rapporten te verzekeren.
-------------------
Beschikbare bronnen voor ondersteuning
Online veel gestelde vragen (FAQ): http://wiki.gnucash.org/wiki/FAQ
Mailing Lijsten: http://wiki.gnucash.org/wiki/Mailing_Lists
IRC (Chat): Channel #gnucash on server irc.gnome.org, see also http://wiki.gnucash.org/wiki/IRC
Als je programmafouten (bugs) of problemen ervaart, aarzel niet om deze te melden in ons
bug opvolgsysteem "Bugzilla":
http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
-------------------
Interessante functies:
* Dubbele boekhouding
* Aandelen-/belegginsrekeningen
* QIF/OFX/HBCI import met dubbele transactie herkenning
* Rapporten, grafieken
* Klein-ondernemingsboekhouding
* Klanten, verkopers, opdrachten, Facturen, Lopende rekening
* Periodieke Transacties
* Financiële berekeningen
Meer informatie en een handleiding om je op weg te helpen vind je
in het "Hulp" menu onder het "Tutorial en concepten gids".
-------------------
Over het programma:
GnuCash is a vrij, open source boekhoudprogramma uitgegeven onder de
GNU General Public License (GPL). Het wordt door 12 personen uit meer dan
6 landen gezamelijk ontwikkeld.
De ontwikkeling van GnuCash begon in 1997, de de eerste uitgave was in 1998.
-------------------
This is the Dutch GnuCash 2.2.x README file for Windows binary packages.
GnuCash is een vrij, open source boekhoudprogramma, uitgegeven
onder de GNU General Public License (GPL) en is beschikbaar voor
GNU/Linux, *BSD, Solaris, Mac OSX, en Microsoft Windows.
Het is een eenvoudig te gebruiken, en tegelijkertijd krachtig en flexibel
programma dat je helpt om je bankrekeningen, aandelen, inkomsten en uitgaven
te beheren. Zo vlot en intuïtief te gebruiken als een dagboek enerzijds, en
anderzijds gebaseerd op professionele boekhoudkundige principes om boeken in
balans en nauwkeurige rapporten te verzekeren.
-------------------
Beschikbare bronnen voor ondersteuning
Online veel gestelde vragen (FAQ): http://wiki.gnucash.org/wiki/FAQ
Mailing Lijsten: http://wiki.gnucash.org/wiki/Mailing_Lists
IRC (Chat): Channel #gnucash on server irc.gnome.org, see also http://wiki.gnucash.org/wiki/IRC
Als je programmafouten (bugs) of problemen ervaart, aarzel niet om deze te melden in ons
bug opvolgsysteem "Bugzilla":
http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
-------------------
Interessante functies:
* Dubbele boekhouding
* Aandelen-/belegginsrekeningen
* QIF/OFX/HBCI import met dubbele transactie herkenning
* Rapporten, grafieken
* Klein-ondernemingsboekhouding
* Klanten, verkopers, opdrachten, Facturen, Lopende rekening
* Periodieke Transacties
* Financiële berekeningen
Meer informatie en een handleiding om je op weg te helpen vind je
in het "Hulp" menu onder het "Tutorial en concepten gids".
-------------------
Over het programma:
GnuCash is a vrij, open source boekhoudprogramma uitgegeven onder de
GNU General Public License (GPL). Het wordt door 12 personen uit meer dan
6 landen gezamelijk ontwikkeld.
De ontwikkeling van GnuCash begon in 1997, de de eerste uitgave was in 1998.
-------------------
This is the Dutch GnuCash 2.2.x README file for Windows binary packages.

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +1,61 @@
!Type:Bank
D01/01/95
T145,608.32
CX
POpening Balance
L[Livret bleu]
^
D01/26/95
CX
MEconomies
T2,500.00
L[Compte courant]
^
D02/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D03/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D04/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D05/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D06/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D07/26/95
CX
MEconomies
T2,500.00
L[Compte courant]
^
D11/12/95
CX
MPour équilibrage
T-4,500.00
L[Compte courant]
^
D12/26/95
CX
MEconomies
T3,500.00
L[Compte courant]
^
!Type:Bank
D01/01/95
T145,608.32
CX
POpening Balance
L[Livret bleu]
^
D01/26/95
CX
MEconomies
T2,500.00
L[Compte courant]
^
D02/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D03/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D04/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D05/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D06/26/95
CX
MEconomies
T3,000.00
L[Compte courant]
^
D07/26/95
CX
MEconomies
T2,500.00
L[Compte courant]
^
D11/12/95
CX
MPour équilibrage
T-4,500.00
L[Compte courant]
^
D12/26/95
CX
MEconomies
T3,500.00
L[Compte courant]
^

View File

@ -1,30 +1,30 @@
!Type:Invst
D07/24/95
T24,618.15
L[Livret bleu]
$24,618.15
NBuyX
YO-Sicav Plus
I304.68
Q60
O6,337.35
^
D10/08/95
T32,544.00
L[Livret bleu]
$32,544.00
NBuyX
YO-Sicav Plus
I339
Q90
O2,034.00
^
D12/10/95
T20,532.00
L[Livret bleu]
$20,532.00
NBuyX
YO-Sicav Plus
I342.2
Q60
^
!Type:Invst
D07/24/95
T24,618.15
L[Livret bleu]
$24,618.15
NBuyX
YO-Sicav Plus
I304.68
Q60
O6,337.35
^
D10/08/95
T32,544.00
L[Livret bleu]
$32,544.00
NBuyX
YO-Sicav Plus
I339
Q90
O2,034.00
^
D12/10/95
T20,532.00
L[Livret bleu]
$20,532.00
NBuyX
YO-Sicav Plus
I342.2
Q60
^

View File

@ -1,268 +1,268 @@
!Type:Invst
D01/01/95
CX
MInitial balance
T4,491.22
NShrsIn
YMicrosoft
I26.5
Q94.008451
O2,000.00
^
D01/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I132.5
Q3.638491
^
D01/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I147.083365
Q3.277733
^
D02/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I148.75
Q3.241008
^
D02/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I150
Q3.214
^
D03/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I150.416664
Q3.205097
^
D03/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I151.666634
Q3.178682
^
D04/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I165.625026
Q2.910792
^
D04/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I160.624988
Q3.001401
^
D05/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I168.749993
Q2.856889
^
D05/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I167.916667
Q2.871067
^
D06/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I172.499976
Q2.794783
^
D06/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I185.62498
Q2.597172
^
D07/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I210.625007
Q2.288902
^
D07/06/95
T18,000.00
L[Livret bleu]
$18,000.00
NBuyX
YUsinor/Sacilor
I180
Q100
^
D07/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I215.625008
Q2.235826
^
D08/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I205.625024
Q2.344559
^
D08/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I215.625008
Q2.235826
^
D09/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I195.624996
Q2.464409
^
D09/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I205.625024
Q2.344559
^
D10/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I200.624971
Q2.402991
^
D10/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I207.083359
Q2.328048
^
D11/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I214.166627
Q2.251051
^
D11/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I195.833352
Q2.461787
^
D11/18/95
T17,200.00
L[Livret bleu]
$17,200.00
NBuyX
YUsinor/Sacilor
I215
Q80
^
D12/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I195.833352
Q2.461787
^
D12/10/95
T17,440.00
L[Livret bleu]
$17,440.00
NBuyX
YUsinor/Sacilor
I218
Q80
^
D12/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I196.041674
Q2.459171
^
!Type:Invst
D01/01/95
CX
MInitial balance
T4,491.22
NShrsIn
YMicrosoft
I26.5
Q94.008451
O2,000.00
^
D01/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I132.5
Q3.638491
^
D01/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I147.083365
Q3.277733
^
D02/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I148.75
Q3.241008
^
D02/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I150
Q3.214
^
D03/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I150.416664
Q3.205097
^
D03/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I151.666634
Q3.178682
^
D04/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I165.625026
Q2.910792
^
D04/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I160.624988
Q3.001401
^
D05/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I168.749993
Q2.856889
^
D05/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I167.916667
Q2.871067
^
D06/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I172.499976
Q2.794783
^
D06/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I185.62498
Q2.597172
^
D07/01/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I210.625007
Q2.288902
^
D07/06/95
T18,000.00
L[Livret bleu]
$18,000.00
NBuyX
YUsinor/Sacilor
I180
Q100
^
D07/16/95
CX
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I215.625008
Q2.235826
^
D08/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I205.625024
Q2.344559
^
D08/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I215.625008
Q2.235826
^
D09/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I195.624996
Q2.464409
^
D09/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I205.625024
Q2.344559
^
D10/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I200.624971
Q2.402991
^
D10/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I207.083359
Q2.328048
^
D11/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I214.166627
Q2.251051
^
D11/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I195.833352
Q2.461787
^
D11/18/95
T17,200.00
L[Livret bleu]
$17,200.00
NBuyX
YUsinor/Sacilor
I215
Q80
^
D12/01/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I195.833352
Q2.461787
^
D12/10/95
T17,440.00
L[Livret bleu]
$17,440.00
NBuyX
YUsinor/Sacilor
I218
Q80
^
D12/16/95
T482.10
L[Livret bleu]
$482.10
NBuyX
YMicrosoft
I196.041674
Q2.459171
^

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +1,50 @@
!Type:Bank
D6/17/97
T2,345.00
NDEP
Pfrom my pillow case
Mmy memo
LOther Inc
^^
D8/ 1/97
T3,300.00
NDEP
Pput in more money
Mthis came out of my pillowcas
LOther Inc
^^
D8/ 1/97
T543.00
N101
Ppaycheck
Mthe boss paid me today!
LGift Received
^^
D9/12/97
T-5,000.00
NTXFR
Pmove a pile of money to trading acct
Manother memo
L[Swipe Brokers]
^^
D11/11/97
T12.00
NTXFR
Phal stock
Mincome
L[Swipe Brokers]
^^
D11/11/97
T11.00
NTXFR
Phal stock
Mincome
L[Swipe Brokers]
^^
D11/12/97
T500.00
NTXFR
Phal stock
Msold some stock!
L[Swipe Brokers]
^^
!Type:Bank
D6/17/97
T2,345.00
NDEP
Pfrom my pillow case
Mmy memo
LOther Inc
^^
D8/ 1/97
T3,300.00
NDEP
Pput in more money
Mthis came out of my pillowcas
LOther Inc
^^
D8/ 1/97
T543.00
N101
Ppaycheck
Mthe boss paid me today!
LGift Received
^^
D9/12/97
T-5,000.00
NTXFR
Pmove a pile of money to trading acct
Manother memo
L[Swipe Brokers]
^^
D11/11/97
T12.00
NTXFR
Phal stock
Mincome
L[Swipe Brokers]
^^
D11/11/97
T11.00
NTXFR
Phal stock
Mincome
L[Swipe Brokers]
^^
D11/12/97
T500.00
NTXFR
Phal stock
Msold some stock!
L[Swipe Brokers]
^^

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +1,78 @@
!Type:Invst
D9/12/97
NXIn
T5,000.00
MMemo: open brokerage acct.
L[ABC Bank]
$5,000.00
^^
D10/16/97
NBuy
YHALCorp.
I35
Q100
T3,500.00
Mthis is the first stock purch
^^
D10/16/97
NDiv
YHALCorp.
T120.00
^^
D10/28/97
NBuy
YTHJ Inc
I2.340
Q100
T234.00
Mpurchase thj shares
^^
D11/11/97
NCGLong
YHALCorp.
T33.45
^^
D11/11/97
NDiv
YTHJ Inc
T34.00
Mmemo-- income I think
^^
D11/11/97
NIntInc
YHALCorp.
T345.00
Mincome
^^
D11/11/97
NCGShortX
YHALCorp.
T12.00
Mincome
L[ABC Bank]
$12.00
^^
D11/11/97
NCGLongX
YHALCorp.
T11.00
Mincome
L[ABC Bank]
$11.00
^^
D11/11/97
NBuy
YTHJ Inc
I2
Q100
T200.00
^^
D11/12/97
NSellX
YHALCorp.
I50
Q10
T500.00
L[ABC Bank]
$500.00
^^
!Type:Invst
D9/12/97
NXIn
T5,000.00
MMemo: open brokerage acct.
L[ABC Bank]
$5,000.00
^^
D10/16/97
NBuy
YHALCorp.
I35
Q100
T3,500.00
Mthis is the first stock purch
^^
D10/16/97
NDiv
YHALCorp.
T120.00
^^
D10/28/97
NBuy
YTHJ Inc
I2.340
Q100
T234.00
Mpurchase thj shares
^^
D11/11/97
NCGLong
YHALCorp.
T33.45
^^
D11/11/97
NDiv
YTHJ Inc
T34.00
Mmemo-- income I think
^^
D11/11/97
NIntInc
YHALCorp.
T345.00
Mincome
^^
D11/11/97
NCGShortX
YHALCorp.
T12.00
Mincome
L[ABC Bank]
$12.00
^^
D11/11/97
NCGLongX
YHALCorp.
T11.00
Mincome
L[ABC Bank]
$11.00
^^
D11/11/97
NBuy
YTHJ Inc
I2
Q100
T200.00
^^
D11/12/97
NSellX
YHALCorp.
I50
Q10
T500.00
L[ABC Bank]
$500.00
^^

View File

@ -1,10 +1,10 @@
Index: dbd_mysql.c
===================================================================
RCS file: /cvsroot/libdbi-drivers/libdbi-drivers/drivers/mysql/dbd_mysql.c,v
retrieving revision 1.31
diff -u -r1.31 dbd_mysql.c
--- drivers/mysql/dbd_mysql.c 13 Aug 2008 22:56:03 -0000 1.31
+++ drivers/mysql/dbd_mysql.c 16 Aug 2008 20:23:23 -0000
Index: dbd_mysql.c
===================================================================
RCS file: /cvsroot/libdbi-drivers/libdbi-drivers/drivers/mysql/dbd_mysql.c,v
retrieving revision 1.31
diff -u -r1.31 dbd_mysql.c
--- drivers/mysql/dbd_mysql.c 13 Aug 2008 22:56:03 -0000 1.31
+++ drivers/mysql/dbd_mysql.c 16 Aug 2008 20:23:23 -0000
@@ -553,15 +553,15 @@
return db;
}

View File

@ -1,24 +1,24 @@
Index: dbd_sqlite3.c
===================================================================
RCS file: /cvsroot/libdbi-drivers/libdbi-drivers/drivers/sqlite3/dbd_sqlite3.c,v
retrieving revision 1.31
diff -u -r1.31 dbd_sqlite3.c
--- drivers/sqlite3/dbd_sqlite3.c 13 Aug 2008 22:56:03 -0000 1.31
+++ drivers/sqlite3/dbd_sqlite3.c 16 Aug 2008 20:23:23 -0000
@@ -1369,11 +1369,11 @@
return db;
}
-int dbd_geterror(dbi_conn_t *conn, int *errno, char **errstr) {
- /* put error number into errno, error string into errstr
- * return 0 if error, 1 if errno filled, 2 if errstr filled, 3 if both errno and errstr filled */
+int dbd_geterror(dbi_conn_t *conn, int *err_no, char **errstr) {
+ /* put error number into err_no, error string into errstr
+ * return 0 if error, 1 if err_no filled, 2 if errstr filled, 3 if both err_no and errstr filled */
- *errno = sqlite3_errcode((sqlite3 *)conn->connection);
+ *err_no = sqlite3_errcode((sqlite3 *)conn->connection);
*errstr = strdup((char*)sqlite3_errmsg((sqlite3 *)conn->connection));
return 3;
}
Index: dbd_sqlite3.c
===================================================================
RCS file: /cvsroot/libdbi-drivers/libdbi-drivers/drivers/sqlite3/dbd_sqlite3.c,v
retrieving revision 1.31
diff -u -r1.31 dbd_sqlite3.c
--- drivers/sqlite3/dbd_sqlite3.c 13 Aug 2008 22:56:03 -0000 1.31
+++ drivers/sqlite3/dbd_sqlite3.c 16 Aug 2008 20:23:23 -0000
@@ -1369,11 +1369,11 @@
return db;
}
-int dbd_geterror(dbi_conn_t *conn, int *errno, char **errstr) {
- /* put error number into errno, error string into errstr
- * return 0 if error, 1 if errno filled, 2 if errstr filled, 3 if both errno and errstr filled */
+int dbd_geterror(dbi_conn_t *conn, int *err_no, char **errstr) {
+ /* put error number into err_no, error string into errstr
+ * return 0 if error, 1 if err_no filled, 2 if errstr filled, 3 if both err_no and errstr filled */
- *errno = sqlite3_errcode((sqlite3 *)conn->connection);
+ *err_no = sqlite3_errcode((sqlite3 *)conn->connection);
*errstr = strdup((char*)sqlite3_errmsg((sqlite3 *)conn->connection));
return 3;
}

View File

@ -1,159 +1,159 @@
/*
* gnc-help-utils.c
*
* Copyright (C) 2007 Andreas Koehler <andi5.py@gmx.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#include "config.h"
#include <glib.h>
#ifdef HAVE_HTMLHELPW
# include <windows.h>
# include <htmlhelp.h>
#endif
#include "gnc-help-utils.h"
#ifdef HAVE_HTMLHELPW
static GHashTable *
parse_hhmap_file(const gchar *chmfile)
{
gchar *mapfile = NULL, *dot;
GKeyFile *keyfile = NULL;
GError *error = NULL;
gchar **keys = NULL, **key;
gint value;
GHashTable *ctxtmap = NULL;
g_return_val_if_fail(chmfile, NULL);
mapfile = g_new(gchar, strlen(chmfile) + 7);
strcpy(mapfile, chmfile);
dot = strrchr(mapfile, '.');
if (dot)
strcpy(dot, ".hhmap");
else
strcat(mapfile, ".hhmap");
keyfile = g_key_file_new();
if (!g_key_file_load_from_file(keyfile, mapfile, G_KEY_FILE_NONE, &error))
goto cleanup_parse;
if (NULL == (keys = g_key_file_get_keys(keyfile, "Map", NULL, &error)))
goto cleanup_parse;
ctxtmap = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
for (key = keys; *key; key++)
{
value = g_key_file_get_integer(keyfile, "Map", *key, &error);
if (error)
goto cleanup_parse;
else
g_hash_table_insert(ctxtmap, g_strdup(*key), GINT_TO_POINTER(value));
}
cleanup_parse:
if (error)
{
g_warning("Could not load help map file: %s", error->message);
g_error_free(error);
if (ctxtmap)
g_hash_table_destroy(ctxtmap);
ctxtmap = NULL;
}
if (keys)
g_strfreev(keys);
if (keyfile)
g_key_file_free (keyfile);
if (mapfile)
g_free(mapfile);
return ctxtmap;
}
void
gnc_show_htmlhelp(const gchar *chmfile, const gchar *anchor)
{
static GHashTable *chmfile_ctxtmap_map;
G_LOCK_DEFINE_STATIC(chmfile_ctxtmap_map);
GHashTable *ctxtmap;
gboolean create_map = FALSE;
wchar_t *wpath;
gint id = 0;
g_return_if_fail(chmfile);
if (anchor)
{
G_LOCK(chmfile_ctxtmap_map);
if (!chmfile_ctxtmap_map)
{
chmfile_ctxtmap_map = g_hash_table_new(g_str_hash, g_str_equal);
create_map = TRUE;
}
else
{
create_map = !g_hash_table_lookup_extended(
chmfile_ctxtmap_map, chmfile, NULL, (gpointer) & ctxtmap);
}
if (create_map)
{
ctxtmap = parse_hhmap_file(chmfile);
g_hash_table_insert(chmfile_ctxtmap_map, g_strdup(chmfile), ctxtmap);
}
if (ctxtmap)
{
gpointer ptr = g_hash_table_lookup(ctxtmap, anchor);
if (ptr)
id = GPOINTER_TO_INT(ptr);
}
G_UNLOCK(chmfile_ctxtmap_map);
if (!id)
g_warning("Could not find anchor '%s'", anchor);
}
wpath = g_utf8_to_utf16(chmfile, -1, NULL, NULL, NULL);
HtmlHelpW(GetDesktopWindow(), wpath, HH_HELP_CONTEXT, id);
g_free(wpath);
}
#else /* !HAVE_HTMLHELPW */
void
gnc_show_htmlhelp(const gchar *chmfile, const gchar *anchor)
{
gchar *argv[3];
g_return_if_fail(chmfile);
argv[0] = "hh";
argv[1] = g_strdup(chmfile);
argv[2] = NULL;
if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
NULL, NULL, NULL, NULL))
if (g_file_test(chmfile, G_FILE_TEST_IS_REGULAR))
g_warning("Found CHM help file, but could not spawn hh to open it");
g_free(argv[1]);
}
#endif /* HAVE_HTMLHELPW */
/*
* gnc-help-utils.c
*
* Copyright (C) 2007 Andreas Koehler <andi5.py@gmx.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#include "config.h"
#include <glib.h>
#ifdef HAVE_HTMLHELPW
# include <windows.h>
# include <htmlhelp.h>
#endif
#include "gnc-help-utils.h"
#ifdef HAVE_HTMLHELPW
static GHashTable *
parse_hhmap_file(const gchar *chmfile)
{
gchar *mapfile = NULL, *dot;
GKeyFile *keyfile = NULL;
GError *error = NULL;
gchar **keys = NULL, **key;
gint value;
GHashTable *ctxtmap = NULL;
g_return_val_if_fail(chmfile, NULL);
mapfile = g_new(gchar, strlen(chmfile) + 7);
strcpy(mapfile, chmfile);
dot = strrchr(mapfile, '.');
if (dot)
strcpy(dot, ".hhmap");
else
strcat(mapfile, ".hhmap");
keyfile = g_key_file_new();
if (!g_key_file_load_from_file(keyfile, mapfile, G_KEY_FILE_NONE, &error))
goto cleanup_parse;
if (NULL == (keys = g_key_file_get_keys(keyfile, "Map", NULL, &error)))
goto cleanup_parse;
ctxtmap = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
for (key = keys; *key; key++)
{
value = g_key_file_get_integer(keyfile, "Map", *key, &error);
if (error)
goto cleanup_parse;
else
g_hash_table_insert(ctxtmap, g_strdup(*key), GINT_TO_POINTER(value));
}
cleanup_parse:
if (error)
{
g_warning("Could not load help map file: %s", error->message);
g_error_free(error);
if (ctxtmap)
g_hash_table_destroy(ctxtmap);
ctxtmap = NULL;
}
if (keys)
g_strfreev(keys);
if (keyfile)
g_key_file_free (keyfile);
if (mapfile)
g_free(mapfile);
return ctxtmap;
}
void
gnc_show_htmlhelp(const gchar *chmfile, const gchar *anchor)
{
static GHashTable *chmfile_ctxtmap_map;
G_LOCK_DEFINE_STATIC(chmfile_ctxtmap_map);
GHashTable *ctxtmap;
gboolean create_map = FALSE;
wchar_t *wpath;
gint id = 0;
g_return_if_fail(chmfile);
if (anchor)
{
G_LOCK(chmfile_ctxtmap_map);
if (!chmfile_ctxtmap_map)
{
chmfile_ctxtmap_map = g_hash_table_new(g_str_hash, g_str_equal);
create_map = TRUE;
}
else
{
create_map = !g_hash_table_lookup_extended(
chmfile_ctxtmap_map, chmfile, NULL, (gpointer) & ctxtmap);
}
if (create_map)
{
ctxtmap = parse_hhmap_file(chmfile);
g_hash_table_insert(chmfile_ctxtmap_map, g_strdup(chmfile), ctxtmap);
}
if (ctxtmap)
{
gpointer ptr = g_hash_table_lookup(ctxtmap, anchor);
if (ptr)
id = GPOINTER_TO_INT(ptr);
}
G_UNLOCK(chmfile_ctxtmap_map);
if (!id)
g_warning("Could not find anchor '%s'", anchor);
}
wpath = g_utf8_to_utf16(chmfile, -1, NULL, NULL, NULL);
HtmlHelpW(GetDesktopWindow(), wpath, HH_HELP_CONTEXT, id);
g_free(wpath);
}
#else /* !HAVE_HTMLHELPW */
void
gnc_show_htmlhelp(const gchar *chmfile, const gchar *anchor)
{
gchar *argv[3];
g_return_if_fail(chmfile);
argv[0] = "hh";
argv[1] = g_strdup(chmfile);
argv[2] = NULL;
if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
NULL, NULL, NULL, NULL))
if (g_file_test(chmfile, G_FILE_TEST_IS_REGULAR))
g_warning("Found CHM help file, but could not spawn hh to open it");
g_free(argv[1]);
}
#endif /* HAVE_HTMLHELPW */

View File

@ -1,36 +1,36 @@
/*
* gnc-help-utils.h
*
* Copyright (C) 2007 Andreas Koehler <andi5.py@gmx.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_HELP_UTILS_H__
#define __GNC_HELP_UTILS_H__
/** Launch HTML Help Viewer and open a given CHM file. Use HtmlHelpW
* if available, or fallback to spawning hh.exe. Possibly scroll to a
* given anchor within the document.
*
* @param chmfile The name of CHM help file to be opened.
*
* @param anchor The anchor the help browser should scroll to.
*/
void gnc_show_htmlhelp(const gchar *chmfile, const gchar *anchor);
#endif /* __GNC_HELP_UTILS_H__ */
/*
* gnc-help-utils.h
*
* Copyright (C) 2007 Andreas Koehler <andi5.py@gmx.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_HELP_UTILS_H__
#define __GNC_HELP_UTILS_H__
/** Launch HTML Help Viewer and open a given CHM file. Use HtmlHelpW
* if available, or fallback to spawning hh.exe. Possibly scroll to a
* given anchor within the document.
*
* @param chmfile The name of CHM help file to be opened.
*
* @param anchor The anchor the help browser should scroll to.
*/
void gnc_show_htmlhelp(const gchar *chmfile, const gchar *anchor);
#endif /* __GNC_HELP_UTILS_H__ */

View File

@ -1,337 +1,337 @@
<HTML>
<HEAD>
<TITLE>Financial Equations Documentation</TITLE>
</HEAD>
<BODY>
<A NAME="TOP"></A>
<A HREF="./finutil.html#FinEquation">Return</A>
<HR>
<br>
<dl>
<dt><A HREF="#BasicEquation">Basic Equation</A></dt>
<dt><A HREF="#SeriesSum">Series Sum</A></dt>
</dl>
<HR>
<h1>Financial Equation Derivation</h1>
<p>The financial equation is derived in the following manner:
<p>Start with the basic equation to find the balance or Present Value, PV[1], after
one payment period. Note PV[1] is the Present Value after one payment and PV[0]
is the initial Present Value. PV[0] will be shortened to just PV.
<p>The interest due at the end of the first payment period is the original present value,
PV, times the interest rate for the payment period plus the periodic payment times the
interest rate for beginning of period payments:
<p>ID[1] = PV * i + X * PMT * i = (PV + X * PMT) * i
<p>The Present Value after one payment is the original Present Value with the periodic
payment, PMT, and interest due, ID[1], added:
<pre>
PV[1] = PV + (PMT + ID[1])
PV[1] = PV + (PMT + (PV + X * PMT) * i)
PV[1] = PV * (1 + i) + PMT * (1 + Xi)
</pre>
<p>This equation works for all of the cash flow diagrams shown previously. The Present Value,
money received or paid, is modified by a payment made at the beginning of a payment
period and multiplied by the effective interest rate to compute the interest
due during the payment period. The interest due is then added to the payment
to obtain the amount to be added to the Present Value to compute the new Present Value.
<p>For diagram 1): PV < 0, PMT == 0, PV[1] < 0
<br>For diagram 2): PV == 0, PMT < 0, PV[1] < 0
<br>For Diagram 3): PV > 0, PMT < 0, PV[1] >= 0 or PV[1] <= 0
<br>For Diagram 4): PV < 0, PMT > 0, PV[1] <= 0 or PV[1] >= 0
<p>X may be 0 or 1 for any diagram.
<p>For the standard loan, PV is the money borrowed, PMT is the periodic payment to repay
the loan, i is the effective interest rate agreed upon and FV is the residual loan amount
after the agreed upon number of periodic payment periods. If the loan is fully paid off
by the periodic payments, FV is zero, 0. If the loan is not completely paid off after the
agreed upon number of payments, a balloon payment is necessary to completely pay off the loan.
FV is then the amount of the needed balloon payment. For a loan in which the borrower pays
only enough to repay the interest due during a payment period, interest only loan, the
balloon payment is equal to the negative of PV.
<p>To calculate the Present Value after the second payment period, the above calculation
is applied iteratively to PV[1] to obtain PV[2]. In fact to calculate the Present Value
after any payment period, PV[n], the above equation is applied iteratively to PV[n-1]
as shown below.
<pre>
PV[2] = PV[1] + (PMT + (PV[1] + X * PMT) * i)
= PV[1] * (1 + i) + PMT * (1 + iX)
= (PV * (1 + i) + PMT * (1 + iX)) * (1 + i) + PMT * (1 + iX)
= PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i)
+ PMT * (1 + iX)
</pre>
<p>Similarly, PV[3] is computed from PV[2] as:
<pre>
PV[3] = PV[2] + (PMT + (PV[2] + X * PMT) * i)
= PV[2] * (1 + i) + PMT * (1 + iX)
= (PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i)
+ PMT * (1+ iX)) * (1 + i)
+ PMT * (1+ iX)
= PV * (1 + i)^3 + PMT * (1 + iX) * (1 + i)^2
+ PMT * (1 + iX) * (1 + i)
+ PMT * (1 + iX)
</pre>
<p>And for the n'th payment, PV[n] is computed from PV[n-1] as:
<pre>
PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i)
PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * (1 + i)^(n-1)
+ PMT * (1 + iX) * (1 + i)^(n-2) +
.
.
.
+ PMT * (1 + iX) * (1 + i)
+ PMT * (1 + iX)
PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... + (1 + i) + 1]
</pre>
<p>The formula for PV[n] can be proven using mathematical induction.
<A NAME="BasicEquation">
<h1>Basic Financial Equation</h1></A>
<p>As shown above, the basic financial transaction equation is simply:
<pre>
PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i)
= PV[n-1] * (1 + i) + PMT * (1 + iX)
for: n >= 1
</pre>
<p>relating the Present Value after n payments, PV[n] to the previous Present Value, PV[n-1].
<!--########################################################################-->
<hr>
<A NAME="SeriesSum">
<h1>Series Sum</h1></A>
<p>The sum of the finite series:
<p>1 + k + (k^2) + (k^3) + ... + (k^n) = (1-k^(n+1))/(1-k)
<p>as can be seen by the following. Let S(n) be the series sum. Then
<p>S(n) - k * S(n) = 1 - k^(n+1)
<p>and solving for S(n):
<p>S(n) = (1-k^(n+1))/(1-k) = 1 + k + (k^2) + (k^3) + ... + (k^n)
<!--########################################################################-->
<hr>
<p>Using this in the equation above for PV[n], we have:
<pre>
PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... + (1 + i) + 1]
= PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[1 - (1 + i)]
= PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[-i]
= PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^n - 1]/i
</pre>
<p>or:
<pre>
PV * (1 + i)^n + PMT * [(1 + i)^n - 1]/i - PV[n] = 0
</pre>
<p>If after n payments, the remaining balance is repaid as a lump sum, the lump sum
is known as the Future Value, FV[n]. Since FV[n] is negative if paid and positive
if received, FV[n] is the negative of PV[n].
<p>Setting: FV[n] = -PV[n]
<p>Since n is assumed to be the last payment, FV[n] will be shortened to simply
FV for the last payment period.
<pre>
PV*(1 + i)^n + PMT*(1 + iX)*[(1 + i)^n - 1]/i + FV = 0
</pre>
<p>Up to this point, we have said nothing about the value of PMT. PMT can be any value mutually
agreed upon by the lender and the borrower. From the equation for PV[1]:
<pre>
PV[1] = PV + (PMT + (PV + X * PMT) * i),
</pre>
<p>Several things can be said about PMT.
<ol>
<li>If PMT = -(PV * i), and X = 0 (end of period payments):
<p>The payment is exactly equal to the interest due and PV[1] = PV. In this case, the borrower
must make larger future payments to reduce the balance due, or make a single payment, after
some agreed upon number of payments, with PMT = -PV to completely pay off the loan. This is
an interest only payment with a balloon payment at the end.
<li>If |PMT| < |PV * i|, and X = 0 and PV > 0
<p>The payment is insufficient to cover even the interest charged and the balance due grows
<li>If |PMT| > |PV * i|, and X = 0 and PV > 0
<p>The payment is sufficient to cover the interest charged with a residual amount to be
applied to reduce the balance due. The larger the residual amount, the faster the loan is
repaid. For most mortgages or other loans made today, the lender and borrower agree upon
a certain number of repayment periods and the interest to be charged per payment period.
The interest may be multiplied by 12 and stated as an annual interest rate. Then the
lender and borrower want to compute a periodic payment, PMT, which will reduce the balance
due to zero after the agreed upon number of payments have been made. If N is the agreed
upon number of periodic payments, then we want to use:
<pre>
PV * (1 + i)^N + PMT*(1 +iX)*[(1 + i)^N - 1]/i + FV = 0
</pre>
<p>with FV = 0 to compute PMT:
<pre>
PMT = -[PV * i * (1 + i)^(N - X)]/[(1 + i)^N - 1]
</pre>
<p>The value of PMT computed will reduce the balance due to zero after N periodic payments.
Note that this is strictly true only if PMT is not rounded to the nearest cent as is the
usual case since it is hard to pay fractional cents. Rounding PMT to the nearest cent has
an effect on the FV after N payments. If PMT is rounded up, then the final Nth payment
will be smaller than PMT since the periodic PMTs have paid down the principal faster than
the exact solution. If PMT is rounded down, then the final Nth payment will be larger than
the periodic PMTs since the periodic PMTs have paid down the principal slower than the
exact solution.
</ol>
<!--#############################################################################-->
<p>With a simple alegebraic re-arrangement, The financial Equation becomes:
<pre>
2) [PV + PMT*(1 + iX)/i][(1 + i)^n - 1] + PV + FV = 0
</pre>
<p>or
<pre>
3) (PV + C)*A + PV + FV = 0
</pre>
<p>where:
<pre>
4) A = (1 + i)^n - 1
5) B = (1 + iX)/i
6) C = PMT*B
</pre>
<p>The form of equation 3) simplifies the calculation procedure for all five
variables, which are readily solved as follows:
<pre>
7) n = ln[(C - FV)/(C + PV)]/ln((1 + i)
8) PV = -[FV + A*C]/(A + 1)
9) PMT = -[FV + PV*(A + 1)]/[A*B]
10) FV = -[PV + A*(PV + C)]
</pre>
<p>Equations 4), 5) and 6) are computed by the functions in the <tt>"fin.exp"</tt> utility:
<br><tt>_A</tt>
<br><tt>_B</tt>
<br><tt>_C</tt>
<p>respectively. Equations 7), 8), 9) and 10) are computed by functions:
<br><tt>_N</tt>
<br><tt>_PV</tt>
<br><tt>_PMT</tt>
<br><tt>_FV</tt>
<p>respectively.
<p>The solution for interest is broken into two cases:
<ol>
<li>PMT == 0
<p>Equation 3) can be solved exactly for i:
<pre>
i = [FV/PV]^(1/n) - 1
</pre>
<li>PMT != 0
<p>Since equation 3) cannot be solved explicitly for i in this case, an
iterative technique must be employed. Newton's method, using exact
expressions for the function of i and its derivative, are employed. The
expressions are:
<pre>
12) i[k+1] = i[k] - f(i[k])/f'(i[k])
where: i[k+1] == (k+1)st iteration of i
i[k] == kth iteration of i
and:
13) f(i) = A*(PV+C) + PV + FV
14) f'(i) = n*D*(PV+C) - (A*C)/i
15) D = (1 + i)^(n-1) = (A+1)/(1+i)
</pre>
<p>To start the iterative solution for i, an initial guess must be made
for the value of i. The closer this guess is to the actual value,
the fewer iterations will have to be made, and the greater the
probability that the required solution will be obtained. The initial
guess for i is obtained as follows:
<ol>
<li>PV case, PMT*FV >= 0
<pre>
| n*PMT + PV + FV |
16) i[0] = | ----------------|
| n*PV |
= abs[(n*PMT + PV + FV)/(n*PV)]
</pre>
<li>FV case, PMT*FV < 0
<ol>
<li>PV != 0
<pre>
| FV - n*PMT |
17) i[0] = |---------------------------|
| 3*[PMT*(n-1)^2 + PV - FV] |
= abs[(FV-n*PMT)/(3*(PMT*(n-1)^2+PV-FV))]
</pre>
<li>PV == 0
<pre>
| FV + n*PMT |
18) i[0] = |---------------------------|
| 3*[PMT*(n-1)^2 + PV - FV] |
= abs[(FV+n*PMT)/(3*(PMT*(n-1)^2+PV-FV))]
</pre>
</ol>
</ol>
</ol>
<HR>
<A HREF="./finutil.html#FinEquation"><IMG SRC="images/back.png" BORDER=0 HEIGHT=13 WIDTH=7>Return</A>
</body>
<HTML>
<HEAD>
<TITLE>Financial Equations Documentation</TITLE>
</HEAD>
<BODY>
<A NAME="TOP"></A>
<A HREF="./finutil.html#FinEquation">Return</A>
<HR>
<br>
<dl>
<dt><A HREF="#BasicEquation">Basic Equation</A></dt>
<dt><A HREF="#SeriesSum">Series Sum</A></dt>
</dl>
<HR>
<h1>Financial Equation Derivation</h1>
<p>The financial equation is derived in the following manner:
<p>Start with the basic equation to find the balance or Present Value, PV[1], after
one payment period. Note PV[1] is the Present Value after one payment and PV[0]
is the initial Present Value. PV[0] will be shortened to just PV.
<p>The interest due at the end of the first payment period is the original present value,
PV, times the interest rate for the payment period plus the periodic payment times the
interest rate for beginning of period payments:
<p>ID[1] = PV * i + X * PMT * i = (PV + X * PMT) * i
<p>The Present Value after one payment is the original Present Value with the periodic
payment, PMT, and interest due, ID[1], added:
<pre>
PV[1] = PV + (PMT + ID[1])
PV[1] = PV + (PMT + (PV + X * PMT) * i)
PV[1] = PV * (1 + i) + PMT * (1 + Xi)
</pre>
<p>This equation works for all of the cash flow diagrams shown previously. The Present Value,
money received or paid, is modified by a payment made at the beginning of a payment
period and multiplied by the effective interest rate to compute the interest
due during the payment period. The interest due is then added to the payment
to obtain the amount to be added to the Present Value to compute the new Present Value.
<p>For diagram 1): PV < 0, PMT == 0, PV[1] < 0
<br>For diagram 2): PV == 0, PMT < 0, PV[1] < 0
<br>For Diagram 3): PV > 0, PMT < 0, PV[1] >= 0 or PV[1] <= 0
<br>For Diagram 4): PV < 0, PMT > 0, PV[1] <= 0 or PV[1] >= 0
<p>X may be 0 or 1 for any diagram.
<p>For the standard loan, PV is the money borrowed, PMT is the periodic payment to repay
the loan, i is the effective interest rate agreed upon and FV is the residual loan amount
after the agreed upon number of periodic payment periods. If the loan is fully paid off
by the periodic payments, FV is zero, 0. If the loan is not completely paid off after the
agreed upon number of payments, a balloon payment is necessary to completely pay off the loan.
FV is then the amount of the needed balloon payment. For a loan in which the borrower pays
only enough to repay the interest due during a payment period, interest only loan, the
balloon payment is equal to the negative of PV.
<p>To calculate the Present Value after the second payment period, the above calculation
is applied iteratively to PV[1] to obtain PV[2]. In fact to calculate the Present Value
after any payment period, PV[n], the above equation is applied iteratively to PV[n-1]
as shown below.
<pre>
PV[2] = PV[1] + (PMT + (PV[1] + X * PMT) * i)
= PV[1] * (1 + i) + PMT * (1 + iX)
= (PV * (1 + i) + PMT * (1 + iX)) * (1 + i) + PMT * (1 + iX)
= PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i)
+ PMT * (1 + iX)
</pre>
<p>Similarly, PV[3] is computed from PV[2] as:
<pre>
PV[3] = PV[2] + (PMT + (PV[2] + X * PMT) * i)
= PV[2] * (1 + i) + PMT * (1 + iX)
= (PV * (1 + i)^2 + PMT * (1 + iX) * (1 + i)
+ PMT * (1+ iX)) * (1 + i)
+ PMT * (1+ iX)
= PV * (1 + i)^3 + PMT * (1 + iX) * (1 + i)^2
+ PMT * (1 + iX) * (1 + i)
+ PMT * (1 + iX)
</pre>
<p>And for the n'th payment, PV[n] is computed from PV[n-1] as:
<pre>
PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i)
PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * (1 + i)^(n-1)
+ PMT * (1 + iX) * (1 + i)^(n-2) +
.
.
.
+ PMT * (1 + iX) * (1 + i)
+ PMT * (1 + iX)
PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... + (1 + i) + 1]
</pre>
<p>The formula for PV[n] can be proven using mathematical induction.
<A NAME="BasicEquation">
<h1>Basic Financial Equation</h1></A>
<p>As shown above, the basic financial transaction equation is simply:
<pre>
PV[n] = PV[n-1] + (PMT + (PV[n-1] + X * PMT) * i)
= PV[n-1] * (1 + i) + PMT * (1 + iX)
for: n >= 1
</pre>
<p>relating the Present Value after n payments, PV[n] to the previous Present Value, PV[n-1].
<!--########################################################################-->
<hr>
<A NAME="SeriesSum">
<h1>Series Sum</h1></A>
<p>The sum of the finite series:
<p>1 + k + (k^2) + (k^3) + ... + (k^n) = (1-k^(n+1))/(1-k)
<p>as can be seen by the following. Let S(n) be the series sum. Then
<p>S(n) - k * S(n) = 1 - k^(n+1)
<p>and solving for S(n):
<p>S(n) = (1-k^(n+1))/(1-k) = 1 + k + (k^2) + (k^3) + ... + (k^n)
<!--########################################################################-->
<hr>
<p>Using this in the equation above for PV[n], we have:
<pre>
PV[n] = PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^(n-1) + ... + (1 + i) + 1]
= PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[1 - (1 + i)]
= PV * (1 + i)^n + PMT * (1 + iX) * [1 - (1 + i)^n]/[-i]
= PV * (1 + i)^n + PMT * (1 + iX) * [(1 + i)^n - 1]/i
</pre>
<p>or:
<pre>
PV * (1 + i)^n + PMT * [(1 + i)^n - 1]/i - PV[n] = 0
</pre>
<p>If after n payments, the remaining balance is repaid as a lump sum, the lump sum
is known as the Future Value, FV[n]. Since FV[n] is negative if paid and positive
if received, FV[n] is the negative of PV[n].
<p>Setting: FV[n] = -PV[n]
<p>Since n is assumed to be the last payment, FV[n] will be shortened to simply
FV for the last payment period.
<pre>
PV*(1 + i)^n + PMT*(1 + iX)*[(1 + i)^n - 1]/i + FV = 0
</pre>
<p>Up to this point, we have said nothing about the value of PMT. PMT can be any value mutually
agreed upon by the lender and the borrower. From the equation for PV[1]:
<pre>
PV[1] = PV + (PMT + (PV + X * PMT) * i),
</pre>
<p>Several things can be said about PMT.
<ol>
<li>If PMT = -(PV * i), and X = 0 (end of period payments):
<p>The payment is exactly equal to the interest due and PV[1] = PV. In this case, the borrower
must make larger future payments to reduce the balance due, or make a single payment, after
some agreed upon number of payments, with PMT = -PV to completely pay off the loan. This is
an interest only payment with a balloon payment at the end.
<li>If |PMT| < |PV * i|, and X = 0 and PV > 0
<p>The payment is insufficient to cover even the interest charged and the balance due grows
<li>If |PMT| > |PV * i|, and X = 0 and PV > 0
<p>The payment is sufficient to cover the interest charged with a residual amount to be
applied to reduce the balance due. The larger the residual amount, the faster the loan is
repaid. For most mortgages or other loans made today, the lender and borrower agree upon
a certain number of repayment periods and the interest to be charged per payment period.
The interest may be multiplied by 12 and stated as an annual interest rate. Then the
lender and borrower want to compute a periodic payment, PMT, which will reduce the balance
due to zero after the agreed upon number of payments have been made. If N is the agreed
upon number of periodic payments, then we want to use:
<pre>
PV * (1 + i)^N + PMT*(1 +iX)*[(1 + i)^N - 1]/i + FV = 0
</pre>
<p>with FV = 0 to compute PMT:
<pre>
PMT = -[PV * i * (1 + i)^(N - X)]/[(1 + i)^N - 1]
</pre>
<p>The value of PMT computed will reduce the balance due to zero after N periodic payments.
Note that this is strictly true only if PMT is not rounded to the nearest cent as is the
usual case since it is hard to pay fractional cents. Rounding PMT to the nearest cent has
an effect on the FV after N payments. If PMT is rounded up, then the final Nth payment
will be smaller than PMT since the periodic PMTs have paid down the principal faster than
the exact solution. If PMT is rounded down, then the final Nth payment will be larger than
the periodic PMTs since the periodic PMTs have paid down the principal slower than the
exact solution.
</ol>
<!--#############################################################################-->
<p>With a simple alegebraic re-arrangement, The financial Equation becomes:
<pre>
2) [PV + PMT*(1 + iX)/i][(1 + i)^n - 1] + PV + FV = 0
</pre>
<p>or
<pre>
3) (PV + C)*A + PV + FV = 0
</pre>
<p>where:
<pre>
4) A = (1 + i)^n - 1
5) B = (1 + iX)/i
6) C = PMT*B
</pre>
<p>The form of equation 3) simplifies the calculation procedure for all five
variables, which are readily solved as follows:
<pre>
7) n = ln[(C - FV)/(C + PV)]/ln((1 + i)
8) PV = -[FV + A*C]/(A + 1)
9) PMT = -[FV + PV*(A + 1)]/[A*B]
10) FV = -[PV + A*(PV + C)]
</pre>
<p>Equations 4), 5) and 6) are computed by the functions in the <tt>"fin.exp"</tt> utility:
<br><tt>_A</tt>
<br><tt>_B</tt>
<br><tt>_C</tt>
<p>respectively. Equations 7), 8), 9) and 10) are computed by functions:
<br><tt>_N</tt>
<br><tt>_PV</tt>
<br><tt>_PMT</tt>
<br><tt>_FV</tt>
<p>respectively.
<p>The solution for interest is broken into two cases:
<ol>
<li>PMT == 0
<p>Equation 3) can be solved exactly for i:
<pre>
i = [FV/PV]^(1/n) - 1
</pre>
<li>PMT != 0
<p>Since equation 3) cannot be solved explicitly for i in this case, an
iterative technique must be employed. Newton's method, using exact
expressions for the function of i and its derivative, are employed. The
expressions are:
<pre>
12) i[k+1] = i[k] - f(i[k])/f'(i[k])
where: i[k+1] == (k+1)st iteration of i
i[k] == kth iteration of i
and:
13) f(i) = A*(PV+C) + PV + FV
14) f'(i) = n*D*(PV+C) - (A*C)/i
15) D = (1 + i)^(n-1) = (A+1)/(1+i)
</pre>
<p>To start the iterative solution for i, an initial guess must be made
for the value of i. The closer this guess is to the actual value,
the fewer iterations will have to be made, and the greater the
probability that the required solution will be obtained. The initial
guess for i is obtained as follows:
<ol>
<li>PV case, PMT*FV >= 0
<pre>
| n*PMT + PV + FV |
16) i[0] = | ----------------|
| n*PV |
= abs[(n*PMT + PV + FV)/(n*PV)]
</pre>
<li>FV case, PMT*FV < 0
<ol>
<li>PV != 0
<pre>
| FV - n*PMT |
17) i[0] = |---------------------------|
| 3*[PMT*(n-1)^2 + PV - FV] |
= abs[(FV-n*PMT)/(3*(PMT*(n-1)^2+PV-FV))]
</pre>
<li>PV == 0
<pre>
| FV + n*PMT |
18) i[0] = |---------------------------|
| 3*[PMT*(n-1)^2 + PV - FV] |
= abs[(FV+n*PMT)/(3*(PMT*(n-1)^2+PV-FV))]
</pre>
</ol>
</ol>
</ol>
<HR>
<A HREF="./finutil.html#FinEquation"><IMG SRC="images/back.png" BORDER=0 HEIGHT=13 WIDTH=7>Return</A>
</body>