HotXLS izvorno u Delphiju i C++Builderu izračunava financijske funkcije za obveznice i trezorske zapise iz Excela: PRICE, YIELD, DURATION, MDURATION, šest primitiva za datume kupona, trojku funkcija za trezorske zapise, obitelj diskontnih funkcija i francuske funkcije amortizacije. Izračunavaju se unutar vlastitog mehanizma formula knjižnice, pa se radna knjiga koja vrednuje portfelj obveznica ponovno izračunava na poslužitelju bez Excela i bez ikakvog dodatka Analysis ToolPak na vidiku
Ove su funkcije nekoć živjele u dodatku Analysis ToolPak, zbog čega i dalje nose reputaciju nezgrapnih. Od Excela 2007 dio su standardnog skupa funkcija i zapisuju se u formatu datoteke bez oznake, bez prefiksa _xlfn. koji nose stvarno novije funkcije. Radna knjiga koja ih koristi obična je radna knjiga; jedino je pitanje zna li ono što je ponovno izračunava te funkcije
Što mehanizam datuma kupona mora ispravno napraviti
Svaki izračun obveznice počiva na istim primitivima: koliko dana od posljednjeg kupona, koliko dana u trenutačnom razdoblju kupona, koliko dana do sljedećeg kupona, kada ti kuponi padaju, i koliko ih preostaje. To su COUPDAYBS, COUPDAYS, COUPDAYSNC, COUPPCD, COUPNCD i COUPNUM, a svaka funkcija cijene i prinosa poziva ih
Ono što ih čini netrivijalnima jest argument baze. U igri je pet konvencija brojanja dana — 30/360 US, actual/actual, actual/360, actual/365 i 30/360 European — a one se ne slažu oko pitanja poput toga što se događa kada datum namire padne na 31. dan u mjesecu, ili kako se datum veljačkog kupona ponaša u prijestupnoj godini. Ispravno provođenje jedne konvencije uz aproksimiranje ostalih proizvodi rezultate koji izgledaju vjerodostojno, a pogrešni su za nekoliko baznih bodova, što je na velikoj poziciji stvaran novac
HotXLS implementira svih pet u samodostatnom ugniježđenom mehanizmu datuma kupona koji dijele sve funkcije kojima je potreban, pa se PRICE i DURATION ne mogu međusobno ne slagati oko toga gdje se nalaze datumi kupona
Cijena i prinos u radnoj knjizi
Ništa u pozivajućem kodu nije posebno: napišite formule, ponovno izračunajte, pročitajte vrijednosti. Upravo je to poanta — radna knjiga je model, a vaša Delphi aplikacija kalkulator:
uses
lxHandleX;
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
begin
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Bond');
Sheet.Cells[1, 1].Value := EncodeDate(2026, 3, 15); // namira
Sheet.Cells[2, 1].Value := EncodeDate(2034, 11, 15); // dospijeće
Sheet.Cells[3, 1].Value := 0.0425; // kuponska stopa
Sheet.Cells[4, 1].Value := 0.0391; // tražen prinos
Sheet.Cells[5, 1].Value := 100; // otkup
Sheet.Cells[6, 1].Value := 2; // učestalost
Sheet.Cells[7, 1].Value := 1; // baza: actual/actual
Sheet.Cells[9, 1].Formula := '=PRICE(A1,A2,A3,A4,A5,A6,A7)';
Sheet.Cells[10, 1].Formula := '=DURATION(A1,A2,A3,A4,A6,A7)';
Sheet.Cells[11, 1].Formula := '=MDURATION(A1,A2,A3,A4,A6,A7)';
Sheet.Cells[12, 1].Formula := '=COUPNUM(A1,A2,A6,A7)';
Book.Recalculate;
Writeln(Format('price %.6f Macaulay %.6f modified %.6f coupons %d',
[Double(Sheet.Cells[9, 1].Value), Double(Sheet.Cells[10, 1].Value),
Double(Sheet.Cells[11, 1].Value),
Integer(Sheet.Cells[12, 1].Value)]));
finally
Book.Free;
end;
end;
Datumi ulaze kao stvarne vrijednosti datuma, a ne kao nizovi znakova. Tekstualni datum radi u Excelu jer ga Excel prisilno pretvara, a ta pretvorba ovisi o lokalizaciji (locale), što je upravo vrsta ovisnosti koju izračun na strani poslužitelja ne bi trebao imati. Pravila sustava datuma koja stoje ispod obrađena su u članku serijski brojevi datuma i sustav 1904
Prinos nema zatvoreni oblik, i to ima posljedice
PRICE je izravan izračun: diskontirajte novčane tokove, zbrojite ih. YIELD je njegov obrat i nema rješenje u zatvorenom obliku za obveznicu s više od jednog preostalog kupona, pa se mora rješavati numerički. HotXLS koristi rješavač bisekcijom, koji pouzdano konvergira, a ne brzo
Slijede dvije praktične posljedice. Prinos je mjerljivo skuplji od cijene, pa revalorizacija portfelja koja izračunava prinose za deset tisuća pozicija stoji primjetno više od one koja izračunava cijene, i vrijedi znati koje od to dvoje vaš model doista treba. A prinos koji se ne može uokviriti (bracket) — jer ulazi opisuju obveznicu koju nijedan prinos ne može vrednovati na zadanu vrijednost — vraća pogrešku umjesto pogrešnog broja, što je ispravno ponašanje i ono koje treba testirati
Trezorski zapisi zasebna su obitelj
Zapisi su diskontni instrumenti bez kupona, pa koriste TBILLPRICE, TBILLYIELD i TBILLEQ umjesto funkcija za obveznice. TBILLEQ pretvara diskontnu stopu u prinos ekvivalentan obveznici, a ima dokumentiranu osobitost vrijednu poznavanja: za dospijeća dulja od 182 dana pretvorba je kvadratna, a ne linearna, jer vrijednosnica obuhvaća više od jednog polugodišnjeg razdoblja
Uvođenje zapisa umjesto toga u PRICE, s nultim kuponom i učestalošću, ne proizvodi isti broj. Obitelj diskontnih instrumenata — DISC, INTRATE, RECEIVED, PRICEDISC i YIELDDISC — postoji upravo zato što se ti instrumenti kotiraju i namiruju drugačije
Ostatak skupa, na jednom mjestu
Osim obveznica i zapisa, ista skupina obuhvaća funkcije koje ih okružuju u stvarnim modelima. PRICEMAT i YIELDMAT obrađuju vrijednosnice koje plaćaju kamatu pri dospijeću. ACCRINTM izračunava obračunatu kamatu za njih. EFFECT i NOMINAL pretvaraju između efektivnih i nominalnih godišnjih stopa, što je pretvorba koju se najčešće pogrešno radi ručno. CUMIPMT i CUMPRINC daju kumulativnu kamatu i glavnicu preko raspona razdoblja. FVSCHEDULE primjenjuje niz različitih stopa redoslijedom, uzimajući raspon ili skalar
DOLLARDE i DOLLARFR pretvaraju između decimalnih i razlomljenih dolarskih kotacija, što je bitno za svaki instrument koji se još uvijek kotira u tridesetdvojinama. A AMORDEGRC i AMORLINC implementiraju francuske metode amortizacije, koje zahtijevaju francuska računovodstvena pravila, a nisu izborna pogodnost
// Pretvorba stope koju ljudi rutinski pogrešno rade ručno
Sheet.Cells[1, 3].Formula := '=EFFECT(0.0425,12)'; // nominalna u efektivnu
Sheet.Cells[2, 3].Formula := '=NOMINAL(0.043338,12)'; // i natrag
// Kumulativna kamata tijekom prve dvije godine 25-godišnjeg zajma
Sheet.Cells[4, 3].Formula :=
'=CUMIPMT(0.0389/12,300,340000,1,24,0)';
// Projekcija promjenjive stope: 3 posto, zatim 3,5, zatim 4
Sheet.Cells[6, 3].Formula := '=FVSCHEDULE(10000,{0.03;0.035;0.04})';
Provjera implementacije koju niste vi napisali
Financijske su funkcije jedino područje gdje "vraća broj" nije dokaz ničega. Broj je po konstrukciji vjerodostojan, a pogreška u konvenciji brojanja dana pomiče rezultate za iznos premalen da bi se primijetio, a prevelik da bi se prihvatio
Test koji doista radi diferencijalan je. Izgradite proračunsku tablicu reprezentativnih instrumenata — jednu obveznicu po bazi brojanja dana, jednu koja se namiruje na kraju mjeseca, jednu koja obuhvaća veljaču u prijestupnoj godini, jedan zapis ispod 182 dana i jedan iznad — izračunajte vrijednosti u Excelu jednom, pohranite ih kao očekivane rezultate, i provjeravajte prema njima nakon svake nadogradnje knjižnice. Pozicije koje premošćuju datum kupona i namire na 31. dan mjesto su gdje se implementacije razilaze, pa oboje namjerno uključite
Za same radne knjige, dva pratioca ove značajke jesu mehanizam izračuna koji odlučuje što ponovno izračunati, opisan u članku prirasni ponovni izračun i graf ovisnosti, i statistička obitelj obrađena u članku statističke funkcije distribucije. Zajedno su to ono što financijskom modelu omogućuje neovisno pokretanje na poslužitelju, što je bio cijeli razlog njihove izvorne implementacije
Financije obveznica, statistika, inženjerske funkcije i mehanizam ponovnog izračuna isporučuju se u jednoj knjižnici za Delphi i C++Builder; potpuni popis značajki nalazi se na stranici HotXLS Delphi komponente za proračunske tablice