|
|
|
Creando un
Indicador para Metatrader |
Para la creación de un Indicador
para Metratader existen varios métodos:
1,- Para que el software
considere que el archivo es un indicador en este debe haber 2
definiciones
|
#property
indicator_chart_window // an
indicator is drawn in the main chart window
|
o
|
#property
indicator_separate_window // an indicator is
drawn in a separate window
|
2.- Para mostrar el
indicador en una diferente ventana.
|
#property
indicator_minimum Min_Value
#property indicator_maximum Max_Value
|
En el siguiente código "Min_Value"
y"Max_Value" corresponden a los valores. Por ejemplo, estos valores
deben ser entre 0 y 100 respectivamente para el indicador RSI.
3.- El numero de
indicadores necesarios necesarios para dibujar el indicar debe ser
definido :
|
#property
indicator_buffers N
|
Donde N toma un valor entre 1 y 8.
4.- Para definir el color
de las líneas de un indicador:
|
#property
indicator_color1 Silver
#property indicator_color2 Red
...
#property indicator_colorN <SomeColor>
|
Donde N es el numero de
indicadores definidos en "#property indicator_buffers".
5.- Existen funciones que permiten
el control del proceso de calculo y visualización del indicador, tal
como se muestra en el siguiente ejemplo del indicador "Ishimoku
Kinko Hyo "
|
//+------------------------------------------------------------------+
//|
Ichimoku.mq4 |
//|
Copyright © 2004, MetaQuotes Software Corp. |
//|
http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software
Corp."
#property link "http://www.metaquotes.net/"
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 SandyBrown
#property indicator_color4 Thistle
#property indicator_color5 Lime
#property indicator_color6 SandyBrown
#property indicator_color7 Thistle
//---- input parameters
extern int Tenkan=9;
extern int Kijun=26;
extern int Senkou=52;
//---- indicator buffers
double Tenkan_Buffer[];
double Kijun_Buffer[];
double SpanA_Buffer[];
double SpanB_Buffer[];
double Chinkou_Buffer[];
double SpanA2_Buffer[];
double SpanB2_Buffer[];
//---- span_a drawing begin
int a_begin;
//+------------------------------------------------------------------+
//| Custom indicator initialization function
|
//+------------------------------------------------------------------+
int init()
{
//----
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,Tenkan_Buffer);
SetIndexDrawBegin(0,Tenkan-1);
SetIndexLabel(0,"Tenkan Sen");
//----
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,Kijun_Buffer);
SetIndexDrawBegin(1,Kijun-1);
SetIndexLabel(1,"Kijun Sen");
//----
a_begin=Kijun; if(a_begin<Tenkan) a_begin=Tenkan;
SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_DOT);
SetIndexBuffer(2,SpanA_Buffer);
SetIndexDrawBegin(2,Kijun+a_begin-1);
SetIndexShift(2,Kijun);
SetIndexLabel(2,NULL);
SetIndexStyle(5,DRAW_LINE,STYLE_DOT);
SetIndexBuffer(5,SpanA2_Buffer);
SetIndexDrawBegin(5,Kijun+a_begin-1);
SetIndexShift(5,Kijun);
SetIndexLabel(5,"Senkou Span A");
//----
SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_DOT);
SetIndexBuffer(3,SpanB_Buffer);
SetIndexDrawBegin(3,Kijun+Senkou-1);
SetIndexShift(3,Kijun);
SetIndexLabel(3,NULL);
SetIndexStyle(6,DRAW_LINE,STYLE_DOT);
SetIndexBuffer(6,SpanB2_Buffer);
SetIndexDrawBegin(6,Kijun+Senkou-1);
SetIndexShift(6,Kijun);
SetIndexLabel(6,"Senkou Span B");
//----
SetIndexStyle(4,DRAW_LINE);
SetIndexBuffer(4,Chinkou_Buffer);
SetIndexShift(4,-Kijun);
SetIndexLabel(4,"Chinkou Span");
//----
return(0);
}
//+------------------------------------------------------------------+
//| Ichimoku Kinko Hyo
|
//+------------------------------------------------------------------+
int start()
{
int i,k;
int counted_bars=IndicatorCounted();
double high,low,price;
//----
if(Bars<=Tenkan || Bars<=Kijun || Bars<=Senkou) return(0);
//---- initial zero
if(counted_bars<1)
{
for(i=1;i<=Tenkan;i++)
Tenkan_Buffer[Bars-i]=0;
for(i=1;i<=Kijun;i++)
Kijun_Buffer[Bars-i]=0;
for(i=1;i<=a_begin;i++) { SpanA_Buffer[Bars-i]=0;
SpanA2_Buffer[Bars-i]=0; }
for(i=1;i<=Senkou;i++) { SpanB_Buffer[Bars-i]=0;
SpanB2_Buffer[Bars-i]=0; }
}
//---- Tenkan Sen
i=Bars-Tenkan;
if(counted_bars>Tenkan) i=Bars-counted_bars-1;
while(i>=0)
{
high=High[i]; low=Low[i]; k=i-1+Tenkan;
while(k>=i)
{
price=High[k];
if(high<price) high=price;
price=Low[k];
if(low>price) low=price;
k--;
}
Tenkan_Buffer[i]=(high+low)/2;
i--;
}
//---- Kijun Sen
i=Bars-Kijun;
if(counted_bars>Kijun) i=Bars-counted_bars-1;
while(i>=0)
{
high=High[i]; low=Low[i]; k=i-1+Kijun;
while(k>=i)
{
price=High[k];
if(highprice)
low=price;
k--;
}
Kijun_Buffer[i]=(high+low)/2;
i--;
}
//---- Senkou Span A
i=Bars-a_begin+1;
if(counted_bars>a_begin-1) i=Bars-counted_bars-1;
while(i>=0)
{
price=(Kijun_Buffer[i]+Tenkan_Buffer[i])/2;
SpanA_Buffer[i]=price;
SpanA2_Buffer[i]=price;
i--;
}
//---- Senkou Span B
i=Bars-Senkou;
if(counted_bars>Senkou) i=Bars-counted_bars-1;
while(i>=0)
{
high=High[i]; low=Low[i]; k=i-1+Senkou;
while(k>=i)
{
price=High[k];
if(high<price) high=price;
price=Low[k];
if(low>price) low=price;
k--;
}
price=(high+low)/2;
SpanB_Buffer[i]=price;
SpanB2_Buffer[i]=price;
i--;
}
//---- Chinkou Span
i=Bars-1;
if(counted_bars>1) i=Bars-counted_bars-1;
while(i>=0) { Chinkou_Buffer[i]=Close[i]; i--; }
//----
return(0);
}
//+------------------------------------------------------------------+
|
6.- La función "SetIndexStyle"
es la encargada de controlar los parámetros del dibujo del
indicador.
El modo de dibujo "DRAW_LINE" se
encarga de los valores entre línea han sido dibujados.
"DRAW_HISTOGRAM" a se aplica al
indicador de la ventana principal. El histograma se dibuja entre los
valores (here: SpanA_Buffer) y (here: SpanB_Buffer), en este
caso se usa el color del mayor.
7.- La función "SetIndexDrawBegin"
indica cual es el elemento que inicia el dibujo.
8.- La función "SetIndexBuffer"
, permite declarar una matriz bi-dimensional.
|
//---- indicator buffers
double Tenkan_Buffer[];
double Kijun_Buffer[];
double SpanA_Buffer[];
double SpanB_Buffer[];
double Chinkou_Buffer[];
double SpanA2_Buffer[];
double SpanB2_Buffer[];
|
La funcion "ArrayResize" no puede
ser aplicada a los indicadores pues es inutil asi como para aplicar
"ArrayInitialize" cuando el indicador no se asignado todavia.
El indicador "array" se ejecuta
automáticamente durante la asignación de memoria.
EMPTY_VALUE, o el valor
especificado por SetIndexEmptyValue función, se utilizan como
valores de inicialización. Los valores "Empty" no se muestran.
9.-
La funcion "SetIndexLabel" establece el nombre y
datos que se motrara en la herramienta de sugerencias en la
ventajan junto con el valore correspondiente (el "ValueN" se
establece por defecto, donde N es el número de índice de la
matriz). Si se transfiere NULL en lugar de un nombre, el valor
correspondiente no se mostrará en la herramienta ni en la
ventana de datos
10.- La funcion "IndicatorCounted"
permite organizar el calculo econmico de un indicador. Esta
función devuelve la cantidad de barras en el momento del
lanzamiento anterior del indicador, es decir, la cantidad de
barras que ya han sido calculadas (potencialmente, si no hay
errores o terminación anticipada durante el lanzamiento), que no
es necesario ningún cálculo. Al reinicira el indicador o al
actualizar el historial, el calculo se reseteara automaticamente
volviendo a 0.
11.- Vamos a proponer
mas ejemplo. El indicador conocido como oscilador acelerador/decelerador.
|
//+------------------------------------------------------------------+
//|
Accelerator.mq4 |
//|
Copyright © 2005, MetaQuotes Software Corp. |
//|
http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes
Software Corp."
#property link "http://www.metaquotes.net/"
//---- indicator settings
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Black
#property indicator_color2 Green
#property indicator_color3 Red
//---- indicator buffers
double ExtBuffer0[];
double ExtBuffer1[];
double ExtBuffer2[];
double ExtBuffer3[];
double ExtBuffer4[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function
|
//+------------------------------------------------------------------+
int init()
{
//---- 2 additional buffers are used for counting.
IndicatorBuffers(5);
//---- drawing settings
SetIndexStyle(0,DRAW_NONE);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexStyle(2,DRAW_HISTOGRAM);
IndicatorDigits(Digits+2);
SetIndexDrawBegin(0,38);
SetIndexDrawBegin(1,38);
SetIndexDrawBegin(2,38);
//---- 4 indicator buffers mapping
SetIndexBuffer(0,ExtBuffer0);
SetIndexBuffer(1,ExtBuffer1);
SetIndexBuffer(2,ExtBuffer2);
SetIndexBuffer(3,ExtBuffer3);
SetIndexBuffer(4,ExtBuffer4);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("AC");
SetIndexLabel(1,NULL);
SetIndexLabel(2,NULL);
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Accelerator/Decelerator Oscillator
|
//+------------------------------------------------------------------+
int start()
{
int limit;
int counted_bars=IndicatorCounted();
double prev,current;
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
//---- macd counted in the 1-st additional buffer
for(int i=0; i<limit; i++)
ExtBuffer3[i]=iMA(NULL,0,5,0,MODE_SMA,PRICE_MEDIAN,i)-
iMA(NULL,0,34,0,MODE_SMA,PRICE_MEDIAN,i);
//---- signal line counted in the 2-nd additional buffer
for(i=0; i=0;
i--)
{
current=ExtBuffer3[i]-ExtBuffer4[i];
prev=ExtBuffer3[i+1]-ExtBuffer4[i+1];
if(current>prev) up=true;
if(current<prev) up=false;
if(!up)
{
ExtBuffer2[i]=current;
ExtBuffer1[i]=0.0;
}
else
{
ExtBuffer1[i]=current;
ExtBuffer2[i]=0.0;
}
ExtBuffer0[i]=current;
}
//---- done
return(0);
}
//+------------------------------------------------------------------+
|
12.-
La Función "IndicatorBuffers" especifica la cantidad de
buffers que utilizara el indicador en sus cálculos. Esta
función se suele usar si se utilizan mas matrices de lo que
es necesario para establecer un indicador.
13.- La función "SetIndexDigits"
gestiona la precisión de la información de salida. En este
caso, cuando la diferencia entre dos medias móviles, así
como la mayor diferencia entre el resultado de señal del
calculo de la línea, el nivel de precisión dentro de 4
caracteres después del punto es obviamente insuficiente.
14.- La función "SetIndexDrawBegin"
especifica los elementos de los datos del indicador con el
que comenzara la serie. En el ejemplo, la línea de señal se
calcula como la media móvil simple de otra media móvil
simple. Esta es la razón por la primera 38 valores del
indicador se consideran vacíos y no se dibujan.
15.- La función "IndicatorShortName"
establece una llamada al nombre corto del indicador que se
mostrará en la esquina superior izquierda de la ventana y el
indicador de "DataWindow". En el caso que el nombre corto no
se haya establecido, se utilizara el nombre utilizado
anteriormente. En el ejemplo anterior, no hay necesidad de
utilizar la función SetIndexLabel, porque sólo es un valor
de salida. Por lo tanto, el nombre del indicador es
suficiente para la salida de un único valor.
16.- La función "SetIndexStyle"
gestiona los parámetros de la matriz del indicador. El modo
de dibujo de DRAW_NONE significa que la línea no necesita
ser extraída. La cuestión es que histograma del
indicador debe ser presentado en 2 colores diferentes
colores. Datos de ExtBuffer0 son asignados en otras dos
matrices, ExtBuffer1 y ExtBuffer2. Con el fin de no duplicar
los datos de salida en la herramienta de sugerencias o en la
ventana de datos, No se usan ningún parámetro de los que
tenga la función SetIndexLabel .
17.-
La entrada de parámetros utilizados para el calculo de los
indicadores personalizados y funciones deben ser definidos
como "externos" y puede ser de cualquier tipo.
18.- Si no se
establece los parámetros de entrada del indicador este usara
el formato mas simple.
|
double current_AC = iCustom( NULL, 0,
"Accelerator", 0, 0 );
|
Los dos primeros valores "NULL"
и "0" significa que la actual tabla se utilizará. El nombre del
archivo correspondiente (sin extensión de mq4) se utiliza como
indicador de nombre del indicador. Si el último parámetro es 0,
significa que estamos interesados en los datos desde el primer
indicador de la matriz. El último parámetro 0 significa
que estamos interesados en el valor del último elemento (es
decir, la más reciente, valor actual) de los indicadores
solicitados de la matriz.
19.- Los parámetros
son transferidos en la función del calculo del indicador en
el orden en que se han descrito. Por ejemplo, el indicador
denominado "Ichimoku" y que tengan parámetros de (9,26,52)
se llamará de la siguiente manera:
|
iCustom( NULL, 0, "Ichimoku", 9, 26,
52, 0, shift );
|
Estrictamente hablando, los
parámetros del indicador de los parámetros no necesitan ser
necesariamente transferidos a la función. Si no hay una variable
externa definida en el programa, es inútil trasnferir
parámetros. O si fuera necesario, valores iniciales pueden ser
utilizados en la descripción de los parámetros. Por
ejemplo, el mismo indicador sin parámetros se llamará de
la siguiente manera:
|
iCustom( NULL, 0, "Ichimoku", 0,
shift );
|
Se refiere a los valores que
se utilizarán para inicializar las variables "Tenkan", "Kijun",
"Senkou", es decir, 9, 26, y 52. Sin embargo, si un indicador
personalizado con diferentes conjuntos de parámetros se llama en
un Robot (expert advisor), la configuración por defecto no es
nada recomendable.
Es impórtate saber que la
acumulación de indicadores así como la utilización de
errores en su escritura puede provocar un relantecimiento
del terminal MT4.
|
|
|