La façon la plus efficace de calculer un Écart-type de déménagement
Ci-dessous vous pouvez voir mon C# méthode pour calculer les Bandes de Bollinger pour chaque point (moyenne mobile, bande, vers le bas de la bande).
Comme vous pouvez le voir, cette méthode utilise 2 boucles for pour calculer le déplacement de l'écart type à l'aide de la moyenne mobile. Il sert à contenir une boucle supplémentaire pour calculer la moyenne mobile sur les n dernières périodes. Ce que je pouvais enlever par l'ajout de la nouvelle valeur de point de total_average au début de la boucle et en supprimant la i - n valeur du point à la fin de la boucle.
Ma question maintenant, c'est en gros: puis-je déposer le reste de la boucle interne similaire à la façon dont j'ai géré avec la moyenne mobile?
public static void AddBollingerBands(SortedList<DateTime, Dictionary<string, double>> data, int period, int factor)
{
double total_average = 0;
for (int i = 0; i < data.Count(); i++)
{
total_average += data.Values[i]["close"];
if (i >= period - 1)
{
double total_bollinger = 0;
double average = total_average / period;
for (int x = i; x > (i - period); x--)
{
total_bollinger += Math.Pow(data.Values[x]["close"] - average, 2);
}
double stdev = Math.Sqrt(total_bollinger / period);
data.Values[i]["bollinger_average"] = average;
data.Values[i]["bollinger_top"] = average + factor * stdev;
data.Values[i]["bollinger_bottom"] = average - factor * stdev;
total_average -= data.Values[i - period + 1]["close"];
}
}
}
Vous devez vous connecter pour publier un commentaire.
La réponse est oui, vous le pouvez. Dans le milieu des années 80, j'ai développé un algorithme (probablement pas d'origine) en FORTRAN pour un processus de surveillance et de contrôle de l'application. Malheureusement, ce n'était plus de 25 ans et je ne me souviens pas les formules exactes, mais la technique est une extension de l'un pour les moyennes mobiles, avec un deuxième ordre de calculs au lieu de simplement linéaires.
Après avoir regardé votre code de certains, je suis penser que je peux suss comment j'ai fait à l'époque. Remarquez comment votre boucle intérieure est de faire une Somme des Carrés?:
dans beaucoup de la même manière que votre moyenne doit avoir eu à l'origine une Somme de Valeurs? Les deux seules différences sont de l'ordre (et de sa puissance de 2 au lieu de 1) et que vous êtes en soustrayant la moyenne de la valeur avant d'équerre. Maintenant, cela peut ressembler inséparables, mais en fait, ils peuvent être séparés:
est
qui devient
qui est
qui est aussi
Maintenant, le premier terme est juste une Somme de Carrés, vous gérer de la même façon que vous faites la somme des Valeurs de la moyenne. Le dernier terme (
k^2*n
) est simplement la moyenne des carrés des fois leperiod
. Puisque vous divisez le résultat par la période de toute façon, vous pouvez simplement ajouter les nouvelles en moyenne au carré sans la boucle supplémentaire.Enfin, dans le deuxième terme (
SUM(-2*v[i]) * k
), depuisSUM(v[i]) = total = k*n
vous pouvez ensuite le modifier dans ce:ou tout simplement
-2*k^2*n
, qui est de -2 fois plus que la moyenne au carré, une fois la période (n
) est divisé de nouveau. Donc au final combiné formule est la suivante:ou
(assurez-vous de vérifier la validité de cette, depuis que je suis dérivant sur le haut de ma tête)
Et de l'intégrer dans votre code devrait ressembler à quelque chose comme ceci:
total_bollinger
n'est jamais utilisé?Le problème avec une approche permettant de calculer la somme des carrés est qu'il et le carré de la somme peut être assez grande, et le calcul de leur différence, peut introduire un très grosse erreur, donc, nous allons penser à quelque chose de mieux. Pour savoir pourquoi cela est nécessaire, voir l'article de Wikipedia sur Algorithmes pour le calcul de la variance et John Cook sur Explication théorique pour les résultats numériques)
Tout d'abord, au lieu de calculer l'écart type, nous allons concentrer sur la variance. Une fois que nous avons la variance, l'écart type est simplement la racine carrée de la variance.
Supposons que les données sont dans un tableau appelé
x
; rouler des n la taille de la fenêtre par l'un peut être considéré comme la suppression de la valeur dex[0]
et en ajoutant la valeur dex[n]
. Nous allons désigner les moyennes dex[0]..x[n-1]
etx[1]..x[n]
par µ et µ’, respectivement. La différence entre les écarts dex[0]..x[n-1]
etx[1]..x[n]
est, après l'annulation de certaines conditions et de l'application de(a²-b²) = (a+b)(a-b)
:Donc la variance est perturbé par quelque chose qui ne vous obligent pas à maintenir la somme des carrés, ce qui est mieux pour la précision numérique.
Vous pouvez calculer la moyenne et la variance d'une fois dans le début avec un algorithme approprié (Welford de la méthode). Après cela, chaque fois que vous devez remplacer une valeur dans la fenêtre
x[0]
par un autrex[n]
mise à jour de la moyenne et de la variance comme ceci:new_Var
est un très petit nombre négatif, et la sqrt échoue. J'ai introduit unif
à la limite de la valeur à zéro pour ce cas. N'a pas d'idée, mais stable. Cela s'est produit lors de chaque valeur dans ma fenêtre avait la même valeur (j'ai utilisé une taille de fenêtre de 20 et la valeur en question était de 0,5, au cas où quelqu'un veut essayer de reproduire cela.)J'ai utilisé des communes-mathématiques (et a contribué à la bibliothèque!) pour quelque chose de très similaire à cela. Il est open-source, le portage C# doit être facile à stocker-acheté à tarte (avez-vous essayé de faire un gâteau à partir de zéro!?). Check it out: http://commons.apache.org/math/api-3.1.1/index.html. Ils ont un StandardDeviation classe. Aller à la ville!
L'information la plus importante a été donnée ci-dessus --- mais c'est peut-être encore de l'intérêt général.
Une petite bibliothèque Java pour calculer le déplacement de la moyenne et l'écart-type est disponible ici:
https://github.com/tools4j/meanvar
La mise en œuvre est basée sur une variante de Welford la méthode mentionnée ci-dessus. Méthodes pour enlever et remplacer les valeurs ont été dérivés qui peuvent être utilisés pour faire passer des valeurs de windows.