Mt4 Fim do apoio. - página 27

 
Реter Konow:
Linear, não-linear... Você está falando de ópera na programação novamente?

De jeito nenhum.

 
Реter Konow:

OK. Sua solução só funciona com carrapatos. O meu está em um temporizador. Você acha que meu método de cronometragem com as aparências em bares tem um inconveniente. Certo. Que seja assim. Vou acrescentar um cheque para a chegada de uma cotação antes de colocar uma nova bandeira de barra. Vou adicionar outro parâmetro à função - um símbolo. O usuário escolherá o símbolo pelo qual deseja receber o novo evento do bar e o enviará para a função. A função irá verificar a hora da última citação deste símbolo. Em seguida, compararemos a hora da apresentação formal do bar e a hora da citação e colocaremos a bandeira do evento.

Acabo de começar a estudar este assunto, mas não vejo nenhuma dificuldade.

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Mt4 Fim do apoio.

Artyom Trishkin, 2017.09.10 22:27

Eu sei como obter citações :)

Em um programa com várias moedas - em um temporizador em loop nos símbolos certos. E a abertura de uma nova barra (física, não virtual - errónea - como com você) é controlada pelo tempo da última citação e comparando esse tempo com o tempo do símbolo da barra zero.

Você, por outro lado, está fazendo ao acaso - um bar virtual que pode não existir. Você não os tem no fim de semana, mas supostamente os tem - isso é a coisa mais simples de se dar como exemplo.

E, veja, você é o único que não o faria dessa maneira. O resto de nós o faz da maneira correta e confiável. Mas isso, é claro, é apenas seu próprio negócio.

Eu queria lhes dizer como fazê-lo corretamente e mostrar a grande diferença na simplicidade de escrever no OOP e nas complicadas reviravoltas no estilo processual ao resolver a mesma tarefa.

Mas você provavelmente sabe mais e não precisa disso. Não me atrevo a parecer que sei mais nada. Desculpe.


 
Galina Bobro:

Não há problema. Hedge para salvar a comparação de operações de cordas, bem, se o cliente é um maníaco e irá negociar em todos os caracteres simultaneamente.

Mas parece que não há outro lugar para salvar operações e memória - tudo é mínimo.

void OnTimer(){

   Alert(Fn_new_bar("EURUSD", PERIOD_D1)); }

//+------------------------------------------------------------------+

uint Sp_Adler32(string line){

   ulong s1 = 1;

   ulong s2 = 0;

   uint buflength=StringLen(line);

   uchar char_array[];

   ArrayResize(char_array, buflength,0);

   StringToCharArray(line, char_array, 0, -1, CP_ACP);

   for (uint n=0; n<buflength; n++){

      s1 = (s1 + char_array[n]) % 65521;

      s2 = (s2 + s1)     % 65521;}

   return ((s2 << 16) + s1);}

//+------------------------------------------------------------------+

bool Fn_new_bar(string symb, ENUM_TIMEFRAMES tf){

   static datetime st_time[]; 

   static uint     st_id[];

   

   //---- set

   datetime new_time = iTime(symb, tf, 0);     if(new_time==0) return(false); 

   uint     new_id   = Sp_Adler32(StringConcatenate(symb,EnumToString(tf))); 

   datetime old_time = 0; 

   uint     old_id   = 0;

   

   //---- find

   int size = ArraySize(st_time); 

   for(int i=0; i<size; i++){

      if(st_id[i]!=new_id) continue; 

      old_id   = st_id  [i]; 

      old_time = st_time[i];

      break;}

   

   //----add new element

   if(old_time==0){

      ArrayResize(st_time, size+1); st_time[size]=new_time;

      ArrayResize(st_id,   size+1); st_id  [size]=new_id; }

   

   //----

   return(old_time>0 && old_time<new_time);}


Parece ser o código mais sensato estruturalmente até agora. Tem uma verificação para um novo símbolo e um tf, não verifica tudo, mas apenas o que você precisa, sem operações desnecessárias, o que significa que deve correr muito rápido.

Saudações cordiais.

P.S. a única pequena coisa que poderia ser adicionada aqui é combinar as matrizes st_time e st_id em uma estrutura, já que elas estão inter-relacionadas, isto reduziria o número de operações de incremento de matrizes no código.

 
Artyom Trishkin:

Eu tinha o objetivo de fazer com que seu código de estilo de procedimento acabasse trabalhando em um loop como este:

 ENUM_TIMEFRAMES array_timeframes[]=
      {
      PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
      };
   int total=SymbolsTotal(true), total_tf=ArraySize(array_timeframes);
   for(int i=0; i<total; i++){
      string symbol_name=SymbolName(i,true);
      for(int j=0; j<total_tf; j++){
         if(IsNewBar(symbol_name,array_timeframes[j])){
            Print("Новый бар на ",symbol_name," ",EnumToString(array_timeframes[j]));
            }
         }
      }


algo parecido com isto (código para MQL5):

int OnInit()
  {
   IsNewBar();  // сбор информации - можно включить здесь, но не обязательно
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

void OnTimer()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }

void OnTick()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }
//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar();   |
//|   - режим вывода информации, out=true                                                             |
//|   tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации)        |
//|   Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации)  |
//+---------------------------------------------------------------------------------------------------+
bool IsNewBar(bool out=false, ENUM_TIMEFRAMES tf=PERIOD_CURRENT, string Sym="") 
  {
   static const ENUM_TIMEFRAMES TF[22]=
     {
      PERIOD_CURRENT,PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
     };
   static bool newbar[];
   static long acb[]; // array of current bars
   static int N_Sym=0;
   if(Sym=="") Sym=Symbol();
   int total=SymbolsTotal(true);
   int n_cur=-1;
   for(int i=0; i<total; i++) if(Sym==SymbolName(i,true)){ n_cur=i; break;}
   if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
   if(out && N_Sym>0) // если режим вывода информации 
     {
      int curtf=0;
      while(TF[curtf]!=tf) curtf++;
      return (newbar[n_cur*22+curtf]);
     }
// режим сбора информации
   if (total!=N_Sym) {ArrayResize(acb,22*total);ArrayInitialize(acb,0); ArrayResize(newbar,22*total); ArrayInitialize(newbar,false); N_Sym=total;}
   for(int j=0,j1=0; j<total; j++,j1+=22)
      for(int i=0;i<22;i++)
        {
         long CurBars=SeriesInfoInteger(SymbolName(j,true),TF[i],SERIES_LASTBAR_DATE);
         if(acb[j1+i]<CurBars) // пришел новый бар
           {
            //if (acb[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+"   "+EnumToString(TF[i]));
            acb[j1+i]=CurBars;
            newbar[j1+i]=true;
           }
         else
           {
            newbar[j1+i]=false;
            if(i==1) for(;i<22;i++) newbar[j1+i]=false;   // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
           }
        }
   return(false);
  }

Mas vou dizer novamente - sou um defensor do OOP.
Apenas um exemplo realmente infeliz para mostrar o que não pode ser feito na programação de procedimentos.

 
Andrey Kisselyov:
Não se trata de chamar uma função em uma EA, trata-se de escrever interfaces universais (handlers).

você tem 1000 tarefas para escrever robôs; na verdade, cada uma delas consiste em
1 função de obter um sinal para abrir
2. função da abertura do pedido
3 função de rastreamento de pedidos
4) A função de receber um sinal para fechar uma ordem.
e assim por diante.
Estas funções são diferentes para cada robô, mas são repetidas dentro de 1000 projetos. Como conseqüência, é possível fundir as funções em módulos universais e, dependendo da tarefa, chamar a função certa.

Bem, se você tem estas funções, não precisa fazer mais nada. Os parâmetros de entrada da função é a interface. Cada complexidade extra aumenta o número de erros possíveis e aumenta o tempo de trabalho do programador.

 
Nikolai Semko:

algo parecido (código para MQL5):

Mas repito - sou um defensor do OOP.
É apenas um exemplo lamentável para mostrar o que não pode ser feito na programação de procedimentos.

Existe tal exemplo em princípio? Mesmo que não seja seu? Tenho profundas dúvidas. No início dos anos 2000 eu parei de contar o número de linhas de código de depuração e de trabalho, que eu havia escrito, porque excedeu um milhão - tornou-se desinteressante. E nunca encontrei a necessidade de criar minha própria classe, embora a variedade e a escala das minhas tarefas fossem muito diversas. Tive que usar variáveis do tipo procedimento quando era necessário fazer trabalho em paralelo para várias pessoas, mas não mais. Por quê?

A propósito, por que você fala de programação processual como uma alternativa ao OOP? Há linguagens sem OOP, não-processuais em princípio (SQL), há até uma direção de desenvolvimento de linguagens - programação funcional https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5: "Alguns conceitos e paradigmas são específicos da programação funcional e, em sua maioria, estranhos à programação imperativa (incluindo a programação orientada a objetos)", "Outra vantagem dos programas funcionais é que eles oferecem vastas oportunidades para a programação automática Acontece que o OOP impede o paralelismo automático dos cálculos. Isto agora deve ser considerado uma desvantagem muito séria, a perspectiva não é para o OOP.

 
Vladimir:

Existe, em princípio, um exemplo disso? Mesmo que não seja seu? Tenho profundas dúvidas.


Penso que é bem possível que tal exemplo não seja encontrado. Pessoalmente, acredito que as principais vantagens do OOP são uma programação mais conveniente de grandes projetos e um mecanismo conveniente para utilizar seus desenvolvimentos no futuro. Isto já foi dito aqui muitas vezes com razão.

 
Andrei:

Já foi discutido que uma única interface não se aplica à programação de nenhuma tarefa computacional... Colocar coisas bonitas na forma de interfaces é um procedimento puramente cosmético, que se aplica apenas ao código já pronto e que também impede um maior suporte e refinamento do código...

Não. Não é "de modo algum aplicável", mas "não vale a pena utilizá-los".

As interfaces não são "um procedimento puramente cosmético aplicável ao código pronto para uso".

Muito pelo contrário - as interfaces estão no centro da arquitetura do sistema. É onde começa o projeto. As interfaces não "atrapalham em nada o apoio e o retrabalho", mas sim os ajudam delineando claramente os limites do que é permitido. Se não houver interfaces, é fácil cruzar essas fronteiras e fazer mudanças onde elas não foram intencionadas, resultando em erros difíceis de computar.

Qualquer sistema complexo (não apenas na programação) começa com o desenvolvimento dos princípios básicos de interação entre suas partes. Mas na programação, como a tarefa inicial geralmente é muito pequena, eles vão na direção oposta. As partes são escritas primeiro e depois combinadas em um todo, muitas vezes encontrando o fato de que as partes não são compatíveis entre si - a propósito, isto explica o desejo de "ter acesso a todas as variáveis disponíveis".

 

Tudo bem, exceto pelo fato de que a função isNewBar() não deveria existir de forma alguma. É engraçado que há tanta dança em torno de uma coisa tão trivial.

É apenas uma variável, e é simplesmente comparada ao tempo da barra; se todos os casos forem bem sucedidos, a variável é atribuída ao tempo da nova barra no final. Caso contrário, apenas uma tentativa é atribuída a todos os casos.

 
Dmitry Fedoseev:

Tudo bem, exceto pelo fato de que a função isNewBar() não deveria existir de forma alguma. É engraçado que há tanta dança em torno de uma coisa tão trivial.

É apenas uma variável, e é simplesmente comparada ao tempo da barra; se todos os casos forem bem sucedidos, a variável é atribuída ao tempo da nova barra no final. Caso contrário, apenas uma tentativa é atribuída a todos os casos.


+1

Razão: