Características da linguagem mql5, subtilezas e técnicas - página 3

 
fxsaber:

O que a OnTradeTransaction poderia ser em um script de negociação? Não no seu código, mas no guião comercial de outra pessoa.
Você acredita seriamente que um robô comercial completo pode ser escrito em um script?
 
Amigos, vamos nos aproximar do assunto: gostaria de ver exemplos de implementação desta ou daquela afirmação. Não necessariamente código, se houver muito dele, você pode descrever a lógica, por exemplo, enviar pedido para ter certeza de que foi enviado, olhe lá, se recebermos o código de retorno, faça so-and-such. Isto é, exemplos da forma mais fiável de obter dados.

Caso contrário, se discutirmos, passaremos de um tópico útil para várias páginas de brigas. Depois temos de limpar tudo para deixar a essência... Exactamente, eu gostaria da essência deste ou daquele processo. Que haja várias versões de alguma implementação de algo. Será possível discutir as vantagens e desvantagens de cada método.

Então, quando se acumulam informações úteis diferentes, há uma ideia para acumular tudo em uma tabela. E reabastecê-lo constantemente quando os próximos chips úteis forem acumulados.
Acho que isto será útil para todos.
 
Pergunta: como converter um número para sistemas octal e hexadecimal.

Respostas:
1.

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

8 e 16 ricas

Taras Slobodyanik, 2017.02.24 22:16

string DecToHex(int n)
  {
   string s = "", c;
   while(n != 0)
     {
      if(n%16<10)
         c=CharToStr(n%16+'0');
      else
         c=CharToStr(n%16+'A'-10);
      s = c + s;
      n = n / 16;
     }
   return(s);
  }
2.

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

8 e 16 ricas

Maxim Kuznetsov, 2017.02.24 22:20

De repente, StringFormat, PrintFormat :-)

PrintFormat("Hex %x e octal %o",1122,1122);
3.

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

8 e 16 ricas

fxsaber, 2017.02.24 22:21

string NumToString( uint Num, const uint Scale = 10 )
{
  static const string digits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
                                  "A", "B", "C", "D", "E", "F", "G", "H", "I", "K",
                                  "L", "M", "N", "O", "P", "Q", "R", "S", "T", "V", "X", "Y", "Z"};
  
  string Str = (Num == 0) ? "0" : "";
  
  while (Num > 0)
  {
    Str = digits[Num % Scale] + Str;
    
    Num /= Scale;
  }
  
  return(Str);
}

void OnStart()
{
  Print(NumToString(123, 8));
  Print(NumToString(123, 16));
}



 
prostotrader:
Você acredita seriamente que um robô comercial completo pode ser escrito em um script?
Você pode
 
Alexey Kozitsyn:

Mova a discussão dos camaradas fxsaber e prostotrader para um tópico separado, se houver discussões aqui, o tópico perderá sua relevância prática. Quando eles encontrarem uma solução real, eles afixarão aqui. E, na minha opinião, isto não deve ser um ramo de dúvidas ou de pesquisa. Deve ser um ramo de soluções práticas. E se algumas pessoas têm visões diferentes sobre o assunto - que o discutam noutro lugar.

<post para apagar

Vamos deixar que a verdade seja encontrada. Eu tive tempo para pensar e decidi postar, e Vitya (Vinin) a quem eu perguntei e pedi para dissipar minhas dúvidas, também sugeriu postar uma discussão (confirmando minhas dúvidas sobre a eliminação) - que a verdade seja encontrada. Acho que isso seria a coisa certa a fazer. Vou começar a tabulá-lo mais tarde de qualquer maneira, para poder afixá-lo aqui à medida que se vai enchendo.
 
prostotrader:

Não tens de esperar alguns milissegundos.

A mensagem virá na OnTradeTransaction

ver código

Qual é o objectivo da sua mensagem? Ele vai chegar na OnTradeTransaction(), e daí? Significa que temos que esperar pelo evento. Nós esperamos na mesma. O significado da mensagem do fxsaber é que após OrderSend() ser executada, a informação sobre a ação executada não aparece imediatamente no terminal. Algumas pessoas gostam de esperar pela OnTradeTransaction(), enquanto outras gostam de ver uma ordem ou um negócio na lista. Aqui está a diferença do MT4, a título de exemplo. Em M4, após OrderSend(), a ordem já está na lista de pedidos, e após OrderClose(), a ordem está sempre no histórico.

 
Artyom Trishkin:
Vamos deixar que a verdade seja encontrada. Eu tive tempo para pensar e decidi deixá-lo, e Vitya (Vinin), a quem pedi e pedi para dissipar as minhas dúvidas, também sugeriu deixar a discussão (confirmando as minhas dúvidas sobre a eliminação) - que nasça a verdade. Acho que isso seria a coisa certa a fazer. Vou começar a tabulá-lo mais tarde de qualquer forma, para ser afixado aqui à medida que se vai enchendo.
Em discussões com o prostotrader a verdade pode não surgir, não é por isso que ele as inicia. Como sempre, ele nem sabe do que está a falar.
 
Que tipo de argumento é que existe, afinal? Não há nenhuma disputa aqui. fxsaber nos lembrou de uma característica do terminal, que é realmente indocumentado e que todos deveriam realmente saber, caso contrário haverá problemas no desenvolvimento de EAs, que você terá que encontrar e limpar mais tarde.
 
Artyom Trishkin:
Vamos deixar que a verdade seja encontrada...

Artyom!

Você é um homem razoável e politicamente correto!

Que verdade? Você sabe exactamente do que estamos a falar.

fxsaber escreveu um roteiro (nada mal), mas ninguém o elogiou, então ele

tenta lembrá-lo em cada linha.

Muito bem!

Mas aqui está o problema, você não pode usar a OnTradeTransaction neste script, então ele tem que "rolar bolas" (como Dormir ou outro cronômetro) do "Sr. OnTradeTransaction".

E claro, "cuidar" de outros usuários que ainda não sabem que o SCRIPT é melhor que o COUNTER!

Dmitry Fedoseev é sempre contra o que eu digo, não importa se estou certo ou errado.

A verdade não pode ser encontrada aqui porque não é uma causa, mas uma causa pessoal que vem à tona.

 
class ORDERSEND  
{
private:
  static const bool IsTester;
  
  static bool Waiting( const bool FlagInit = false )
  {
    static ulong StartTime = 0;

    const bool Res = FlagInit ? false : (::GetMicrosecondCount() - StartTime < ORDERSEND::OrderSend_MaxPause);

    if (FlagInit)
      StartTime = ::GetMicrosecondCount();
    else if (Res)
      ::Sleep(0);

    return(Res);
  }

  static bool EqualPrices( const double Price1, const double Price2, const int digits)
  {
    return(::NormalizeDouble(Price1 - Price2, digits) == 0);
  }

  static bool HistoryDealSelect( MqlTradeResult &Result )
  {
    if ((Result.deal == 0) && (Result.order != 0))
    {
      if (::HistorySelectByPosition(::HistoryOrderGetInteger(Result.order, ORDER_POSITION_ID)))
        for (int i = ::HistoryDealsTotal() - 1; i >= 0; i--)
        {
          const ulong DealTicket = ::HistoryDealGetTicket(i);

          if (Result.order == ::HistoryDealGetInteger(DealTicket, DEAL_ORDER))
          {
            Result.deal = DealTicket;

            break;
          }
        }
    }

    return(::HistoryDealSelect(Result.deal));
  }

#define TMP_ORDERSEND_BENCHMARK(A) \
  static ulong Max##A = 0;         \
                                   \
  if (Interval##A > Max##A)        \
  {                                \
    ORDERSEND_BENCHMARK            \
                                   \
    Max##A = Interval##A;          \
  }

  static void OrderSend_Benchmark( const ulong Interval1, const ulong Interval2 = 0 )
  {
    #ifdef ORDERSEND_BENCHMARK
      TMP_ORDERSEND_BENCHMARK(1)
      TMP_ORDERSEND_BENCHMARK(2)
    #endif // ORDERSEND_BENCHMARK

    return;
  }

#undef TMP_ORDERSEND_BENCHMARK

#define WHILE(A) while ((!(Res = (A))) && ORDERSEND::Waiting())

public:
  static uint OrderSend_MaxPause; // максимальное время на синхронизацию в мкс.
  
  // Полностью синхронизированный с торговым окружением OrderSend.
  // По окончании работы ГАРАНТИРОВАННО и за МИНИМАЛЬНОЕ время доступно корректное торговое окружение.
  // По скорости ничем не уступает связке OrderSendAsync + OnTradeTransaction.
  // Учтены MT5-нюансы: Result.deal == 0, STATE_STARTED и STATE_MODIFY pending.
  // В тестере/оптимизаторе производительность равна штатной OrderSend.

  static bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
  {
    const ulong StartTime1 = ::GetMicrosecondCount();

    bool Res = ::OrderSend(Request, Result);

    const ulong Interval1 = ::GetMicrosecondCount() - StartTime1;

    const ulong StartTime2 = ::GetMicrosecondCount();

    if (Res && !ORDERSEND::IsTester && (Result.retcode < TRADE_RETCODE_ERROR) && (ORDERSEND::OrderSend_MaxPause > 0))
    {
      Res = (Result.retcode == TRADE_RETCODE_DONE);
      ORDERSEND::Waiting(true);

      if (Request.action == TRADE_ACTION_DEAL)
      {
        WHILE(::HistoryOrderSelect(Result.order))
          ;

        Res = Res && (((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_FILLED) ||
                      ((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_PARTIAL));

        if (Res)
          WHILE(ORDERSEND::HistoryDealSelect(Result))
            ;
      }
      else if (Request.action == TRADE_ACTION_PENDING)
      {
        if (Res)
          WHILE(::OrderSelect(Result.order) && ((ENUM_ORDER_STATE)::OrderGetInteger(ORDER_STATE) == ORDER_STATE_PLACED))
            ;
        else
        {
          WHILE(::HistoryOrderSelect(Result.order))
            ;

          Res = false;
        }
      }
      else if (Request.action == TRADE_ACTION_SLTP)
      {
        if (Res)
        {
          bool EqualSL = false;
          bool EqualTP = false;

          const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);

          if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
          {
            EqualSL = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
            EqualTP = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
          }

          WHILE((EqualSL && EqualTP))
            if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
            {
              EqualSL = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
              EqualTP = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
            }
        }
      }
      else if (Request.action == TRADE_ACTION_MODIFY)
      {
        if (Res)
        {
          bool EqualSL = false;
          bool EqualTP = false;
          bool EqualPrice = false;

          const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);

          if (::OrderSelect(Result.order))
          {
            EqualSL = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
            EqualTP = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
            EqualPrice = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_PRICE_OPEN), Request.price, digits);
          }

          WHILE((EqualSL && EqualTP && EqualPrice))
            if (::OrderSelect(Result.order) && ((ENUM_ORDER_STATE)::OrderGetInteger(ORDER_STATE) != ORDER_STATE_REQUEST_MODIFY))
            {
              EqualSL = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
              EqualTP = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
              EqualPrice = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_PRICE_OPEN), Request.price, digits);
            }
        }
      }
      else if (Request.action == TRADE_ACTION_REMOVE)
        if (Res)
          WHILE(::HistoryOrderSelect(Result.order))
            ;
    }

    const ulong Interval2 = ::GetMicrosecondCount() - StartTime2;

    Result.comment += " " + ::DoubleToString(Interval1 / 1000.0, 3) + " + " + ::DoubleToString(Interval2 / 1000.0, 3) + " ms";

    ORDERSEND::OrderSend_Benchmark(Interval1, Interval2);

    return(Res);
  }

#undef WHILE
};

static const bool ORDERSEND::IsTester = (::MQLInfoInteger(MQL_TESTER) || ::MQLInfoInteger(MQL_OPTIMIZATION) ||
                                         ::MQLInfoInteger(MQL_VISUAL_MODE) || ::MQLInfoInteger(MQL_FRAME_MODE));

static uint ORDERSEND::OrderSend_MaxPause = 1000000; // максимальное время на синхронизацию в мкс.

// Эта строчка позволяет сделать все OrderSend корректными.
#define OrderSend ORDERSEND::OrderSendSync

Tudo é embrulhado deliberadamente na aula para reduzir o número de problemas potenciais.

Usando

OrderSend(Request, Result); // Все так же, как со штатной OrderSend

Ou seja, para que todas as ordens sejam sincronizadas com o ambiente de negociação e evitar as armadilhas, é suficiente escrever este código fonte como um arquivo mqh- e usar o #include correspondente em seus programas.

Razão: