InternalRateOfReturnの値が正常でない場合は

解決


クッキー  2004-07-14 17:21:28  No: 9905

InternalRateOfReturn の結果とエクセルのIRR関数の結果を比較すると
値が異なる場合があります
エクセルでは+なのですが  InternalRateOfReturn  ではーになります。
数値を変えてみた結果、エクセルのほうが正しいように思えます
何かよい解決方法はありませんか


にしの  2004-07-14 19:06:36  No: 9906

InternalRateOfReturn関数を使用したことがないのですが、具体的な値を示していただくとお答えできるかもしれません。
結果が違うのなら、自前でルーチンを作成する必要が出てくるかもしれませんね。


クッキー  2004-07-15 07:28:14  No: 9907

IRR := internalRateOfReturn(0,[-111586,
      42161,39619,39576,39576,37572,
      37654,37470,35772,35654,-184712]);

エクセルでは0.272741ですがDELPHIでは-0.07536435となります
最初の引数Guessを0.2にすれば正しく表示されました

Flag := False;
for i := 8 downto 0 do
begin
   Guess := i * 0.1;
   IRR := internalRateOfReturn(Guess,
    [S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,S10]);
   if (IRR >= Ges) and (IRR < Ges + 0.1) then
   begin
      Flag := True;
      Break;
   end;
end;

で一応は正しい値が帰ってきますが、Guessの値が戻り値とかけ離れている場合、エラーになりはしないか気がかりです


う〜む  2004-07-15 09:47:48  No: 9908

下のコードを実行すると、結果は2種類の値にわかれますね。
この場合なら、負の数は間違った計算結果ということになりますが、
Guessの値によって間違った計算結果が出るのは内部計算のバグなんでしょうか…

procedure TForm1.Button1Click(Sender: TObject);
var
  Guess, IRR : Extended;
begin
  Guess := 20;
  while True do begin
    IRR := internalRateOfReturn(Guess, [-111586,
      42161,39619,39576,39576,37572,
      37654,37470,35772,35654,-184712]);
    ListBox1.Items.Add(Format('%8.5f ⇒ %18.15f',[Guess, IRR]));
    if Guess > 1 then Guess := Guess - 1
    else
    if Guess > 0.11 then Guess := Guess - 0.01
    else
    if Guess > 0.05 then Guess := Guess - 0.0001
    else break;
  end;
end;


クッキー  2004-07-15 17:10:30  No: 9909

internalRateOfReturn  はニュートンの解法により近似値を計算しています
ニュートンの解法の理論はわかりません。力学で、予想値から、方程式を解いていく問題をしたこととがあります。そのとき、予想値がかけ離れていると回答不能になりました。また、解が2つ出てくる場合もあり、誤っているほうは捨てることになります。
  internalRateOfReturn  では、誤っている解が選択されたのではないかと思うのですが。
う〜むさんのコードでGuessに20を代入してもエラーにならないことがわかりました。internalRateOfReturn  の  Guessを  0 から 0.5にしているためおそらくエラーは起こらないとは思うのですが


にしの  2004-07-15 19:22:36  No: 9910

Delphi, Excelのバージョンはいくつですか?
こちらの環境(Delphi7Pro, Excel2000SP3)では、
Excel:  -0.07536435 (小数点以下8桁に丸めた場合)
Delphi: -0.07536435 (小数点以下8桁に丸めた場合)
と出ますよ。

Excelでは、上で示していただいた値を、
[A列]
 1: -111586
 2: 42161
 3: 39619
 4: 39576
 5: 39576
 6: 37572
 7: 37654
 8: 37470
 9: 35772
10: 35654
11: -184712
12: =IRR(A1:A11,0)

として表示しました。
IRRは複数の解答を持つそうで、その場合、ニュートン法の初期値によっては違う値を返します。
そのために、Guess引数(Delphiの場合は第1引数、Excelの場合は第2引数)で推測値を設定します。
ニュートン法の処理によっては、どちらかの解に振れてしまうこともありそうですし。


クッキー  2004-07-16 08:40:55  No: 9911

どうもありがとうございました。
戻り値と推定値を比較して正しい解を見つけるという方法を取りました


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加