Problema no código do indicar

 
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

input int    AP1 = 5;         // ATR Period (Fast)
input double AF1 = 0.5;       // ATR Multiplier (Fast)
input int    AP2 = 10;        // ATR Period (Slow)
input double AF2 = 2.0;       // ATR Multiplier (Slow)
input bool   plot_color = true; // Paint color on chart
input bool   plot_buy_sell = true; // Plot Buy/Sell arrows

double Trail1Buffer[];
double Trail2Buffer[];
double BuySellBuffer[];

int OnInit()
{
    SetIndexBuffer(0, Trail1Buffer);
    SetIndexBuffer(1, Trail2Buffer);
    SetIndexBuffer(2, BuySellBuffer);
    IndicatorSetString(INDICATOR_SHORTNAME, "CDC ATR Trailing Stop 2.1");

    // Define as cores para os plots
    PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrBlue); // Cor para o plot Trail1
    PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrRed);  // Cor para o plot Trail2
    PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrNONE); // Cor para o plot BuySell (clrNONE significa que ele não será colorido)

    return(INIT_SUCCEEDED);
}

double CustomSMA(int period, const double &price[], int start)
{
    double sum = 0;
    for (int i = start; i < start + period; i++)
    {
        sum += price[i];
    }
    return sum / period;
}

double CalculateATR(int period, const double &price[], int start)
{
    double sum = 0;
    for (int i = start; i < start + period; i++)
    {
        double high = iHigh(Symbol(), Period(), i);
        double low = iLow(Symbol(), Period(), i);
        double close = iClose(Symbol(), Period(), i);
        double tr = MathMax(high - low, MathMax(MathAbs(high - close), MathAbs(low - close)));
        sum += tr;
    }
    return sum / period;
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
    int limit = MathMin(rates_total, prev_calculated);
    if (limit <= 0)
        return (0);

    double SL1, SL2; // Declaração das variáveis SL1 e SL2

    for (int i = limit - 1; i >= 0; i--)
    {
        if (i - AP1 < 0 || i - AP2 < 0)
            continue;  // Pule o cálculo se estivermos fora do alcance

        SL1 = AF1 * CalculateATR(AP1, price, i);
        SL2 = AF2 * CalculateATR(AP2, price, i);

        Trail1Buffer[i] = (CustomSMA(AP1, price, i) > CustomSMA(AP2, price, i + 1)) ? 
                           MathMax(Trail1Buffer[i + 1], price[i] - SL1) : 
                           MathMin(Trail1Buffer[i + 1], price[i] + SL1);

        Trail2Buffer[i] = (CustomSMA(AP1, price, i) > CustomSMA(AP2, price, i + 1)) ? 
                           MathMax(Trail2Buffer[i + 1], price[i] - SL2) : 
                           MathMin(Trail2Buffer[i + 1], price[i] + SL2);

        BuySellBuffer[i] = 0;
        if (plot_color)
        {
            if (Trail1Buffer[i] > Trail2Buffer[i] && Trail1Buffer[i + 1] <= Trail2Buffer[i + 1])
                BuySellBuffer[i] = 1;
            else if (Trail1Buffer[i] < Trail2Buffer[i] && Trail1Buffer[i + 1] >= Trail2Buffer[i + 1])
                BuySellBuffer[i] = -1;
        }
    }

    return (rates_total);
}

O código compila sem erros e nenhum erro aparece na aba experts, porém n aparece nd no gráfico, alguém sabe dizer o pq?

 
Por favor não criar tópicos aleatoriamente sem ter em conta a secção adequada. O seu tópico foi movido para a secção: Indicadores técnicos
 
Maike Oliveira:

O código compila sem erros e nenhum erro aparece na aba experts, porém n aparece nd no gráfico, alguém sabe dizer o pq?

Sim, faz um teste de mesa nas tres primeiras linhas do OnCalculate que vai entender.

 
Ricardo Rodrigues Lucca #:

Sim, faz um teste de mesa nas tres primeiras linhas do OnCalculate que vai entender.

Dei uma alterado no código e fiz alguns testes para saber se os dados estão sendo pegos corretamente, as funções iHigh, iLow e iClose tem resultados estranhos. Exemplo


  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48099: High =108.606, Low =108.539, Close =108.584
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48100: High =0.0, Low =0.0, Close =0.0
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48101: High =0.0, Low =0.0, Close =0.0
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48102: High =0.0, Low =0.0, Close =0.0
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48103: High =0.0, Low =0.0, Close =0.0
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48099: High =108.606, Low =108.539, Close =108.584

  • Esses são os dados q vem das funções, as vezes ele pega, mas na maiorias das vezes os dados vem zerados, o indicador não consegue realizar o calculo dessa maneira. Vou deixar o codigo atual aqui se alguém conseguir entender o pq isso está acontecendo e como resolver.

  • #property indicator_chart_window
    #property indicator_buffers 3
    #property indicator_plots   3
    
    input int    AP1 = 5;         // ATR Period (Fast)
    input double AF1 = 0.5;       // ATR Multiplier (Fast)
    input int    AP2 = 10;        // ATR Period (Slow)
    input double AF2 = 2.0;       // ATR Multiplier (Slow)
    input bool   plot_color = true; // Paint color on chart
    input bool   plot_buy_sell = true; // Plot Buy/Sell arrows
    
    double Trail1Buffer[];
    double Trail2Buffer[];
    double BuySellBuffer[];
    
    int OnInit()
    {
        SetIndexBuffer(0, Trail1Buffer);
        SetIndexBuffer(1, Trail2Buffer);
        SetIndexBuffer(2, BuySellBuffer);
        IndicatorSetString(INDICATOR_SHORTNAME, "CDC ATR Trailing Stop 2.1");
    
        // Define as cores para os plots
        PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrBlue); // Cor para o plot Trail1
        PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrRed);  // Cor para o plot Trail2
        PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrNONE); // Cor para o plot BuySell (clrNONE significa que ele não será colorido)
    
        return(INIT_SUCCEEDED);
    }
    
    double CustomSMA(int period, const double &price[], int start)
    {
        double sum = 0;
        for (int i = start; i < start + period; i++)
        {
            sum += price[i];
        }
        return sum / period;
    }
    
    double CalculateATR(int period, const double &price[], int start)
    {
        double sum = 0;
        for (int i = start; i < start + period; i++)
        {
            double high = iHigh(Symbol(), Period(), i);
            double low = iLow(Symbol(), Period(), i);
            double close = iClose(Symbol(), Period(), i);
    
            // Adicione estas linhas para imprimir os valores
            Print("Barra ", i, ": High =", high, ", Low =", low, ", Close =", close);
    
            double tr = MathMax(high - low, MathMax(MathAbs(high - close), MathAbs(low - close)));
            sum += tr;
        }
        return sum / period;
    }
    
    int OnCalculate(const int rates_total,
                    const int prev_calculated,
                    const int begin,
                    const double &price[])
    {
        if (rates_total <= 0)
        {
            Print("Não há dados suficientes para calcular o indicador.");
            return (0);
        }
    
        int limit = MathMin(rates_total, prev_calculated);
    
        double SL1, SL2; // Declaração das variáveis SL1 e SL2
    
        for (int i = limit - 1; i >= 0; i--)
        {
            if (i - AP1 < 0 || i - AP2 < 0)
                continue;  // Pule o cálculo se estivermos fora do alcance
    
            SL1 = AF1 * CalculateATR(AP1, price, i);
            SL2 = AF2 * CalculateATR(AP2, price, i);
    
            if (i < ArraySize(Trail1Buffer))
            {
                Trail1Buffer[i] = (CustomSMA(AP1, price, i) > CustomSMA(AP2, price, i + 1)) ?
                                   MathMax(Trail1Buffer[i + 1], price[i] - SL1) :
                                   MathMin(Trail1Buffer[i + 1], price[i] + SL1);
            }
    
            if (i < ArraySize(Trail2Buffer))
            {
                Trail2Buffer[i] = (CustomSMA(AP1, price, i) > CustomSMA(AP2, price, i + 1)) ?
                                   MathMax(Trail2Buffer[i + 1], price[i] - SL2) :
                                   MathMin(Trail2Buffer[i + 1], price[i] + SL2);
            }
    
            if (i < ArraySize(BuySellBuffer))
            {
                BuySellBuffer[i] = 0;
                if (plot_color)
                {
                    if (Trail1Buffer[i] > Trail2Buffer[i] && Trail1Buffer[i + 1] <= Trail2Buffer[i + 1])
                        BuySellBuffer[i] = 1;
                    else if (Trail1Buffer[i] < Trail2Buffer[i] && Trail1Buffer[i + 1] >= Trail2Buffer[i + 1])
                        BuySellBuffer[i] = -1;
                }
            }
        }
    
        return (rates_total);
    }
    
 
Maike Oliveira #:

Dei uma alterado no código e fiz alguns testes para saber se os dados estão sendo pegos corretamente, as funções iHigh, iLow e iClose tem resultados estranhos. Exemplo


  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48099: High =108.606, Low =108.539, Close =108.584

  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48100: High =0.0, Low =0.0, Close =0.0
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48101: High =0.0, Low =0.0, Close =0.0
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48102: High =0.0, Low =0.0, Close =0.0
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48103: High =0.0, Low =0.0, Close =0.0
  • 2023.09.15 00:15:01.850 CDC ATR (USDJPY,M30) Barra 48099: High =108.606, Low =108.539, Close =108.584

  • Esses são os dados q vem das funções, as vezes ele pega, mas na maiorias das vezes os dados vem zerados, o indicador não consegue realizar o calculo dessa maneira. Vou deixar o codigo atual aqui se alguém conseguir entender o pq isso está acontecendo e como resolver.



Olha so, no primeiro codigo seu problema era a linha "int limit = MathMin...." que ele sempre saia no proximo IF por ser sempre zero o previous_rate. Agora, nesse codigo a primeira execucao ele nao faz nada e no proximo tick ele recebe o nessa variavel limit, provavelmente, o mesmo valor de rates_total e dai tu comecaria a andar da vela mais recente ate a ultima que quase nao tem negocio. Logo, voce esta na penultima vela quando faz o calculo de ATR e o calculo do ATR anda pra frente de 5 a 10 velas. Entendeu?

Vamos revisar, voce esta na penultima vela e acessa a ultima vela e depois acessa quatro velas futuras que nao tem valor (zero). No seu calculo do ATR para corraborar com o seu OnCalculate ele deve ir na mesma direcao - isto eh - para tras. O mesmo erro esta naquela CustomSMA. Talvez o mais facil seria alterar o for do OnCalculate invertendo o for para algo assim

//for (int i = limit - 1; i >= 0; i--)
for (int i = MathMax(0,limit - 1); i+1 < rates_total; i++)
{
    if (rates_total - i <= MathMax(AP1, AP2))
        continue;  // Pule o cálculo se estivermos fora do alcance

...
}

Dessa forma, voce inicia a execucao quando o limit eh negativo em zero e voce ainda nao faz a ultima vela por conta do i+1.