10 Mayıs 2010 Pazartesi

Ortalama vade bulma

Toplu çek alış/verişlerde, birden fazla çek vermek yerine tek çek verildiğini görmüşsünüzdür. Bu yazıda sizlere java kodları ile ortalama vade nasıl bulunur bunu anlatacağım. Kodlamaya geçmeden önce, anlatımı somutlaştırmak adına üç ayrı senaryo oluşturarak hesaplamaları bunlar üzerinden yapacağım. Tüm senaryolar için, içinde bulunduğumuz tarihi : 04/03/2010 alalım ve bu tarihe BAZ TARİH diyelim.

Senaryo 1:
---------- --------
Vade Tutar
---------- --------
04/04/2010 100 TL
04/05/2010 100 TL
04/06/2010 100 TL
---------- --------
toplam : 300 TL
vadeler : 30 gün

Senaryo 2:
-------------------
Vade Tutar
---------- --------
04/04/2010 300 TL
04/05/2010 500 TL
04/06/2010 1000 TL
---------- --------
toplam : 1800 TL
vadeler : 30 gün

Senaryo 3:
-------------------
Vade Tutar
---------- --------
01/04/2010 600 TL
22/05/2010 300 TL
13/06/2010 500 TL
---------- --------
toplam : 1400 TL
vadeler : düzensiz
-------------------------------------------------------------------

İlk etapta ortalama vadenin nasıl bulunduğunu formül bazında görelim. (İsimlendirmeler terminolojiye uygun olmayabilir. Buradaki amacım, bir programcının ortalama vade hesabını nasıl yapacağını izah etmek. Bu yüzden isimlendirmelere çok özenmedim.)

1 - Çek tutarları toplanarak toplam tutar bulunur (TT)
2 - Her bir çekin vadesinin baz tarihe olan uzaklığı gün cinsinden bulunur (VG)
3 - Bu gün farklarının tamamı toplanır ve vade günlerinin toplamı bulunur (TVG)
4 - Toplam Vade Günleri, Toplam Tutara bölünerek Ortak Çarpan bulunur (TVG/TT=OÇ)
5 - Herbir çek için; Ortak Çarpan, vade günü ve çekin tutarı çarpılarak Derece bulunur (D)
6 - Derece, Toplam Vade Gününe bölünerek Etki Mesafesi bulunur (D/OÇ=EM)
7 - Etki Mesafeleri toplanarak Baz Tarihe eklenir ve ortlama vade bulunmuş olur


Senaryo-1 çeklerini yukarıdaki formüle göre hesaplarsak,

1 - TT=300
2 - VG1=31, VG2=61, VG3=92
3 - TVG=184
4 - OÇ=0.61
5 - D1=1901.33, D2=3741.33, D3=5642.67
6 - EM1=10.33, EM2=20.33, EM3=30.67 (Toplam=61.33 gün eder)
7 - 04/03/2010 + 61.33 = 04/05/2010

Bu durumda:
Senaryo-1 in ortalama vadesi : 04/05/2010
Senaryo-2 nin ortalama vadesi : 16/05/2010
Senaryo-3 ün ortalama vadesi : 08/05/2010 olur

Java'da nasıl yapıldığına gelince de;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Valor {

/*
* Girisi noktasi ve ornekleme
*/
public static void main(String[] args) {
Date base = new Date("2010/03/04");
List<Cheque> chequeList = new ArrayList<Cheque>();

chequeList.add(new Cheque( new Date("2010/04/01"), 600));
chequeList.add(new Cheque(new Date("2010/05/22 "), 300));
chequeList.add(new Cheque(new Date("2010/06/13"), 500));

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sdf.format(getAvgDate(base, chequeList)));
}

/*
* Asil hesaplarin yapildigi kisim burasi
*/
private static Date getAvgDate(Date base, List<Cheque> chequeList) {
double totalAmount = 0;
double totalDays = 0;
int index = 0;
double totalEffects = 0;
List<Integer> dayDitanceList = new ArrayList<Integer>();

for (Cheque c: chequeList) {
int days = getDateDiff(c.maturity, base);

dayDitanceList.add(days);
totalDays += days;
totalAmount += c.amount;
}
double factor = totalDays / totalAmount;

for (Cheque c: chequeList) {
double degree = factor * c.amount * dayDitanceList.get(index);
double effect = degree / totalDays;
totalEffects += effect;
index++;
}

return addDate(base, new Double(totalEffects).intValue());
}

/*
* Iki tarih arasindaki gun farkini bulur
*/
private static int getDateDiff(Date big, Date little) {
long diff = big.getTime() - little.getTime();
return (int) (diff / (1000 * 60 * 60 * 24) + 1);
}

/*
* Verilen tarihe gun ekler
*/
private static Date addDate(Date date, int day) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, day);
return cal.getTime();
}

/*
* Orneklemenin daha net okunabilmesi icin, cek bilgilerini tasiyan pojo
*/
private static class Cheque {

private Date maturity;
private double amount;

Cheque(Date maturity, double amount) {
this.maturity = maturity;
this.amount = amount;
}

}

}