(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Microsoft.VisualBasic / Microsoft.VisualBasic / Financial.cs
blobdc89f1f951f8b29b4b1da63bf2d1b9777d82a79e
1 //
2 // Financial.cs
3 //
4 // Author:
5 // Chris J Breisch (cjbreisch@altavista.net)
6 //
7 // (C) 2002 Chris J Breisch
8 //
11 // Copyright (c) 2002-2003 Mainsoft Corporation.
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System;
35 using System.Runtime.InteropServices;
36 using Microsoft.VisualBasic.CompilerServices;
38 namespace Microsoft.VisualBasic
40 [StandardModule]
41 sealed public class Financial {
42 // Declarations
43 // Constructors
44 private Financial() {} // prevent public default constructor
45 // Properties
46 // Methods
47 public static double DDB (double Cost, double Salvage, double Life, double Period,
48 [Optional, __DefaultArgumentValue(2)] double Factor)
50 // LAMESPEC: MSDN says Life and Factor only throws exception if < 0, but Implementation throws exception if <= 0
51 if (Cost < 0
52 || Salvage < 0
53 || Life <= 0
54 || Period < 0
55 || Factor <= 0
56 || Period > Life)
57 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "Factor"));
59 return (((Cost - Salvage) * Factor) / Life) * Period;
62 public static double FV (double Rate, double NPer, double Pmt,
63 [Optional, __DefaultArgumentValue(0)] double PV,
64 [Optional, __DefaultArgumentValue(0)] DueDate Due)
66 Pmt = -Pmt;
67 PV = -PV;
68 double currentRate = Math.Pow (Rate + 1, NPer);
69 double sum = 0;
71 if (Rate != 0)
72 sum = Pmt * ((currentRate - 1) / Rate);
73 else
74 sum = Pmt * NPer;
76 if (Due == DueDate.BegOfPeriod)
77 sum *= (1 + Rate);
79 return PV * currentRate + sum;
82 public static double IPmt (double Rate, double Per, double NPer, double PV,
83 [Optional, __DefaultArgumentValue(0)] double FV,
84 [Optional, __DefaultArgumentValue(0)] DueDate Due)
86 double totalFutureVal;
87 double totalPaymentValue;
88 double numberOfPeriods;
90 if ((Per <= 0) || (Per >= (NPer + 1)))
91 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "Per"));
92 if ((Due == DueDate.BegOfPeriod) && (Per == 1))
93 return 0;
95 totalPaymentValue = Pmt (Rate, NPer, PV, FV, Due);
96 if (Due == DueDate.BegOfPeriod)
97 PV = (PV + totalPaymentValue);
99 numberOfPeriods = Per - ((int)Due) - 1;
100 totalFutureVal =
101 Financial.FV (Rate, numberOfPeriods, totalPaymentValue, PV, DueDate.EndOfPeriod);
103 return (totalFutureVal * Rate);
106 public static double IRR (ref double[] ValueArray, [Optional, __DefaultArgumentValue(0.1)] double Guess)
108 double origPV, updatedPV, updateGuess, tmp;
109 double rateDiff = 0.0;
110 double pvDiff = 0.0;
111 int length;
113 // MS.NET 2.0 docs say that Guess may not be <= -1
114 if (Guess <= -1)
115 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "Guess"));
116 try {
117 length = ValueArray.GetLength(0);
119 catch {
120 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "ValueArray"));
122 if (length < 2)
123 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "ValueArray"));
125 origPV = NPV (Guess, ref ValueArray);
126 updateGuess = (origPV > 0) ? Guess + 0.00001 : Guess - 0.00001;
128 if (updateGuess < -1)
129 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "Rate"));
131 rateDiff = updateGuess - Guess;
132 updatedPV = NPV (updateGuess, ref ValueArray);
133 pvDiff = updatedPV - origPV;
134 for (int i = 0; i < 20; i++) {
135 Guess = (updateGuess > Guess) ? (Guess - 0.00001) : (Guess + 0.00001);
136 origPV = NPV (Guess, ref ValueArray);
137 rateDiff = updateGuess - Guess;
138 pvDiff = updatedPV - origPV;
139 if (pvDiff == 0)
140 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue"));
141 Guess = updateGuess - (rateDiff * updatedPV / pvDiff);
142 if (Guess < -1)
143 Guess = -1;
144 origPV = NPV (Guess, ref ValueArray);
145 if ((Math.Abs (origPV) < 0.0000001) && (Math.Abs (rateDiff) < 0.00001))
146 return Guess;
148 tmp = Guess;
149 Guess = updateGuess;
150 updateGuess = tmp;
151 tmp = origPV;
152 origPV = updatedPV;
153 updatedPV = tmp;
155 double origPVAbs = Math.Abs (origPV);
156 double updatedPVAbs = Math.Abs (updatedPV);
157 if ((origPVAbs < 0.0000001) && (updatedPVAbs < 0.0000001))
158 return (origPVAbs < updatedPVAbs) ? Guess : updateGuess;
159 else if (origPVAbs < 0.0000001)
160 return Guess;
161 else if (updatedPVAbs < 0.0000001)
162 return updateGuess;
163 else
164 throw new ArgumentException(Utils.GetResourceString ("Argument_InvalidValue"));
167 public static double MIRR (ref double[] ValueArray, double FinanceRate, double ReinvestRate)
169 double [] array = ValueArray;
170 double loansVal = 0;
171 double assetsVal = 0;
172 double currentLoanRate = 1;
173 double currentAssetsRate = 1;
174 double totalInterestRate = 0;
175 int arrayLength = 0;
176 if (array.Rank != 1)
177 throw new ArgumentException (Utils.GetResourceString ("Argument_RankEQOne1", "ValueArray"));
178 else if (FinanceRate == -1)
179 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "FinanceRate"));
180 else if (ReinvestRate == -1)
181 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "ReinvestRate"));
183 arrayLength = array.Length;
184 if (arrayLength < 2)
185 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "ValueArray"));
187 for (int i = 0; i < arrayLength; i++) {
188 currentLoanRate *= (1 + FinanceRate);
189 currentAssetsRate *= (1 + ReinvestRate);
190 if (array [i] < 0)
191 loansVal += (array [i] / currentLoanRate);
192 else if (array [i] > 0)
193 assetsVal += (array [i] / currentAssetsRate);
196 if (loansVal == 0)
197 throw new DivideByZeroException (Utils.GetResourceString ("Financial_CalcDivByZero"));
199 totalInterestRate =
200 ((-assetsVal * Math.Pow (ReinvestRate + 1, arrayLength))
201 / (loansVal * (FinanceRate + 1)));
202 if (totalInterestRate < 0)
203 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue"));
205 return (Math.Pow (totalInterestRate, 1 / (double) (arrayLength - 1))) - 1;
208 public static double NPer (double Rate, double Pmt, double PV,
209 [Optional, __DefaultArgumentValue(0)] double FV,
210 [Optional, __DefaultArgumentValue(0)] DueDate Due)
212 double totalIncomeFromFlow, sumOfPvAndPayment, currentValueOfPvAndPayment;
213 if (Rate == 0 && Pmt == 0)
214 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "Pmt"));
215 else if (Rate == 0)
216 return (- (PV + FV) / Pmt);
217 // MainSoft had Rate < -1, but MS.NET 2.0 Doc says Rate should not be <= -1
218 else if (Rate <= -1)
219 throw new ArgumentException(Utils.GetResourceString ("Argument_InvalidValue1", "Rate"));
220 totalIncomeFromFlow = (Pmt / Rate);
221 if (Due == DueDate.BegOfPeriod)
222 totalIncomeFromFlow *= (1 + Rate);
224 sumOfPvAndPayment = (-FV + totalIncomeFromFlow);
225 currentValueOfPvAndPayment = (PV + totalIncomeFromFlow);
226 if ((sumOfPvAndPayment < 0) && (currentValueOfPvAndPayment < 0)) {
227 sumOfPvAndPayment = -sumOfPvAndPayment;
228 currentValueOfPvAndPayment = -currentValueOfPvAndPayment;
230 else if ((sumOfPvAndPayment <= 0) || (currentValueOfPvAndPayment < 0))
231 throw new ArgumentException (Utils.GetResourceString ("Financial_CannotCalculateNPer"));
233 double totalInterestRate = sumOfPvAndPayment / currentValueOfPvAndPayment;
234 return Math.Log (totalInterestRate) / Math.Log (Rate + 1);
237 public static double NPV (double Rate, ref double[] ValueArray)
239 if (ValueArray == null)
240 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidNullValue1", "ValueArray"));
242 double [] arr = ValueArray;
243 if (arr.Rank != 1)
244 throw new ArgumentException (Utils.GetResourceString ("Argument_RankEQOne1", "ValueArray"));
245 if (Rate == -1)
246 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "Rate"));
247 int length = arr.Length;
248 if (length < 0)
249 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "ValueArray"));
251 double currentValue = 0;
252 double currentRate = 1;
253 double sum = 0;
254 for (int index = 0; index < length; index++) {
255 currentValue = arr [index];
256 currentRate *= (1 + Rate);
257 sum += (currentValue / currentRate);
259 return sum;
262 public static double Pmt (double Rate, double NPer, double PV,
263 [Optional, __DefaultArgumentValue(0)] double FV,
264 [Optional, __DefaultArgumentValue(0)] DueDate Due)
266 PV = -PV;
267 FV = -FV;
268 if (NPer == 0)
269 throw new ArgumentException (Utils.GetResourceString ("Argument_InvalidValue1", "NPer"));
271 double totalFutureVal = 0;
272 double geometricSum = 0;
273 if (Rate == 0) {
274 totalFutureVal = FV + PV;
275 geometricSum = NPer;
277 else if (Due == DueDate.EndOfPeriod) {
278 double totalRate = Math.Pow (Rate + 1, NPer);
279 totalFutureVal = FV + PV * totalRate;
280 geometricSum = (totalRate - 1) / Rate;
282 else if (Due == DueDate.BegOfPeriod) {
283 double totalRate = Math.Pow (Rate + 1, NPer);
284 totalFutureVal = FV + PV * totalRate;
285 geometricSum = ((1 + Rate) * (totalRate - 1)) / Rate;
287 return (totalFutureVal) / geometricSum;
290 public static double PPmt (double Rate, double Per, double NPer, double PV,
291 [Optional, __DefaultArgumentValue(0)] double FV,
292 [Optional, __DefaultArgumentValue(0)] DueDate Due)
294 if ((Per <= 0) || (Per >= (NPer + 1)))
295 throw new ArgumentException(Utils.GetResourceString ("PPMT_PerGT0AndLTNPer", "Per"));
296 double interestPayment = IPmt (Rate, Per, NPer, PV, FV, Due);
297 double totalPayment = Pmt (Rate, NPer, PV, FV, Due);
298 return (totalPayment - interestPayment);
301 public static double PV (double Rate, double NPer, double Pmt,
302 [Optional, __DefaultArgumentValue(0)] double FV,
303 [Optional, __DefaultArgumentValue(0)] DueDate Due)
305 Pmt = -Pmt;
306 FV = -FV;
307 double currentRate = 1;
308 double sum = 0;
309 for (int index = 1; index <= NPer; index++) {
310 currentRate *= (1 + Rate);
311 sum += (Pmt / currentRate);
314 if (Due == DueDate.BegOfPeriod)
315 sum *= (1 + Rate);
316 return sum + FV / currentRate;
319 public static double Rate (double NPer, double Pmt, double PV,
320 [Optional, __DefaultArgumentValue(0)] double FV,
321 [Optional, __DefaultArgumentValue(0)] DueDate Due,
322 [Optional, __DefaultArgumentValue(0.1)] double Guess)
324 double updatedGuess, tmp, origFv, updatedFv;
325 double rateDiff = 0.0;
326 double fvDiff = 0.0;
328 if (NPer < 0)
329 throw new ArgumentException (Utils.GetResourceString ("Rate_NPerMustBeGTZero"));
330 origFv = -Financial.FV (Guess, NPer, Pmt, PV, Due) + FV;
331 updatedGuess = (origFv > 0) ? (Guess / 2) : (Guess * 2);
332 rateDiff = updatedGuess - Guess;
333 updatedFv = -Financial.FV (updatedGuess, NPer, Pmt, PV, Due) + FV;
334 fvDiff = updatedFv - origFv;
335 for (int i = 0; i < 20; i++) {
336 Guess += (updatedGuess > Guess) ? -0.00001 : 0.00001;
337 origFv = -Financial.FV (Guess, NPer, Pmt, PV, Due) + FV;
338 rateDiff = updatedGuess - Guess;
339 fvDiff = updatedFv - origFv;
340 if (fvDiff == 0)
341 throw new ArgumentException (Utils.GetResourceString ("Financial_CalcDivByZero"));
342 Guess = updatedGuess - (rateDiff * updatedFv / fvDiff);
343 origFv = -Financial.FV (Guess, NPer, Pmt, PV, Due) + FV;
344 if (Math.Abs (origFv) < 0.0000001)
345 return Guess;
346 tmp = Guess;
347 Guess = updatedGuess;
348 updatedGuess = tmp;
349 tmp = origFv;
350 origFv = updatedFv;
351 updatedFv = tmp;
353 double origFVAbs = Math.Abs (origFv);
354 double updatedFVAbs = Math.Abs (updatedFv);
355 if ((origFVAbs < 0.0000001) && (updatedFVAbs < 0.0000001))
356 return (origFVAbs < updatedFVAbs) ? Guess : updatedGuess;
357 else if (origFVAbs < 0.0000001)
358 return Guess;
359 else if (updatedFVAbs < 0.0000001)
360 return updatedGuess;
361 else
362 throw new ArgumentException (Utils.GetResourceString ("Financial_CannotCalculateRate"));
365 public static double SLN (double Cost, double Salvage, double Life)
367 if (Life == 0)
368 throw new ArgumentException (Utils.GetResourceString ("Financial_LifeNEZero"));
370 return (Cost - Salvage) / Life;
373 public static double SYD (double Cost, double Salvage, double Life, double Period)
375 if (Period <= 0)
376 throw new ArgumentException (Utils.GetResourceString("Financial_ArgGTZero1", "Period"));
377 else if (Salvage < 0)
378 throw new ArgumentException (Utils.GetResourceString("Financial_ArgGEZero1", "Salvage"));
379 else if (Period > Life)
380 throw new ArgumentException (Utils.GetResourceString("Financial_PeriodLELife"));
382 double depreciation = (Cost - Salvage);
383 double sumOfDigits = (Life + 1) * Life / 2;
384 double currentPeriodPart = Life + 1 - Period ;
386 return depreciation * currentPeriodPart / sumOfDigits;
388 // Events