2012-07-16 4 views
1

ok laisse dire que j'ai une table simple, à partir du compte de négociation avec toutes les informations sur les transactions typiques:calcul maxdrawdown dans SQL

Account  ID Type OrderID Points NetPL Balance 
13543564678 16 BUY 389745683 4.55 100.00 1,000,000.00 
13543564678 16 BUY 389745684 4.55 100.00 1,000,100.00 
13543564678 16 BUY 389745685 4.55 100.00 1,000,200.00 
13543564678 16 SELL 389745686 4.55 100.00 1,000,300.00 
13543564678 16 BUY 389745687 4.55 100.00 1,000,400.00 
13543564678 16 SELL 389745688 4.55 100.00 1,000,500.00 
13543564678 16 SELL 389745689 4.55 100.00 1,000,600.00 
13543564678 16 SELL 389745690 4.55 -100.00 1,000,700.00 
13543564678 16 SELL 389745691 4.55 -100.00 1,000,600.00 
13543564678 16 SELL 389745692 4.55 -100.00 1,000,500.00 
13543564678 16 SELL 389745693 4.55 -100.00 1,000,400.00 
13543564678 16 SELL 389745694 4.55 100.00 1,000,300.00 
13543564678 16 SELL 389745695 4.55 100.00 1,000,400.00 
13543564678 16 BUY 389745696 4.55 100.00 1,000,500.00 
13543564678 16 BUY 389745697 4.55 100.00 1,000,600.00 
13543564678 16 BUY 389745698 4.55 100.00 1,000,700.00 
13543564678 16 BUY 389745699 4.55 100.00 1,000,800.00 
13543564678 16 BUY 389745700 4.55 100.00 1,000,900.00 
13543564678 16 BUY 389745701 4.55 100.00 1,001,000.00 
13543564678 16 BUY 389745702 4.55 100.00 1,001,100.00 
13543564678 16 BUY 389745703 4.55 100.00 1,001,200.00 
13543564678 16 BUY 389745704 4.55 -100.00 1,001,300.00 
13543564678 16 BUY 389745705 4.55 -100.00 1,001,200.00 
13543564678 16 BUY 389745706 4.55 -100.00 1,001,100.00 
13543564678 21 BUY 389745707 4.55 -100.00 1,001,000.00 
13543564678 21 SELL 389745708 4.55 -100.00 1,000,900.00 
13543564678 21 SELL 389745709 4.55 -100.00 1,000,800.00 
13543564678 21 SELL 389745710 4.55 -100.00 1,000,700.00 
13543564678 21 BUY 389745711 4.55 -100.00 1,000,600.00 
13543564678 21 SELL 389745712 4.55 -100.00 1,000,500.00 
13543564678 21 BUY 389745713 4.55 -100.00 1,000,400.00 
13543564678 21 SELL 389745714 4.55 -100.00 1,000,300.00 
13543564678 21 SELL 389745715 4.55 100.00 1,000,200.00 
13543564678 21 BUY 389745716 4.55 100.00 1,000,300.00 

ce que je dois ici est de calculer un tirage max en utilisant sql SEULEMENT. Je peux facilement le faire sur Java (exécuter une boucle), mais cette chose devrait faire partie d'une grande requête, en calculant différents paramètres d'acc. Alors laissez-moi vous expliquer la formule: max drawdown est une valeur montrant le plus grand déséquilibre vers négatif, pour tous les enregistrements acc disponibles dans le DB. En regardant dans ex ci-dessus, le premier drawdown est de 400 $ (première section négative de 100 $), le second est plus grand, son 1200 $ (deuxième). Comme vous le savez, ces abaissements se produisent régulièrement, donc l'histoire de l'histoire devrait l'avoir beaucoup, pas seulement 2 comme indiqué ici. Habituellement, il calcule ce type de données sur un énorme ensemble de données, à partir de 100 000 enregistrements et plus.

env est l'oracle 11gr2, accès en lecture seulement. des idées intelligentes seraient très appréciées!

ok, on dirait que le système écrase les modifications donc je dois le mettre en 1 consolidé. J'ai essayé d'ajouter une colonne d'artefacts où la carte négative trades comme 'Y' et a essayé de trouver un moyen de faire sum() après eux. le problème ici est que n'importe quel enregistrement peut être plus que n'importe quelle somme() d'enregistrements consécutifs.

+2

utilisation LEAD ou LAG pour calculer le tirage pour chaque ligne - puis enveloppez cette requête pour trouver le maximum – Randy

+0

thats ce que j'ai essayé. à la fin je vais simplement obtenir la colonne comme je l'ai dans le NETPL, avec 1 ligne derrière. la chose ici est que je dois faire sum() en quelque sorte coz avoir une valeur cumulative à partir de multiples (ou simples, quoi de plus gros en somme), pas seulement pour une seule ligne. enfin il devrait me renvoyer seulement 1 valeur - 1200. – user1324100

+0

après ce que vous avez essayé pour le raffinement. ça devrait encore fonctionner. (aussi, les commandes ACHETER et VENDRE font-elles une différence sur ce qui compte comme drawdown?) – Randy

Répondre

1

Vous souhaitez d'abord énumérer les abaissements. Je fais cela en utilisant la fonction de décalage avec une somme cumulative. Le décalage trouve le début d'une baisse, en regardant le PL précédent étant positif et le négatif actuel. La somme cumulative attribue une valeur.

Le reste découle de l'identification de ces périodes.

select Account, MAX(DrawDownAmount) 
from (select Account, DrawDownNum, SUM(-NetPl) as DrawDownAmount 
     from (select t.*, 
        sum(BeginDrawDown) over (partition by Account order by orderid) as DrawDownNum 
      from (select t.*, 
         (case when NetPL < 0 then 1 else 0 end) as isdrawdown, 
         (case when coalesce(lag(NetPl, 1) over (partition by Account order by orderid), 1) >= 0 and 
            NetPl < 0 
           then 1 
           else 0 
        end) as BeginDrawDown 
        from t 
       ) t 
      ) t 
     where isdrawdown = 1 
     group by Account, DrawDownNum 
    ) t 
group by Account 
+0

merci laissez-moi l'essayer – user1324100

+0

@ user1324100: Dans le cas où vous ne pouviez pas faire ce travail, il y avait un élément GROUP BY manquant. Vous pouvez essayer à nouveau cette solution, si vous voulez, cela semble fonctionner (http://sqlfiddle.com/#!4/c725c/3) maintenant. –

+0

Merci @AndriyM. –