Implementing Excel и функция IRR VB

Благодаря @BertilBaron я нашел способ избежать ожидания длинных вычислений в R-Shiny. Статью, которую я использовал, можно найти здесь .

По сути, вы выполняете каждый процесс параллельно, используя пакет future. С этим пакетом каждый раз, когда пользователь нажимает на кнопку, будет выполняться расчет. Так что имейте в виду, что вы должны создать блок для нетерпеливых пользователей.

Мой рабочий пример

library(shiny)
library(promises)
library(future)
plan(multiprocess)

ui <- fluidPage(
  actionButton('button', 'klik'),
  textOutput('first'),
  textOutput('second')
)

server <- function(input, output) {
  nclicks <- reactiveVal(0)
  nclicks2 <- reactiveVal(0)
  result_val <- reactiveVal()
  result_val2 <- reactiveVal()

  observeEvent(input$button,{
    # Don't do anything if analysis is already being run
    if(nclicks() != 0 | nclicks2() != 0){
      showNotification("Already running analysis")
      return(NULL)
    }

    # Increment clicks and prevent concurrent analyses
    nclicks(nclicks() + 1)
    nclicks2(nclicks2() + 1)

    result <- future({
      # Long Running Task
      Sys.sleep(10)

      #Some results
      Sys.time()
    }) %...>% result_val()

    result2 <- future({
      #Some results
      Sys.time()
    }) %...>% result_val2()

    # Catch inturrupt (or any other error) and notify user
    result <- catch(result,
                    function(e){
                      result_val(NULL)
                      print(e$message)
                      showNotification(e$message)
                    })
    result2 <- catch(result2,
                    function(e){
                      result_val2(NULL)
                      print(e$message)
                      showNotification(e$message)
                    })

    # After the promise has been evaluated set nclicks to 0 to allow for anlother Run
    result <- finally(result,
                      function(){
                        nclicks(0)
                      })
    result2 <- finally(result2,
                      function(){
                        nclicks2(0)
                      })

    # Return something other than the promise so shiny remains responsive
    NULL
  })

  output$first <- renderText({
    req(result_val())
  })
  output$second <- renderText({
    req(result_val2())
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

6
задан GateKiller 10 February 2009 в 14:52
поделиться

3 ответа

Это довольно легко кодировать использование повторяющегося решателя, такого как метод деления пополам или метод Newton. Если Ваши потоки наличности C_t_j происходите время от времени t_j затем внутренняя рентабельность r удовлетворяет сумму j = 1 кому: n из

C_t_j / (1 + r)^t_j

равняется нулю. Назовите это f(r). Затем f'(r) сумма j = 1 кому: n из

-t_j * C_t_j / (1 + r)^(t_j+1).

Теперь можно применить метод Newton для решения для r.

2
ответ дан 17 December 2019 в 20:35
поделиться

Вот является IRR макросом Excel, который я записал много лет назад. Я не могу объяснить, как это больше работает, но я думаю, что это делает правильную вещь:

Это вызывается как: =IrrCont (A8:A15, F8:F15), где первый диапазон является диапазоном дат и второго, является диапазоном значений. Некоторые значения должны быть положительными, и некоторые должны быть отрицательными.

Option Explicit
'
' Internal Rate of return -- Calculation
' Returns a result (Double) or an error message (String)

Private Function IrrCalc(DateRange As Object, ValueRange As Object)
    Dim i As Integer
    Dim it As Integer
    Dim Count As Integer
    Dim u As Double
    Dim time As Double
    Dim d_positive As Double
    Dim positive As Double
    Dim d_negative As Double
    Dim negative As Double
    Dim sum As Double
    Const epsilon As Double = 0.000001
    Const iterations As Integer = 20
    Dim StartTime As Double
    Dim pos As Boolean
    Dim neg As Boolean
    Dim value As Double
    Dim temp As Double
    Dim delta As Double

    If DateRange.Count <> ValueRange.Count Then
      IrrCalc = "*** Date Range (argument 1) and Value Range " & _
          "(argument 2) must contain the same number of cells. ***"
      Exit Function
    End If

    Count = DateRange.Count

    For i = 1 To Count
      If ValueRange.Cells(i).value > 0 Then pos = True
      If ValueRange.Cells(i).value < 0 Then neg = True
      If pos And neg Then Exit For
    Next i

    If Not pos Or Not neg Then
      IrrCalc = "*** Cannot calculate IRR: Need both income and expenditure. ***"
      Exit Function
    End If

    StartTime = Application.Min(DateRange)

    u = 0 ' Initial interest rate guess

    For it = 1 To iterations
      positive = 0
      d_positive = 0
      negative = 0
      d_negative = 0

      For i = 1 To Count
        value = ValueRange.Cells(i).value
        time = (DateRange.Cells(i).value - StartTime) / 365.2425
        If value > 0 Then
          temp = value * Exp(u * time)
          positive = positive + temp
          d_positive = d_positive + temp * time
        ElseIf value < 0 Then
          temp = -value * Exp(u * time)
          negative = negative + temp
          d_negative = d_negative + temp * time
        End If
      Next i
      delta = Log(negative / positive) / (d_negative / negative - d_positive / positive)
      If Abs(delta) < epsilon Then Exit For
      u = u - delta
    Next it

    If it > iterations Then
      IrrCalc = "*** irr does not converge in " & Str(iterations) & " iterations ***"
    Else
      IrrCalc = u
    End If
End Function

' ====================================================================================================
'
' Internal Rate of Return: Discrete interest calculation

Function IrrDiscrete(DateRange As Object, ValueRange As Object)
  Dim result As Variant
  result = IrrCalc(DateRange, ValueRange)
  If VarType(result) = vbDouble Then
    IrrDiscrete = Exp(-result) - 1#
  Else
    IrrDiscrete = result
  End If
End Function

' ====================================================================================================
'
' Internal Rate of Return: Continuous (compounding) interest calculation

Function IrrCont(DateRange As Object, ValueRange As Object)
  Dim result As Variant
  result = IrrCalc(DateRange, ValueRange)
  If VarType(result) = vbDouble Then
    IrrCont = -result
  Else
    IrrCont = result
  End If
End Function
0
ответ дан 17 December 2019 в 20:35
поделиться

Ниже моя повторяющаяся реализация, в ActionScript:


package xattam.net.math
{
    public class Financial
    {
        public static const MAX_IRR_ITERATIONS:int = 1000;

        public static function IRR(cashFlow:Array,guess:Number=0.1):Number {
            var npv:Number;
            var cnt:Number = 0;
            do
            {
                npv = Financial.NPV(guess,cashFlow);
                guess+= 0.001;

                if(cnt > Financial.MAX_IRR_ITERATIONS) return NaN;
                else cnt++;
            }
            while(npv > 0)

            return guess;
        }
        public static function NPV(discountRate:Number,cashFlow:Array):Number {
            var npv:Number = 0;
            for(var t:int = 0; t < cashFlow.length;t++) {

                npv += cashFlow[t] / Math.pow((1+ discountRate),t);
            }
            return npv;
        }
    }   
}

0
ответ дан 17 December 2019 в 20:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: