1   /**
2    * Investor, the open-source investment library
3    *
4    * (C) Copyright 2008, by individual contributors as indicated by the @author tag.
5    *
6    * This library is free software; you can redistribute it and/or modify it
7    * under the terms of the GNU Lesser General Public License as
8    * published by the Free Software Foundation; either version 2.1 of
9    * the License, or (at your option) any later version.
10   *
11   * This software is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this software; if not, write to the Free
18   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20   */
21  package com.nickokiss.investor.fin.element;
22  
23  import java.math.BigDecimal;
24  
25  import com.nickokiss.investor.calc.MathCalc;
26  import com.nickokiss.investor.fin.env.Env;
27  
28  /**
29   * 
30   * @author Tomasz Koscinski <tomasz.koscinski@nickokiss.com>
31   */
32  public class Bond implements FinElement {
33    // private BigDecimal timeToMaturity = null;
34    private BigDecimal couponRate = null;
35    private BigDecimal paymentsPerYear = null;
36    private BigDecimal yield = null;
37  
38    private MathCalc mathCalc = new MathCalc();
39  
40    private StreamElement faceValue = new StreamElement();
41  
42    public BigDecimal getYield() {
43      return yield;
44    }
45  
46    public void setYield(BigDecimal yield) {
47      this.yield = yield;
48    }
49  
50    public BigDecimal getFaceValue() {
51      return faceValue.getValue();
52    }
53  
54    public void setFaceValue(BigDecimal faceValue) {
55      this.faceValue.setValue(faceValue);
56    }
57  
58    public BigDecimal getCouponRate() {
59      return couponRate;
60    }
61  
62    public void setCouponRate(BigDecimal couponRate) {
63      this.couponRate = couponRate;
64    }
65  
66    public BigDecimal getPaymentsPerYear() {
67      return paymentsPerYear;
68    }
69  
70    public void setPaymentsPerYear(BigDecimal paymentsPerYear) {
71      this.paymentsPerYear = paymentsPerYear;
72    }
73  
74    public BigDecimal getTimeToMaturity() {
75      return faceValue.getTime();
76    }
77  
78    public void setTimeToMaturity(BigDecimal timeToMaturity) {
79      this.faceValue.setTime(timeToMaturity);
80    }
81  
82    public void setCouponRate(String value) {
83      setCouponRate(new BigDecimal(value));
84    }
85  
86    public void setTimeToMaturity(String value) {
87      setTimeToMaturity(new BigDecimal(value));
88    }
89  
90    public void setFaceValue(String value) {
91      setFaceValue(new BigDecimal(value));
92    }
93  
94    public void setPaymentsPerYear(String value) {
95      setPaymentsPerYear(new BigDecimal(value));
96    }
97  
98    /**
99     * <pre>
100    * P - current price of the bond 
101    * F - face value of the bond 
102    * r - yield to maturity (YTM) 
103    * m - number of coupon payments per year 
104    * n - number of remaining coupon payments 
105    * C - coupon payments sum = F * couponValue
106    * 
107    * Bond price formula: 
108    * P = (F * (1 + r/m)^(-n)) + (C/r)*(1 - (1 + r/m)^(-n)) 
109    * P = compIntCalc.getPresentValue(F,r,m,n) + annCalc.getPresentValue(C,r,m,n)
110    * </pre>
111    * 
112    */
113   public BigDecimal getValue(Env env, BigDecimal time) {
114     return getCashFlowStream().getValue(env, time);
115   }
116 
117   public CashFlowStream getCashFlowStream() {
118     CashFlowStream cashFlowStream = new CashFlowStream();
119     BigDecimal couponAmount = getCouponPeriodAmount(faceValue.getValue(), couponRate, paymentsPerYear);
120     BigDecimal remainingCouponPayments = getRemainingCouponPayments(faceValue.getTime(), paymentsPerYear);
121     BigDecimal distance = mathCalc.div(mathCalc.ONE, paymentsPerYear);
122     cashFlowStream.addElements(couponAmount, remainingCouponPayments.intValue(), distance);
123     cashFlowStream.addElement(faceValue);
124     return cashFlowStream;
125   }
126 
127   private BigDecimal getCouponYearAmount(BigDecimal faceValue, BigDecimal couponValue) {
128     return faceValue.multiply(couponValue);
129   }
130 
131   private BigDecimal getCouponPeriodAmount(BigDecimal faceValue, BigDecimal couponValue, BigDecimal paymentsPerYear) {
132     return mathCalc.div(getCouponYearAmount(faceValue, couponValue), paymentsPerYear);
133   }
134   
135   private BigDecimal getRemainingCouponPayments(BigDecimal timeToMaturity, BigDecimal paymentsPerYear) {
136     return timeToMaturity.multiply(paymentsPerYear);
137   }
138 
139 
140 }