Bibliotecas: Price_Compare

 

Price_Compare:

Comparação elegante e ágil de valores "duplos" de "preço".

Autor: fxsaber

 
Automated-Trading:

Preço_Comparar:

Autor: fxsaber

Por que você gosta tanto de instruções do pré-processador? Você as tem em todos os códigos que vi. O tópico é interessante sobre a normalização em si, mas ela pode ser implementada sem instruções do pré-processador, a linguagem permite que você faça isso.

E em seu estilo de comunicação - dê um exemplo em que o uso de sua biblioteca mostrará uma velocidade maior do que a normalização normal :)

 
coderex:

Por que você gosta tanto das instruções do pré-processador? Você as tem em todos os códigos que vi. O tópico é interessante em termos da normalização em si, mas pode ser implementado sem instruções do pré-processador, pois a linguagem permite que você faça isso.

Código repetitivo é irritante. Gosto de brevidade, eficiência e lógica. Por exemplo

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

Testando 'CopyTicks'

fxsaber, 2016.10.19 07:59

Isso é o que o date-to-date fará. CopyTicks tentando ajustar a sintaxe às funções de cópia apenas por causa da presença de Copy no nome não trará conveniência. É conveniente e justificável quando você pode fazer coisas de pré-processador como esta

// Permite, como no MT4, trabalhar com séries temporais: Open[Pos], High[Pos], Low[Pos], Close[Pos], Time[Pos], Volume[Pos].
// Ele também define as funções usuais do MT4: iOpen, iHigh, iLow, iClose, iTime, iVolume.
#define DEFINE_TIMESERIE(NAME,FUNC,T)                                                                         \
  class CLASS##NAME                                                                                           \
  {                                                                                                           \
  public:                                                                                                     \
    static T Get( const string Symb, const int TimeFrame, const int iShift )                                  \
    {                                                                                                         \
      T tValue[];                                                                                             \
                                                                                                              \
      return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
    }                                                                                                         \
                                                                                                              \
    T operator []( const int iPos ) const                                                                     \
    {                                                                                                         \
      return(CLASS##NAME::Get(_Symbol, _Period, iPos));                                                       \
    }                                                                                                         \
  };                                                                                                          \
                                                                                                              \
  CLASS##NAME NAME;                                                                                           \
                                                                                                              \
  T i##NAME( const string Symb, const int TimeFrame, const int iShift )                                       \
  {                                                                                                           \
    return(CLASS##NAME::Get(Symb, TimeFrame, iShift));                                                        \
  }

DEFINE_TIMESERIE(Volume, TickVolume, long)
DEFINE_TIMESERIE(Time, Time, datetime)
DEFINE_TIMESERIE(Open, Open, double)
DEFINE_TIMESERIE(High, High, double)
DEFINE_TIMESERIE(Low, Low, double)
DEFINE_TIMESERIE(Close, Close, double)
E para CopyTicks você não pode fazer isso, porque há dois threads físicos diferentes (TRADE e INFO) e um thread sintético (ALL) - sinalizadores.

E em seu estilo de comunicação - dê um exemplo em que o uso de sua biblioteca mostrará uma velocidade maior do que a normalização :)

Isso depende muito da taxa de bits do terminal. No MT4, as diferenças de velocidade devem ser especialmente perceptíveis. Renat fez uma comparação neste tópico.

Альтернативные реализации стандартных функций/подходов
Альтернативные реализации стандартных функций/подходов
  • www.mql5.com
NormalizeDouble Результат 1123275 и 1666643 в пользу MyNormalizeDouble (Optimize=1). Без оптимизации - быстрее раза в четыре (на память...
 
fxsaber:

Código repetitivo e irritante. Gosto de brevidade, eficiência e lógica. Por exemplo


Depende muito da taxa de bits do terminal. No MT4, as diferenças de velocidade devem ser especialmente perceptíveis. Renat fez uma comparação neste tópico.

Obrigado )))). Recebi muitas informações úteis.
 
coderex:
Outro exemplo de utilidade do pré-processador

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

Perguntas de iniciantes

fxsaber, 2016.10.19 15:23

#define ORDER_TYPE_BUY ORDER_TYPE_BUY_STOP   // Coloque-o logo no início do Expert Advisor, se você quiser recusar negociações de COMPRA
#define ORDER_TYPE_SELL ORDER_TYPE_SELL_STOP // coloque-o logo no início do EA, se for necessário recusar negociações de VENDA
 
fxsaber:
Outro exemplo da utilidade do pré-processador
Às vezes é impossível recusar completamente o pré-processador, mas seu código é simplesmente escrito com instruções do pré-processador. Esse código se torna difícil de ler.
 
coderex:
Às vezes, é impossível recusar completamente o pré-processador, mas seu código é simplesmente escrito com base nas instruções do pré-processador. Esse código se torna difícil de ler.

Eu defino os nomes de variáveis, tipos, classes, funções/métodos e macros de forma clara. Se você vir abusos, mostre-me.

O maior obstáculo para mim na leitura do kodobase é o estilo forçado. Quase todo o meu código no kodobase foi submetido a esse procedimento. E dificilmente consigo ler meu próprio código depois disso.

 
fxsaber:

Os nomes de variáveis, tipos, classes, funções/métodos e macros são definidos de forma clara. Se você vir abusos, mostre-me.

O maior obstáculo para mim na leitura do kodobase é o estilo forçado. Quase todo o meu código no kodobase foi submetido a esse procedimento. E dificilmente consigo ler meu próprio código depois disso.

Não estou falando de mim mesmo, qualquer código cheio de macros será mal lido, além de ser muito difícil de depurar, por isso sempre tento usar o pré-processador o mínimo possível e somente quando absolutamente necessário. As macros presentes no código indicam um algoritmo mal planejado. Não me lembro exatamente a quem pertencem essas palavras, acho que a Straustrup, mas elas refletem a essência: o código deve ser limpo.
 
coderex:
Não estou falando de mim mesmo, qualquer código cheio de macros será mal lido, além de ser muito difícil de depurar, por isso sempre tento usar o pré-processador o mínimo possível e somente quando absolutamente necessário. As macros presentes no código falam de um algoritmo mal pensado. Não me lembro exatamente a quem pertencem essas palavras, acho que a Straustrup, mas elas refletem a essência: o código deve ser limpo.
Eu discordo
string GetTickFlag( uint tickflag )
{
  string flag = "";

#define TICKFLAG_MACRO(A) flag += ((bool)(tickflag & TICK_FLAG_##A)) ? " TICK_FLAG_" + #A : "";
  TICKFLAG_MACRO(BID)
  TICKFLAG_MACRO(ASK)
  TICKFLAG_MACRO(LAST)
  TICKFLAG_MACRO(VOLUME)
  TICKFLAG_MACRO(BUY)
  TICKFLAG_MACRO(SELL)
#undef TICKFLAG_MACRO

  if (flag == "")
    flag = " FLAG_UNKNOWN (" + (string)tickflag + ")";
    
  return(flag);
}

#define TOSTRING(A) " " + #A + " = " + (string)Tick.A

string TickToString( const MqlTick &Tick )
{
  return(TOSTRING(time) + "." + (string)IntegerToString(Tick.time_msc %1000, 3, '0') +
         TOSTRING(bid) + TOSTRING(ask) + TOSTRING(last)+ TOSTRING(volume) + GetTickFlag(Tick.flags));
}

void OnStart()
{
  MqlTick Tick;
  
  if (SymbolInfoTick(_Symbol, Tick))
    Print(TickToString(Tick));
}

Resultado

2016.10.19 18:14:51.604 Test (GBPUSD,M1)         time = 2016.10.19 18:15:58.649 bid = 1.23008 ask = 1.23018 last = 0.0 volume = 0 TICK_FLAG_ASK

Acho que é bonito. Caso contrário, deveríamos desistir dos modelos também.

 
fxsaber:
Eu discordo
string GetTickFlag( uint tickflag )
{
  string flag = "";

#define TICKFLAG_MACRO(A) flag += ((bool)(tickflag & TICK_FLAG_##A)) ? " TICK_FLAG_" + #A : "";
  TICKFLAG_MACRO(BID)
  TICKFLAG_MACRO(ASK)
  TICKFLAG_MACRO(LAST)
  TICKFLAG_MACRO(VOLUME)
  TICKFLAG_MACRO(BUY)
  TICKFLAG_MACRO(SELL)
#undef TICKFLAG_MACRO

  if (flag == "")
    flag = " FLAG_UNKNOWN (" + (string)tickflag + ")";
    
  return(flag);
}

#define TOSTRING(A) " " + #A + " = " + (string)Tick.A

string TickToString( const MqlTick &Tick )
{
  return(TOSTRING(time) + "." + (string)IntegerToString(Tick.time_msc %1000, 3, '0') +
         TOSTRING(bid) + TOSTRING(ask) + TOSTRING(last)+ TOSTRING(volume) + GetTickFlag(Tick.flags));
}

void OnStart()
{
  MqlTick Tick;
  
  if (SymbolInfoTick(_Symbol, Tick))
    Print(TickToString(Tick));
}

Resultado.

2016.10.19 18:14:51.604 Test (GBPUSD,M1)         time = 2016.10.19 18:15:58.649 bid = 1.23008 ask = 1.23018 last = 0.0 volume = 0 TICK_FLAG_ASK

Até que é bonitinho. Caso contrário, você terá que abrir mão dos modelos também.

O fato de você gostar dele é compreensível )))), mas TickToString poderia ser implementado em uma linguagem pura, na minha opinião.

A questão é que as macros vieram do C e foram projetadas para outras finalidades. É como uma microcalculadora - o objetivo de sua criação era o mesmo, mas em sua época as pessoas começaram a jogar no MK-62 (inclusive eu), mas depois isso foi forçado devido à falta de PCs, e agora parecerá nostalgia com perversão ou pura perversão :). O mesmo acontece com macros.... É claro que você pode escrever o código como quiser, eu apenas disse o que chamou sua atenção.

 
coderex:
TickToString, na minha opinião, poderia ser implementado em uma linguagem pura

É claro que sim! Mas como isso seria feio?

Na biblioteca TypeToBytes sem macros, isso não seria apenas assustador, mas também não seria conveniente. Ou seja, a biblioteca poderia ser simplesmente jogada fora.

Acho que tudo se resume à proficiência na linguagem. Quando eu não conhecia/entendia a OOP, eu não a usava. Tudo mudou.