Overblog Suivre ce blog
Administration Créer mon blog
14 mai 2009 4 14 /05 /mai /2009 20:35

Algorithme de Goertzel : recherche de l'amplitude, de la période et de la phase du cycle.

Dans le dernier article sur l'algorithme de Goertzel, le programme permettait de retrouver les 2 périodes des cycles qui avaient la meilleure réponse.  Je l'ai complèté et corrigé pour qu'il sorte également l'amplitude correcte du cycle ainsi que la phase : cela afin de pouvoir redessiner la courbe.
Dans l'exemple ci-dessous, le signal (en noir) est une sinusoïde de période 11 ajoutée à une sinusoïde de période 19 (d'amplitude 2) avec un décalage de phase (90),  le tout avec une pincée de bruit..   Les 2 courbes (rouge et bleue) sont reconstruites par le programme, il reste à les superposer pour avoir le signal sans bruit.



Le code pour Prorealtime (k, en variable, est la fréquence déjà trouvée) :

////////////////// sous prgm goertzel  biss ////////////
a=barindex
sig=sin(360*a/11)+2*sin(360*a/19+90)
b=SQRT(barindex*(b+1))
b=abs((b-ROUND(b))*4)
c=b-1
sig=sig+c
n=200
pr=sig
alpha=2*cos(360*1/k)
q1=0
q2=0
for i=n downto 0//fenêtre de 200 barres
    q3=pr[i]+alpha*q1-q2
    q2=q1
    q1=q3
next
amp=sqrt(square(q1)+square(q2)-alpha*q1*q2)
real=q1-(alpha*q2)/2
imag=q2*sin(360*1/k)
phas=atan(imag/real)
if real<0 then
    phas=phas+180
elsif real>=0 and imag<0 then
    phas=phas+360
endif
return (2*amp/n)*sin(360/k+phas[1]+90),sig
Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
21 octobre 2008 2 21 /10 /octobre /2008 10:04

Algorithme de Goertzel et analyse du signal.

Dans un papier (MESA vs Goertzel), Dennis Meyers compare l'utilisation de l'algorithme de Goertzel avec la méthode de Ehlers pour l'analyse du signal : trouver le cycle dominant.  Dans l'article qui suit, je me base sur la publication de Meyers pour tester, comme il l'a fait, les 2 méthodes.  Cela m'a également été utile pour voir si les codes programmés sur PRT donnaient des résultats corrects.

J'ai donc créé, comme Meyers, un signal fictif :  1 sinusoïde de période 11 ajoutée à une sinusoïde de période 19 avec un décalage de phase, le tout avec une pincée de bruit.  Voici ce que cela donne, en fenêtre 1, le signal sans bruit (les 2 sinusoïdes mélangées) en fenêtre 2, le bruit (variant de -1 à +1), et en fenêtre 3, le signal avec le bruit.



Sur ce signal, j'applique l'algorithme de Goertzel et le programme de Ehlers pour essayer de retrouver les cycles dominants : soit les périodes 11 et 19.  Ci-dessous, le résultat avec l'algo de Goertzel.  Il y a bien une détection du cycle de période 11, mais elle n'est pas continuelle.  Pour le cycle de période 19, l'affichage est continu mais varie de 19 à 20.  Le programme retourne les deux fréquences qui ont la meilleure réponse.



Voici une vue du programme de Elhers "brut" (une seule fréquence est affichée), la détection des périodes 11 et 19 est moins évidente :



Et une autre vue avec le code bidouillé pour avoir 2 fréquences en sortie :



Le même, en élargissant la fenêtre d'analyse de 50 à 100 barres :



Conclusions : 
- Les codes ont l'air corrects, les cycles 11 et 19 apparaissent.
- La précision de la détection dépend pour les 2 programmes, de la longueur de le fenêtre de calcul.  Plus elle est longue, plus le calcul dure longtemps, et plus il est précis.  Meyers préconise 3 fois la longueur du cycle estimé, mais 5 ou 6 fois me paraît indispensable d'après les tests.
- Pour les 2 méthodes, il y a des périodes où le cycle 11 n'est pas détecté.  Par contre, le cycle 19 est toujours présent avec plus ou moins de précision.
- La structure des programmes est similaire, avec une subroutine, et donc c'est assez lourd à faire tourner.
- Reste à appliquer la détection sur les cours, préalablement "detrented", pour un prochain article.

Voici les différents codes pour Prorealtime, utilisés dans l'article :

/////////// signal sans bruit ////////////
b=barindex
sig=sin(360*b/11)+sin(360*b/19+90)
return sig,0

/////////////// bruit //////////////////
b=SQRT(barindex*(b+1))
b=abs((b-ROUND(b))*4)
c=b-1
return c,0

////////////////// sous prgm goertzel ////////////
a=barindex
sig=sin(360*a/11)+sin(360*a/19+90)
b=SQRT(barindex*(b+1))
b=abs((b-ROUND(b))*4)
c=b-1
sig=sig+c

pr=sig
alpha=2*cos(360*1/k)
q1=0
q2=0
for i=200 downto 0//fenêtre de 200 barres
    q3=pr[i]+alpha*q1-q2
    q2=q1
    q1=q3
next
amp=sqrt(square(q1)+square(q2)-alpha*q1*q2)
return amp

/////////////////// prgm goertzel ///////////////////
l=0
maxi=l
maxo=0
for p=5 to 25//détection de cycle de période de 5 à 25
    my = CALL "goertzel sous"[p]
    if my>maxi then
        per=p
        maxi=my
    endif
    if my>maxo and my<maxi then
        peri=p
        maxo=my
    endif
next
return max(per,peri),min(per,peri)

////////////// sous prgm ehlers ////////////////
a=barindex
sig=sin(360*a/11)+sin(360*a/19+90)
b=SQRT(barindex*(b+1))
b=abs((b-ROUND(b))*4)
c=b-1
sig=sig+c
cl=sig

cospart=0
sinpart=0
for n=0 to 99// fenetre de 100 barres
    cycper=(360*n)/peri
    cospart=cospart+cl[n]*cos(cycper)
    sinpart=sinpart+cl[n]*sin(cycper)
next
pwr=square(cospart)+square(sinpart)
return pwr

/////////////// prgm ehlers ///////////////
mix=0
maxpwr = CALL "sousprog dft"[8]
pero=8

for ki=9 to 30//détection de cycle de période de 9 à 30
    mys=call "sousprog dft"[ki]
    if mys>maxpwr then
        maxpwr=mys
        pero=ki
    endif
    if mys>mix and mys<maxpwr then
        mix=mys
        por=ki
    endif
next
return pero,por


Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
14 février 2008 4 14 /02 /février /2008 16:20

Fourier Transform for Traders, by John Ehlers.

 

Dans le numéro de janvier 2007 de S&C, on retrouve un dernier article de John Ehlers sur la façon d'utiliser les cycles pour le trading.  Il propose d'utiliser la "Discrete Fourier Transform" (DFT) pour le tuning des indicateurs.  Il prend en exemple un RSI où la période est fonction du cycle dominant calculé par la DFT.  Je ne suis pas un fan du RSI, j'ai rentré la période adaptative dans un système de moyennes mobiles (exemple proposé par le développeur de WEALTH-LAB).  Les signaux sont donnés par le croisement de la courbe de régression linéaire (de période = 1/4 cycle) avec la moyenne mobile simple (de période = 1/2 cycle).  Voici une vue de KO avec les 2 moyennes et dans la fenêtre du bas, l'indicateur qui retourne le cycle dominant.

 

hk84.gif

 

Plusieurs remarques :

 - Je ne suis pas certain de l'exactitude des calculs, après une rapide comparaison avec le graphe d'IBM présenté dans l'article.  J'éditerai le programme au besoin (vous pouvez toujours laisser un commentaire dans la file dédiée si vous trouvez un bug).

 - Le logiciel Prorealtime montre une nouvelle fois toutes ses limites avec l'impossibilité d'inclure des boucles dans des boucles.........  Message de boucle sans fin !  Après avoir planché pendant plus d'une semaine, je vous donne le résultat même si comme je l'ai signalé plus haut, je ne suis pas sûr de celui-ci.

 - Le programme rame, il faut près de 40 minutes pour afficher un graphe de 150 barres !  Il est donc inexploitable dans sa forme actuelle, j'imagine le temps nécessaire pour un screener ou un backtest !

 - Prochaines étapes : essayer de rendre le programme plus rapide et le comparer avec la méthode proposée par Dennis Meyers (Mesa Vs Goertzel DFT).

 

Voici le code pour Prorealtime de l'indicateur de cycle dominant :

 

maxpwr = CALL "sousprog dft"[8]
for kk=9 to 50
    mys=call "sousprog dft"[kk]
    if mys>maxpwr then
        maxpwr=mys
    endif
next
if barindex <60 then
    maxpwr=undefined
endif
num=0
denom=0
for kk=8 to 50
    mys=call"sousprog dft"[kk]
    db=-10*log(0.01/(1-0.99*mys/maxpwr))/log(10)
    if db>20 then
        db=20
    endif
    if db<3 then
        thre=3-db
        num=num+kk*thre
        denom=denom+thre
    endif
next
if barindex>60 then
    cyc=num/denom
else
    cyc=undefined
endif

return cyc

 

Ainsi que le code du sous-programme utilisé pour contourner les faiblesses du logiciel, il faut introduire la période en variable (peri) :

 

pr=medianprice
if barindex<=5 then
    hp=pr
    cl=pr
else
    per=360/40
    cosper=cos(per)
    alph=(1-sin(per))/cosper
    hp=0.5*(1+alph)*(pr-pr[1])+alph*hp[1]
    cl=(hp+2*hp[1]+3*hp[2]+3*hp[3]+2*hp[4]+hp[5])/12
endif
cospart=0
sinpart=0
for n=0 to 49
    cycper=(360*n)/peri
    cospart=cospart+cl[n]*cos(cycper)
    sinpart=sinpart+cl[n]*sin(cycper)
next
pwr=square(cospart)+square(sinpart)

return pwr

Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
14 février 2008 4 14 /02 /février /2008 15:21

Comment visionner la longueur et l'amplitude du cycle d'une action ?

 

Tout d'abord, un petit graphe pour bien illustrer le caractère changeant du tracé des courbes dessinées pour l'instant avec le programme.  Dans le dernier article, je postais un graphe d'INTC en pariant sur un rebond vers le haut du canal mauve.  Sur le nouveau graphe, on voit que le pronostic était bien correct mais surtout que j'ai été bien aidé par le déplacement des courbes !  En effet, si vous comparez les 2 vues (ça fait un peu jeu des 7 erreurs ), vous constaterez que les courbures ont changé.

 

hk81.gif

 

Dans le dernier message, je disais également chercher à automatiser les longueurs et largeurs des enveloppes de Hurst.  Alors que Bressert prétendait qu'il n'y avait qu'un cycle et identifiait celui-ci avec une moyenne 20 centrée, Hurst avance le fait qu'il y a plusieurs cycles qui se superposent.  Dès lors mon programme "Detrend20" présenté le 21/10 basé sur la théorie de Bressert ne me suffit plus.

 

B. J. Millard, dans son livre "Channels & Cycles - A Tribute to J. M. Hurst", décrit un moyen d'identifier les différents cycles.  Il soustrait à une moyenne centrée de longueur égale au cycle à isoler, une seconde moyenne centrée de longueur égale à la moitié de la première.  J'ai trouvé une version "Amibroker" de l'indicateur, je l'ai adapté.  Voici une vue de HG avec l'indicateur en fenêtre 1 et le cours en fenêtre 2.

 

hk82.gif

 

D'une part, l'indicateur est beaucoup plus propre, et d'autre part, il permet de visualiser plusieurs cycles.

 

Je m'essaye à une petite analyse, voici une vue de l'indice Dow Jones avec l'indicateur de cycles :

 

hk83.gif

 

On peut voir que le cycle à 6 mois (noir/blanc) est toujours présent et que son amplitude a augmenté depuis 1996, que le cycle à 2 ans était bien défini jusque 1999 et que l'on aurait un cycle de 3 ans qui se dessine depuis 2003.  Cette semaine (14/02/08), le cycle à 6 mois se retournerait mais en allant contre les cycles plus longs.

 

Reste maintenant à trouver, comme pour le RSI3M3, un indicateur qui colle en temps réel pour me permettre une extrapolation convenable.

Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
14 février 2008 4 14 /02 /février /2008 15:02

Cycles : le point sur les enveloppes.

 

Comme je vois que certains sont impatients de lire la suite des articles consacrés aux cycles, je vous poste ce petit compte rendu qui vous montre où j'en suis.  Voici le graphe d'INTC.

 

hk80.gif

 

Pour l'instant, j'arrive à tracer les enveloppes qui sont décrites par Hurst et Millard.  J'ai encore quelques problèmes d'ajustements : en A, B,  et C, la courbe inférieure long terme devrait se décaler vers le haut, par contre en D, c'est la courbe supérieure qui est trop basse.  Les courbes sont tracées par tâtonnement, j'essaye d'automatiser la longueur et la largeur de celles-ci.

 

Si l'analyse des cycles est correcte, on devrait avoir un rebond d'INTC vers le haut du canal mauve.  N'oubliez toujours pas que les courbes sont tracées avec les données futures connues et qu'elles changent !

Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
14 février 2008 4 14 /02 /février /2008 14:34

Cycles : au début, il y eut J. M. Hurst.

 

J. M. Hurst est l'auteur de "The Profit Magic Of Stock Transaction Timing", écrit à la fin des années 60.  Ce livre fut un des premiers à parler de cyclicité des marchés financiers.  W.Bressert, J. Tillman, P. Eliades, R. Zukowski...   poursuivent dans cette voie et ont utilisé les travaux de Hurst.  Par exemple, beaucoup de ce que J. Ehlers publie, est déjà dans le livre de Hurst.

 

Dans les premiers chapitres de son livre, Hurst construit des enveloppes de largeurs constantes autour des cours.  il s'en sert pour  illustrer une partie de sa théorie sur l'importance du timing dans le trading.  Un exemple de graphique utilisant les bandes, se trouve ici

 

Voici pour l'instant ce à quoi j'arrive avec Prorealtime en me basant sur un code Metastock (graphique de AAPL) :

 

hk77.gif

 

Il faut savoir que ce genre de représentation ne peut être utilisée pour le trading car elle fait appel aux données du futur.  Ainsi, les courbes qui apparaissent en même temps que la ligne jaune, sont susceptibles de changer.  Il y a deux défis à relever : d'abord, avoir  des enveloppes et une courbe correctes pour les données "établies" et ensuite essayer de trouver un moyen d'extrapoler les courbes de façon la plus exacte possible.

 

Voici une autre vue pour illustrer le principe (SNDK) :

 

hk78.gifhk79.gif

 

On voit que le programme prend une moyenne mobile triangulaire, y ajoute 2 enveloppes à +/- 7% et recentre le tout 11 barres en arrière.  Les coéfficients dépendent des cycles et sont donc propres à chaque graphe.  Les bandes peuvent être construites également avec un montant fixe (exemple : 2$) ou un multiple de l'ATR.  Les channels dessinées depuis la barre -11 sont, par nature, pure fiction !  Je continue l'exploration.....

Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
14 février 2008 4 14 /02 /février /2008 13:45

Cycles : le Bandpass Filter.

 

Dans son dernier fichier (février 2007), J. Ehlers présente le Bandpass Filter et des conseils pour son utilisation.  Il faudrait faire varier les paramètres du filtre (espacement et largeur) afin de se constituer un échantillon.  Hors de ces résultats, on prend le filtre qui a la plus grande amplitude en sortie, celui-ci nous donne le cycle dominant actuellement pour les cours.  Il suffit alors d'introduire cette donnée dans nos indicateurs favoris pour obtenir des indicateurs adaptés aux conditions du marché.

 

Par exemple : RSI = 0.5 * cycle, STOCHASTIC = 0.5 * cycle, CCI = cycle, MACD 0.5 * cycle et 1 * cycle.

 

Voici une vue de l'ES avec le Bandpass Filter et les différents paramètres : 10,12,14,16,18,20.

 

hk75-copie-1.gif

hk76.gif

On constate bien les amplitudes changeantes suivant les conditions du marché, mais comment l'utiliser pour le trading ?

 

Voici le code du filtre pour Prorealtime, il faut introduire en variable la période (period, de 8 à ....) et le delta (0.05, 0.10,  0.25, ......), le programme retourne également la dernière amplitude (pour d'éventuelles comparaisons) :

 

pr=(high+low)/2
if barindex>1 then
    beta=cos(360/period)
    gama=1/cos(720*delta/period)
    alpha=gama-sqrt(gama*gama-1)
    bp=0.5*(1-alpha)*(pr-pr[2])+beta*(1+alpha)*bp[1]-alpha*bp[2]
    lead=(period/6.28318)*(bp-bp[1])
endif
if bp>bp[1] and bp[1]<bp[2] then
    rep1=rep
    rep=bp[1]
endif
if bp<bp[1] and bp[1]>bp[2] then
    rep1=rep
    rep=bp[1]
endif
ecart=abs(rep-rep1)
return bp,lead,0,ecart

 

Une documentation est téléchargeable ici.

Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
14 février 2008 4 14 /02 /février /2008 13:05

Cycles : les publications de J. Ehlers, partie 3.

 

Dans le numéro d'août 2006 de S&C, on peut lire un article de J. Ehlers : "Modeling The Market = Building Trading Strategies".  Il y présente 3 indicateurs ainsi que 3 stratégies. 

 

Une vue du Bund avec les indicateurs : en fenêtre 1,  le cours avec l'Instantaneous Trendline (en blanc) et le Modeling The Market (en jaune), en fenêtre 2, l'indicateur Cyclic Component et en fenêtre 3, le StochasticRSI transformation appliqué au Model.

 

hk72.gif

 

Voici les codes pour Prorealtime, on peut faire varier le prix de référence (medianprice par défaut), la longueur de la moyenne (20 par défaut) ainsi que les paramètres du StochasticRSI :

 

pr=(high+low)/2
len=20
sma=average[len](pr)
sl=pr-pr[len-1]
ssl=(sl+2*sl[1]+2*sl[2]+sl[3])/6
itrend=sma+0.5*ssl

a=(1-SIN(360/len))/cos(360/len)
if barindex<50 then
   
    hp=exponentialaverage[2*len+1]((1+a)*(pr-pr[1]))
else
   
    hp=(0.5*(1+a)*(pr-pr[1]))+(a*hp[1])
endif

shp=(hp+2*hp[1]+2*hp[2]+hp[3])/6
model=itrend+shp

return itrend,model


----------------------------------------

 

pr=(high+low)/2
len=20
a=(1-SIN(360/len))/cos(360/len)
if barindex<50 then
    hp=exponentialaverage[2*len+1]((1+a)*(pr-pr[1]))
else
    hp=(0.5*(1+a)*(pr-pr[1]))+(a*hp[1])
endif
shp=(hp+2*hp[1]+2*hp[2]+hp[3])/6

return shp,0

 

-----------------------------------

 

pr=(high+low)/2
len=20
rlen=8
stolen=8
wlen=5
sma=average[len](pr)
sl=pr-pr[len-1]
ssl=(sl+2*sl[1]+2*sl[2]+sl[3])/6
itrend=sma+0.5*ssl

a=(1-SIN(360/len))/cos(360/len)
if barindex<50 then
    hp=exponentialaverage[2*len+1]((1+a)*(pr-pr[1]))
else
    hp=(0.5*(1+a)*(pr-pr[1]))+(a*hp[1])
endif
shp=(hp+2*hp[1]+2*hp[2]+hp[3])/6
model=itrend+shp

cu=0
cd=0
cu=max(0,model-model[1])
cd=max(0,model[1]-model)
cu1=average[rlen](cu)
cd1=average[rlen](cd)
if cuave<>-cdave then
    rsio=cuave/(cuave+cdave)
endif
if barindex >60 then
    cuave=(cuave[1]*(rlen-1)+cu1)/rlen
    cdave=(cdave[1]*(rlen-1)+cd1)/rlen
endif
if cuave<>-cdave then
    rsio=cuave/(cuave+cdave)
endif
mrs=rsio
hir=highest[stolen](mrs)
lor=lowest[stolen](mrs)
stor=(mrs-lor)/(hir-lor)
stari=0
div=0
for i=0 to wlen-1
    stari=stari+(wlen-i)*stor[i]
    div=div+i+1
next
stori=stari/div
trig=0.05+0.9*stori[1]
if stori>trig then
    flag=-.1
else
    flag=0
endif
if stori<trig then
    flagb=-.1
else
    flagb=0
endif

return stori,trig,flag,flagb

 

-----------------------------------

 

La première stratégie utilise uniquement l'Instantaneous Trendline.  On rentre à l'achat quand la courbe croise à la hausse l'indicateur retardé de 2 périodes.  Les conditions de vente sont inverses, on a un système SAR.  Sur la vue suivante, j'ai  optimisé la période de la moyenne et le nombre de barres de retard.  Voici l'EC avec len=27 et delay=3 (pas de slippage, frais de 4 eur A/R par contrat) :

 

hk73.gif

 

Et maintenant, le code du backtest pour Prorealtime :

 

pr=(high+low)/2
len=a
rem b=delay
sma=average[len](pr)
sl=pr-pr[len-1]
ssl=(sl+2*sl[1]+2*sl[2]+sl[3])/6
itrend=sma+0.5*ssl
REM Achat
c1 = (itrend CROSSES OVER itrend[b])
IF c1 THEN
    BUY 1 SHARES AT MARKET THISBARONCLOSE
ENDIF
REM Vente
c2 = (itrend CROSSES UNDER itrend[b])
IF c2 THEN
    SELL  AT MARKET THISBARONCLOSE
ENDIF
REM Vente à découvert
c3 = (itrend CROSSES UNDER itrend[b])
IF c3 THEN
    SELLSHORT 1 SHARES AT MARKET THISBARONCLOSE
ENDIF
REM Rachat
c4 = (itrend CROSSES OVER itrend[b])
IF c4 THEN
    EXITSHORT  AT MARKET THISBARONCLOSE
ENDIF

 

--------------------------------------------------------------------------------

 

La seconde stratégie consiste à prendre position au croisement du StochasticRSI avec son signal, c'est également un système SAR.  Voici une vue de l'EC avec les paramètres optimisés, len=19, rlen=16, stolen=19, wlen=7 (pas de slippage et 4 eur de frais A/R par contrat) :

 

hk74.gif

 

Et le code Prorealtime du backtest :

 

pr=(high+low)/2
len=aa
rlen=bb
stolen=cc
wlen=dd
sma=average[len](pr)
sl=pr-pr[len-1]
ssl=(sl+2*sl[1]+2*sl[2]+sl[3])/6
itrend=sma+0.5*ssl

a=(1-SIN(360/len))/cos(360/len)
if barindex<50 then
    hp=exponentialaverage[2*len+1]((1+a)*(pr-pr[1]))
else
    hp=(0.5*(1+a)*(pr-pr[1]))+(a*hp[1])
endif
shp=(hp+2*hp[1]+2*hp[2]+hp[3])/6
model=itrend+shp

cu=0
cd=0
cu=max(0,model-model[1])
cd=max(0,model[1]-model)
cu1=average[rlen](cu)
cd1=average[rlen](cd)
if cuave<>-cdave then
    rsio=cuave/(cuave+cdave)
endif
if barindex >60 then
    cuave=(cuave[1]*(rlen-1)+cu1)/rlen
    cdave=(cdave[1]*(rlen-1)+cd1)/rlen
endif
if cuave<>-cdave then
    rsio=cuave/(cuave+cdave)
endif
mrs=rsio
hir=highest[stolen](mrs)
lor=lowest[stolen](mrs)
stor=(mrs-lor)/(hir-lor)
stari=0
div=0
for i=0 to wlen-1
    stari=stari+(wlen-i)*stor[i]
    div=div+i+1
next
stori=stari/div
trig=0.05+0.9*stori[1]

REM Achat
c1 = (stori CROSSES OVER trig)
IF c1 THEN
    BUY 1 SHARES AT MARKET THISBARONCLOSE
ENDIF
REM Vente
c2 = (stori CROSSES UNDER trig)
IF c2 THEN
    SELL  AT MARKET THISBARONCLOSE
ENDIF
REM Vente à découvert
c3 = (stori CROSSES UNDER trig)
IF c3 THEN
    SELLSHORT 1 SHARES AT MARKET THISBARONCLOSE
ENDIF
REM Rachat
c4 = (stori CROSSES OVER trig)
IF c4 THEN
    EXITSHORT  AT MARKET THISBARONCLOSE
ENDIF

Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
14 février 2008 4 14 /02 /février /2008 12:51

Cycles : les publications de J. Ehlers, partie 2.

 

Voici un second système présenté dans le fichier "TAG22 Rocket Science".  Les codes viennent toujours d'Arnaudbzh chez dakoté.  J'ai trouvé relativement peu d'information sur son utilisation.  Comme pour le système 1, il y a une trendline et un filtre mais le code est différent.  De même le calcul de la période et du rapport signal/bruit est autre.  Au final, les zones de cycle et de trend ne sont pas communes aux 2 systèmes.  L'indicateur Awesome est fait pour confirmer le signal sur le Sinewave.  La valeur du rapport signal/bruit négative me paraît bizarre.  J'ai corrigé la fonction ROUND en INTEGER, de même dans le fichier que j'ai, il n'est pas fait mention de la condition de bruit>6 dB codée par Arnaudbzh pour le Mode.

 

Voici une vue du CAC avec les indicateurs : en fenêtre 1, le prix avec la TRENDLINE et le filtre, en fenêtre 2, le MODE version Arnaudbzh, en fenêtre 3, le MODE version hk, en fenêtre 4,  l'indicateur CORE, en fenêtre 5, l'indicateur de PHASE, en fenêtre 6, l'indicateur SNR, en fenêtre 7, le SINEWAVE et en fenêtre 8, l'indicateur AWESOME.

 

hk71.gif

 

Et maintenant les codes :

 

REM CORE CODE - CYCLE PERIOD CODE
REM Indicateur "CORE"

Price = (High+Low)/2

IF Barindex > 5 THEN
   
    REM Compensating Hilbert Transforms
    Smoother = (4*Price + 3*Price[1] + 2*Price[2] + Price[3]) / 10
    Detrender = (0.25*Smoother + 0.75*Smoother[2] - 0.75*Smoother[4] - 0.25*Smoother[6]) * (0.046*Period [1] + 0.332)
   
    REM Compute InPhase and Quadrature components
    Q1 = (0.25*Detrender + 0.75*Detrender[2] - 0.75*Detrender[4] - 0.25*Detrender[6]) * (0.046*Period[1] + 0.332)
    I1 = Detrender[3]
   
    REM advance the phase of I1 and Q1 by 90 degrees
    JI = 0.25*I1 + 0.75*I1[2] - 0.75*I1[4] - 0.25*I1[6]
    JQ = 0.25*Q1 + 0.75*Q1[2] - 0.75*Q1[4] - 0.25*Q1[6]
   
    REM Phasor addition to equalize amplitude due to quadrature calculations (and 3 bar averaging)
    I2 = I1 - JQ
    Q2 = Q1 + JI
   
    REM Smooth the I and Q components before applying the discriminator
    I2 = 0.15*I2 + 0.85*I2[1]
    Q2 = 0.15*Q2 + 0.85*Q2[1]
   
    REM Homodyne Discriminator
    REM Complex Conjugate Multiply
    X1 = I2*I2[1]
    X2 = I2*Q2[1]
    Y1 = Q2*Q2[1]
    Y2 = Q2*I2[1]
    Re = X1 + Y1
    Im = X2 - Y2
   
    REM Smooth to remove undesired cross products
    Re = 0.2*Re + 0.8*Re[1]
    Im = 0.2*Im + 0.8*Im[1]
   
    REM Compute cycle period
    IF Im <> 0 and Re <> 0 THEN
        Period = 360/ATAN(Im/Re)
    ENDIF
   
    IF Period > 1.5*Period[1] THEN
        Period = 1.5*Period[1]
    ENDIF
   
    IF Period < 0.67*Period[1] THEN
        Period = 0.67*Period[1]
    ENDIF
   
    IF Period < 6 THEN
        Period = 6
    ENDIF
   
    IF Period > 50 THEN
        Period = 50
    ENDIF
   
    Period = 0.2*Period + 0.8*Period[1]
   
ENDIF

RETURN Period as "PERIOD" , Q1 as "Q1" , I1 as "I1"


-------------------------------------------------------------------

 

REM Measuring Phase
REM Indicateur "CORE PHASE2"


Price = (High + Low)/2
myPERIOD, myQ1,myI1 = CALL "CORE"

IF Barindex > 50 THEN
    p1=myperiod/10 MOD 10
    p2=myperiod mod 10
    int=p1*10+p2
   
    value5 =int
    RealPart = 0
    ImagPart = 0
   
    IF Value5 > 6 THEN
        For count = 0 To Value5 - 1
            RealPart = RealPart + Sin(360 * count / Value5) * (Price[count])
            ImagPart = ImagPart + Cos(360 * count / Value5) * (Price[count])
        NEXT
    ENDIF
   
    RealPart = 0.33*RealPart + 0.67*RealPart[1]
    ImagPart = 0.33*ImagPart + 0.67*ImagPart[1]
   
    IF ABS(ImagPart) > 0.001 THEN
        DCPhase = ATAN(RealPart / ImagPart)
    ENDIF
   
    If ABS(ImagPart) <= 0.001 THEN
        DCPhase = 90 *SGN(RealPart)
       
    ENDIF
   
    REM Compensate phase for smoothing lag prior to taking the arctangent
    DCPhase = DCPhase + 720 / myPERIOD
    DCPhase = DCPhase + 90
   
    IF ImagPart < 0 and myQ1 <> 500 and myI1 <> 500 THEN
        DCPhase = DCPhase + 180
    ENDIF
   
    IF DCPhase > 270 THEN
        DCPhase = DCPhase - 360
    ENDIF
   
ENDIF

RETURN DCPhase as "DCPhase"

----------------------------------------------------

 

REM Signal-to-Noise Indicator Code
REM Indicateur "CORE SNR"
REM Ajout ligne horizontale = 6

ignored, my1,my12 = CALL "CORE"

IF Barindex > 50 THEN
   
   
   
    REM Signal Amplitude Squared comes directly from the discriminator
    Signal = SQRT(my12*my12 + my1*my1)
   
    REM Noise is a 20 bar EMA of ranges squared
    Noise = 0.1*(High - Low)*(High - Low) + 0.9*Noise[1]
   
    REM Convert to dB and smooth with EMA
    IF Noise <> 0 and Signal <> 0  THEN
        SNR = 0.33*(10*Log(Signal/Noise)/Log(10)) + 0.67*SNR[1]
    ENDIF
   
ENDIF

RETURN SNR as "SNR",6

-----------------------------------------------------------

 

REM The Sinewave Indicator
REM Indicateur "CORE SINEWAVE"
REM Calcul du SINE et du LEAD_SINE
REM Sinus de la phase et ce même sinus avancé de 45°

myDCPhase = CALL "CORE PHASE2"

IF Barindex > 5 THEN
    SINE = SIN(myDCPhase)
    LEADSINE = SIN(myDCPhase + 45)
ENDIF


RETURN SINE as "SINE" , LEADSINE as "LEAD SINE"

----------------------------------------------------------------------

 

REM The Awesome Oscillator
REM Indicateur "CORE AWESOME"

Price = (High+Low)/2

IF Barindex > 12 THEN
   
    Value1 = (4*Price + 3*Price[1] + 2*Price[3] + Price[4])/10
    Value2 = Value1 + 0.088*Value2[6]
    Value3 = Value2 - Value2[6] + 1.2*Value3[6] - 0.7*Value3[12]
   
    Detrend = Value3[12] - 2*Value3[6] + Value3
    Smooth = 0.13785*(2*Detrend - Detrend[1]) + 0.0007*(2*Detrend[1] - Detrend[2])+ 0.13785*(2*Detrend[2] - Detrend[3]) + 1.2103*Smooth[1] - 0.4687*Smooth[2]
   
ENDIF

RETURN Detrend as "Detrend" , Smooth as "Smooth",0

 

------------------------------------------------------------------------------

 

REM Instantaneous Trendline Code
REM Indicateur "CORE TRENDLINE"

Price = (High + Low)/2
myPERIOD, ignored,ignored = CALL "CORE"

IF Barindex <= 50 tHEN
    aa = Close
ENDIF

IF Barindex > 50 THEN
    p1=myperiod/10 MOD 10
    p2=myperiod mod 10
    int=p1*10+p2
   
    value5 =int
   
    aa = 0
endif

FOR count = 0 TO Value5 - 1
    aa = aa + Price[count]
NEXT

IF Value5 <> 0 THEN
    aa = aa / Value5
   
    bb = 0.25*aa + 0.75*bb[1]
    Smooth = (7*Price + 6*Price[1] + 5*Price[2] + 4*Price[3] + 3*Price[4] + 2*Price[5] + Price[6])/28
   
ENDIF

return bb as "Trend", Smooth as "Smooth"

---------------------------------------------------------------

 

REM Market Mode Detector
REM Indicateur "CORE MODE2"

myDCPhase = CALL "CORE PHASE2"
myPERIOD, myQ1,myI1 = CALL "CORE"
//mySNR,ignored = CALL "core snr"

p1=myperiod/10 MOD 10
p2=myperiod mod 10
int=p1*10+p2

value5 =int

REM Rule 1: Sinewave Indicator Crossing initializes half cycle crossing timing when SNR > 6 dB
IF Sin(myDCPhase) Crosses Over Sin(myDCPhase + 45) OR Sin(myDCPhase) Crosses Under Sin(myDCPhase + 45) then//and mySNR > 6 THEN
    DaysInTrend = 0
    Trend = 0
    Cycles = 1
ENDIF

DaysInTrend = DaysInTrend + 1

REM Rule2: Phase rate of change must be within 50% of dominant cycle phase rate of change
IF Value5 <> 0 and myDCPhase - myDCPhase[1] > 0.67*360/Value5 and myDCPhase - myDCPhase[1] < 1.5*360/Value5 THEN
    Trend = 0
    Cycles = 1
ENDIF

IF DaysInTrend > 0.5*myPERIOD and myQ1 <> 500 and myI1 <> 500 THEN
    Trend = 1
    Cycles = 0
ENDIF

RETURN Trend as "Trend" , Cycles as "Cycles"

 

Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article
14 février 2008 4 14 /02 /février /2008 12:06

Cycles : les publications de J. Ehlers (partie 1).

 

J. Ehlers publie sur son site (mesasoftware.com)  une série de papiers, d'indicateurs et de systèmes sur le trading à base de cycles.  Je reprends, ici, pour un premier système, les codes écrits par Arnaudbzh pour Prorealtime chez dakoté ainsi que les explications de Smallcaps90 sur son fonctionnement.  Je ne suis pas convaincu de l'efficacité du système clefs en mains, mais la façon dont Ehlers aborde le problème des cycles devait figurer dans ce dossier.  Ce système est présenté dans le fichier "OWorld2000RocketScience".

 

Une vue du CAC avec les différents indicateurs.  En fenêtre 1, le cycle Prorealtime pour comparaison.  En fenêtre 2, le CAC avec l'indicateur TRENDLINE (magenta) et le filtre KALMAN (blanc).  En fenêtre 3,  l'indicateur de PERIODE.  En fenêtre 4, l'indicateur de PHASE.  En fenêtre 5, l'indicateur de RAPPORT SIGNAL/BRUIT (RSB).  En fenêtre 6, l'indicateur SINEWAVE et en fenêtre 7, l'indicateur de MODE CYCLE/TENDANCE.

 

hk70.gif

 

Les commentaires de Smallcaps90 :

 

"Le programme recherche le cycle dominant présent en calculant sa période, sa phase et le rapport signal/bruit en dB.  Il permet de déterminer le mode dans lequel les cours se trouvent : cycle ou tendance.  La méthode est basée sur la transformation de Hilbert et les travaux de J. P. Burg sur le "maximum d'entropie" pour extraire d'un signal sa composante sinusoïdale dominante.

 

Lorsque le filtre de Kalman croise la Trendline, on calcule la période.  Si la courbe Kalman ne recroise pas la Trendline avant un demi-cycle, alors on est en mode tendance.  Si on rentre à ce moment, le signal de sortie est le prochain croisement de Kalman avec la Trendline où on quitte le mode tendance pour le mode cycle.

 

En mode cycle, on prend position au croisement du Sinewave par la courbe Lead-Sinewave.  On ressort au croisement suivant.  Un rapport signal/bruit > 6 dB conforte l'hypothèse du mode cycle dominant.  Ehlers propose le critère suivant pour l'entrée : le rapport de la distance crête à creux (ou l'inverse) sur le filtre Kalman par la moyenne des longueurs des barres des cours sur la partie précédente de courbe comprise entre les croisements précédents du Sinewave et de son signal.  Si ce rapport est au moins de 2, une prise de position est possible (en fait un filtre sur la volatilité et l'amplitude du cycle) et l'amplitude attendue du futur mouvement serait suffisante.

 

Les règles de passage d'un mode à l'autre sont les suivantes :

-Un croisement Sinewave/Lead-Sinewave fait passer en mode cycle si le rapport signal/bruit est > 6 dB et si la phase du cycle est quasiment linéaire sur une période complète de ce cycle (Smallcaps90 utilise un taux de variation de la phase de 0.3).

-Lorsqu'un croisement entre la Trendline et le filtre Kalman apparaît, on enclenche un compteur qui s'incrémente à chaque barre.  Si le mode est tendance, la confirmation de celui-ci n'intervient qu'après un nombre de barres égale à la demi-période du cycle."

 

Les codes d'Arnaudbzh des indicateurs pour Prorealtime :

 

REM TRENDLINE DE J. EHLERS
REM Indicateur "MESA PERIODE"
REM Calcul de la période du cycle dominant

PRIX = (high + low) / 2

IF Barindex <= 5 THEN
    PERIODE = 0
    V5 = 0
ENDIf

IF Barindex > 5 THEn
    REM Détermination de la phase de chaque tic
    V1 = PRIX - PRIX[6]
    V2 = V1[3]
    V3 = 0.75*(V1-V1[6])+0.25*(V1[2]-v1[4])
    ENPHASE = 0.33*V2+0.67*ENPHASE[1]
    ENQUADRATURE = 0.2*V3 + 0.8*ENQUADRATURE[1]
    IF ABS(ENPHASE + ENPHASE[1]) > 0 THEN
        A = ABS((ENQUADRATURE + ENQUADRATURE[1]) / (ENPHASE+ENPHASE[1]))
        PHASEDEG = ATAN(A)
    endif
   
    REM Correction si autres quadrants
    IF ENPHASE < 0 AND ENQUADRATURE > 0 THEN
        PHASEDEG = 180 - PHAsedeg
    endif
   
    IF ENPHASE < 0 AND ENQUADRATURE < 0 THEN
        PHASEDEG = 180 + PHASEDeg
    endif
   
    IF ENPHASE > 0 AND ENQUADRATURE < 0 THEN
        PHASEDEG = 360 - PHASedeg
    endif
   
    REM Phase différentielle et corrections éventuelles
    DELTAPHASE = PHASEDEg[1]-phasedeg
    IF PHASEDEG[1] < 90 AND PHASEDEG > 270 THEN
        DELTAPHASE = 360 + DELTaphase
    endif
   
    IF DELTAPHASE < 1 THEN
        DELTAPhase=1
    endif
   
    IF DELTAPHASE > 60 THEN
        DELTAphase=60
    endif
   
    REM Calcul de la période instantanée du cycle actuel
    REM et correction éventuelle
    PERIODEINSTANT = 0
    V4 = 0
    J = 0
    WHILE J<41
        V4 = V4 + DELTAPHASE[J]
        IF V4>360 AND PERIODEINSTANT=0 THEN
            PERIODEINSTANT =J
        ENDIF
        J=J+1
    WEND
   
    IF PERIODEINSTANT=0 THEN
        PERIODEINSTANT = PERIODEINSTANT[1]
    ENDIF
   
    REM Calcul de la PERIODE
    V5 = 0.25 * PERIODEINSTANT +0.75*V5[1]
    periode=v5
ENDIF

RETURN PERIODE as "PERIODE" , DELTAPHASE as "deltaphase"

-------------------------------------------------------------------------------

REM TRENDLINE DE J. EHLERS
REM Indicateur "MESA PHASE"
REM Calcul de la phase du cycle dominant

IF Barindex > 5 THEN
   
    PRIX = (high + low) / 2
    myPERIODE, myDELTAPHASE = CALL "MESA PERIODE"
   
    PERIODE = ROUND(myPERIODE)
   
    PARTIEREELLE = 0
    PARTIEIMAGINAIRE = 0
   
    K = 0
    REM Calcul en degrés
    WHILE K < PERIODE
        PARTIEREELLE = PARTIEREELLE + SIN(360*K/PERIODE)*PRIX[K]
        PARTIEIMAGINAIRE = PARTIEIMAGINAIRE + COS(360*K/PERIODE)*PRIX[K]
        K = K+1
    WEND
   
    IF ABS(PARTIEIMAGINAIRE) > 0.001 THEN
        DCPHASEDEG = ATAN(PARTIEREELLE/PARTIEIMAGINAIRE)
    ENDIF
   
    IF ABS(PARTIEIMAGINAIRE) <= 0.001 THEN
        IF PARTIEREELLE >= 0 THEN
            SIGNEPARTIEREELLE=1
        ELSE
            SIGNEPARTIEREELLE=-1
        ENDIF
        DCPHASEDEG = 90*SIGNEPARTIEREELLE
    ENDIF
   
    DCPHASEDEG = DCPHASEDEG + 90
   
    IF PARTIEIMAGINAIRE<0 THEN
        DCPHASEDEG = DCPHASEDEG + 180
    ENDIF
   
    IF DCPHASEDEG>315 AND DCPHASEDEG<=360 and myDELTAPHASE <> 500 THEN
        DCPHASEDEG = DCPHASEDEG - 360
    ENDIF
   
    PHASE = DCPHASEDEG
       
ENDIF

RETURN PHASE as "PHASE"

-------------------------------------------------------------------------------------------

REM Indicateur "MESA RSB"
REM Calcul du rapport signal / bruit (RSB en dB)
REM Ajout ligne horizontale = 6


IF Barindex <= 8 THEN
    RSB = 0
    RANGERSB = 0
    ENPHASE = 0
    ENQUADRATURE = 0
ENdif

IF Barindex > 8 THEn
    PRIX = (high + low) /2
    REM Détermination des composantes en phase et en quadrature
    REM Transformation de Hilbert
    RANGERSB = 0.2*(high - low) + 0.8*RANGERSB[1]
    V1 = PRIX-PRIX[6]
    V2 = V1[3]
    V3 = 0.75*(V1-V1[6]) + 0.25*(V1[2]-V1[4])
    ENPHASE = 0.33*V2 + 0.67*ENPHASE[1]
    ENQUADRATURE = 0.2*V3 + 0.8*Enquadrature[1]
    REM Lissage du rapport signal/bruit
    V2 = 0.2*(square(ENPHASE) + square(ENQUADRATURE)) + 0.8*V2[1]
    REM Calcul du rapport signal/bruit lissé
    IF V2<0.001 THEN
        V2=0.001
    endif
   
    IF RANGE>0 THEN
        RSB = 0.25*(10* LOG(V2 / square(RANGERSB)) / LOG(10)+4.7) + 0.75*RSB[1]
    ENDif
endif

RETURN RSB as "Rapport Signal-Bruit"

---------------------------------------------------------------------------------------

REM TRENDLINE DE J. EHLERS
REM Indicateur "MESA SINEWAVE"
REM Calcul du SINEWAVE et du LEAD_SINEWAVE
REM Sinus de la phase et ce même sinus avancé de 45°

myPHASE = CALL "MESA PHASE"

IF Barindex > 5 THEN
    PHASE = myPHASE
    SINEWAVE = SIN(PHASE)
    LEADSINEWAVE = SIN(PHASE + 45)
ENDif

RETURN SINEWAVE as "SINEWAVE" , LEADSINEWAVE as "LEAD SINEWAVE"
------------------------------------------------------------------------------------------------

REM TRENDLINE DE J. EHLERS
REM Indicateur "MESA TRENDLINE"
REM Calcul de la TRENDLINE et du FILTRE DE KALMAN
REM Utilisés comme 2 moyennes mobiles adaptatives en mode Tendance

IF Barindex > 5 THEN
   
    PRIX = (high + low) /2
    myPERIODE, myDELTAPHASE = CALL "MESA PERIODE"
   
    PERIODE = ROUND(myPERIODE)
    TRENDLINE = 0
    J =0
    WHILE J < PERIODE+2
        TRENDLINE = TRENDLINE + PRIX[J]
        J = J+1
    wend
   
    IF PERIODE>0 THEN
        TRENDLINE = TRENDLINE / (PERIODE+2)
    endif
   
    REM Filtre de Kalman zero lag
    KALMAN = 0.33*(PRIX + 0.5*(PRIX - PRIX[3])) + 0.67*Kalman[1]
    IF Barindex<26 and myDELTAPHASE <> 500 THEN
        TRENDLINE = PRIX
        KALMAN =prix
    ENDIf
endif

RETURN TRENDLINE as "TRENDLINE" , KALMAN as "KALMan"
----------------------------------------------------------------------------------------

REM TRENDLINE DE J. EHLERS
REM Indicateur "MESA CYCLE TENDANCE"
REM Essai de détermination du mode cycle ou tendance
REM Variable P1 = 0.3

myPERIODE, myDELTAPHASE = CALL "MESA PERIODE"
mySINEWAVE, myLEADSINEWAVE = CALL "MESA SINEWAVE"
myTRENDLINE, myKALMAN = CALL "MESA TRENDLINE"
myRapportSignalBruit = CALL "MESA RSB"

P = myPERIODE
DEL = myDELTAPHASE
S = mySINEWAVE
LS = myLEADSINEWAVE
TL = myTRENDLINE
K = myKALMAN
RSB = myRapportSignalBruit

TENDANCE=1
CYCLES=0

REM Détecter un croisement LS/S et initialiser le mode cycle si RSB suffisant
IF LS crosses over S OR LS crosses under S AND RSB>6 THEN
    TENDANCE=0
    CYCLES=1
ENDIf

REM Vérifier progressivité de la variation de la phase
IF P<>0 AND DEL>(1-P1)*360 / P AND DEL<(1+P1)*360 / P THEN
    TENDANCE=0
    CYCLES=1
endif

REM Détecter un croisement K/TL et initialiser le compteur de jours
IF K crosses over TL OR K crosses under TL THEN
    NB=0
endif
REM Incrémenter compteur de jours
NB=nb+1
REM Confirmer mode cycle si compteur < une demi-période, sinon tendance
IF NB<P/2 THEN
    CYCLES=1
    TENDANCE=0
ELSE
    CYCLEs=0
    tendance=1
endif

RETURN CYCLES as "CYCLES", TENDANCE as "TENDANCE"

Repost 0
Published by hk_lisse - dans Les Cycles
commenter cet article