2 votos

Generando números aleatorios distribuidos normalmente usando el generador Sobol en QuantLib

Estoy tratando de usar el generador de números aleatorios de baja discrepancia Sobol RNG para generar números aleatorios distribuidos normalmente y llenar una matriz Eigen con esos números aleatorios. La matriz representa una canasta de 5 activos (filas), cada uno con 5000 ensayos (columnas). Después de revisar la documentación de QuantLib, he llegado al siguiente código. Sin embargo, los números aleatorios generados son todos iguales para cada columna en la matriz.

MoroInverseCumulativeNormal invGauss;
MatrixXd quasi = MatrixXd::Zero(num_credits,num_trials);
double current_sobol_num{}, current_normal_number{};
for (int c{0}; c< num_credits;++c){
  SobolRsg sobolEngine(1);
  for (int t{0}; t < num_trials;++t){
    current_sobol_num = (sobolEngine.nextSequence().value)[0];
    current_normal_number = invGauss(current_sobol_num);
    quasi(c,t) = current_normal_number;
  };
}

La matriz después de ejecutar el código anterior es :

Activo

t0

t1

t2

t3

t4

Primero

0

0.6745

-0.6745

-0.3186

1.1503

Segundo

0

0.6745

-0.6745

-0.3186

1.1503

Tercero

0

0.6745

-0.6745

-0.3186

1.1503

Cuarto

0

0.6745

-0.6745

-0.3186

1.1503

Quinto

0

0.6745

-0.6745

-0.3186

1.1503

¿Alguna idea de qué estoy haciendo mal? ¿Hay alguna manera de obtener los 5000 aleatorios de una vez en lugar de sacar uno a la vez?

Estoy usando QuantLib solo para las funciones de SobolRng e Inverse Gaussian. Estoy abierto a usar cualquier otra biblioteca de código abierto si se sugiere.

Muchas gracias por su tiempo.

0 votos

Para cada c, reinicias el rsg con la semilla predeterminada en 0. ¿Has intentado mover la instanciación de SobolRsg sobolEngine fuera del bucle for?

0 votos

Sí, he intentado moverlo fuera del bucle. No estoy seguro de cuál debería ser el parámetro "dimensión" para el RNG. Si uso 5000 como "SobolRsg sobolEngine(5000)", obtengo una matriz que parece "aleatoria" pero los resultados de mi simulación cuasi son muy diferentes a la simulación pseudo.

2voto

Brad Tutterow Puntos 5628

Como dijo Dimitri, la inicialización del RNG debería estar fuera del bucle.

El parámetro de dimensión es, en pocas palabras, cuántos números aleatorios necesitas para una muestra.

Si una de tus pruebas consiste en los precios de tus 5 activos, tendrás que inicializar el RNG con dimensión 5 (porque necesitas un número aleatorio para cada precio) y luego obtendrás una lista de 5 precios para los 5 activos cada vez que llames a sobolEngine.nextSequence().value.

(Si, en cambio, estuvieras generando trayectorias aleatorias para un activo en $N$ pasos, una muestra completa sería una trayectoria y la dimensión sería $N$. Si estuvieras generando trayectorias aleatorias para $M$ activos en $N$ pasos, una muestra completa sería una trayectoria para cada activo y la dimensión sería $M \times N$.)

Sin embargo, hay una consideración adicional e importante: las secuencias de baja discrepancia como Sobol tienen restricciones que el RNG usual no tiene. Por ejemplo, no puedes extraer cualquier número de muestras. Sobol y otros RNG de baja discrepancia están diseñados para cubrir de manera justa el dominio utilizando $2^N-1$ muestras para cualquier $N$ dado. Si extraes 4095 muestras ($2^{12}-1$) o 8191 muestras ($2^{13}-1$), obtendrás resultados correctos de tu simulación. Si extraes 5000 muestras, no lo harás, porque no cubrirás el dominio justamente. Si necesitas trabajar con ese número específico de muestras, tendrás que optar por un generador cuasi-aleatorio clásico.

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X