Comment puis-je obtenir un tableau des transactions ? Jusqu'à présent, cela n'a pas d'importance qu'il s'agisse d'un indicateur ou d'un conseiller expert. Si périodiquement (dans OnTimer() ou dans OnTick()) nous recevons l'historique des ticks par CopyTicks - ils seront ajoutés au tableauMqlTick.
Mais une simple analyse de ce tableau ne donnera pas de réponse - y a-t-il eu de nouvelles transactions ou non, car la comparaison des temps de ticks n'est pas toujours correcte, car il peut y avoir plusieurs transactions dans une milliseconde :
Utilisez l'événement onBookEvent() - il est déclenché à chaque changement du marché.
Comment puis-je obtenir un tableau des transactions ? Jusqu'à présent, cela n'a pas d'importance qu'il s'agisse d'un indicateur ou d'un conseiller expert. Si périodiquement (dans OnTimer() ou dans OnTick()) nous recevons l'historique des ticks par CopyTicks - ils seront ajoutés au tableauMqlTick.
Mais une simple analyse de ce tableau ne donnera pas de réponse - y a-t-il eu de nouvelles transactions ou non, car la comparaison des temps de ticks n'est pas toujours correcte, car il peut y avoir plusieurs transactions dans une milliseconde :
Utilisez l'événement onBookEvent(), il sera déclenché à chaque changement de taux.
La coupe est, grosso modo, un "twitch de la table des opérations" - il ne s'agit pas nécessairement d'un changement dans la table des opérations.
Utilisez la deuxième coupure. Par exemple, dans MqlTick ou même dans OnEvent, copiez les nouveaux ticks reçus au cours de la dernière seconde dans le tableau. La différence entre la valeur précédente et la taille actuelle du tableau indiquera le nombre de nouveaux ticks.
Un pari est, pour dire les choses crûment, un "tic-tac" du tableau de tous les échanges - ce n'est pas nécessairement un changement dans le tableau de tous les échanges.
Si l'on y réfléchit un peu, il y a forcément tous les métiers.
Voici un exemple simple de l'indicateur All Trades Tape
//+------------------------------------------------------------------+ //| DealsLent.mq5 | //| Copyright 2016, prostotrader | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, prostotrader" #property link "https://www.mql5.com" #property version "1.00" input int Ticks = 100; //Тики #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 //--- plot Label1 #property indicator_label1 "Sell" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Label1 #property indicator_label2 "Buy" #property indicator_type2 DRAW_LINE #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- indicator buffers double SellBuffer[]; double BuyBuffer[]; double sell_deals; double buy_deals; long curr_time; int event_cnt; bool on_call; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { curr_time=0; if(!MarketBookAdd(Symbol())) { Print(__FUNCTION__,": Стакан символа "+Symbol()+" не добавден!"); return( INIT_FAILED ); } //--- Period if(Period()!=PERIOD_M1) { Print("Ошибка! Период графика должен быть 'M1'"); return( INIT_FAILED ); } //--- IndicatorSetInteger(INDICATOR_DIGITS,0); IndicatorSetString(INDICATOR_SHORTNAME,"DealsLent"); //--- SetIndexBuffer(0,SellBuffer,INDICATOR_DATA); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE); ArraySetAsSeries(SellBuffer,true); //--- SetIndexBuffer(1,BuyBuffer,INDICATOR_DATA); PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE); ArraySetAsSeries(BuyBuffer,true); //--- event_cnt=0; on_call=false; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { MarketBookRelease(Symbol()); if(reason==REASON_INITFAILED) { int window=ChartWindowFind(ChartID(),"DealsLent"); ChartIndicatorDelete(ChartID(),window,"DealsLent"); } } //+------------------------------------------------------------------+ //| Custom indicator On book event function | //+------------------------------------------------------------------+ void OnBookEvent(const string &symbol) { MqlTick ticks[]; if(symbol==Symbol()) { if(curr_time==0) { if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,1)==1) { curr_time=ticks[0].time_msc; } } else { sell_deals= 0; buy_deals = 0; if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,Ticks)==Ticks) { for(int i=0; i<Ticks; i++) { if(ticks[i].time_msc!=curr_time) { if(( ticks[i].flags &TICK_FLAG_BUY)==TICK_FLAG_BUY) { buy_deals++; } else if(( ticks[i].flags &TICK_FLAG_SELL)==TICK_FLAG_SELL) { sell_deals++; } } } } curr_time=ticks[0].time_msc; double price[]; on_call=true; OnCalculate(event_cnt,event_cnt,0,price); } } } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { if(prev_calculated==0) { ArrayInitialize(SellBuffer,EMPTY_VALUE); ArrayInitialize(BuyBuffer,EMPTY_VALUE); } else { if(rates_total==event_cnt) { if(on_call) { on_call=false; //--- for(int i=rates_total-1; i>0; i--) { SellBuffer[i]= SellBuffer[i-1]; BuyBuffer[i] = BuyBuffer[i-1]; } SellBuffer[0]= double(sell_deals); BuyBuffer[0] = double(buy_deals); } } else { if(on_call) { on_call=false; SellBuffer[0]= double(sell_deals); BuyBuffer[0] = double(buy_deals); } else { SellBuffer[0]= SellBuffer[1]; BuyBuffer[0] = BuyBuffer[1]; } } } event_cnt=rates_total; //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Si on y réfléchit un peu, il y a forcément tous les métiers.
Voici un exemple simple de l'indicateur All Trades Ribbon
Échec de l'exécution :
2016.08.24 15:54:41.700 DealsLent (RTS-12.16,M1) array out of range in 'DealsLent.mq5' (118,25)
Échec du démarrage :
void OnBookEvent(const string &symbol) { MqlTick ticks[]; if(symbol==Symbol()) { if(curr_time==0) { if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,1)==1) { curr_time=ticks[0].time_msc; } } else { sell_deals= 0; buy_deals = 0; if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,Ticks)==Ticks) { for(int i=0; i<Ticks; i++) { if(ticks[i].time_msc!=curr_time) { if(( ticks[i].flags &TICK_FLAG_BUY)==TICK_FLAG_BUY) { buy_deals++; } else if(( ticks[i].flags &TICK_FLAG_SELL)==TICK_FLAG_SELL) { sell_deals++; } } } curr_time=ticks[0].time_msc; double price[]; on_call=true; OnCalculate(event_cnt,event_cnt,0,price); } } } }
Un pari est, pour dire les choses crûment, un "tic-tac" - il ne s'agit pas nécessairement d'un changement dans le tableau de tous les échanges.
Faites quelque chose comme un masque faire : 0-1-0-1, et si le masque est stable avec environ cinq et dix lignes - cela signifie une correspondance garantie ?Karputov Vladimir
Un indicateur complet "All Trades Feed".
//+------------------------------------------------------------------+ //| DealsLent.mq5 | //| Copyright 2016, prostotrader | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, prostotrader" #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 //--- plot Label1 #property indicator_label1 "Sell" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Label1 #property indicator_label2 "Buy" #property indicator_type2 DRAW_LINE #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- indicator buffers double SellBuffer[]; double BuyBuffer[]; double sell_deals; double buy_deals; ulong start_time; int event_cnt; bool on_call; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { start_time=0; if(!MarketBookAdd(Symbol())) { Print(__FUNCTION__,": Стакан символа "+Symbol()+" не добавден!"); return( INIT_FAILED ); } //--- Bars int bars=Bars(Symbol(),PERIOD_CURRENT); if (bars<3) { Print(__FUNCTION__,": Не достаточно баров на текущем таймфрейме!"); return( INIT_FAILED ); } //--- IndicatorSetInteger(INDICATOR_DIGITS,0); IndicatorSetString(INDICATOR_SHORTNAME,"DealsLent"); //--- SetIndexBuffer(0,SellBuffer,INDICATOR_DATA); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE); ArraySetAsSeries(SellBuffer,true); //--- SetIndexBuffer(1,BuyBuffer,INDICATOR_DATA); PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE); ArraySetAsSeries(BuyBuffer,true); //--- event_cnt=0; on_call=false; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { MarketBookRelease(Symbol()); if(reason==REASON_INITFAILED) { int window=ChartWindowFind(ChartID(),"DealsLent"); ChartIndicatorDelete(ChartID(),window,"DealsLent"); } } //+------------------------------------------------------------------+ //| Custom indicator On book event function | //+------------------------------------------------------------------+ void OnBookEvent(const string &symbol) { MqlTick ticks[]; if(symbol==Symbol()) { if(start_time==0) { if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,1)==1) { start_time=ulong(ticks[0].time_msc); } } else { sell_deals= 0; buy_deals = 0; int copied= CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,start_time,0); if(copied>0) { for(int i=0; i<copied; i++) { if(( ticks[i].flags &TICK_FLAG_BUY)==TICK_FLAG_BUY) { buy_deals++; } else if(( ticks[i].flags &TICK_FLAG_SELL)==TICK_FLAG_SELL) { sell_deals++; } } start_time=ulong(ticks[copied - 1].time_msc); double price[]; on_call=true; OnCalculate(event_cnt,event_cnt,0,price); } } } } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { if(prev_calculated==0) { ArrayInitialize(SellBuffer,EMPTY_VALUE); ArrayInitialize(BuyBuffer,EMPTY_VALUE); } else { if(rates_total==event_cnt) { if(on_call) { on_call=false; //--- for(int i=rates_total-1; i>0; i--) { SellBuffer[i]= SellBuffer[i-1]; BuyBuffer[i] = BuyBuffer[i-1]; } SellBuffer[0]= double(sell_deals); BuyBuffer[0] = double(buy_deals); } } else { if(on_call) { on_call=false; SellBuffer[0]= double(sell_deals); BuyBuffer[0] = double(buy_deals); } else { SellBuffer[0]= SellBuffer[1]; BuyBuffer[0] = BuyBuffer[1]; } } } event_cnt=rates_total; //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Karputov Vladimir
Un indicateur complet "All Trades Feed".
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation
Comment puis-je obtenir un tableau des transactions ? Jusqu'à présent, cela n'a pas d'importance qu'il s'agisse d'un indicateur ou d'un conseiller expert. Si périodiquement (dans OnTimer() ou dans OnTick()) nous recevons l'historique des ticks par CopyTicks - ils seront ajoutés au tableauMqlTick.
Mais une simple analyse de ce tableau ne donnera pas de réponse - y a-t-il eu de nouvelles transactions ou non, car la comparaison des temps de ticks n'est pas toujours correcte, car il peut y avoir plusieurs transactions dans une milliseconde :