library(shiny) library(DT) library(ggplot2)

ui <- fluidPage( titlePanel(“App Unificada de Amortizaciones”),

sidebarLayout( sidebarPanel( selectInput(“tipo”, “Tipo de amortización:”, choices = c(“Cuotas Constantes (Francés)”, “Amortización Constante”, “Renta Variable (Gradiente Aritmético)”)),

  numericInput("capital", "Capital inicial (C):", value = 195000),
  numericInput("n", "Número de pagos:", value = 12),
  numericInput("tasa", "Tasa de interés anual (%):", value = 12.0),
  
  selectInput("frecuencia", "Capitalización:",
              choices = c("Quincenal" = 24, "Mensual" = 12, "Bimestral" = 6,
                          "Trimestral" = 4, "Semestral" = 2, "Anual" = 1)),
  
  conditionalPanel(
    condition = "input.tipo == 'Renta Variable (Gradiente Aritmético)'",
    numericInput("R1", "Primer pago (R₁):", value = 50000),
    numericInput("d", "Incremento por periodo (d):", value = 6500)
  ),
  
  conditionalPanel(
    condition = "input.tipo == 'Amortización Constante'",
    numericInput("R1_ac", "Primer pago (R₁):", value = 24335)
  ),
  
  actionButton("calcular", "Calcular")
),

mainPanel(
  h4("Resultados"),
  verbatimTextOutput("renta_text"),
  DTOutput("tabla"),
  h4("Evolución del Saldo"),
  plotOutput("grafico")
)

) )

server <- function(input, output) {

resultados <- eventReactive(input\(calcular, { C <- input\)capital n <- input\(n i <- (input\)tasa / 100) / as.numeric(input\(frecuencia) tipo <- input\)tipo tabla <- data.frame() renta_val <- NA

if (tipo == "Cuotas Constantes (Francés)") {
  R <- C * (i / (1 - (1 + i)^(-n)))
  saldo <- C
  
  for (t in 1:n) {
    interes <- saldo * i
    amort <- R - interes
    saldo <- saldo - amort
    
    tabla <- rbind(tabla, data.frame(
      Periodo = t, Renta = round(R, 2), Interes = round(interes, 2),
      Amortizacion = round(amort, 2), Saldo = round(max(saldo, 0), 2)
    ))
  }
  renta_val <- R
  
} else if (tipo == "Amortización Constante") {
  A <- C / n
  R1 <- input$R1_ac
  saldo <- C
  
  for (t in 1:n) {
    interes <- saldo * i
    renta <- A + interes
    saldo <- saldo - A
    
    tabla <- rbind(tabla, data.frame(
      Periodo = t, Renta = round(renta, 2), Interes = round(interes, 2),
      Amortizacion = round(A, 2), Saldo = round(max(saldo, 0), 2)
    ))
  }
  
} else if (tipo == "Renta Variable (Gradiente Aritmético)") {
  R1 <- input$R1
  d <- input$d
  T <- (1 - (1 + i)^(-n)) / i
  V <- (1 - (1 + n * i) * (1 + i)^(-n)) / (i^2)
  VP <- R1 * T + d * V
  saldo <- VP
  
  for (t in 1:n) {
    R <- R1 + (t - 1) * d
    interes <- saldo * i
    amort <- R - interes
    saldo <- saldo - amort
    
    tabla <- rbind(tabla, data.frame(
      Periodo = t, Renta = round(R, 2), Interes = round(interes, 2),
      Amortizacion = round(amort, 2), Saldo = round(max(saldo, 0), 2)
    ))
  }
  renta_val <- NA
}

list(tabla = tabla, renta_val = renta_val)

})

output\(renta_text <- renderText({ res <- resultados() if (!is.null(res\)renta_val)) { paste0(“Renta constante: \(", format(round(res\)renta_val, 2), nsmall = 2)) } else {”Renta variable.” } })

output\(tabla <- renderDT({ datatable(resultados()\)tabla, options = list(pageLength = 15)) })

output\(grafico <- renderPlot({ res <- resultados() ggplot(res\)tabla, aes(x = Periodo, y = Saldo)) + geom_line(color = “steelblue”, size = 1.2) + geom_point(color = “darkblue”) + theme_minimal() + labs(title = “Evolución del Saldo Insoluto”, y = “Saldo”, x = “Periodo”) }) }

shinyApp(ui = ui, server = server)