Comment travailler correctement dans MT5 avec OrderSend ? - page 9

 
prostotrader:
https://www.mql5.com/ru/forum/97557/page4#comment_2891988
Документация по MQL5: Программы MQL5 / Выполнение программ
Документация по MQL5: Программы MQL5 / Выполнение программ
  • www.mql5.com
Программы MQL5 / Выполнение программ - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
fxsaber:

Désolé, je n'ai pas envie de m'occuper de vos scripts.

Ajouté par

Mais il y a un moyen de s'en sortir.

Puisque la fonction OrderrSend() est synchrone, après avoir reçu l'ordre, nous...

s'assurer que l'historique est synchronisé dans OnTradeTransaction()

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
    switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
         switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Ордер синхронизирован с историей
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }

Et pas de danse !

 
prostotrader:

Pas de danse !

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

Comment travailler correctement dans MT5 avec OrderSend ?

fxsaber, 2016.11.10 10:00

Notez qu'il s'agit d'un script et qu'il ne peut pas y avoir d'Event-over. La seule façon de s'en sortir est un sommeil stupide.

Si vous réécrivez ce script avec SB, rien ne changera.

 
fxsaber:
VOUS pouvez être aussi tordu que vous le souhaitez avec Sleep.....
 
prostotrader:
Vous pouvez vous moquer de Sleep comme vous le souhaitez....

Pourquoi répéter la même chose qui a déjà été suggérée et exprimée auparavant par d'autres personnes ?

Le fil de discussion dit tout sur les problèmes possibles avec OnTradeTransaction. Elle concerne notamment le fonctionnement de plusieurs Expert Advisors simultanément.

Les gens font des béquilles, cela ne veut pas dire qu'ils ne connaissent pas la documentation et ne savent pas comment utiliser les fonctionnalités.

OnTrade et OnTradeTransaction ont été développés exactement dans ce but. Lorsqu'ils l'ont lancé, les développeurs pensaient qu'il serait idiot de gérer plus d'un conseiller expert simultanément dans un compte.

Eh bien, ils ont eu tort à ce sujet.

Essayez d'écrire la fonction suivante dans votre Expert Advisor

  1. i = 0.
  2. Nous ouvrons une position sur le symbole [i].
  3. Si i++ >= 5, nous sortons.
  4. S'il n'y a pas de dérapage, nous retournons à l'étape 2. S'il y a un dérapage, nous sortons.
 
fxsaber:

Pourquoi répéter la même chose qui a déjà été suggérée et exprimée auparavant par d'autres personnes ?

Le fil de discussion dit tout sur les problèmes possibles avec OnTradeTransaction. Elle concerne notamment le fonctionnement de plusieurs Expert Advisors simultanément.

Les gens font des béquilles, cela ne veut pas dire qu'ils ne connaissent pas la documentation et ne savent pas comment utiliser les fonctionnalités.

OnTrade et OnTradeTransaction ont été développés exactement dans ce but. Lorsqu'ils l'ont lancé, les développeurs pensaient qu'il serait idiot de gérer plus d'un conseiller expert simultanément dans un compte.

Eh bien, ils ont eu tort à ce sujet.

Essayez d'écrire la fonction suivante dans votre Expert Advisor

  1. i = 0.
  2. Nous ouvrons une position sur le symbole [i].
  3. Si i++ >= 5, nous sortons.
  4. S'il n'y a pas de dérapage, nous retournons à l'étape 2. S'il y a un dérapage, nous sortons.

Actuellement, j'ai 41 conseillers experts qui travaillent sur un compte réel (dans un terminal) et qui se réunissent pendant une journée de négociation.

Ils ont défini 2000 ordres d'ouverture et de fermeture de positions et je ne rencontre aucune difficulté !

Ajouté

Quant à la fonctionnalité dont nous disposons, elle devrait être basée sur ce que nous avons et non sur ce dont nous avons "besoin".

Les développeurs, si possible, corrigent les bugs et les anomalies, en tenant compte des souhaits de

utilisateurs (bien que très lentement).

Je pense qu'ils vont bientôt s'occuper aussi de OederSend().

 
prostotrader:

J'ai 41 conseillers experts sur mon compte réel (dans un terminal) qui fonctionnent tous ensemble pendant une journée de négociation.

Ils établissent 2000 ordres, ouvrent et ferment des positions et je n'ai aucun problème !

Cela s'appelle s'éloigner du sujet.

Quand il s'agit de la logique la plus simple.

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

Comment travailler correctement dans MT5 avec OrderSend ?

fxsaber, 2016.11.15 13:30

Essayez d'écrire la fonction suivante dans votre EA

  1. i = 0.
  2. Ouvrir une position sur le symbole [i].
  3. Si i++ >= 5, nous sortons.
  4. Si la nouvelle position n'a pas de dérapage, nous retournons à l'étape 2. S'il y a un dérapage, nous sortons.
Quelqu'un l'échange immédiatement.
// MQL4&5-code

#property strict

#include <MT4Orders.mqh>    // https://www.mql5.com/ru/code/16006

void Func( const string &Symbols[] )
{
  const int Total = ArraySize(Symbols);
  
  for (int i = 0; i < Total; i++)
  {
    const double Price = SymbolInfoDouble(Symbols[i], SYMBOL_ASK);
    const int digits = (int)SymbolInfoInteger(Symbols[i], SYMBOL_DIGITS);
    
    if (!OrderSelect(OrderSend(Symbols[i], OP_BUY, 1, Price, 100, 0, 0, DoubleToString(Price, digits)), SELECT_BY_TICKET) ||
        (NormalizeDouble(Price - OrderOpenPrice(), digits) != 0)) // если не получилось открыть или есть проскальзывание - выходим
      break;
  }
}

void OnStart() // OnTick
{
  const string Symbols[] = {"EURUSD", "GBPUSD", "AUDUSD", "USDCAD", "USDJPY"};
  
  Func(Symbols);
}

Et quelqu'un attend le mana des développeurs.
 

J'ai déjà dit que vous êtes libre de le déformer comme vous le souhaitez (tout le monde a ce droit).

 
prostotrader:

J'ai déjà dit que vous êtes libre de déformer comme vous le souhaitez (tout le monde a ce droit).

c'était il y a longtemps, mais je me souviens de ce type, et bien, cefxsaber a fait des merveilles,

ses codes sont toujours stockés dans la base de code MT4, son code pour lire les sites sur WinInet

est encore utilisé par de nombreux programmeurs...

et donc, il me semble, qu'il n'est pas un pervers...

 
J'ai extrait l'OrderSendSync de la bibliothèque ici.
uint OrderSend_MaxPause = 1000000; // максимальное время на синхронизацию в мкс.

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

bool Waiting( const bool FlagInit = false )
{
  static ulong StartTime = 0;

  if (FlagInit)
    StartTime = ::GetMicrosecondCount();

  const bool Res = (::GetMicrosecondCount() - StartTime < OrderSend_MaxPause);

  if (Res)
    ::Sleep(0);

  return(Res);
}

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

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

bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
{
  bool Res = ::OrderSend(Request, Result);

  if (Res && !IsTester && (Result.retcode < TRADE_RETCODE_ERROR) && (OrderSend_MaxPause > 0))
  {
    Res = (Result.retcode == TRADE_RETCODE_DONE);
    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(::HistoryDealSelect(Result.deal))
          ;
    }
    else if (Request.action == TRADE_ACTION_PENDING)
    {
      if (Res)
        WHILE(::OrderSelect(Result.order))
          ;
      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 = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
          EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
        }

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

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

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

        WHILE((EqualSL && EqualTP))
          if (::OrderSelect(Result.order))
          {
            EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
            EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
          }
      }
    }
    else if (Request.action == TRADE_ACTION_REMOVE)
      if (Res)
        WHILE(::HistoryOrderSelect(Result.order))
          ;
  }

  return(Res);
}

#undef WHILE
L'idée du code doit être claire. J'ai peut-être négligé quelque chose. Je n'ai pas remarqué d'erreurs de fonctionnement.
Raison: