2015-07-27 1 views
0

J'ai un comportement étrange dans ma tentative de coder le fichier NORMINV() d'Excel en C. Comme norminv() j'ai pris la fonction this d'un mathématicien, c'est probablement correct puisque j'ai aussi essayé différents avec le même résultat. Voici le code:Augmenter l'écart moyen avec l'augmentation de la taille de l'échantillon sur le fichier NORMINV d'Excel()

double calculate_probability(double x0, double x1) 
{ 
    return x0 + (x1 - x0) * rand()/((double)RAND_MAX); 
} 

int main() { 

long double probability = 0.0; 
long double mean = 0.0; 
long double stddev = 0.001; 
long double change_percentage = 0.0; 
long double current_price = 100.0; 
srand(time(0)); 
int runs = 0; 
long double prob_sum = 0.0; 
long double price_sum = 0.0; 

while (runs < 100000) 
{ 
    probability = calculate_probability(0.00001, 0.99999); 
    change_percentage = mean + stddev * norminv(probability); //norminv(p, mu, sigma) = mu + sigma * norminv(p) 
    current_price = current_price * (1.0 + change_percentage); 
    runs++; 
    prob_sum += probability; 
    price_sum += current_price; 
} 
printf("\n\n%f %f\n", price_sum/runs, prob_sum/runs); 
return 0; 
} 

Maintenant, je veux simuler NORMINV Excel (rand(), 0, 0,001) où rand() est une valeur> 0 et < 1, 0 est la moyenne et 0,001 serait la norme déviation.

Avec 1000 valeurs, il semble correct:

100,729780 0,501135

Avec 10000 valeurs, il se propage trop:

107,781909 0,502301

Avec 100000 valeurs il se répand parfois même plus:

87.876500 0.498738

Maintenant, je ne sais pas pourquoi cela se produit. Mon hypothèse est que le générateur de nombres aléatoires doit également être distribué normalement. Dans mon cas probability est calculé bien puisque la moyenne est à peu près 0.5 tout le temps. Je ne sais donc pas pourquoi la déviation moyenne augmente. Quelqu'un peut-il m'aider?

+1

Pourquoi cette diffusion est-elle «trop»? Avec la petite stddev que vous utilisez, ce que vous faites est très proche d'une marche aléatoire additive avec des pas qui ont un écart-type de 0.1 (0.1 == 100.0 * 0.001). Si vous prenez N étapes, je m'attendrais à ce que la valeur finale ait un écart type de sqrt (N) * 0.1. Si quelque chose, la réponse de 1000 pas ressemble étonnamment près de 100. –

Répondre

1

Vous faites quelque chose dans le style d'un random walk, sauf que vos déplacements utilisent un facteur de mise à l'échelle multiplicatif plutôt que des pas d'addition. Considérons deux mouvements successifs, le premier donnant 20% de gonflage, le second 20% de dégonflage. À partir d'une base de 100, après la première étape, vous êtes à 120. Si vous prenez maintenant 80% de 120, vous obtenez 96 plutôt que 100 d'origine. Autrement dit, les facteurs d'échelle apparemment symétriques ne sont pas réellement symétriques. Alors que vos facteurs d'échelle sont aléatoires, ils sont toujours créés symétriquement autour de 1, donc je ne suis pas surpris de voir les écarts s'accumuler.

+0

Pouvez-vous m'expliquer où se situe le problème dans le code? Est-ce que norminv() est lui-même? calculate_probability() devrait être ok, non? Je me demande parce que dans Excel, il n'y a pas une déviation moyenne et en fait je fais exactement la même chose. Puisque change_percentage est négatif dans 50% des cas, je ne vois pas ce que vous voulez dire exactement. – JohnnyFromBF

+0

Le problème est que '100 * (1 + 0.2) * (1 - 0.2) = 96! = 100'. Lorsque les écarts «symétriques» sont ajoutés ou soustraits à un facteur d'échelle et multipliés, ils ne sont pas symétriques. Deux écarts, que vous pensiez probablement symétriques et qui vous ramèneraient à cent, ne s'équilibrent pas. – pjs

+0

Ok, je vois ce que vous voulez dire, je me demande simplement comment mon code diffère de l'implémentation de norminv() dans excel, vu [ici] (https://www.youtube.com/watch?v=1ot7HOI3wQE). – JohnnyFromBF