¿Cómo puedo obtener una tabla de operaciones? Hasta ahora, no importa de indicador o Asesor Experto. Si periódicamente (en OnTimer() o en OnTick()) recibimos el historial de ticks a través de CopyTicks - se añadirán al arrayMqlTick.
Pero un simple análisis de esta matriz no dará una respuesta: si hubo nuevas operaciones o no, porque la comparación de los tiempos de los ticks no siempre es correcta, ya que puede haber varias operaciones en un milisegundo:
Utilizar el evento onBookEvent() - se activa para cada cambio del mercado.
¿Cómo puedo obtener una tabla de operaciones? Hasta ahora, no importa de indicador o Asesor Experto. Si periódicamente (en OnTimer() o en OnTick()) recibimos el historial de ticks a través de CopyTicks - se añadirán al arrayMqlTick.
Pero un simple análisis de esta matriz no dará una respuesta: si hubo nuevas operaciones o no, porque la comparación de los tiempos de los ticks no siempre es correcta, ya que puede haber varias operaciones en un milisegundo:
Utilice el evento onBookEvent(), se activará en cada cambio de tarifa.
La copa es, a grandes rasgos, un "tick chart twitch" - no es necesariamente un cambio en la tabla de todas las operaciones.
Utiliza los segundos cortes. Por ejemplo, en MqlTick o incluso en OnEvent copiar los nuevos ticks recibidos durante el último segundo en el array. La diferencia entre el valor anterior y el tamaño actual del array indicará el número de nuevos ticks.
Una apuesta es, por decirlo crudamente, una "sacudida del gráfico de ticks": no es necesariamente un cambio en la tabla de todas las operaciones.
Si lo piensas un poco, necesariamente serán todos los oficios.
Este es un ejemplo sencillo del indicador 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 lo piensas un poco, seguro que hay todos los oficios.
Este es un ejemplo sencillo del indicador All Trades Ribbon
No se ha podido ejecutar:
2016.08.24 15:54:41.700 DealsLent (RTS-12.16,M1) array out of range in 'DealsLent.mq5' (118,25)
No se ha podido iniciar:
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); } } } }
Una apuesta es, por decirlo crudamente, una "sacudida del gráfico de ticks": no es necesariamente un cambio en la tabla de todas las operaciones.
Hacer algo como una máscara de hacer: 0-1-0-1, y si la máscara es estable con alrededor de cinco y diez líneas - que significa un partido garantizado?Karputov Vladimir
Un indicador "All Trades Feed" completo
//+------------------------------------------------------------------+ //| 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 indicador "All Trades Feed" completo
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
¿Cómo puedo obtener una tabla de operaciones? Hasta ahora, no importa de indicador o Asesor Experto. Si periódicamente (en OnTimer() o en OnTick()) recibimos el historial de ticks a través de CopyTicks - se añadirán al arrayMqlTick.
Pero un simple análisis de esta matriz no dará una respuesta: si hubo nuevas operaciones o no, porque la comparación de los tiempos de los ticks no siempre es correcta, ya que puede haber varias operaciones en un milisegundo: