如何解决如何在Delphi中实现XIRR实现?
|解决方法
与其重新发明轮子,不如看看SysTools出色的StFIN.pas:
函数NonperiodicIRR(const Values:Double的数组;
const Dates:TStDate的数组;
猜猜:扩展):扩展;
您可以在这里获取:
http://sourceforge.net/projects/tpsystools
, 这是代码;
function XIRR(Values: array of double; Dates: array of tDateTime; var Rate: double): Boolean;
const MAX_STEPS = 100;
function CalcValue(Rate: double): double;
function disc(d: tDateTime; v: double): double;
var
Exp,coef: double;
begin
Exp := (d - Dates[0]) / 365;
coef := Power(1 + Rate / 100,Exp);
result := v / coef;
end;
var
i: integer;
begin
result := 0;
for i := 0 to High(Dates) do
result := result + disc(Dates[i],Values[i]);
end;
var
SaveFPUCW: word;
CWChgReq: Boolean;
Rate1,Rate2,RateN: double;
F1,F2,FN,dF,Scale: double;
Quit: Boolean;
N: integer;
begin
RateN := 0;
FN := 0;
Assert(length(Values) = length(Dates));
Assert(length(Values) >= 2);
SaveFPUCW := Get8087CW;
CWChgReq := (SaveFPUCW and $1F3F) <> $1332;
If CWChgReq then Set8087CW($1332);
try
result := true;
Rate1 := Rate;
Rate2 := Rate + 1;
Quit := false;
N := 0;
Scale := 1;
F1 := CalcValue(Rate1);
F2 := CalcValue(Rate2);
while not Quit do
begin
if (F2 = F1) or (Rate2 = Rate1) then
begin
Quit := true;
result := false;
end
else
begin
dF := (F2 - F1) / (Rate2 - Rate1);
RateN := Rate1 + (0 - F1) / dF / Scale;
N := N + 1;
if RateN > -100 then := CalcValue(RateN);
if Abs(RateN - Rate1) / ((Abs(Rate1) + Abs(Rate2)) / 2) < 0.0000005 then
Quit := true
else if N >= MAX_STEPS then
begin
Quit := true;
result := false;
end
else if not(RateN > -100) then
begin
Scale := Scale * 2;
end
else
begin
Scale := 1;
Rate2 := Rate1;
F2 := F1;
Rate1 := RateN;
F1 := FN;
end;
end;
end;
if result then Rate := RateN
else Rate := 0;
Finally
If CWChgReq then Set8087CW(SaveFPUCW);
end;
end;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。