Caractéristiques du langage mql5, subtilités et techniques - page 3

 
fxsaber:

Que pourrait être OnTradeTransaction dans un script de trading ? Pas dans votre code, mais dans le script de trading de quelqu'un d'autre.
Croyez-vous sérieusement qu'un robot de trading à part entière peut être écrit dans un script ?
 
Mes amis, rapprochons-nous du sujet : j'aimerais voir des exemples de mise en œuvre de telle ou telle déclaration. Pas nécessairement du code, s'il y en a beaucoup, vous pouvez décrire la logique, par exemple, envoyer une requête pour s'assurer qu'elle est envoyée, regarder là, si vous obtenez tel ou tel code de retour, faire telle ou telle chose. C'est-à-dire des exemples de la manière la plus fiable d'obtenir des données.

Sinon, si nous nous disputons, nous passerons d'un sujet utile à plusieurs pages de chamailleries. Ensuite, nous devons tout nettoyer pour en laisser l'essence... Exactement, je voudrais l'essence de tel ou tel processus. Qu'il y ait plusieurs versions d'une implémentation de quelque chose. Il sera possible de discuter des avantages et des inconvénients de chaque méthode.

Puis, lorsque suffisamment d'informations différentes et utiles sont accumulées, l'idée vient de tout regrouper dans un tableau. Et le réapprovisionner constamment lorsque les prochains jetons utiles sont accumulés.
Je pense que cela sera utile à tout le monde.
 
Question: comment convertir un nombre en systèmes octal et hexadécimal.

Des réponses :
1.

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

8 et 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 sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

8 et 16 ricas

Maxim Kuznetsov, 2017.02.24 22:20

Soudainement, StringFormat, PrintFormat :-)

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

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

8 et 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:
Croyez-vous sérieusement qu'un robot de trading à part entière peut être écrit dans un script ?
Vous pouvez
 
Alexey Kozitsyn:

Déplacez la discussion sur les camarades fxsaber et prostotrader vers un fil séparé, s'il y a des discussions ici, le fil perdra sa pertinence pratique. Lorsqu'ils trouveront une véritable solution, ils la publieront ici. Et à mon avis, cela ne devrait pas être une branche des doutes ou de la recherche. Elle devrait être une branche de solutions pratiques. Et si quelques personnes ont des visions différentes de la question - laissez-les en discuter ailleurs.

<post to delete

Laissons la vérité se faire. J'ai eu le temps d'y réfléchir et j'ai décidé de le poster, et Vitya (Vinin) à qui j'ai demandé de dissiper mes doutes, a également suggéré de poster une discussion (confirmant mes doutes sur la suppression) - que la vérité soit trouvée. Je pense que ce serait la bonne chose à faire. Je vais commencer à les compiler plus tard de toute façon, donc je peux les poster ici au fur et à mesure qu'ils se remplissent.
 
prostotrader:

Vous n'avez pas besoin d'attendre quelques millisecondes.

Le message viendra dans OnTradeTransaction

voir code

Quel est le but de votre message ? Il arrivera dans OnTradeTransaction(), et alors ? Cela signifie que nous devons attendre l'événement. Nous attendons quand même. La signification du message de fxsaber est qu'après l'exécution de OrderSend(), les informations concernant l'action exécutée n'apparaissent pas immédiatement dans le terminal. Certaines personnes aiment attendre la fonction OnTradeTransaction(), tandis que d'autres aiment voir un ordre ou une transaction dans la liste. Voici la différence avec MT4, à titre d'exemple. Dans M4, après OrderSend(), l'ordre est déjà dans la liste des ordres, et après OrderClose(), l'ordre est toujours dans l'historique.

 
Artyom Trishkin:
Laissons la vérité se faire. J'ai eu le temps d'y réfléchir et j'ai décidé de laisser tomber, et Vitya (Vinin), à qui j'ai demandé et demandé de dissiper mes doutes, a également suggéré de laisser la discussion (confirmant mes doutes sur la suppression) - laisser naître la vérité. Je pense que ce serait la bonne chose à faire. Je vais de toute façon commencer à les comptabiliser plus tard, et les afficher ici au fur et à mesure qu'ils se remplissent.
Dans les discussions avec prostotrader, la vérité peut ne pas surgir, ce n'est pas pour cela qu'il les entame. Comme d'habitude, il ne sait même pas de quoi il parle.
 
Quel genre d'argument y a-t-il de toute façon ? Il n'y a pas de contestation ici. fxsaber nous a rappelé une fonctionnalité du terminal qui est vraiment non documentée et que tout le monde doit vraiment connaître, sinon il y aura des problèmes lors du développement des EA, que vous devrez trouver et nettoyer plus tard.
 
Artyom Trishkin:
Laissons la vérité se faire...

Artyom !

Vous êtes un homme raisonnable et politiquement correct !

Quelle vérité ? Vous savez exactement de quoi nous parlons.

fxsaber a écrit un script (pas mal), mais personne n'en a fait l'éloge, alors il...

essaie de le rappeler dans chaque fil de discussion.

Bien joué !

Mais voici le problème, vous ne pouvez pas utiliser OnTradeTransaction dans ce script, donc il doit "rouler des balles" (comme Sleep ou un autre timer) de "M. OnTradeTransaction".

Et bien sûr, "se soucier" des autres utilisateurs qui ne savent pas encore que SCRIPT est meilleur que COUNTER !

EtDmitry Fedoseev est toujours contre ce que je dis, peu importe que j'aie raison ou tort.

La vérité ne peut pas être trouvée ici, car ce n'est pas une cause, mais une cause personnelle qui est mise en avant.

 
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

Tout est enveloppé délibérément dans la salle de classe pour réduire le nombre de problèmes potentiels.

Utilisation de

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

C'est-à-dire que pour rendre tous les OrderSend synchronisés avec l'environnement de trading et éviter les pièges, il suffit d'écrire ce code source comme un fichier mqh et d'utiliser le #include correspondant dans vos programmes.

Raison: