//+------------------------------------------------------------------+ //| Demo_iOBV.mq5 | //| Copyright 2011, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2000-2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property description "El indicador demuestra cómo hay que obtener los datos" #property description "de los búfers indicadores para el indicador técnico iOBV." #property description "El símbolo y el período de tiempo en el que se calcula el indicador" #property description "se establecen mediante los parámetros symbol y period." #property description "El modo de crear el manejador (handle) se establece mediante el parámetro 'type' (tipo de función)." #property indicator_separate_window #property indicator_buffers 1 #property indicator_plots 1 //--- iOBV #property indicator_label1 "iOBV" #property indicator_type1 DRAW_LINE #property indicator_color1 clrLightSeaGreen #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //+------------------------------------------------------------------+ //| Enumeración de modos de crear el manejador | //+------------------------------------------------------------------+ enum Creation { Call_iOBV , // usar iOBV Call_IndicatorCreate // usar IndicatorCreate }; //--- parámetros de entrada input Creation type=Call_iOBV; // tipo de función input ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK; // tipo de volumen input string symbol=" "; // símbolo input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe //--- búfers indicadores double iOBVBuffer[]; //--- variable para guardar el manejador del indicador iOBV int handle; //--- variable para guardar string name=symbol; //--- nombre del indicador en el gráfico string short_name; //--- vamos a guardar el número de los valores en el indicador On Balance Volume int bars_calculated=0; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- vinculación del array al búfer indicador SetIndexBuffer(0,iOBVBuffer,INDICATOR_DATA); //--- determinamos el símbolo para el que se construye el indicador name=symbol; //--- eliminaremos los espacios del lado izquierdo y derecho StringTrimRight(name); StringTrimLeft(name); //--- si después de eso la longitud de la cadena name obtiene el valor cero, if(StringLen(name)==0) { //--- cogeremos el símbolo del gráfico en el que está iniciado el indicador name=_Symbol; } //--- crearemos el manejador del indicador if(type==Call_iOBV) handle=iOBV(name,period,applied_volume); else { //--- llenaremos la estructura con los valores de los parámetros del indicador MqlParam pars[1]; //--- tipo de volumen pars[0].type=TYPE_INT; pars[0].integer_value=applied_volume; handle=IndicatorCreate(name,period,IND_OBV,1,pars); } //--- si no se puede crear el manejador if(handle==INVALID_HANDLE) { //--- avisaremos sobre el fallo y mostraremos el número del error PrintFormat("Fallo al crear el manejador del indicador iOBV para el par %s/%s, código del error %d", name, EnumToString(period), GetLastError()); //--- el trabajo del indicador se finaliza anticipadamente return(INIT_FAILED); } //--- mostraremos sobre qué par símbolo/período ha sido calculado el indicador On Balance Volume short_name=StringFormat("iOBV(%s/%s, %s)",name,EnumToString(period), EnumToString(applied_volume)); IndicatorSetString(INDICATOR_SHORTNAME,short_name); //--- inicialización correcta del indicador return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- número de valores copiados desde el indicador iOBV int values_to_copy; //--- vamos a averiguar el número de valores calculados en el indicador int calculated=BarsCalculated(handle); if(calculated<=0) { PrintFormat("BarsCalculated() ha devuelto %d, el código del error %d",calculated,GetLastError()); return(0); } //--- si se trata del primer arranque del proceso de calculación de nuestro indicador o se ha cambiado el número de valores en el indicador iOBV //--- o si es necesario calcular el indicador para dos o más barras (entonces algo se ha cambiado en el historial) if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1) { //--- si el array iOBVBuffer supera el número de valores en el indicador iOBV sobre el par symbol/period, entonces no copiamos todo //--- en caso contrario, copiaremos menos que el tamaño de los búfers indicadores if(calculated>rates_total) values_to_copy=rates_total; else values_to_copy=calculated; } else { //--- significa que no es la primera vez que se calcula nuestro indicador y desde el momento de la primera llamada de OnCalculate()) //--- se ha añadido no más de una barra para la calculación values_to_copy=(rates_total-prev_calculated)+1; } //--- llenamos los arrays con los valores desde el indicador iOBV //--- si FillArrayFromBuffer ha devuelto false, significa que los datos no están listos - entonces finalizamos el trabajo if(!FillArrayFromBuffer(iOBVBuffer,handle,values_to_copy)) return(0); //--- creamos el mensaje string comm=StringFormat("%s ==> Actualizados los valores en el indicador %s: %d", TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS), short_name, values_to_copy); //--- mostraremos en el gráfico un mensaje de servicio Comment(comm); //--- recordaremos el número de valores en el indicador On Balance Volume bars_calculated=calculated; //--- devolveremos el valor prev_calculated para la siguiente llamada return(rates_total); } //+------------------------------------------------------------------+ //| Llenamos el búfer indicador desde el indicador iOBV | //+------------------------------------------------------------------+ bool FillArrayFromBuffer(double &obv_buffer[], // búfer indicador de valores OBV int ind_handle, // manejador del indicador iOBV int amount // número de valores a copiar ) { //--- actualizaremos el código del error ResetLastError(); //--- llenamos una parte del array iOBVBuffer con los valores desde el búfer indicador con el índice 0 if(CopyBuffer(ind_handle,0,0,amount,obv_buffer)<0) { //--- si el proceso de copiado ha fallado, comunicaremos el código del error PrintFormat("Fallo al copiar los datos desde el indicador iOBV, código del error %d",GetLastError()); //--- finalizaremos con el resultado nulo - eso quiere decir que el indicador será considerado como no calculado return(false); } //--- todo ha salido bien return(true); } //+------------------------------------------------------------------+ //| Indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(handle!=INVALID_HANDLE) IndicatorRelease(handle); //--- limpiaremos el gráfico tras eliminar el indicador Comment(""); } |