Lógica Difusa con Indicador

14
EJEMPLO SIMPLE DE CREACIÓN DE UN INDICADOR USANDO LA LÓGICA DIFUSA Introducción El uso de distintos métodos en el análisis de los mercados financieros se está haciendo cada vez más popular entre los operadores en los últimos años. Me gustaría realizar mi aportación y mostrar cómo realizar un buen indicador escribiendo un par de docenas de líneas de código. También le mostraré brevemente los fundamentos de la lógica difusa. Cualquiera que esté interesado en este tema y quiera explorarlo en mayor profundidad puede leer los siguientes trabajos: 1. Leonenkov А . " Fuzzy Simulation in MATLAB and fuzzyTECH " (en ruso). 2. Bocharnikov V." Fuzzy Technology: Mathematical Background. Simulation Practice in Economics " (en ruso). 3. S.N. Sivanandam, S. Sumathi, S.N. Deepa. Introduction to Fuzzy Logic using MATLAB. 4. C. Kahraman. Fuzzy Engineering Economics with Applications (Studies in Fuzziness and Soft Computing). 1. Fundamentos de la lógica difusa ¿Cómo podemos explicar a nuestras máquinas informáticas los significados de las expresiones simples "..un poco más", "...demasiado rápido" o "...casi nada..."? De hecho, esto puede hacerse usando los elementos de la teoría de conjuntos difusos o las llamadas "funciones de afiliación". Este es un ejemplo del libro de A. Leonenkov: Vamos a describir la función de afiliación para la frase "café caliente": la temperatura del café se estimará en el rango de 0 a 100 grados centígrados por la simple razón de que a temperaturas inferiores a 0 grados se convertirá en hielo, mientras que a temperaturas por encima de los 100 grados centígrados se evaporará. Es bastante obvio que de una taza de café con una temperatura de 20 grados centígrados no puede decirse que esté caliente, es decir, la función de afiliación en la categoría "caliente" es igual a 0, mientras que una taza de café con una temperatura de 70 grados centígrados pertenece definitivamente a la categoría "caliente" y, por tanto, el valor de la función se iguala a 1 en este caso. Por lo que respecta a los valores de la temperatura que se sitúan entre estos dos valores extremos, la situación no es tan clara. Algunas personas pueden considerar que una taza de café con una temperatura de 55

description

Ejemplo Simple de Creación de Un Indicador Usando La Lógica Difusa

Transcript of Lógica Difusa con Indicador

Page 1: Lógica Difusa con Indicador

EJEMPLO SIMPLE DE CREACIÓN DE UN INDICADOR USANDO LA LÓGICA DIFUSA

IntroducciónEl uso de distintos métodos en el análisis de los mercados financieros se está haciendo cada vez más popular entre los operadores en los últimos años. Me gustaría realizar mi aportación y mostrar cómo realizar un buen indicador escribiendo un par de docenas de líneas de código. También le mostraré brevemente los fundamentos de la lógica difusa.

Cualquiera que esté interesado en este tema y quiera explorarlo en mayor profundidad puede leer los siguientes trabajos:

1.  Leonenkov А. "Fuzzy Simulation in MATLAB and fuzzyTECH" (en ruso).2.  Bocharnikov V."Fuzzy Technology: Mathematical Background. Simulation Practice in Economics" (en ruso).3.  S.N. Sivanandam, S. Sumathi, S.N. Deepa. Introduction to Fuzzy Logic using MATLAB.4.  C. Kahraman. Fuzzy Engineering Economics with Applications (Studies in Fuzziness and Soft Computing).

1. Fundamentos de la lógica difusa¿Cómo podemos explicar a nuestras máquinas informáticas los significados de las expresiones simples "..un poco más", "...demasiado rápido" o "...casi nada..."? De hecho, esto puede hacerse usando los elementos de la teoría de conjuntos difusos o las llamadas "funciones de afiliación". Este es un ejemplo del libro de A. Leonenkov: 

Vamos a describir la función de afiliación para la frase "café caliente": la temperatura del café se estimará en el rango de 0 a 100 grados centígrados por la simple razón de que a temperaturas inferiores a 0 grados se convertirá en hielo, mientras que a temperaturas por encima de los 100 grados centígrados se evaporará. Es bastante obvio que de una taza de café con una temperatura de 20 grados centígrados no puede decirse que esté caliente, es decir, la función de afiliación en la categoría "caliente" es igual a 0, mientras que una taza de café con una temperatura de 70 grados centígrados pertenece definitivamente a la categoría "caliente" y, por tanto, el valor de la función se iguala a 1 en este caso.

Por lo que respecta a los valores de la temperatura que se sitúan entre estos dos valores extremos, la situación no es tan clara. Algunas personas pueden considerar que una taza de café con una temperatura de 55 grados está "caliente" mientras que otras pueden pensar que "no lo son tanto". Esto es "difusión".

No obstante, podemos imaginar el aspecto aproximado de la función de afiliación: es "monótona creciente":

Page 2: Lógica Difusa con Indicador

La figura anterior muestra la función de afiliación "lineal por segmentos".

Por tanto, la función puede ser definida por la siguiente expresión analítica:

Usaremos tales funciones para nuestro indicador.

2. Función de afiliaciónDe una u otra forma, la tarea de cualquier indicador técnico es determinar el estado actual del mercado (plano, tendencia al alza, tendencia a la baja), así como la generación de señales de entrada/salida del mercado. ¿Cómo puede hacerse esto con la ayuda de las funciones de afiliación? Muy fácil.

En primer lugar necesitamos definir las condiciones límite. Supongamos que tenemos las siguientes condiciones límite: para "100% de tendencia al alza" será el cruce de EMA con un periodo 2, basado en el precio típico (H+L+C)/3 con el borde superior de Envelopes con los parámetros 8, 0.08 SMA, Close, mientras que para "100% de tendencia a la baja" será el cruce de la misma EMA con el borde inferior de Envelopes. Todo lo que está entre estas condiciones se asumirá que es plano. Vamos a añadir un envelope más con los parámetros 32, 0.15, SMA, Close. 

Como resultado obtendremos dos funciones de afiliación idénticas. La señal buy se activará cuando ambas funciones sean iguales a 1, mientras que la señal sell se activará cuando ambas funciones sean iguales a -1, respectivamente. Al ser conveniente construir gráficos con el rango de -1 a 1, el gráfico resultante se obtendrá como la media aritmética de dos funciones F(x)= (f1(x)+f2(x))/2.

Así es como aparece en el gráfico:

Page 3: Lógica Difusa con Indicador

En este caso la función de afiliación tendrá la siguiente representación gráfica:

Page 4: Lógica Difusa con Indicador

Analíticamente puede escribirse de la siguiente forma:

,

donde a y b son líneas envelope superiores e inferiores, respectivamente, mientras que x es un valor de EMA(2).

Con la función definida podemos ahora seguir escribiendo el código del indicador.

3. Crear el código del programaEn primer lugar, debemos definir qué y cómo vamos a dibujar.

Los resultados de los cálculos de la función de afiliación se mostrarán en pantalla como una línea roja y azul, respectivamente.

La media aritmética se mostrará en pantalla como un histograma de línea cero y en uno de los cinco colores en función del valor resultante de la función:

Para esto se usará el estilo de dibujo DRAW_COLOR_HISTOGRAM.

Vamos a dibujar los rectángulos azules y rojos como señales comprar/salir sobre las barras del histograma, los valores iguales a 1 o -1.

Es el momento de ejecutar MetaEditor y empezar. Nuevo -> Indicador personalizado -> Siguiente... Rellenamos el campo "Parámetros":

Page 5: Lógica Difusa con Indicador

 Creamos los buffers:

Page 6: Lógica Difusa con Indicador

Después de hacer clic en el botón "Finalizar" recibimos un código fuente y empezamos a mejorarlo.

Antes de nada vamos a definir el número de buffers. Siete de ellos ya fueron creados por el Wizard (5 para los datos y 2 para el color). Necesitamos 5 más:

#property indicator_minimum -1.4 // Setting fractional values

#property indicator_maximum 1.4  // Expert Advisors wizard ignores fractional parts for some reason

#property indicator_buffers 12   // Changing the value from 7 to 12 (5 more buffers have been added)

Vamos a editar los parámetros de entrada:

input string txt1="----------";

input int                  Period_Fast=8;

input ENUM_MA_METHOD        Method_Fast = MODE_SMA; /*Smoothing method*/ //moving average smoothing method

input ENUM_APPLIED_PRICE    Price_Fast  = PRICE_CLOSE;

input double               Dev_Fast=0.08;

input string txt2="----------";

input int                  Period_Slow=32;

input ENUM_MA_METHOD        Method_Slow = MODE_SMA;

input ENUM_APPLIED_PRICE    Price_Slow  = PRICE_CLOSE;

input double               Dev_Slow=0.15;  /*Deviation parameter*/

input string txt3="----------";

input int                  Period_Signal=2;

input ENUM_MA_METHOD        Method_Signal = MODE_EMA;

input ENUM_APPLIED_PRICE    Price_Signal  = PRICE_TYPICAL;

input string txt4="----------";

Los comentarios que siguen a las variables declaradas son prácticos. El texto de los comentarios es insertado en la ventana de parámetros del indicador.

La posibilidad de crear listas también es muy útil:

Page 7: Lógica Difusa con Indicador

Reservar las variables para los controladores del indicador y buffers:

int Envelopes_Fast;     // Fast envelope

int Envelopes_Slow;     // Slow envelope

int MA_Signal;          // Signal line

double Env_Fast_Up[];   // Fast envelope upper border

double Env_Fast_Dn[];   // Fast envelope lower border

double Env_Slow_Up[];   // Slow envelope upper border

double Env_Slow_Dn[];   // Slow envelope lower border

double Mov_Sign[];      // Signal line

Ahora nos vamos a la función OnInit().

Vamos a añadir algo: especificamos el nombre del indicador y eliminamos los ceros decimales adicionales:

IndicatorSetInteger(INDICATOR_DIGITS,1); // setting display accuracy, we do not need some outstanding accuracy values

string name;     // indicator name

StringConcatenate(name, "FLE ( ", Period_Fast, " , ", Dev_Fast, " | ", Period_Slow, " , ", Dev_Slow, " | ", Period_Signal, " )");

IndicatorSetString(INDICATOR_SHORTNAME,name);

Page 8: Lógica Difusa con Indicador

y añadimos los buffers:

SetIndexBuffer(7,Env_Fast_Up,INDICATOR_CALCULATIONS);

SetIndexBuffer(8,Env_Fast_Dn,INDICATOR_CALCULATIONS);

SetIndexBuffer(9,Env_Slow_Up,INDICATOR_CALCULATIONS);

SetIndexBuffer(10,Env_Slow_Dn,INDICATOR_CALCULATIONS);

SetIndexBuffer(11,Mov_Sign,INDICATOR_CALCULATIONS);

El parámetro INDICATOR_CALCULATIONS significa que el dato del buffer es necesario solo para los cálculos intermedios. No se muestran en el gráfico.

Observe cómo se declaran los indicadores con buffers de color:

SetIndexBuffer(4,SignalBuffer1,INDICATOR_DATA);     // All indicator buffers at first

SetIndexBuffer(5,SignalBuffer2,INDICATOR_DATA);     // as this is Color Histogram2, then it has 2 data buffers

SetIndexBuffer(6,SignalColors,INDICATOR_COLOR_INDEX);// the color buffer comes next.

Rellenando los controladores:

Envelopes_Fast = iEnvelopes(NULL,0,Period_Fast,0,Method_Fast,Price_Fast,Dev_Fast);

Envelopes_Slow = iEnvelopes(NULL,0,Period_Slow,0,Method_Slow,Price_Slow,Dev_Slow);

MA_Signal      = iMA(NULL,0,Period_Signal,0,Method_Signal,Price_Signal);

Todo el trabajo con la función OnInit() ha terminado.

Ahora vamos a crear la función que calculará el valor de la función de afiliación:

double Fuzzy(double x,double a, double c)

{

double F;

     if (a<x)          F=1;                // 100% uptrend

else if (x<=a && x>=c)  F=(1-2*(a-x)/(a-c));// Flat

else if (x<c)           F=-1;               // 100% downtrend

return (F);

}

Los preparativos han terminado. Se han declarado las variables y buffers y los controladores han sido asignados.

Ahora es el momento de trabajar con la función básica OnCalculate().

Page 9: Lógica Difusa con Indicador

En primer lugar, vamos a escribir los valores de los indicadores necesarios en los buffers intermedios. Usamos la función CopyBuffer().

CopyBuffer(Envelopes_Fast,  // Indicator handle

           UPPER_LINE,      // Indicator buffer

           0,              // The point to start 0 - from the very beginning

           rates_total,    // How many to be copied - All

           Env_Fast_Up);   // The buffer the values are written in

// - the rest are done in a similar way

CopyBuffer(Envelopes_Fast,LOWER_LINE,0,rates_total,Env_Fast_Dn);

CopyBuffer(Envelopes_Slow,UPPER_LINE,0,rates_total,Env_Slow_Up);

CopyBuffer(Envelopes_Slow,LOWER_LINE,0,rates_total,Env_Slow_Dn);

CopyBuffer(MA_Signal,0,0,rates_total,Mov_Sign);

 Aquí debemos añadir el código para la optimización de los cálculos (solo se realiza el recálculo de la última barra):

// declaring start variable for storing the index of the bar, recalculation of the indicator buffers will be

// carried out from.

int start;              

if (prev_calculated==0)  // in case no bars have been calculated

    {

    start = Period_Slow; // not all indicators have been calculated up to this value, therefore, there is no point in executing the code

    }

else start=prev_calculated-1;

for (int i=start;i<rates_total;i++)

      {

      // All remaining code will be written here

      }

No queda mucho del código.

Establecer los parámetros x, a y b, realizar los cálculos del valor de la función de afiliación y escribirlo en el buffer apropiado:

double x = Mov_Sign[i]; // Signal

Page 10: Lógica Difusa con Indicador

// Setting the first membership function parameters:

double a1 = Env_Fast_Up[i]; // Upper border

double b1 = Env_Fast_Dn[i];

// setting the first membership function value and writing it to the buffer

Rule1Buffer[i] = Fuzzy(x,a1,b1);

// Setting the second membership function parameters:

double a2 = Env_Slow_Up[i]; // Upper border

double b2 = Env_Slow_Dn[i];

// setting the second membership function value and writing it to the buffer

Rule2Buffer[i] = Fuzzy(x,a2,b2);

Se han construido dos líneas del indicador.

Ahora vamos a calcular el valor resultante.

ResultBuffer[i] = (Rule1Buffer[i]+Rule2Buffer[i])/2;

A continuación debemos dibujar las barras del histograma con los colores adecuados: como tenemos cinco colores, ResultColors[i] puede tener cualquier valor comprendido entre 0 y 4.

Generalmente, el número de colores posibles es de 64. Por tanto, es una gran oportunidad para aplicar las capacidades creativas de cada uno.

for (int ColorIndex=0;ColorIndex<=4;ColorIndex++)

    {

    if (MathAbs(ResultBuffer[i])>0.2*ColorIndex && MathAbs(ResultBuffer[i])<=0.2*(ColorIndex+1))

        {

        ResultColors[i] = ColorIndex;

        break;

        }

    }

A continuación debemos dibujar los rectángulos de la señal. Usaremos el estilo de dibujo DRAW_COLOR_HISTOGRAM2.

Tiene dos buffers de datos con una barra del histograma y un buffer de color construido entre ellos.

Los valores de los buffers de datos serán siempre los mismos: 1.1 y 1.3 para una señal buy, y -1.1 y -1.3 para una señal sell, respectivamente.

EMPTY_VALUE significará ausencia de señal..

Page 11: Lógica Difusa con Indicador

      if (ResultBuffer[i]==1)

        {

        SignalBuffer1[i]=1.1;

        SignalBuffer2[i]=1.3;

        SignalColors[i]=1;

        }

      else if (ResultBuffer[i]==-1)

        {

        SignalBuffer1[i]=-1.1;

        SignalBuffer2[i]=-1.3;

        SignalColors[i]=0;

        }

      else

        {

        SignalBuffer1[i]=EMPTY_VALUE;

        SignalBuffer2[i]=EMPTY_VALUE;

        SignalColors[i]=EMPTY_VALUE;

        }

Hacemos clic en "Compilar" y ¡voilá!

Page 12: Lógica Difusa con Indicador

Conclusión¿Qué más puede añadirse? En este artículo he tratado el enfoque más básico de la lógica difusa.

Es posible hacer aquí varios experimentos. Por ejemplo, podemos usar la siguiente función:

Page 13: Lógica Difusa con Indicador

Creo que no le será difícil escribir la expresión analítica para ella y encontrar las condiciones adecuadas.

¡Buena suerte!