#!/usr/bin/perl

use 5.040.3;

# vie 06 mar 2026 12:04:42 CET
# Dado que no encuentro fallo lógico pero no confio en el output
# Publico el script tal cual. Ya vendrán versiones
# (c) Jesús Lozano Mosterín, 2026


my $year = 365.2425;    # días  ->  esto no se va a usar
my $nweek = 52.143;     # semanas / año
my $week = 7;

my $n;    # número de transacciones
my ($x, $y);  # fracciones de ese periodo inicial y final (retirada)
my $f;

# my ($i, $j);  # intereses tanto por 1 referidos al año, normal y de fracciones, $j < $i por conveniencia

# my $k1 = 1/$week;   # supuesto 1 el periodo es la semana y la fracción menos que eso 
# my $k = 7 * 1/$year;   # supuesto 2 el periodo es el día y las fracciones son días fuera del año
# esto convierte a la simulación en no discreta, casi por narices

my $ITER = 10_000_000;

my $t = 0;

my $V0 = 1_000;   # constante

my $Vfinal;
my $Rfinal;
my $RAfinal;

my ($vf, $vn);

my @max = ("0 0 0 -9e99 -9e99 -9e99 0 0 0") x 12;
my @min = ("0 0 0 9e99 9e99 9e99 0 0 0") x 12;

my $titulo = "ntransac   intp              intf            Vfinal             Rfinal             RAfinal             vfrac                t               vt";
my $j;
for (1 .. $ITER){
    $t = 0;
    $vn = $V0;
    for my $n (1 .. int(1+rand()*10)){    # número de transacciones
	for (my $i = 0.015; $i <= 0.04; $i += 0.0025){
	    $j = (0.2 + rand()) * $i;   # sólo pasa una vez. Puede haber prima al principio
	    $x = rand();
	    $vf = (1+ $j / $nweek) * $x * $V0;    # si son semanas es un número concreto, int(52.xy)
	
# suposición gorda: la ida y la vuelta es sobre lo mismo (la vuelta debería ser sobre más, pero luego)
# ya no     
	    while ( ++$t <= int(1+rand()*100) ){              # duración: peor de los casos 100 semanas
		$vn = (1 + $i/ $nweek) * $vn ;
	    }
	    $j = (10 + 80 * rand()) * $i / 100;          # de la fracción final no hay prima seguro
	    $y = rand();
	    $Vfinal = (1 + $j / $nweek) * $y * ($vn + $vf) + $vn + $vf;
	    
	    $Rfinal =  ($Vfinal-$V0)/$V0 ;
	    
	    $RAfinal = (( 1 + $Rfinal ) ** (1/($n*$x+$y)) -1 );
	    
	    if ($RAfinal > (split (/\s+/, $max[$n]) )[4] ) { $max[$n] = "$n   $i   $j   $Vfinal   $Rfinal   $RAfinal   $vf   $t   $vn"; }  
	    if ($RAfinal < (split (/\s+/, $min[$n]) )[4] ) { $min[$n] = "$n   $i   $j   $Vfinal   $Rfinal   $RAfinal   $vf   $t   $vn"; }
	}    
    }
}

say "V0 = $V0";
say $titulo;
for (1 .. 10){
    say $max[$_];
    say $min[$_];
}

exit 3;


