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.util; 22 23 import java.math.RoundingMode; 24 25 /** 26 * 27 * @author Tomasz Koscinski <tomasz.koscinski@nickokiss.com> 28 */ 29 public class TkFinConstants { 30 31 public static final int DEFAULT_SCALE = 10; 32 public static final RoundingMode DEFAULT_ROUNDING_MODE = RoundingMode.HALF_UP; 33 34 public static final String MESSAGE_INFIN_PV_CYCLE_LENGHT_0 = "Can't calculate infinite present value: cycle lenght = 0"; 35 public static final String MESSAGE_SPOT_RATE_NOT_SPECIFIED = "Spot rate not specified for value of time: "; 36 37 //TODO - REFACTORING 38 39 // Remove: tkfin constant (use Investor instead) 40 // new BigDecimal(i) => mathCalc.value(i) 41 // BigDecimal bd = ... => Quantity q = ... (q.value, q.unit) 42 // Calendar as a time elements factory 43 // Create VOs to represent Bond, CashFlowStream, Interest, ... 44 // Create builders to build financial objects: interest, cashFlowStream, bond, annuity 45 // - set some values and calculate the rest 46 // - specify if object has enough values filled to calculate the rest 47 // - for every equation with n variables we need (n-1) of them to be set 48 // - if X equations describe the object, we can miss X variables 49 // Re-factoring: specify relations between financial objects 50 // new method: PortfolioCalc.getSurplus(portfolio, obligation, environment); 51 // Organise TkFinConstants comments 52 // move methods from Calc to MathCalc 53 // BigDecimal.ZERO,... -> MathCalc.ZERO,... 54 // Introduce FinNumber interface (BigDecimal, float implementations) 55 // (??) Bond - divide by streamElement and annuity 56 // (??) Differentiate time and money 57 // (??) move calculations from calcs to functions 58 // paymentsPerYear and yield relation? 59 // Use functions in calcs (no code duplication) 60 // stream - set end, instead of adding zero element 61 // stream - starting point is always zero!! no need to define zero element! 62 // stream - present value (time 0), start value (start time), end value of the stream (end time) 63 // Improve performance of comparator - move calculations into cashFlowStream and cache result as long as values are the same 64 // Improve maven reports 65 // Reduce bugs in maven reports 66 67 //TODO - BUG FIXES 68 69 // Java heap space - too many objects (when calculating value of the bond using cashFlowStream) 70 // bondCalc - correct problem with zero-coupon bond, why estimated price change is different? 71 // BondCalc.getCouponAmount - error? what in case of many payments per year 72 // Check stream1 - why IRR can't be calculated? repair 73 // Bug in the book or in the algorithm? car B PV: 58795 ?? 74 75 //TODO - NEW NON-FUNCTIONAL REQUIREMENTS 76 77 // (??) Jester 78 // Checkstyle - configure and add to maven 79 // fix checkstyle bugs 80 // add javadoc (especially description of the class) 81 // (??) Maven historic dashboard reports - mySQL 82 // Spring test framework - add data from xml files 83 // Add log4j logging, also during Unit testing 84 85 //TODO - NEW FUNCTIONAL REQUIREMENTS 86 87 // Is it possible to compute all variants using dynamic programming? (probably not) 88 // Dynamic programming (graph) 89 // Zero-one programming problem (benefit, cost ratio of cashflowstream) 90 // 1. zero-one algorithm - try all combinations (2^n combinations - n = number of projects) 91 // (can be used for small number of projects) 92 // 2. projects sorted and pick up from the top 93 // Algorithm: choose bonds with minimal price to meet obligations (linear algebra) 94 // Compare cost-benefit ratio to PV(interest rate needed) and internal-rate-of-return 95 // Algorithm - how to choose projects 96 // Portfolio.getOptimizedSet(time, availableMoney) 97 // Portfolio.getOptimizedSet(availableMoney) 98 // portfolio.getOptimizedSet(money, comparator) 99 // Comparator - compare CashFlowSteams (finElements) 100 // Portfolio.sort(IRRComparator/PVComparator/CostsBenefitsComparator) 101 // Mortgage finElement: principal stream, interest stream, types of payments, lowering/equal 102 // IMPLEMENT PORTFOLIO IMMUNIZATION: (versions: 2 BONDS, >2 bonds) 103 // Quasi-modified duration (periodic compounding) (sk -> sk + value for all k) 104 // Fisher-Weil duration (continuous compounding) (sk -> sk + value for all k) 105 // Duration of FinElement 106 // Annuity duration 107 // Floating rate bond 108 // Running present value (need to define environment first) 109 // immunization calculations 110 // Bond price, duration, convexity under continuous compounding (bond exercises) 111 // Perpetual annuity duration 112 // Bond: calculate other values: 113 // * F - face value of the bond 114 // * m - number of coupon payments per year 115 // * C - coupon payments sum = F * couponValue * n 116 // CY - current yield 117 // Improve iterative function calc (scale -> 1.2.3.4.5...) 118 // Yield to call (YTC) 119 // Running amortization - (bank statement: current interest / payment received) 120 // Annuity - getInterestRate, getNumberOfPeriods - use function to calculate 121 // Perpetual annuities: P = A/r (example 3.1) 122 // stream.merge(stream2) - merge values at the same time 123 // CashFlowStream.merge(cashFlowStream) - add without changing values 124 // stream.negate() - negate all values (subtract = stream.merge(stream2.getCopy().negate()) ) 125 // stream - remove zero values (define starting point time) (what in case of additive creator - value of added element can be zero) 126 // * What in case of removing some elements? middle zero element can become first! (change definition of time) 127 // Write function graph. Use Function interface 128 // Yearly growth rate of the stream (2 vs sqrt(3) - cut tree example) = 1 + IRR 129 // CashFlowStream.removeZeroValues() 130 // StreamElement \n to toString 131 // Calculate NWW 132 // Find a library to calculate: 133 // - minimum of function 134 // - maximum of function 135 // - x for specified f(x) 136 // Crossover value of 2 streams 137 // If stream A cross stream B? (calculate) 138 139 //TODO - MISSED EXERCISES 140 141 // Example 2.2 142 // Example 2.3 143 // Example 2.9 - depreciation 144 // Example 2.10 - inflation (real interest rate) 145 // exercise 4. (CFS) Newton's method 146 // exercise 8. (CFS) copy machines 147 // exercise 10. (CFS) oil depletion allowance 148 // exercise 11. (CFS) Answer on the question? Why? 149 // exercise 11. (CFS) calculate crossover value 150 // exercise 13. (CFS) crossover value (the value of interestRate? for which 2 streams have the same present value) 151 // exercise 14. (CFS) 152 // exercise 15. (CFS) 153 // exercise4 (spot rates) (Spot rate project) 154 // exercise5 (spot rates) (instantaneous rates) 155 // exercise6 (spot rates) (Discount conversion) - based on d[i,k] = d[i,j] * d[j,k] (no need) 156 // exercise7 (spot rates) (bond taxes) 157 // exercise8 (spot rates) (real zeros) 158 // exercise9 (spot rates) (flat forwards) (no need) 159 // exercise10 (spot rates) (too difficult) 160 // exercise12 (spot rates) duration 161 // exercise13 (spot rates) portfolio immunization 162 // exercise14 (spot rates) mortgage: principal stream and interest stream 163 // exercise15 (spot rates) short rate sensitivity 164 165 }