Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 531

 
Vitaly Muzichenko:

Compare a próxima barra, e se a seqüência for quebrada, reinicialize a bandeira e registre quantos estavam corretos, e continue no loop.

É suficiente descobrir que a barra está em alta e a próxima está em baixa, a próxima, se for a mesma que a anterior, você anota o valor e zera a bandeira. E assim por diante até o final.

Mas o primeiro pode não ser ousado.

   for(int i=limit-1; i>0; i--)

     {


      if(open[i]<close[i]&&open[i+1]>close[i+1]&&open[i+3]<close[i+3])

        {

         up++;

        }

      else up=0;

    
    
if(max_c<up)max_c=up;

Comment(max_c);
}

//--- return value of prev_calculated for next call

   return(rates_total);

  }

 
PolarSeaman:

mas o primeiro pode não ser um touro, mas não há como.

Aqui está uma variante, embora não muito correta, sempre contando de uma vela de baixa

Arquivos anexados:
aCandle.mq4  8 kb
 
Vitaly Muzichenko:

Aqui está uma variante, embora não muito correta, sempre contando de uma vela de baixa

Obrigado. Se você ajustar este número e adicionar um, o resultado é correto.

É verificado se(i%2==0)?
 
PolarSeaman:

mas o primeiro pode não ser um touro, nem pensar.


Aqui está um exemplo de encontrar as mesmas velas e mudar a direção da corrente:

//+------------------------------------------------------------------+
//|                                              CandlesSequence.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot Sequence
#property indicator_label1  "Sequence"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  clrGreen,clrRed,clrGray
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- enums
enum ENUM_CANDLE_TYPE
  {
   CANDLE_TYPE_BULL  =  0,       // Bullish candle
   CANDLE_TYPE_BEAR  =  1,       // Bearish candle
   CANDLE_TYPE_DOJI  = -1        // Doji candle
  };
//--- indicator buffers
double         BufferSeq[];
double         BufferSeqColors[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferSeq,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSeqColors,INDICATOR_COLOR_INDEX);
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"Candles sequence");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferSeq,true);
   ArraySetAsSeries(BufferSeqColors,true);
//---
   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[])
  {
//--- Проверка на минимальное колиество баров для расчёта
   if(rates_total<2) return 0;
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   ENUM_CANDLE_TYPE type_refs=CANDLE_TYPE_DOJI;
   ENUM_CANDLE_TYPE type_curr=CANDLE_TYPE_DOJI;
//--- Проверка и расчёт количества просчитываемых баров   
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-2;
      ArrayInitialize(BufferSeq,EMPTY_VALUE);
      BufferSeq[rates_total-1]=open[rates_total-1];
     }
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      type_refs=GetTypeCandle(i+1,open,close);
      type_curr=GetTypeCandle(i,open,close);
   //--- смена направления цепочки свечей
      if(!CheckCandle(type_refs,type_curr))
        {
         BufferSeq[i]=(type_curr==CANDLE_TYPE_BULL ? low[i]: type_curr==CANDLE_TYPE_BEAR ? high[i]: open[i]);
        }
   //--- свечи одного типа
      else
        {
         BufferSeq[i]=BufferSeq[i+1];
        }
      BufferSeqColors[i]=(type_curr==CANDLE_TYPE_BULL ? 0 : type_curr==CANDLE_TYPE_BEAR ? 1 : 2);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Возвращает тип свечи                                             |
//+------------------------------------------------------------------+
ENUM_CANDLE_TYPE GetTypeCandle(const int shift,const double &open[],const double &close[])
  {
   return(close[shift]>open[shift] ? CANDLE_TYPE_BULL : close[shift]<open[shift] ? CANDLE_TYPE_BEAR : CANDLE_TYPE_DOJI);
  }
//+------------------------------------------------------------------+
//| Сравнивает два типа свечей                                       |
//+------------------------------------------------------------------+
bool CheckCandle(const ENUM_CANDLE_TYPE reference_candle_type,const ENUM_CANDLE_TYPE checked_candle_type)
  {
   return(reference_candle_type==checked_candle_type ? true : false);
  }
//+------------------------------------------------------------------+

Agora onde a corrente continua, você pode contar o número de velas na corrente e salvar em uma lista, e onde a corrente muda para uma nova, iniciar uma nova contagem.

O número de velas em cada cadeia pode ser armazenado em uma lista ordenada. Então, ordenando a lista, é possível encontrar as seqüências máxima e mínima.

 
PolarSeaman:

Obrigado. Se o número obtido for ao quadrado e um for adicionado, o resultado é correto.

É isso que estamos verificando se(i%2==0)?

Se eu for um múltiplo de dois.

É o restante de i dividido por 2

 
Juer:

Aqui o tamanho das variáveis locais é muito grande (mais de 512kb) durante a compilação.

Onde procurar e o que fazer? Há um conjunto de fios CArrayString na função, eu suspeito que possa ser um erro.

Eu o preencho usando o método Add(), depois faço Clear( ) e Shutdown() novamente. E então eu o preencho novamente com novos dados usando o método Add(). Neste caso, a matriz será preenchida com zero itens novamente?

Temos que remover tais membros das classes que já ocupam memória na fase de compilação. Estes dados serão alocados na memória da pilha, que é sempre muito pequena. A solução para este problema é alocar memória para os membros da classe que ocupam muita memória de forma dinâmica.

Por exemplo, se houver um membro da classe:

class A
{
   double m_arrfArray[9999999];
};

deve ser substituído por:

class A
{
   double m_arrfMyArray[];
};

bool A::Init()
{
   if (ArrayResize(m_arrfMyArray, 9999999) != 9999999)
      return false;
   ....
}
 
Ihor Herasko:

Precisamos remover das classes os membros que já ocupam memória na fase de compilação. Estes dados serão colocados na memória da pilha, que é sempre muito pequena. A solução para este problema é alocar memória para os membros da classe que ocupam muita memória de forma dinâmica.

Por exemplo, se houver um membro da classe:

então deve ser substituído por:

Obrigado. De alguma forma eu me livrei deste problema removendo a classe dos parâmetros em cada função. Em geral, foi possível rubricar este objeto de uma vez por todas.

Tenho outra pergunta sobre a classe CArray, mais especificamente sobre o CArrayObj. Existe um método Delete(), mas ele não move o elemento da matriz? Isto é, eu apago Delete(18), ele remove um item nesta posição e mais tarde, se eu quiser consultar o item por este índice, eu recebo um ponteiro inválido. Existe tal método que apague e mova elementos para que, neste caso, o 18º elemento seja o 19º após a eliminação?

 
Juer:

Obrigado. De alguma forma eu me livrei deste problema removendo a classe dos parâmetros em cada uma das funções. Em geral, foi possível inicializar este objeto de uma vez por todas.

Tenho outra pergunta sobre a classe CArray, mais especificamente sobre o CArrayObj. Existe um método Delete(), mas ele não move um elemento da matriz? Isto é, eu apago Delete(18), ele remove um item nesta posição e mais tarde, se eu quiser consultar o item por este índice, eu recebo um ponteiro inválido. Existe tal método que apague e mova itens para que o 18º item seja o 19º após a eliminação?

Eu não trabalhei com a biblioteca padrão, mas de acordo com a ajuda, o método Delete() deve remover fisicamente o elemento, mudando o tamanho da matriz. Exceção: se o mecanismo de gerenciamento de memória estiver desativado. Por padrão, este mecanismo é ativado. O método FreeMode é usado para verificar o estado da bandeira de gerenciamento de memória.

De minha parte, eu recomendaria usar minhas próprias matrizes em MQL (embora em C++ eu mesmo use vetores e listas) e gerenciamento de memória, porque não vejo nenhuma conveniência ou vantagem particular na classe CArray. Eu excluo itens de matriz em minhas próprias matrizes muito rapidamente usando este método:

template<typename Array>
bool DeleteArrayElement(Array &array[], int nIndex)
{
   int nArraySize = ArraySize(array);
   if (nIndex < 0 || nIndex >= nArraySize)
      return true;
   
   array[nIndex] = array[nArraySize - 1];
   return (ArrayResize(array, nArraySize - 1, ARRAY_RESERVE_SIZE) == nArraySize - 1);
}

Sua única desvantagem é que não mantém a seqüência de itens de matriz. Ou seja, ele pode ser aplicado a todas as matrizes, exceto as ordenadas (ordenadas).

 

Olá, você poderia me dizer onde posso encontrar um roteiro que me permita colocar pedidos pendentes de compra e venda na MT4 de uma vez por um certo número de pips do preço atual, ou seja, não contar manualmente e talvez nem mesmo entrar na janela de pedidos? Não quero ir para a janela do pedido. Obrigado.

PS: talvez eu esteja perguntando algo errado, eu nunca usei scripts antes.

 

Por favor, explique-me o ponto -"Ordens de mercado não podem ser fechadas se seus valores StopLoss ou TakeProfit violarem o parâmetro FreezeLevel".

Isto significa literalmente que uma ordem de mercado não pode ser fechada se seu TakeProfit ou StopLoss não atingir o nível FreezeLevel? Eu simplesmente não entendo bem como uma ordem de mercado aberto pode ter paradas que violam as regras do StopLevel ou FreezeLevel? Afinal de contas, se as paradas erradas forem definidas, o servidor apenas dará um erro e nenhuma parada será definida.

Além disso, por favor, informe o que mais precisamos saber ao fechar uma ordem de mercado, quando um corretor utiliza o FreezeLevel?

Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
  • book.mql4.com
В таблицах указаны расчётные значения, ограничивающие проведение торговых операций при открытии, закрытии, установке, удалении и модификации ордеров. Для получения значения минимальной дистанции StopLevel и дистанции заморозки FreezeLevel необходимо вызвать функцию MarketInfo(). Требования. Правильные цены, используемые при осуществлении...
Razão: