Saludos. Estoy aprendiendo a hacer indicadores en MQL5. Quiero conocer la estructura general de un indicador.
Para hacer esto, estoy diseñando el siguiente indicador (solo resta el ATR de dos velas anteriores al valor del ATR de la vela anterior), pero no se está mostrando, es decir, aunque al compilar no indica que falte algo, una vez que selecciono el indicador personalizado para incorporarlo, en diario dice que el indicador fue cargado exitosamente, y se carga, pero no se ve ninguna linea.
Aquí el código:
//+------------------------------------------------------------------+
//| ATR.mq4 |
//| Copyright 2014,J |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014,J"
#property link ""
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//--- buffers
double Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexStyle(0,DRAW_LINE);
//---
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[])
{
double ATR1, ATR2;
ATR1=iATR(NULL, 14, PERIOD_CURRENT, 1);
ATR2=iATR(NULL, 14, PERIOD_CURRENT, 1);
//---
Buffer[0]=ATR1-ATR2;
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
El error está en cómo manejas el puntero del indicador (iATR()).
Tienes que "apuntar" a los datos del indicador en OnInit(), al principio, una sóla vez, y luego cargarlos, cuando los necesitas, en OnCalculate() con CopyBuffer().
Con la expresión Buffer[0]= ATR1-ATR2 no calculas nada puesto que ATR1 Y ATR2 son dos valores booleanos devueltos por iATR() según se haya ejecutado con éxito o no la operación. Además, tampoco generas el bucle de carga de datos del indicador en cada vela.
Te adjunto un resumen de código de indicador que genera un canal-ATR
void OnInit() { /.../ SetIndexBuffer(0, MAbuffer, INDICATOR_DATA); SetIndexBuffer(1, supATRBuffer,INDICATOR_DATA); //---- set supATRBuffer[] and infATRBuffer[] dynamic arrays into indicator buffers SetIndexBuffer(2, infATRBuffer,INDICATOR_DATA); ArraySetAsSeries(MAbuffer, true); //---- indexing the elements in the buffer as timeseries ArraySetAsSeries(supATRBuffer, true); ArraySetAsSeries(infATRBuffer, true); /.../ ResetLastError(); puntATR= iATR(simb, 0, ATRperiodo); puntMA= iMA(simb, PERIOD_CURRENT, MAperiodoTrab, 0, MODE_SMA, precioAplic); if(puntATR==INVALID_HANDLE || puntMA==INVALID_HANDLE) infoError(GetLastError(), "Canal ATR "+__FUNCTION__); /.../ } int OnCalculate(const int rangoTotal, const int preCalculado, const int inicio, const double &precio[]) { int vela, limite,aCopiar; double ATR[], atr; //comprobando si el número de barras es suficiente para el cálculo if(BarsCalculated(puntMA)<rangoTotal || BarsCalculated(puntATR)<rangoTotal || rangoTotal<minRangoTotal) return(0); ArraySetAsSeries(ATR,true); limite= rangoTotal-preCalculado; //inicializa el índice para el cálculo de nueva barra if(preCalculado>rangoTotal || preCalculado<=0) limite= rangoTotal-minRangoTotal-1; //inicializa el índice para el cálculo de todas las barras aCopiar= limite+1; if(CopyBuffer(puntATR, 0, 0, aCopiar, ATR)<=0) return(0); if(CopyBuffer(puntMA, 0, 0, aCopiar, MAbuffer)<=0) return(0); for(int vela= limite; vela>=0; vela--) { atr= factorATR*ATR[vela]; supATRBuffer[vela]= MAbuffer[vela]+atr; infATRBuffer[vela]= MAbuffer[vela]-atr; } return(rangoTotal); }
El error está en cómo manejas el puntero del indicador (iATR()).
Tienes que "apuntar" a los datos del indicador en OnInit(), al principio, una sóla vez, y luego cargarlos, cuando los necesitas, en OnCalculate() con CopyBuffer().
Con la expresión Buffer[0]= ATR1-ATR2 no calculas nada puesto que ATR1 Y ATR2 son dos valores booleanos devueltos por iATR() según se haya ejecutado con éxito o no la operación. Además, tampoco generas el bucle de carga de datos del indicador en cada vela.
Te adjunto un resumen de código de indicador que genera un canal-ATR
![MQL5 - Lenguaje de estrategias comerciales para el terminal de cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- 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
Saludos. Estoy aprendiendo a hacer indicadores en MQL5. Quiero conocer la estructura general de un indicador.
Para hacer esto, estoy diseñando el siguiente indicador (solo resta el ATR de dos velas anteriores al valor del ATR de la vela anterior), pero no se está mostrando, es decir, aunque al compilar no indica que falte algo, una vez que selecciono el indicador personalizado para incorporarlo, en diario dice que el indicador fue cargado exitosamente, y se carga, pero no se ve ninguna linea.
Aquí el código:
//+------------------------------------------------------------------+
//| ATR.mq4 |
//| Copyright 2014,J |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014,J"
#property link ""
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//--- buffers
double Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexStyle(0,DRAW_LINE);
//---
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[])
{
double ATR1, ATR2;
ATR1=iATR(NULL, 14, PERIOD_CURRENT, 1);
ATR2=iATR(NULL, 14, PERIOD_CURRENT, 1);
//---
Buffer[0]=ATR1-ATR2;
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+