Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 3

 
fxsaber:

Quale OnTradeTransaction potrebbe essere in uno script di trading? Non nel tuo codice, ma nello script di trading di qualcun altro.
Credete seriamente che un vero e proprio robot di trading possa essere scritto in uno script?
 
Amici, avviciniamoci all'argomento: vorrei vedere esempi di attuazione di questa o quella affermazione. Non necessariamente il codice, se ce n'è molto, si può descrivere la logica, per esempio, inviare la richiesta per assicurarsi che venga inviata, guardare lì, se si ottiene tale-e-questo codice di ritorno, fare così-e-così. Cioè esempi del modo più affidabile per ottenere dati.

Altrimenti, se discutiamo, passeremo da un argomento utile a diverse pagine di battibecchi. Poi dobbiamo pulire tutto per lasciarne l'essenza... Esattamente vorrei l'essenza di questo o quel processo. Che ci siano diverse versioni di qualche implementazione di qualcosa. Sarà possibile discutere vantaggi e svantaggi di ogni metodo.

Poi, quando si accumulano abbastanza informazioni utili diverse, c'è l'idea di accumulare tutto in una tabella. E rifornirlo costantemente quando si accumulano i prossimi chip utili.
Penso che questo sarà utile a tutti.
 
Domanda: come convertire un numero nei sistemi ottale ed esadecimale.

Risposte:
1.

Forum sul trading, sistemi di trading automatico e strategie di trading di prova

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.

Forum sul trading, sistemi di trading automatico e strategie di trading di prova

8 e 16 ricas

Maxim Kuznetsov, 2017.02.24 22:20

Improvvisamente, StringFormat, PrintFormat :-)

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

Forum sul trading, sistemi di trading automatico e strategie di trading di prova

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:
Credete seriamente che un vero e proprio robot di trading possa essere scritto in uno script?
È possibile
 
Alexey Kozitsyn:

Spostare la discussione dei compagni fxsaber e prostotrader in un thread separato, se ci sono discussioni qui, il thread perderà la sua rilevanza pratica. Quando troveranno una vera soluzione, la pubblicheranno qui. E secondo me, questo non dovrebbe essere un ramo dei dubbi o della ricerca. Dovrebbe essere un ramo di soluzioni pratiche. E se alcune persone hanno visioni diverse della questione - lasciatele discutere altrove.

<post da cancellare

Lasciamo che la verità sia trovata. Ho avuto il tempo di pensarci su e ho deciso di postarlo, e Vitya (Vinin) che mi sono informato e ho chiesto di dissipare i miei dubbi, mi ha anche suggerito di postare una discussione (confermando i miei dubbi sulla cancellazione) - che la verità sia trovata. Penso che sarebbe la cosa giusta da fare. Più tardi comincerò comunque a fare la tabulazione, così posso postarla qui man mano che si riempie.
 
prostotrader:

Non è necessario aspettare qualche millisecondo.

Il messaggio arriverà in OnTradeTransaction

vedere il codice

Qual è lo scopo del suo messaggio? Arriverà in OnTradeTransaction(), e allora? Significa che dobbiamo aspettare l'evento. Aspettiamo comunque. Il significato del messaggio di fxsaber è che dopo l'esecuzione di OrderSend(), le informazioni sull'azione eseguita non appaiono immediatamente nel terminale. Ad alcune persone piace aspettare OnTradeTransaction(), mentre ad altre piace vedere un ordine o un affare nella lista. Ecco la differenza rispetto a MT4, come esempio. In M4, dopo OrderSend(), l'ordine è già nella lista degli ordini, e dopo OrderClose(), l'ordine è sempre nella storia.

 
Artyom Trishkin:
Lasciamo che la verità sia trovata. Ho avuto il tempo di pensarci su e ho deciso di lasciare, e anche Vitya (Vinin), a cui ho chiesto e richiesto di dissipare i miei dubbi, ha suggerito di lasciare la discussione (confermando i miei dubbi sulla cancellazione) - lasciate che la verità nasca. Penso che sarebbe la cosa giusta da fare. Più tardi comincerò comunque a fare la tabulazione, da postare qui man mano che si riempie.
Nelle discussioni con prostotrader la verità può non emergere, non è per questo che le inizia. Come al solito non sa nemmeno di cosa sta parlando.
 
Che tipo di argomentazione c'è comunque? Non c'è alcuna controversia qui. fxsaber ci ha ricordato una caratteristica del terminale che è davvero non documentata e che tutti hanno davvero bisogno di conoscere, altrimenti ci saranno problemi quando si sviluppano gli EA, che si dovranno trovare e pulire in seguito.
 
Artyom Trishkin:
Lasciamo che la verità sia trovata...

Artyom!

Lei è un uomo ragionevole e politicamente corretto!

Quale verità? Sai esattamente di cosa stiamo parlando.

fxsaber ha scritto uno script (non male), ma nessuno l'ha lodato, quindi

cerca di ricordarlo in ogni thread.

Ben fatto!

Ma ecco il problema, non si può usare OnTradeTransaction in questo script, quindi deve "tirare le palle" (come Sleep o un altro timer) da "Mr.

E naturalmente, "preoccuparsi" degli altri utenti che non sanno ancora che SCRIPT è meglio di COUNTER!

EDmitry Fedoseev è sempre contro quello che dico, non importa se ho ragione o torto.

La verità non può essere trovata qui perché non è una causa, ma una causa personale che viene alla ribalta.

 
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

Tutto è avvolto deliberatamente nella classe per ridurre il numero di potenziali problemi.

Utilizzando

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

Cioè, per rendere tutti gli OrderSend sincronizzati con l'ambiente di trading ed evitare le insidie, è sufficiente scrivere questo codice sorgente come un file mqh e utilizzare il corrispondente #include nei vostri programmi.

Motivazione: