Lógica de aprendizaje - página 4

 

Aquí está la función original start() de este indicador

int start()
{
   int limit;
   double a;
   int counted_bars = IndicatorCounted();
   if(counted_bars < 0) return(-1);
   if(counted_bars > 0) counted_bars--;
   limit = Bars - counted_bars;
   for(int i = 0; i < limit; i++)
    {
      for(int j = 0; j < nPeriod; j++)
       {
         a = a + (iHigh(NULL, 0, i + j) + iLow(NULL, 0, i + j) + iClose(NULL, 0, i + j) * 2) / 4;
       }       
      MaBuffer[i]  =  a / nPeriod;
      a = 0;
      if(iClose(NULL, 0, i) > MaBuffer[i])
       {
         MaTUp[i] = MaBuffer[i] + iATR(NULL, 0, nPeriod, i) * Deviation;
         MaTDn[i] = MaBuffer[i] - iATR(NULL, 0, nPeriod, i);
       }  
      else if(iClose(NULL, 0, i) < MaBuffer[i])
       {
         MaTDn[i] = MaBuffer[i] - iATR(NULL, 0, nPeriod, i) * Deviation;
         MaTUp[i] = MaBuffer[i] + iATR(NULL, 0, nPeriod, i);
       } 
      else if(iClose(NULL, 0, i) == MaBuffer[i])
       {
         MaTDn[i] = MaBuffer[i] - iATR(NULL, 0, nPeriod, i) * Deviation;
         MaTUp[i] = MaBuffer[i] + iATR(NULL, 0, nPeriod, i) * Deviation;
       }  
    }  
   //-----
   return(0);
}

La función utiliza el cálculo de la media. Hay que sustituirla por una función estándar.

Se ve así

//=================================================================================================
// Замена расчета среднего на стандартную функцию
//=================================================================================================
//   Старый вариант расчета
//      for(int j = 0; j < nPeriod; j++)
//       {
//         a = a + (iHigh(NULL, 0, i + j) + iLow(NULL, 0, i + j) + iClose(NULL, 0, i + j) * 2) / 4;
//       }       
//      MaBuffer[i]  =  a / nPeriod;
//      a = 0;
//=================================================================================================
//   Новый вариант расчета

      MaBuffer[i]=iMA(NULL, 0, nPeriod, 0,MODE_SMA,PRICE_WEIGHTED,i);
//=================================================================================================

Se adjunta la variante del indicador con la corrección

Archivos adjuntos:
 

Ahora pasemos a la lógica del indicador en sí (no digo que la versión propuesta sea la ideal)

Simplemente me gusta más

      // Вариант два. Убираем избыточные условия  и делаем одно обращение к функции
      
      atr=iATR(NULL, 0, nPeriod, i);
      MaTDn[i] = MaBuffer[i] - atr * Deviation;
      MaTUp[i] = MaBuffer[i] + atr * Deviation;

      if(iClose(NULL, 0, i) > MaBuffer[i])
       {
         MaTDn[i] = MaBuffer[i] - atr;
       }  
      else if(iClose(NULL, 0, i) < MaBuffer[i])
       {
         MaTUp[i] = MaBuffer[i] + atr;
       } 
Archivos adjuntos:
 
Ese es un buen ejemplo. Sólo que se trata más de optimización que de lógica.
 
denis_orlov:
Un buen ejemplo. Pero se trata más de la optimización que de la lógica.


Y la lógica también, la lógica del pensamiento.

La tercera opción es abandonar por completo las condiciones lógicas del indicador. La pregunta que se plantea es si es posible.

Intentemos

Para ello vamos a añadir un par de variables lógicas

El código completo de la función de inicio ahora es

int start()
{
   int limit;
   double atr;
   bool bUP, bDN;
   int counted_bars = IndicatorCounted();
   if(counted_bars < 0) return(-1);
   if(counted_bars > 0) counted_bars--;
   limit = Bars - counted_bars;
   for(int i = 0; i < limit; i++)
    {

      MaBuffer[i]=iMA(NULL, 0, nPeriod, 0,MODE_SMA,PRICE_WEIGHTED,i);

      // Вариант три. 
      
      atr=iATR(NULL, 0, nPeriod, i);
      bUP=Close[i] < MaBuffer[i];
      bDN=Close[i] > MaBuffer[i];
      MaTDn[i] = MaBuffer[i] - atr - atr * (Deviation - 1.0) * bUP;
      MaTUp[i] = MaBuffer[i] + atr + atr * (Deviation - 1.0) * bDN;

    }  
   //-----
   return(0);
}
Archivos adjuntos:
 

if(counted_bars < 0) return(-1);

¿En qué lógica se basa esta línea?

 
Roger:

if(counted_bars < 0) return(-1);

¿En qué lógica se basa esta línea?


No es mi línea. Es el autor de

Código óptimo para start()

int start()
{
   int limit;
   double atr;
   int counted_bars = IndicatorCounted();
   
   limit = Bars - counted_bars-1;
   if(Bars - counted_bars > 2) limit = Bars - nPeriod-1;

   for(int i = limit; i >=0; i--)
    {
      MaBuffer[i]=iMA(NULL, 0, nPeriod, 0,MODE_SMA,PRICE_WEIGHTED,i);
      atr=iATR(NULL, 0, nPeriod, i);

      MaTDn[i] = MaBuffer[i] - iATR(NULL, 0, nPeriod, i) * Deviation;
      MaTUp[i] = MaBuffer[i] + iATR(NULL, 0, nPeriod, i) * Deviation;

      if(iClose(NULL, 0, i) > MaBuffer[i])
       {
         MaTDn[i] = MaBuffer[i] - iATR(NULL, 0, nPeriod, i);
       }  
      else if(iClose(NULL, 0, i) < MaBuffer[i])
       {
         MaTUp[i] = MaBuffer[i] + iATR(NULL, 0, nPeriod, i);
       } 

    }  
   //-----
   return(0);
}
Archivos adjuntos:
 

Análisis comparativo de las opciones de trabajo

Opción óptima número 2. Las condiciones booleanas no se pueden descartar

La opción 5 se basa en ella

Archivos adjuntos:
 

Se olvidó del guión

Archivos adjuntos:
 
Vinin:

Se olvidó del guión

método ingenioso, lo acepto ))
 
Mathemat:

Me gustaría añadir algo sobre la sección criticada por gip:


No entiendo por qué tenemos que bailar alrededor de las variables booleanas cuando podemos escribirlo de esta manera:

   showEUR  = ( StringFind(Symbol(), "EUR", 0) != -1);
   showUSD  = ( StringFind(Symbol(), "USD", 0) != -1);
   showGBP  = ( StringFind(Symbol(), "GBP", 0) != -1);
   showCHF  = ( StringFind(Symbol(), "CHF", 0) != -1);
   showJPY  = ( StringFind(Symbol(), "JPY", 0) != -1);