2010-05-10 18 views
1

Je suis un débutant Linq donc je cherche quelqu'un pour me faire savoir s'il est possible de mettre en œuvre avec Linq et si oui, quelques conseils pour l'atteindre. Je veux transformer une liste de séries temporelles financières en une autre où la liste de secondes séries sera de même longueur ou plus courte que la première liste (elle sera généralement plus courte, c'est-à-dire qu'elle devient une nouvelle liste où les éléments eux-mêmes représentent l'agrégation d'information d'un ou plusieurs éléments de la 1ère liste). La façon dont il réduit la liste de l'un à l'autre dépend des données de la première liste. L'algorithme doit suivre un calcul qui est réinitialisé sur les nouveaux éléments ajoutés à la deuxième liste. Il peut être plus facile de décrire par un exemple:Comment transformer une liste en une autre liste semi-agrégée via LINQ?

Liste 1 (temps commandé du début à la fin la série des cours de clôture et le volume):

{P = 7, V = 1}, {P = 10, V = 2}, {P = 10, V = 1}, {P = 10, V = 3}, {P = 11, V = 5}, {P = 12, V = 1}, {P = 13, V = 2}, {P = 17, V = 1}, {P = 15, V = 4}, {P = 14, V = 10}, {P = 14, V = 8}, {P = 10, V = 2}, {P = 9, V = 3}, {P = 8, V = 1}

Liste 2 (série de fourchettes de prix d'ouverture/fermeture et sommation de volume pour une telle période de gamme en utilisant ces 2 param paramètres pour transformer la liste 1 à la liste 2: pARAM 1: Gamme de prix Étape Taille = 3, 2 param: Gamme de prix inversion étape Taille = 6):

{O = 7, C = 10, V = 1 + 2 + 1}, {O = 10, C = 13, V = 3 + 5 + 1 + 2}, {O = 13, C = 16, V = 0}, {O = 16, C = 10, V = 1 + 4 + 10 + 8 + 2}, {O = 10, C = 8, V = 3 + 1}

Dans la liste 2, je explicitement montre la sommation des attributs V de la liste 1 dans la liste 2. Mais V est juste un long donc ce serait juste un nombre dans la réalité. Donc, comment cela fonctionne est le prix d'ouverture de séries chronologiques est de 7. Ensuite, nous recherchons le premier prix à partir de ce prix de départ initial où delta est de 3 à partir de 7 (via param 1 paramètre). Dans la liste 1, au fur et à mesure que nous passons à travers la liste, l'étape suivante passe à 10 et nous avons donc établi une tendance ascendante. Alors maintenant nous construisons notre premier élément dans la liste 2 avec Open = 7, Close = 10 et résumons le volume de toutes les barres utilisées dans la première liste pour arriver à cette première étape dans la liste 2. Maintenant, le point de départ de l'élément suivant est 10. construire une autre étape, nous avons besoin d'avancer de 3 vers le haut pour créer un autre pas vers le haut ou nous pourrions inverser et descendre 6 (param 2). Avec les données de la liste 1, nous atteignons d'abord 13, ce qui construit notre deuxième élément dans la liste 2 et résume tous les attributs V utilisés pour arriver à cette étape. Nous continuons sur ce processus jusqu'à la fin du traitement de la liste 1.

Notez le saut de l'écart qui se produit dans la liste 1. Nous voulons toujours créer un élément étape de {O = 13, C = 16, V = 0}. Le V de 0 indique simplement que nous avons un mouvement de gamme qui a traversé cette étape mais avait un volume de 0 (aucun prix réel de la liste 1 ne s'est produit ici - il était au dessus mais nous voulons construire l'ensemble des étapes qui conduisent au prix c'était au-dessus).

deuxième à la dernière entrée dans la liste 2 représente l'inversion de haut en bas.

entrée finale dans la liste 2 utilise juste Fermer la liste finale 1, même si elle n'a vraiment pas fini encore établir étape de gamme complète.

Merci pour tous les pointeurs de la façon dont cela pourrait être fait via potentiellement Linq le cas échéant.

+2

+1 Une question intéressante. J'espère que quelqu'un avec une meilleure capacité d'attention que moi a le moxy pour lui donner une réponse réfléchie. –

+1

Oui, mes yeux ont juste explosé hors de ma tête, mais il semble cool ... – Aren

+0

Il n'y a pas de méthode intégrée dans LINQ qui fait cela. Est-ce que ça répond à votre question? Suggestion: poster du code (stackoverflow userz besoin de codez ... http://images.icanhascheezburger.com/completestore/2008/12/11/128734873544229946.jpg) et demander comment le LINQify :) – dtb

Répondre

1

Ma première pensée est, pourquoi essayer d'utiliser LINQ à ce sujet? Il semble être une meilleure situation pour faire un nouveau Enumerable en utilisant le mot-clé yield pour traiter partiellement, puis cracher une réponse.

Quelque chose le long des lignes de celle-ci:

public struct PricePoint 
{ 
    ulong price; 
    ulong volume; 
} 

public struct RangePoint 
{ 
    ulong open; 
    ulong close; 
    ulong volume; 
} 

public static IEnumerable<RangePoint> calculateRanges(IEnumerable<PricePoint> pricePoints) 
{ 
    if (pricePoints.Count() > 0) 
    { 
     ulong open = pricePoints.First().price; 
     ulong volume = pricePoints.First().volume; 

     foreach(PricePoint pricePoint in pricePoints.Skip(1)) 
     { 
      volume += pricePoint.volume; 
      if (pricePoint.price > open) 
      { 
       if ((pricePoint.price - open) >= STEP) 
       { 
        // We have established a up-trend. 
        RangePoint rangePoint; 
        rangePoint.open = open; 
        rangePoint.close = close; 
        rangePoint.volume = volume; 

        open = pricePoint.price; 
        volume = 0; 

        yield return rangePoint; 
       } 
      } 
      else 
      { 
       if ((open - pricePoint.price) >= REVERSAL_STEP) 
       { 
        // We have established a reversal. 
        RangePoint rangePoint; 
        rangePoint.open = open; 
        rangePoint.close = pricePoint.price; 
        rangePoint.volume = volume; 

        open = pricePoint.price; 
        volume = 0; 

        yield return rangePoint; 
       } 
      } 
     } 

     RangePoint lastPoint; 
     lastPoint.open = open; 
     lastPoint.close = pricePoints.Last().price; 
     lastPoint.volume = volume; 
     yield return lastPoint; 
    } 
} 

Ce n'est pas encore terminée. Par exemple, il ne gère pas l'espacement, et il existe un cas de contour non manipulé où le dernier point de données peut être consommé, mais il traitera toujours un "dernier point". Mais cela devrait suffire pour commencer.

+0

Bonnes choses! Cela me permettra de commencer sur la bonne voie, je crois. Merci! –

Questions connexes