-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProblemSet3B.java
More file actions
159 lines (133 loc) · 4.89 KB
/
ProblemSet3B.java
File metadata and controls
159 lines (133 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package ProblemSets;
public class ProblemSet3B {
public static void main(String[] args) {
}
}
// YieldCalculation interface
interface YieldCalculation {
double yieldToMaturity (Bond bond);
}
// Bond Class
class Bond {
private double sellingPrice;
private double faceValue;
private double interestPayment;
private double duration;
private YieldCalculation yieldCalculation;
// default constructor
private Bond(double sellingPrice, double faceValue, double interestPayment, double duration)
throws IllegalArgumentException{
if (sellingPrice <= 0 || faceValue <= 0 || duration <= 0 || interestPayment < 0){
throw new IllegalArgumentException("Requirement (c): Invalid parameters for bond");
}
this.sellingPrice = sellingPrice;
this.faceValue = faceValue;
this.interestPayment = interestPayment;
this.duration = duration;
}
// TODO (b) : getter methods for instance variables
public double getSellingPrice(){
return sellingPrice;
}
public double getFaceValue(){
return faceValue;
}
public double getInterestPayment(){
return interestPayment;
}
public double getDuration(){
return duration;
}
// TODO (d) : setter method for instance variable yieldCalculation for objects that implement
// YieldCalculation interface
public void setYieldCalculation(YieldCalculation yieldCalculation){
this.yieldCalculation = yieldCalculation;
}
// TODO (a) : BondBuilder
public static class BondBuilder{
private double sellingPrice = 1000.00;
private double faceValue = 1000.00;
private double interestPayment = 10.0;
private double duration = 1.0;
public BondBuilder setSellingPrice(double sellingPrice){
this.sellingPrice = sellingPrice;
return this;
}
public BondBuilder setFaceValue(double faceValue){
this.faceValue = faceValue;
return this;
}
public BondBuilder setInterestPayment(double interestPayment){
this.interestPayment = interestPayment;
return this;
}
public BondBuilder setDuration(double duration){
this.duration = duration;
return this;
}
public Bond createBond(){
return new Bond(sellingPrice, faceValue, interestPayment, duration);
}
}
// TODO (e) : calculateYTM()
public double calculateYTM(){
if (yieldCalculation == null) {
return 0.01;
}
return yieldCalculation.yieldToMaturity(this);
}
}
// TODO (f) : class ZeroCouponYield & WithCouponYield
class ZeroCouponYield implements YieldCalculation{
@Override
public double yieldToMaturity(Bond bond) {
double faceValue = bond.getFaceValue();
double sellingPrice = bond.getSellingPrice();
double duration = bond.getDuration();
return (Math.pow(faceValue / sellingPrice, 1 / duration) - 1);
}
}
class WithCouponYield implements YieldCalculation{
@Override
public double yieldToMaturity(Bond bond) {
double interestPayment = bond.getInterestPayment();
double faceValue = bond.getFaceValue();
double duration = bond.getDuration();
double sellingPrice = bond.getSellingPrice();
return calculateYTM(interestPayment, faceValue, duration, sellingPrice);
}
private double presentValue(double interestPayment, double faceValue, double ytm, double duration){
double pv = 0.0;
for (int t = 1; t <= duration; t++) {
pv += interestPayment / Math.pow(1 + ytm, t);
}
pv += faceValue / Math.pow(1 + ytm, duration);
return pv;
}
private double calculateYTM(double interestPayment, double faceValue, double duration, double sellingPrice){
double ytm = 0.0;
double lowerBound = 0.0;
double upperBound = 1.0;
while (Math.abs(sellingPrice - presentValue(interestPayment, faceValue, ytm, duration)) > 0.0001) {
ytm = (lowerBound + upperBound) / 2.0;
if (presentValue(interestPayment, faceValue, ytm, duration) < sellingPrice) {
upperBound = ytm;
}
else {
lowerBound = ytm;
}
}
return ytm;
}
}
class TestBond {
public static void main(String[] args) {
Bond.BondBuilder bondBuilder = new Bond.BondBuilder();
Bond bond1 = bondBuilder.createBond();
bond1.setYieldCalculation(new WithCouponYield());
System.out.println("YTM for bond1: " + bond1.calculateYTM());
Bond bond2 = bondBuilder.setDuration(1).setFaceValue(1000).setSellingPrice(900).setInterestPayment(0).createBond();
bond2.setYieldCalculation(new ZeroCouponYield());
System.out.println("YTM for bond2: " + bond2.calculateYTM());
}
}