Teknik Makale

HotXLS ile Delphi'de Tahvil ve Hazine Formülleri

HotXLS, Excel'in tahvil ve hazine finans işlevlerini Delphi ve C++Builder'da yerel olarak değerlendirir: PRICE, YIELD, DURATION, MDURATION, altı kupon tarihi ilkeli, hazine bonosu üçlüsü, iskonto ailesi ve Fransız amortisman işlevleri. Bunlar kitaplığın kendi formül motorunun içinde hesaplanır, bu yüzden bir tahvil portföyünü fiyatlandıran bir çalışma kitabı, ortalıkta hiçbir Excel ve hiçbir Analysis ToolPak eklentisi olmayan bir sunucuda yeniden hesaplanır

Bu işlevler eskiden Analysis ToolPak'ta yaşardı; hâlâ sakıncalı olma itibarını taşımalarının nedeni budur. Excel 2007'den beri standart işlev kümesinin bir parçası olmuşlardır ve gerçekten daha yeni işlevlerin taşıdığı _xlfn. önekine sahip olmadan dosya biçiminde çıplak yazılırlar. Bunları kullanan bir çalışma kitabı sıradan bir çalışma kitabıdır; tek soru, onu her ne yeniden hesaplıyorsa işlevleri bilip bilmediğidir

Kupon Tarihi Motorunun Doğru Yapması Gerekenler

Her tahvil hesaplaması aynı ilkellere dayanır: son kupondan bu yana kaç gün geçti, geçerli kupon döneminde kaç gün var, bir sonraki kupona kaç gün kaldı, bu kuponlar ne zaman düşer ve kaç tanesi kaldı. Bunlar COUPDAYBS, COUPDAYS, COUPDAYSNC, COUPPCD, COUPNCD ve COUPNUM'dir ve her fiyat ve getiri işlevi bunları çağırır

Bunları önemsiz olmaktan çıkaran, basis (taban) argümanıdır. Beş gün sayım kuralı devrededir — 30/360 ABD, gerçek/gerçek, gerçek/360, gerçek/365 ve 30/360 Avrupa — ve bunlar, bir valör tarihinin bir ayın 31'ine denk gelmesi durumunda ne olacağı veya bir Şubat kupon tarihinin bir artık yılda nasıl davranacağı gibi sorularda anlaşmazlığa düşer. Bir kuralı doğru yapıp diğerlerini yaklaşık olarak hesaplamak, akla yatkın görünen ama birkaç baz puan yanlış olan sonuçlar üretir; bu da büyük bir pozisyonda gerçek paradır

HotXLS, beşini de, ihtiyacı olan her işlev tarafından paylaşılan kendi kendine yeterli, iç içe geçmiş bir kupon tarihi motorunda uygular, bu yüzden PRICE ve DURATION kupon tarihlerinin nerede olduğu konusunda birbirleriyle anlaşmazlığa düşemez

Delphi için HotXLS kupon tarihi motoru: tahvil girdileri ve seçilen gün sayım tabanı, PRICE, YIELD, DURATION ve MDURATION tarafından paylaşılan altı COUP ilkelini besler
Beş gün sayım tabanının tamamı, HotXLS'teki her finansal işlev tarafından paylaşılan tek bir iç içe geçmiş kupon tarihi motorunu besler, bu yüzden PRICE ve DURATION kupon tarihlerinin nereye düştüğü konusunda hiçbir zaman anlaşmazlığa düşemez

Bir Çalışma Kitabında Fiyatlandırma ve Getiri

Çağıran kodda özel hiçbir şey yoktur: formülleri yazın, yeniden hesaplayın, değerleri okuyun. Konu tam olarak budur — çalışma kitabı modeldir ve Delphi uygulamanız hesap makinesidir:

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);   // valör
    Sheet.Cells[2, 1].Value := EncodeDate(2034, 11, 15);  // vade
    Sheet.Cells[3, 1].Value := 0.0425;                    // kupon oranı
    Sheet.Cells[4, 1].Value := 0.0391;                    // istenen getiri
    Sheet.Cells[5, 1].Value := 100;                       // itfa
    Sheet.Cells[6, 1].Value := 2;                         // sıklık
    Sheet.Cells[7, 1].Value := 1;                         // taban: gerçek/gerçek

    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;

Tarihler dize olarak değil gerçek tarih değerleri olarak girer. Bir metin tarihi Excel'de çalışır, çünkü Excel onu dönüştürür ve dönüştürme locale'e bağlıdır; bu, tam olarak bir sunucu taraflı yeniden hesaplamanın sahip olmaması gereken türde bir bağımlılıktır. Altında yatan tarih sistemi kuralları, tarih seri numaraları ve 1904 sistemi başlığında ele alınmıştır

Getirinin Kapalı Formu Yoktur ve Bunun Sonuçları Vardır

PRICE doğrudan bir hesaplamadır: nakit akışlarını iskonto edin, toplayın. YIELD onun tersidir ve birden fazla kuponu kalan bir tahvil için kapalı formda bir çözümü yoktur, bu yüzden sayısal olarak çözülmelidir. HotXLS, hızlı değil güvenilir bir şekilde yakınsayan bir ikiye bölme çözücüsü kullanır

İki pratik sonuç ortaya çıkar. Getiri, ölçülebilir şekilde fiyattan daha pahalıdır, bu yüzden on bin pozisyon için getiri hesaplayan bir portföy yeniden değerlemesi, fiyat hesaplayan birine kıyasla belirgin şekilde daha maliyetlidir ve modelinizin gerçekte ikisinden hangisine ihtiyaç duyduğunu bilmeye değer. Ve sınırlanamayan bir getiri — girdiler, hiçbir getirinin verilen değerde fiyatlandıramayacağı bir tahvili tanımladığı için — yanlış bir sayı yerine bir hata döndürür; bu, doğru davranıştır ve test edilmesi gereken davranıştır

Delphi'de HotXLS'te PRICE tek bir doğrudan iskonto edilmiş nakit akışı geçişidir, YIELD ise kapalı forma sahip değildir ve hiçbir sınır bulunmadığında hata döndüren bir ikiye bölme döngüsüyle çözülür
PRICE, iskonto edilmiş nakit akışları üzerinde tek bir doğrudan geçiştir; YIELD ise kapalı forma sahip değildir, sınırlanır ve ikiye bölünür; girdiler fiyatlandırılamadığında yanlış bir sayı yerine bir hata döndürür

Hazine Bonoları Kendi Aileleridir

Bonolar, kuponsuz iskonto araçlarıdır, bu yüzden tahvil işlevleri yerine TBILLPRICE, TBILLYIELD ve TBILLEQ kullanırlar. TBILLEQ, bir iskonto oranını tahvil eşdeğeri bir getiriye dönüştürür ve bilinmeye değer belgelenmiş bir tuhaflığı vardır: 182 günden uzun vadeler için dönüşüm doğrusal değil ikinci derecedendir, çünkü menkul kıymet birden fazla yarı yıllık dönemi kapsar

Bunun yerine bir bonoyu, sıfır kupon ve bir sıklıkla PRICE'a beslemek aynı sayıyı üretmez. İskonto aracı ailesi — DISC, INTRATE, RECEIVED, PRICEDISC ve YIELDDISC — tam olarak bu araçların farklı şekilde kote edildiği ve valörlendiği için var olur

Kümenin Geri Kalanı, Tek Bir Yerde

Tahviller ve bonoların ötesinde, aynı grup, gerçek modellerde bunları çevreleyen işlevleri de kapsar. PRICEMAT ve YIELDMAT, vadede faiz ödeyen menkul kıymetleri ele alır. ACCRINTM, bunlar için tahakkuk eden faizi hesaplar. EFFECT ve NOMINAL, efektif ve nominal yıllık oranlar arasında dönüştürür; bu, elle en sık yanlış yapılan dönüşümdür. CUMIPMT ve CUMPRINC, bir dönem aralığı üzerinde kümülatif faiz ve anapara verir. FVSCHEDULE, bir aralık veya bir skaler alarak bir dizi farklı oranı sırayla uygular

DOLLARDE ve DOLLARFR, ondalık ve kesirli dolar kotasyonları arasında dönüştürür; bu, hâlâ otuz ikide birlerle kote edilen herhangi bir araç için önemlidir. Ve AMORDEGRC ve AMORLINC, isteğe bağlı kolaylıklar değil Fransız muhasebe kurallarının gerektirdiği Fransız amortisman yöntemlerini uygular

// İnsanların elle rutin olarak yanlış yaptığı bir oran dönüşümü
Sheet.Cells[1, 3].Formula := '=EFFECT(0.0425,12)';   // nominalden efektife
Sheet.Cells[2, 3].Formula := '=NOMINAL(0.043338,12)'; // ve geri

// 25 yıllık bir kredinin ilk iki yılı üzerindeki kümülatif faiz
Sheet.Cells[4, 3].Formula :=
  '=CUMIPMT(0.0389/12,300,340000,1,24,0)';

// Değişken oranlı bir projeksiyon: yüzde 3, sonra 3,5, sonra 4
Sheet.Cells[6, 3].Formula := '=FVSCHEDULE(10000,{0.03;0.035;0.04})';

Yazmadığınız Bir Uygulamayı Doğrulamak

Finansal işlevler, "bir sayı döndürüyor" ifadesinin hiçbir şeyin kanıtı olmadığı tek alandır. Sayı, yapısı gereği akla yatkındır ve bir gün sayım kuralındaki bir hata, sonuçları fark edilemeyecek kadar küçük ama kabul edilemeyecek kadar büyük bir miktarda kaydırır

Gerçekte işe yarayan test, diferansiyel olandır. Temsili araçlardan oluşan bir elektronik tablo oluşturun — gün sayım tabanı başına bir tahvil, bir ay sonunda valörlenen bir tahvil, bir artık yıl Şubatını kapsayan bir tahvil, 182 günün altında bir bono ve üstünde bir bono — değerleri Excel'de bir kez hesaplayın, bunları beklenen sonuçlar olarak saklayın ve her kitaplık yükseltmesinden sonra bunlara karşı doğrulayın. Bir kupon tarihini kapsayan pozisyonlar ve ayın 31'indeki valörler, uygulamaların ayrıştığı yerlerdir, bu yüzden ikisini de kasıtlı olarak dahil edin

Delphi'deki HotXLS tahvil ve hazine işlevleri için diferansiyel doğrulama kümesi: artık yıl ve ay sonu durumlarını içeren temsili araçlar Excel'de bir kez hesaplanır ve her kitaplık yükseltmesinden sonra doğrulanır
Bir diferansiyel test paketi, temsili araçları Excel'de bir kez fiyatlandırır, değerleri beklentiler olarak saklar ve her HotXLS yükseltmesinden sonra bunları doğrular, bu yüzden baz puan sapması akla yatkın çıktının arkasına saklanamaz

Çalışma kitaplarının kendisi için, bu özelliğin iki yoldaşı; neyin yeniden hesaplanacağına karar veren hesaplama motoru, artımlı yeniden hesaplama ve bağımlılık grafiği başlığında anlatılmıştır, ve istatistiksel aile, istatistiksel dağılım işlevleri başlığında ele alınmıştır. Birlikte, bir finansal modelin bir sunucuda gözetimsiz çalışmasını sağlayan şey bunlardır; bunları yerel olarak uygulamanın tüm nedeni de buydu

Tahvil finansı, istatistik, mühendislik işlevleri ve yeniden hesaplama motoru, Delphi ve C++Builder için tek bir kitaplıkta gelir; eksiksiz özellik listesi HotXLS Delphi elektronik tablo bileşeni sayfasında bulunur