Discussão do artigo "LifeHack para traders: "amassando" ForEach com os define (#define)"

 

Novo artigo LifeHack para traders: "amassando" ForEach com os define (#define) foi publicado:

Passo intermediário para aqueles que ainda escrevem em MQL4, mas não conseguem migrar para MQL5. Continuamos a procurar oportunidades para escrever código em estilo MQL4. Desta vez, examinaremos a substituição de macros do pré-processador - #define.

A criação de experts ou robôs de negociação implica quase sempre um monte de trabalho com ciclos. Os ciclos estão ao nosso redor em toda parte: pesquisa detalhada de ordens, operações no histórico, objetos no gráfico, símbolos na Observação do mercado, barras no buffer de indicador. Para facilitar a vida do programador, ao MetaEditor foram adicionados trechos de código ("snippets"), eles se desenrolam automaticamente num pequeno pedaço de código quando você digita os primeiros caracteres de uma função ou tarefa e pressiona o Tab. Veja como funciona um trecho de código para o ciclo for:


Não é ruim, mas não cobre todas as nossas necessidades. O exemplo mais simples pode ser quando queremos examinar todos os símbolos na Observação do mercado.

Autor: Vladimir Karputov

 
Para o cofrinho

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Bibliotecas: CDouble & CDoubleVector

amrali, 2018.02.12 23:53

#define  forEach(element, array)  for (int __i = 0, __max = ArraySize((array)); __i < __max && ((element) = array[__i]) == (element); __i++)
Tudo precisa ser colocado nas partes internas do for, para que você possa chamar o forEach repetidamente. Caso contrário, será uma chatice com variáveis redefinidas.
 
HistorySelect antes de TimeCurrent é um erro típico. Como o significado das declarações para alguém pode depender do autor, aqui está um conjunto de citações

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

FORTES. Perguntas sobre execução

Renat Fatkhullin, 2015.02.10 08:16

Ainda não executei o código, mas o código-fonte mostra o erro clássico de data final incorreta em HistorySelect.

Todo primeiro programador que chama essa função com a data errada, constantemente verifica o fim do histórico e detecta "negociação de longo tempo entrando no histórico".

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

FORTES. Perguntas sobre execução

Renat Fatkhullin, 2015.02.10 09:15

O erro é que as pessoas não pensam sobre qual é o momento atual e substituem a data errada tirada da fonte errada.

Basta especificar uma data distante conhecida como a data final, e não o obsoleto serverTime.

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

FORTES. Perguntas sobre execução

Renat Fatkhullin, 2015.02.10 13:56

E a data de início e término deve ser definida com a realização de erros e com uma margem obrigatória. Ou seja, menos N segundos e mais N segundos, no mínimo.

TimeTradeServer() não é um tempo preciso, mas é atualizado somente com base nos ticks de preço que chegam à visão geral do mercado.


Se de repente você não tiver dados na amostra do histórico, isso significa que 99% do erro está nos limites da consulta.

HistorySelect(0, LONG_MAX);
 

Предопределённые переменные _XXXX переводятся в функции MQL5 при помощи беспараметрической формы #define:

//--- a variável _Digits armazena o número de dígitos após um ponto decimal,
#define _Digits         Digits()
Por quê? Além disso, com essa macro, você não pode usar _Digits como parâmetro de entrada de algumas funções. Ou seja, o código deixará de funcionar.
 
//--- o último preço conhecido do vendedor (preço de venda) para o símbolo atual 
double GetAsk()
  {
   MqlTick tick;
   SymbolInfoTick(Symbol(),tick);
   return(tick.ask);
  }

Terrivelmente caro! Se você realmente quiser fazer isso por meio da estrutura, deveria pelo menos ter feito isso. E, por algum motivo, não há verificação.

O SymbolInfoDouble é totalmente compatível com o MT4.

 
#define IsTradeContextBusy  true

Não?

talvez falso?
 
Para MarketInfo, é melhor usar a abordagem por meio de enumerações + sobrecargas

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação.

Consultores especializados: Quantum 103

fxsaber, 2017.09.26 09:55 pm.

bool RefreshRates( void ) { return(true); }

double MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )  { return(SymbolInfoDouble(Symb, Property)); }
int    MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property ) { return((int)SymbolInfoInteger(Symb, Property)); }

bool IsTesting(void)            { return(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION)); }
bool IsTradeContextBusy( void ) { return(false); }
bool IsTradeAllowed(void)       { return(MQLInfoInteger(MQL_TRADE_ALLOWED)); }
bool IsExpertEnabled(void)      { return(AccountInfoInteger(ACCOUNT_TRADE_EXPERT)); }

int    ObjectFind( const string Name )   { return(ObjectFind(0, Name)); }
int    ObjectsTotal( void )              { return(ObjectsTotal(0)); }
bool   ObjectDelete( const string Name ) { return(ObjectDelete(0, Name)); }
string ObjectName( const int Pos )       { return(ObjectName(0, Pos)); }

double AccountFreeMarginCheck(const string Symb,const int Cmd,const double dVolume)
{
 double Margin;

 return(OrderCalcMargin((ENUM_ORDER_TYPE)Cmd, Symb, dVolume,
        SymbolInfoDouble(Symb, (Cmd == ORDER_TYPE_BUY) ? SYMBOL_ASK : SYMBOL_BID), Margin) ?
        AccountInfoDouble(ACCOUNT_MARGIN_FREE) - Margin : -1);
}

#define False false
#define True  true

#define Digits _Digits
#define Point  _Point

#define MODE_BID       SYMBOL_BID
#define MODE_ASK       SYMBOL_ASK
#define MODE_POINT     SYMBOL_POINT
#define MODE_DIGITS    SYMBOL_DIGITS
#define MODE_STOPLEVEL SYMBOL_TRADE_STOPS_LEVEL
#define MODE_SPREAD    SYMBOL_SPREAD

#define StrToTime    StringToTime
#define StrToInteger StringToInteger
#define TimeToStr    TimeToString
#define DoubleToStr  DoubleToString

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
 
Apenas as funções de negociação simplificadas da MQL4 estão faltando para a compatibilidade total. Mas até mesmo esse problema pode ser resolvido, se desejado.
Para fazer isso, você precisa entender muito bem as duas arquiteturas. Nem tudo ainda é óbvio.
 

fxsaber:
В копилку

#define  forEach(element, array)  for (int __i = 0, __max = ArraySize((array)); __i < __max && ((element) = array[__i]) == (element); __i++)

Técnica interessante e não óbvia )

[Excluído]  

Quantas coisas distorcidas você pode fazer?

Definir é uma substituição estúpida de um texto por outro. Não há poder nelas!

É melhor tentar fazer a mesma coisa nos modelos.

 
Koldun Zloy:

Quantas vezes você pode fazer isso?

Definir é uma substituição estúpida de um texto por outro. Não há poder neles!

Às vezes, escrever menos é conveniente

É melhor tentar fazer a mesma coisa nos modelos.

É apenas uma questão de viabilidade, usabilidade e desempenho.