docmaboul | damtoul a écrit :
L'idée de base que j'avais c'était de transposer vitesse et accélération au sens physique vers les datas d'un marché, le fx en l'occurence.
Donc oui des rapports entre vitesses et accélérations seraient intéressants ainsi que des pips/s.
Dans mon esprit le but de bouzin c'est de détecter soit les points d'équilibre (=retournement de marché/fin de retracement) soit les points d'accélération significatifs(=démarrage de trends).
Je ne sais pas si c'est exploitable mais c'est une piste à défricher.
|
Bon, voilà une toute première mouture:
Code :
- //+------------------------------------------------------------------+
- //| TickOMeter2
- //| DocMaboul
- //| http://forum.hardware.fr/forum2.ph [...] te_only=0&new=0&nojs=0
- //+------------------------------------------------------------------+
- #property copyright "DocMaboul"
- #property link "http://forum.hardware.fr/forum2.php?config=hfr.inc&cat=13&subcat=422&post=87292&page=1&p=1&sondage=0&owntopic=1&trash=0&trash_post=0&print=0&numreponse=0"e_only=0&new=0&nojs=0"
- double asks[];
- double bids[];
- double spreads[];
- double prices[];
- datetime times[];
- int next_pos=0;
- extern int buffer_size=10000;
- extern int digits=4;
- bool buffer_is_full=false;
- double digits_fact;
- #define AVG_SEC 0x0001
- #define AVG_MIN 0x0002
- #define AVG_ABS 0x0004
- //+------------------------------------------------------------------+
- //| expert initialization function |
- //+------------------------------------------------------------------+
- int init() {
- ArrayResize(asks, buffer_size);
- ArrayResize(bids, buffer_size);
- ArrayResize(spreads, buffer_size);
- ArrayResize(prices, buffer_size);
- ArrayResize(times, buffer_size);
-
- ObjectCreate("pip_per_sec1", OBJ_LABEL, 0, 0, 0);
- ObjectSet("pip_per_sec1", OBJPROP_CORNER, 1);
- ObjectSet("pip_per_sec1", OBJPROP_YDISTANCE, 25);
- ObjectCreate("pip_per_min1", OBJ_LABEL, 0, 0, 0);
- ObjectSet("pip_per_min1", OBJPROP_CORNER, 1);
- ObjectSet("pip_per_min1", OBJPROP_YDISTANCE, 25);
- ObjectSet("pip_per_min1", OBJPROP_XDISTANCE, 125);
- ObjectCreate("pip_per_sec2", OBJ_LABEL, 0, 0, 0);
- ObjectSet("pip_per_sec2", OBJPROP_CORNER, 1);
- ObjectSet("pip_per_sec2", OBJPROP_YDISTANCE, 40);
- ObjectCreate("pip_per_min2", OBJ_LABEL, 0, 0, 0);
- ObjectSet("pip_per_min2", OBJPROP_CORNER, 1);
- ObjectSet("pip_per_min2", OBJPROP_YDISTANCE, 40);
- ObjectSet("pip_per_min2", OBJPROP_XDISTANCE, 125);
- ObjectCreate("pip_per_sec3", OBJ_LABEL, 0, 0, 0);
- ObjectSet("pip_per_sec3", OBJPROP_CORNER, 1);
- ObjectSet("pip_per_sec3", OBJPROP_YDISTANCE, 65);
- ObjectCreate("pip_per_min3", OBJ_LABEL, 0, 0, 0);
- ObjectSet("pip_per_min3", OBJPROP_CORNER, 1);
- ObjectSet("pip_per_min3", OBJPROP_YDISTANCE, 65);
- ObjectSet("pip_per_min3", OBJPROP_XDISTANCE, 125);
- ObjectCreate("pip_per_sec4", OBJ_LABEL, 0, 0, 0);
- ObjectSet("pip_per_sec4", OBJPROP_CORNER, 1);
- ObjectSet("pip_per_sec4", OBJPROP_YDISTANCE, 80);
- ObjectCreate("pip_per_min4", OBJ_LABEL, 0, 0, 0);
- ObjectSet("pip_per_min4", OBJPROP_CORNER, 1);
- ObjectSet("pip_per_min4", OBJPROP_YDISTANCE, 80);
- ObjectSet("pip_per_min4", OBJPROP_XDISTANCE, 125);
- digits_fact=MathPow(10, digits);
- return(0);
- }
- //+------------------------------------------------------------------+
- //| expert deinitialization function |
- //+------------------------------------------------------------------+
- int deinit() {
- ObjectDelete("pip_per_sec1" );
- ObjectDelete("pip_per_sec2" );
- ObjectDelete("pip_per_sec3" );
- ObjectDelete("pip_per_sec4" );
- ObjectDelete("pip_per_min1" );
- ObjectDelete("pip_per_min2" );
- ObjectDelete("pip_per_min3" );
- ObjectDelete("pip_per_min4" );
- return(0);
- }
- void on_new_tick() {
- bids[next_pos]=Bid;
- asks[next_pos]=Ask;
- prices[next_pos]=(Ask+Bid)/2;
- spreads[next_pos]=Ask-Bid;
- times[next_pos]=TimeCurrent();
- next_pos=(next_pos+1)%buffer_size;
- if ( next_pos == 0 ) buffer_is_full=true;
- }
- double get_pips_avg(int seconds, int mode) {
- double pips=0, res, last_val;
- int start_pos, pos;
- datetime end_time, start_time;
- if ( buffer_is_full ) {
- start_pos=next_pos-1;
- if ( start_pos == -1 ) start_pos=buffer_size-1;
- pos=start_pos-1;
- if ( pos == -1 ) pos=buffer_size-1;
- last_val=prices[start_pos];
- end_time=times[start_pos];
- while ( end_time-times[pos] <= seconds && pos != start_pos ) {
- start_time=times[pos];
- if ( mode & AVG_ABS == AVG_ABS )
- pips+=MathAbs(last_val-prices[pos]);
- else
- pips+=(last_val-prices[pos]);
- last_val=prices[pos];
- pos=pos-1;
- if ( pos == -1 ) pos = buffer_size-1;
- }
- if ( end_time != start_time ) {
- if ( mode & AVG_MIN == AVG_MIN )
- res=60*(digits_fact*pips)/(end_time-start_time);
- else
- res=(digits_fact*pips)/(end_time-start_time);
- }
- else
- res=0;
- }
- else {
- start_pos=next_pos-1;
- if ( start_pos == -1 ) return(0);
- pos=start_pos-1;
- if ( pos == -1 ) return(0);
- last_val=prices[start_pos];
- end_time=times[start_pos];
- while ( end_time-times[pos] <= seconds ) {
- start_time=times[pos];
- if ( mode & AVG_ABS == AVG_ABS )
- pips+=MathAbs(last_val-prices[pos]);
- else
- pips+=(last_val-prices[pos]);
- last_val=prices[pos];
- pos=pos-1;
- if ( pos == -1 ) break;
- }
- if ( end_time != start_time ) {
- if ( mode & AVG_MIN == AVG_MIN )
- res=60*(digits_fact*pips)/(end_time-start_time);
- else
- res=(digits_fact*pips)/(end_time-start_time);
- }
- else
- res=0;
- }
- return(res);
- }
- //+------------------------------------------------------------------+
- //| expert start function |
- //+------------------------------------------------------------------+
- int start() {
- on_new_tick();
-
- double avg;
- int text_color;
- int font_size=8;
- string font="Tahoma";
-
- avg=get_pips_avg(60, AVG_SEC|AVG_ABS);
- ObjectSetText("pip_per_sec1","p/s="+DoubleToStr(avg, 2),font_size,font,White);
- ObjectSetText("pip_per_min1","p/m="+DoubleToStr(avg*60, 2),font_size,font,White);
- avg=get_pips_avg(300, AVG_SEC|AVG_ABS);
- ObjectSetText("pip_per_sec2","p/s="+DoubleToStr(avg, 2),font_size,font,White);
- ObjectSetText("pip_per_min2","p/m="+DoubleToStr(avg*60, 2),font_size,font,White);
- avg=get_pips_avg(60, AVG_SEC);
- if ( avg < 0 ) text_color=Red;
- else text_color=Green;
- ObjectSetText("pip_per_sec3","p/s="+DoubleToStr(avg, 2),font_size,font,text_color);
- ObjectSetText("pip_per_min3","p/m="+DoubleToStr(avg*60, 2),font_size,font,text_color);
- avg=get_pips_avg(300, AVG_SEC);
- if ( avg < 0 ) text_color=Red;
- else text_color=Green;
- ObjectSetText("pip_per_sec4","p/s="+DoubleToStr(avg, 2),font_size,font,text_color);
- ObjectSetText("pip_per_min4","p/m="+DoubleToStr(avg*60, 2),font_size,font,text_color);
- return(0);
- }
|
Pour l'implémentation, j'ai utilisé des listes circulaires. J'ai stocké un peu toutes les informations (ask, bid, spread, prix) mais seul le prix est utilisé pour l'instant. Le prix est estimé à (ask+bid)/2. Le gros du boulot est fait par la fonction get_pips_avg. Elle va calculer une moyenne selon le paramètre mode (un simple ou binaire) sur une durée donnée. Pour l'instant, il n'y a que deux modes que l'on peut combiner:
- AVG_SEC ou AVG_MIN: calcule la moyenne à la seconde ou à la minute
- AVG_ABS : calcule la moyenne en valeur absolue (si présent) ou en relatif (si pas positionné). En gros, l'idée est que si le paramètre n'est pas présent, ça donne la moyenne de la variation du cours alors que s'il est présent, ça donne la moyenne de la vitesse à laquelle il varie (sans tenir compte du sens des variations).
Bon, c'est pas terrible terrible mais c'est un premier jet.
edit: pour copier le code, c'est plus simple d'utiliser "répondre au message" afin de virer les numéros de ligne  |