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

 
Olá a todos.
Esta é minha primeira vez no fórum, se eu estiver fazendo algo errado no fórum, por favor, me perdoe com antecedência.
Estou olhando para gráficos com indicadores há muito tempo. Recentemente eu perdi 2 depósitos. Quero verificar a rentabilidade da estratégia sobre os dados históricos antes de abrir uma nova conta. Estou usando uma conta demo no MT4.
Não sou nada um programador. Só posso instalar o indicador no MT4 e talvez mudar a espessura da linha indicadora no MetaEditor (muito provavelmente não poderei mudar a cor no código indicador, somente no terminal).
Você tem alguma informação clara para alguém com meus conhecimentos, onde começar a testar passo a passo (em inglês simples "instruções para os negros como usar o banheiro")? A estratégia tem 3 indicadores: MA (3 simples), Stochastic com níveis padrão, e CCI com 5 níveis. Abertura de negócios curtos após cruzamento dos níveis de indicadores de cima para baixo, negócios longos vice-versa (acho que é claro...). Definição de tomada e perda.
Gostaria de poder acompanhar visualmente a estratégia em modo automático, bem como sem visualização, para selecionar parâmetros de indicadores e ordens.
 
ZebStamp:
Olá a todos.
Esta é minha primeira vez no fórum, se eu estiver fazendo algo errado no fórum, por favor, me perdoe com antecedência.
Estou olhando para gráficos com indicadores há muito tempo. Recentemente eu perdi 2 depósitos. Antes de abrir uma nova conta, quero verificar a rentabilidade da estratégia no histórico. Estou usando uma conta demo no MT4.
Não sou nada um programador. Só posso instalar o indicador no MT4 e talvez mudar a espessura da linha indicadora no MetaEditor (muito provavelmente não poderei mudar a cor no código indicador, somente no terminal).
Você tem alguma informação clara para alguém com meus conhecimentos, onde começar a testar passo a passo (em inglês simples "instruções para os negros como usar o banheiro")? A estratégia tem 3 indicadores: MA (3 simples), Stochastic com níveis padrão, e CCI com 5 níveis. Abertura de negócios curtos após cruzamento dos níveis de indicadores de cima para baixo, negócios longos vice-versa (acho que é claro...). Definição de tomada e perda.
Gostaria de poder acompanhar visualmente a estratégia em modo automático, bem como sem visualização para selecionar parâmetros de indicadores e ordens.

Ao criar um objeto gráfico (GO), como o TrendLine, você seleciona a cor. Quando você recria a TrendLine, ela é criada com a mesma cor. Para a Hline - você escolhe uma cor - e a próxima é como esta. Tomar amarelo, azul, ...

Se a CS cria o Expert Advisor, indicador, roteiro - então como você escreve no programa. Algumas vezes a escolha dos parâmetros

 
STARIJ:

Se você acha que alguém olhando para seu código pode encontrar rapidamente um erro, você está enganado. O compilador procura por erros. O texto do programa deve ser formatado - o MetaEditor tem uma ferramenta de estilo para isso. Se você gosta de um estilo diferente - use, por exemplo, o programa AStyle.exe. Depois de estilizar, você verá rapidamente que o programa 1) tem um parêntese de fechamento extra. 2) Variável declarada: datetime date_Buf_1; // matriz de data indicadora - para que esta seja uma matriz, ela deve ser [tamanho] ou [] para uma matriz dinâmica e então o tamanho deve ser definido como ArrayResize que parece. E isso deve ser feito antes de usar uma matriz - veja os posts acima sobre isso. 3) FileOpen(InpDirectoryName+"//"+InpFileName - parece que os bastões devem ser inclinados na outra direção. E é melhor fazer sem InpDirectoryName+"//" - você encontrará o arquivo na pasta Arquivos de qualquer forma.

na linha: int copied=CopyTime(NULL,0,0,0,0,data_Buf_1); o compilador fica bravo, start=0=0


Obrigado. Consegui consertar algo, mas de forma mais intuitiva do que através da compreensão. Mas ainda temos 3 erros relativos à matriz:

Buf_1' - matriz requerida 111.mq4 93 21

data_Buf_1' - matriz requerida 111.mq4 94 21

Buf_1' - matriz necessária 111.mq4 100 16


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input string             InpFileName="111.csv";      // Имя файла 
input string             InpDirectoryName="Data";     // Имя каталога 

datetime Время=0;   // Время прошлого бара
double Bid1;
double   Buf_1[];
// double ExtBuffer;
long V1; // объем для текущего тика вверх
long V2; // накопленный объем для всех тиков вверх текущего бара
long V3; // объем текущего тика вниз
long V4; // накопленный объем для всех тиков вниз для текущего бара
long V5;  // отрицательные и положительные iVolume нарастающим итогом
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
  {
   IndicatorDigits(0);
   SetIndexBuffer(0,Buf_1);
//SetIndexBuffer(1,Buf_2);
   Bid1=Bid;
   V5=0;

  }
//+------------------------------------------------------------------+
//| 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[])
  {
   datetime Вр=Time[0];   // Время текущего бара
   if(Вр>Время)           // Если новый бар
     {
      Время=Вр;           // Запомнить
                          //      Buf_1[0]=0;         // и обнулить последний элемент буфера
     }

   datetime date_Buf_1[]; // массив дат индикатора 
   datetime time_Buf_1[]; // массив времени 
                          // --- считаю объем для положительных и отрицательных тиков      
   if(Bid>=Bid1)
     {
      if(Bid>Bid1) // если тик положительный..
        {
         V1=iVolume(NULL,0,0); // если повышающий цену тик, то находим его объем
         V2= V1 + V2;
        }
      else
        {
         V1=0;                // если Bid1 = Bid2, т.е. изменение цены = 0, то iVolume этого тика присваиваем 0;
         V2= V1 + V2;
        }
     }
   else
     {
      V3 = iVolume(NULL, 0, 0); // если понижающий цену тик 
      V4 = V3 + V4;             // то находим его объем  
     }

   V5=V2-V4;               // определяем разницу (дельту) между объемами положительных и отрицательных тиков
   Bid1=Bid;
   Buf_1[0]=V5; // в буфер сгружаем  дельту

                //   ExtBuffer = Buf_1 [0];
//   double macurrent=iMAOnArray(ExtBuffer,0,5,0,MODE_LWMA,0); 

// запись в файл данных буфера


//--- установим для массивов признак таймсерии 
   ArraySetAsSeries(Buf_1[0],true);
   ArraySetAsSeries(date_Buf_1[0],true);

//--- скопируем таймсерию 
   int copied=CopyTime(NULL,0,10000,0,date_Buf_1);

//--- подготовим массив Buf_1 
   ArrayResize(Buf_1[0],copied);

//--- скопируем значения линии индикатора  
   for(int i=0;i<copied;i++)
     {
      Buf_1[i]=V5;
     }
//--- откроем файл для записи значений индикатора 
   ResetLastError();
   int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
   if(file_handle!=INVALID_HANDLE)
     {
      PrintFormat("Файл %s открыт для записи",InpFileName);
      PrintFormat("Путь к файлу: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
      //--- сначала запишем значения индикатора 
      FileWrite(file_handle,Buf_1[0]);
      //--- запишем время и значения в файл 
      for(int i=0;i<Buf_1[0];i++)
         FileWrite(file_handle,time_Buf_1[0],Buf_1[0]);
      //--- закрываем файл 
      FileClose(file_handle);
      PrintFormat("Данные записаны, файл %s закрыт",InpFileName);
     }
   else
      PrintFormat("Не удалось открыть файл %s, Код ошибки = %d",InpFileName,GetLastError());

   return(rates_total);
  }
//+------------------------------------------------------------------+


Eu não entendo como implementar seus comentários. Mas eu encontrei um grampo extra :)
 
YarTrade:

Obrigado. Consegui consertar algo, mas de forma mais intuitiva do que através da compreensão. Mas ainda tenho 3 erros relativos à matriz:

Buf_1' - matriz requerida 111.mq4 93 21

data_Buf_1' - matriz requerida 111.mq4 94 21

Buf_1' - matriz necessária 111.mq4 100 16



Eu não entendo como implementar seus comentários. Mas eu encontrei um suporte extra :)
Deixe apenas os nomes das variáveis da matriz. Remova "[]" naquelas linhas de código para as quais o compilador aponta você.
 
Artyom Trishkin:
Deixar apenas nomes de arrays variáveis. Remova "[]" nas linhas de código para as quais o compilador aponta você.

Obrigado. Vou ver o que acontece na vida real. Tenho grandes dúvidas de que algo será escrito no arquivo :)

 

Uma série de perguntas surgiram, espero muito por sua ajuda. Encontrei uma coisa muito triste, que o desempenho da EA durante os testes e em tempo real é muito diferente, portanto, gostaria de analisar os erros mais comuns e típicos. Primeiramente escreverei sobre as que encontrei. Gostaria que você pudesse compartilhar suas experiências com o programador que sabe o que ele deve ter em mente e o que ele deve manter em seu código.

1. O erro de divisão por zero estava aparecendo no modo real de comercialização, apesar do fato de que a divisão por zero não estava presente no código e não tinha ocorrido durante os backtests. O programador resolveu o problema escrevendo cada divisor como NormalizeDouble(x,Dígitos);

2. O negócio não foi aberto. Na sexta-feira, o negócio foi aberto quando o backtest estava funcionando, mas nenhum negócio foi aberto durante a negociação real. Além disso, a revista do Consultor Especialista não mostrou nenhum erro. Não sei qual pode ser o problema aqui, mas tenho um par de coisas. Primeiro, recebi avisos como "valor de retorno de 'orderend' deve ser verificado", mas se eu entendi corretamente, isso não deve afetar a execução do código? Ou é tudo uma questão de escorregamento? Meu valor é 1, que não é muito pequeno. E o bar no qual eu deveria realizar uma entrada abriu sem uma lacuna.

Peguei a linha "if(Volume[0]>1) return;" do exemplo padrão com escorregões e a inseri no início do código. Ou seja, meu código só é executado durante o primeiro tique quando uma nova barra aparece. Pode ser que uma barra abra com um volume e meu código não seja executado?

4. Por favor, aconselhe sobre coisas para prestar atenção ou erros típicos quando trabalhar com EA com histórico e tempo real, por favor


 
LuckySith:

Uma série de perguntas surgiram, espero muito por sua ajuda. Encontrei uma coisa muito triste, que o desempenho da EA durante os testes e em tempo real é muito diferente, portanto, gostaria de analisar os erros mais comuns e típicos. Primeiramente escreverei sobre as que encontrei. Gostaria que você pudesse compartilhar suas experiências com o programador que sabe o que ele deve ter em mente e o que ele deve manter em seu código.

1. O erro de divisão por zero estava aparecendo no modo real de comercialização, apesar do fato de que a divisão por zero não estava presente no código e não tinha ocorrido durante os backtests. O programador resolveu o problema escrevendo cada divisor como NormalizeDouble(x,Dígitos);

2. O negócio não foi aberto. Na sexta-feira, o negócio foi aberto quando o backtest estava funcionando, mas nenhum negócio foi aberto durante a negociação real. Além disso, a revista do Consultor Especialista não mostrou nenhum erro. Não sei qual pode ser o problema aqui, mas tenho um par de coisas. Primeiro, recebi avisos como "valor de retorno de 'orderend' deve ser verificado", mas se eu entendi corretamente, isso não deve afetar a execução do código? Ou é tudo uma questão de escorregamento? Meu valor é 1, que não é muito pequeno. E o bar no qual eu deveria realizar uma entrada abriu sem uma lacuna.

Peguei a linha "if(Volume[0]>1) return;" do exemplo padrão com escorregões e a inseri no início do código. Ou seja, meu código só é executado durante o primeiro tique quando uma nova barra aparece. Pode ser que uma barra abra com um volume e meu código não seja executado?

4. Por favor, aconselhe sobre coisas para prestar atenção, ou erros típicos ao trabalhar com a EA com história e tempo real, por favor

Substitua essa construção selvagem "se(Volume[0]>1) voltar;" por uma verificação normal da "Nova Barra", o fórum está cheio delas.

Os avisos do tipo "valor de retorno do 'orderend' deve ser verificado" não são erros até o momento, são erros potenciais para o futuro. Não deve haver avisos no código, muito menos quando se trabalha on-line.

"Eu tenho 1, que não é muito pouco" - isto pode ser muito pouco na abertura de um novo bar, e especialmente na abertura de meia hora ou uma hora, neste momento o spread se amplia muito.

O que precisamos: fazer uma verificação no novo bar, e se for novo, então observe as condições de entrada, se elas coincidirem - faça um acordo. Depois disso, temos que registrar que o bar funcionou e esperar pelo novo.

O que temos agora: se(Volume[0]>1) retornar; = se houver uma nova barra, procuramos por condições, a condição não coube == grande spread = sair novamente em OnTick(), no próximo tick se(Volume[0]>1) retornar; não irá mais longe, então o comércio já está faltando, mesmo que o spread seja 0,0001

 

Olá. Pode, por favor, me dizer como descrever o seguinte com o código: Há um plano, delimitado por linhas horizontais superiores e inferiores. O Expert Advisor os detecta e os define por si só.

Precisamos da EA para detectar quando o preço deixa a zona plana e depois retorna a esta zona. E só depois disso é que abre uma posição.

Para filtrar o ruído, uso um alvo móvel com o parâmetro 2 ou 3

 
Vitaly Muzichenko:

Substitua tais construções selvagens "se(Volume[0]>1) voltar;" por uma verificação normal "Nova Barra", há muitas delas aqui no fórum.

Avisos como "valor de retorno de 'orderend' deve ser verificado" - isto ainda não é um erro, é um erro potencial para o futuro. Não deve haver avisos no código, muito menos quando se trabalha on-line.

"Eu tenho 1, que não é muito pouco" - isto pode ser muito pouco na abertura de um novo bar, e especialmente na abertura de meia hora ou uma hora, neste momento o spread se alarga muito.

O que precisamos: fazer uma verificação no novo bar, e se for novo, então observe as condições de entrada, se elas coincidirem - faça um acordo. Depois disso, temos que registrar que o bar funcionou e esperar pelo novo.

O que temos agora: se(Volume[0]>1) retornar; = se houver uma nova barra, então olhe para as condições, a condição não se encaixa == grande spread = sair novamente em OnTick(), no próximo tick se(Volume[0]>1) retornar; não falhará mais, então o comércio será perdido mesmo se o spread for 0,0001


Sobre a abertura de um novo bar. Seria bom? :

datetime counted_bar = 0;

int OnInit()
{
   counted_bar = 0; // если нужно, чтоб при перезапуске последний бар был проанализирован
   ...

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      counted_bar = iTime( _Symbol, _Period, 0 );

      // Анализируем индикаторы
      ...
   }
 
LuckySith:

Sobre a abertura de um novo bar. Essa seria uma boa opção? :

Que seja assim inicialmente.

Em seguida, precisamos fazer uma fixação adequada de que a barra é trabalhada, mas aqui precisamos calcular toda a abordagem do TOR.

Até onde posso ver pelo seu posto, temos que fazer desta maneira:

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      // Анализируем индикаторы
      if(SpreadMax > текущий спред) return;

      counted_bar = iTime( _Symbol, _Period, 0 );
      ...
   }

A essência é a seguinte: se o spread for maior que o normal, então saímos novamente paraOnTick, e em um novo tick verificamos o spread, se for normal - enviamos um pedido e lembramos que havia uma troca neste bar.

Há também uma segunda maneira:

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      if(SpreadMax > текущий спред) return;
      // Анализируем индикаторы
      ...
      result = OrderSend(...);
      // если открылась позиция, то result будет тикет позиции
       if(result>0) counted_bar = iTime( _Symbol, _Period, 0 );
   }

Em geral, é preciso definir a lógica, quando ela deve ser registrada, e não verificar novamente antes da formação de uma "Nova Barra".