La grande et terrible MT4 pour toujours (ou comment organiser une transition) - page 23

 

il semble que cela fonctionne comme ça :

#include <Trade\Trade.mqh>
void OnStart()
{
   CTrade Trade;
   while(PositionsTotal() < 10)
   {
      if(OrdersTotal() > 0) continue;
      if(!Trade.Buy(0.01)) continue;
      if(OrdersTotal() == 0 && PositionsTotal() >= 10) return;
   }
}

mais c'est très lent, et ce n'est pas une très bonne solution.

 
Igor Makanu:

il semble que ça fonctionne comme ça :

mais c'est très lent, et ce n'est pas une très bonne solution.

Vous avez fait presque cette option.

 

En général, nous avons besoin d'une sorte de RefreshPositions() synchrone de la part des développeurs qui renverra de manière fiable du serveur l'état des positions et des commandes.

Ensuite, celui qui en a besoin envoie des ordres de manière asynchrone, et celui qui n'en a pas besoin attend la réponse du serveur dans le corps du programme.

 
Ihor Herasko:

C'est ça le truc, ça l'a fait. Lorsque le script termine son exécution, une ou deux positions sont laissées en suspens (en fonction du nombre d'impressions insérées dans le code).

Code :

Résultat :

Pour compléter le tableau, ajoutez l'écouteur d'événement de transaction de l'article https://www.mql5.com/ru/article s/2513 au graphique adjacent

Pour voir l'ordre des événements

//+------------------------------------------------------------------+
//|                                     TradeTransactionListener.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   PrintFormat("LAST PING=%.f ms",
               TerminalInfoInteger(TERMINAL_PING_LAST)/1000.);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   static int counter=0;   // счетчик вызовов OnTradeTransaction()
   static uint lasttime=0; // время последнего вызова OnTradeTransaction()
//---
   uint time=GetTickCount();
//--- если последняя транзакция была больше 1 секунды назад
   if(time-lasttime>1000)
     {
      counter=0; // значит, это новая торговая операция и можно сбросить счетчик
      if(IS_DEBUG_MODE)
         Print(" Новая торговая операция");
     }
   lasttime=time;
   counter++;
   Print(counter,". ",__FUNCTION__);
//--- результат выполнения торгового запроса
   ulong            lastOrderID   =trans.order;
   ENUM_ORDER_TYPE  lastOrderType =trans.order_type;
   ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- имя символа, по которому произошла транзакция
   string trans_symbol=trans.symbol;
//--- тип транзакции
   ENUM_TRADE_TRANSACTION_TYPE  trans_type=trans.type;
   switch(trans.type)
     {
      case  TRADE_TRANSACTION_POSITION:   // изменение позиции
        {
         ulong pos_ID=trans.position;
         PrintFormat("MqlTradeTransaction: Position  #%d %s modified: SL=%.5f TP=%.5f",
                     pos_ID,trans_symbol,trans.price_sl,trans.price_tp);
        }
      break;
      case TRADE_TRANSACTION_REQUEST:     // отправка торгового запроса
         PrintFormat("MqlTradeTransaction: TRADE_TRANSACTION_REQUEST");
         break;
      case TRADE_TRANSACTION_DEAL_ADD:    // добавление сделки
        {
         ulong          lastDealID   =trans.deal;
         ENUM_DEAL_TYPE lastDealType =trans.deal_type;
         double        lastDealVolume=trans.volume;
         //--- идентификатор сделки во внешней системе - тикет, присваиваемый Московской биржей
         string Exchange_ticket="";
         if(HistoryDealSelect(lastDealID))
            Exchange_ticket=HistoryDealGetString(lastDealID,DEAL_EXTERNAL_ID);
         if(Exchange_ticket!="")
            Exchange_ticket=StringFormat("(MOEX deal=%s)",Exchange_ticket);

         PrintFormat("MqlTradeTransaction: %s deal #%d %s %s %.2f lot   %s",EnumToString(trans_type),
                     lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
        }
      break;
      case TRADE_TRANSACTION_HISTORY_ADD: // добавление ордера в историю
        {
         //--- идентификатор ордера во внешней системе - тикет, присваиваемый Московской биржей
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_FILLED)
           {
            if(HistoryOrderSelect(lastOrderID))
               Exchange_ticket=HistoryOrderGetString(lastOrderID,ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("(MOEX ticket=%s)",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%d %s %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
      default: // прочие транзакции  
        {
         //--- идентификатор ордера во внешней системе - тикет, присваиваемый Московской биржей
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_PLACED)
           {
            if(OrderSelect(lastOrderID))
               Exchange_ticket=OrderGetString(ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("MOEX ticket=%s",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%d %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
     }
//--- тикет ордера    
   ulong orderID_result=result.order;
   string retcode_result=GetRetcodeID(result.retcode);
   if(orderID_result!=0)
      PrintFormat("MqlTradeResult: order #%d retcode=%s ",orderID_result,retcode_result);
//---   
  }
//+------------------------------------------------------------------+
//| переводит числовые коды ответов в строковые мнемокоды            |
//+------------------------------------------------------------------+
string GetRetcodeID(int retcode)
  {
   switch(retcode)
     {
      case 10004: return("TRADE_RETCODE_REQUOTE");             break;
      case 10006: return("TRADE_RETCODE_REJECT");              break;
      case 10007: return("TRADE_RETCODE_CANCEL");              break;
      case 10008: return("TRADE_RETCODE_PLACED");              break;
      case 10009: return("TRADE_RETCODE_DONE");                break;
      case 10010: return("TRADE_RETCODE_DONE_PARTIAL");        break;
      case 10011: return("TRADE_RETCODE_ERROR");               break;
      case 10012: return("TRADE_RETCODE_TIMEOUT");             break;
      case 10013: return("TRADE_RETCODE_INVALID");             break;
      case 10014: return("TRADE_RETCODE_INVALID_VOLUME");      break;
      case 10015: return("TRADE_RETCODE_INVALID_PRICE");       break;
      case 10016: return("TRADE_RETCODE_INVALID_STOPS");       break;
      case 10017: return("TRADE_RETCODE_TRADE_DISABLED");      break;
      case 10018: return("TRADE_RETCODE_MARKET_CLOSED");       break;
      case 10019: return("TRADE_RETCODE_NO_MONEY");            break;
      case 10020: return("TRADE_RETCODE_PRICE_CHANGED");       break;
      case 10021: return("TRADE_RETCODE_PRICE_OFF");           break;
      case 10022: return("TRADE_RETCODE_INVALID_EXPIRATION");  break;
      case 10023: return("TRADE_RETCODE_ORDER_CHANGED");       break;
      case 10024: return("TRADE_RETCODE_TOO_MANY_REQUESTS");   break;
      case 10025: return("TRADE_RETCODE_NO_CHANGES");          break;
      case 10026: return("TRADE_RETCODE_SERVER_DISABLES_AT");  break;
      case 10027: return("TRADE_RETCODE_CLIENT_DISABLES_AT");  break;
      case 10028: return("TRADE_RETCODE_LOCKED");              break;
      case 10029: return("TRADE_RETCODE_FROZEN");              break;
      case 10030: return("TRADE_RETCODE_INVALID_FILL");        break;
      case 10031: return("TRADE_RETCODE_CONNECTION");          break;
      case 10032: return("TRADE_RETCODE_ONLY_REAL");           break;
      case 10033: return("TRADE_RETCODE_LIMIT_ORDERS");        break;
      case 10034: return("TRADE_RETCODE_LIMIT_VOLUME");        break;
      case 10035: return("TRADE_RETCODE_INVALID_ORDER");       break;
      case 10036: return("TRADE_RETCODE_POSITION_CLOSED");     break;
      default:
         return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode));
         break;
     }
//---
  }
//+------------------------------------------------------------------+



+ addrequest_id - ID de la demande à définir par le terminal lors de l' envoi de la commande.

  printf("Перед открытием. PositionsTotal: %d, OrdersTotal: %d", PositionsTotal(), OrdersTotal());
      Trade.Buy(0.01); // Если нет позиции и ордера - открываем позицию.
      MqlTradeResult result;
      Trade.Result(result);
      PRINT(result.request_id);
      ...

Combien de commandes y sont réellement envoyées

С чего начать при создании торгового робота для Московской биржи MOEX
С чего начать при создании торгового робота для Московской биржи MOEX
  • www.mql5.com
Многие трейдеры на Московской бирже хотели бы автоматизировать свои торговые алгоритмы, но не знают с чего начать. Язык MQL5 предлагает не только огромный набор торговых функций, но и готовые классы, которые максимально облегчают первые шаги в алготрейдинге.
 

imho, OnTradeTransaction() ne garantit rien non plus, la séquence des événements n'est pas garantie, de même que la livraison des informations au terminal lui-même - je veux parler du cas des fournisseurs d'accès à Internet qui ne sont pas les plus fiables

il n'y a pas de mécanisme contrôlant OnTradeTransaction(), ou j'ai ou je n'ai pas reçu tous les événements dans une séquence stricte


PZY : J'aimerais qu'un programmeur MQ pas trop occupé trouve 2 heures pour écrire une fonction renvoyant une description textuelle du code d'erreur. Ce serait génial, et il y aurait moins d'écriture dans MQL5 et aucun besoin dans MT4 - laissez-les faire manuellement.

;)

 

Trouvé dans la codobase et les derniers codes ajoutés

//+------------------------------------------------------------------+
//| Возврат стрингового результата торговой операции по его коду     |
//+------------------------------------------------------------------+
string ResultRetcodeDescription(int retcode)
  {
   string str;
//----
   switch(retcode)
     {
      case TRADE_RETCODE_REQUOTE:
         str="TRADE_RETCODE_REQUOTE(Реквота)";
         break;
      case TRADE_RETCODE_REJECT:
         str="TRADE_RETCODE_REJECT(Запрос отвергнут)";
         break;
      case TRADE_RETCODE_CANCEL:
         str="TRADE_RETCODE_CANCEL(Запрос отменен трейдером)";
         break;
      case TRADE_RETCODE_PLACED:
         str="TRADE_RETCODE_PLACED(Ордер размещен)";
         break;
      case TRADE_RETCODE_DONE:
         str="TRADE_RETCODE_DONE(Заявка выполнена)";
         break;
      case TRADE_RETCODE_DONE_PARTIAL:
         str="TRADE_RETCODE_DONE_PARTIAL(Заявка выполнена частично)";
         break;
      case TRADE_RETCODE_ERROR:
         str="TRADE_RETCODE_ERROR(Ошибка обработки запроса)";
         break;
      case TRADE_RETCODE_TIMEOUT:
         str="TRADE_RETCODE_TIMEOUT(Запрос отменен по истечению времени)";
         break;
      case TRADE_RETCODE_INVALID:
         str="TRADE_RETCODE_INVALID(Неправильный запрос)";
         break;
      case TRADE_RETCODE_INVALID_VOLUME:
         str="Неправильный объем в запросе";
         break;
      case TRADE_RETCODE_INVALID_PRICE:
         str="TRADE_RETCODE_INVALID_VOLUME(Неправильная цена в запросе)";
         break;
      case TRADE_RETCODE_INVALID_STOPS:
         str="TRADE_RETCODE_INVALID_STOPS(Неправильные стопы в запросе)";
         break;
      case TRADE_RETCODE_TRADE_DISABLED:
         str="TRADE_RETCODE_TRADE_DISABLED(Торговля запрещена)";
         break;
      case TRADE_RETCODE_MARKET_CLOSED:
         str="TRADE_RETCODE_MARKET_CLOSED(Рынок закрыт)";
         break;
      case TRADE_RETCODE_NO_MONEY:
         str="TRADE_RETCODE_NO_MONEY(Нет достаточных денежных средств для выполнения запроса)";
         break;
      case TRADE_RETCODE_PRICE_CHANGED:
         str="TRADE_RETCODE_PRICE_CHANGED(Цены изменились)";
         break;
      case TRADE_RETCODE_PRICE_OFF:
         str="TRADE_RETCODE_PRICE_OFF(Отсутствуют котировки для обработки запроса)";
         break;
      case TRADE_RETCODE_INVALID_EXPIRATION:
         str="TRADE_RETCODE_INVALID_EXPIRATION(Неверная дата истечения ордера в запросе)";
         break;
      case TRADE_RETCODE_ORDER_CHANGED:
         str="TRADE_RETCODE_ORDER_CHANGED(Состояние ордера изменилось)";
         break;
      case TRADE_RETCODE_TOO_MANY_REQUESTS:
         str="TRADE_RETCODE_TOO_MANY_REQUESTS(Слишком частые запросы)";
         break;
      case TRADE_RETCODE_NO_CHANGES:
         str="TRADE_RETCODE_NO_CHANGES(В запросе нет изменений)";
         break;
      case TRADE_RETCODE_SERVER_DISABLES_AT:
         str="TRADE_RETCODE_SERVER_DISABLES_AT(Автотрейдинг запрещен сервером)";
         break;
      case TRADE_RETCODE_CLIENT_DISABLES_AT:
         str="TRADE_RETCODE_CLIENT_DISABLES_AT(Автотрейдинг запрещен клиентским терминалом)";
         break;
      case TRADE_RETCODE_LOCKED:
         str="TRADE_RETCODE_LOCKED(Запрос заблокирован для обработки)";
         break;
      case TRADE_RETCODE_FROZEN:
         str="TRADE_RETCODE_FROZEN(Ордер или позиция заморожены)";
         break;
      case TRADE_RETCODE_INVALID_FILL:
         str="TRADE_RETCODE_INVALID_FILL(Указан неподдерживаемый тип исполнения ордера по остатку)";
         break;
      case TRADE_RETCODE_CONNECTION:
         str="TRADE_RETCODE_CONNECTION(Нет соединения с торговым сервером)";
         break;
      case TRADE_RETCODE_ONLY_REAL:
         str="TRADE_RETCODE_ONLY_REAL(Операция разрешена только для реальных счетов)";
         break;
      case TRADE_RETCODE_LIMIT_ORDERS:
         str="TRADE_RETCODE_LIMIT_ORDERS(Достигнут лимит на количество отложенных ордеров)";
         break;
      case TRADE_RETCODE_LIMIT_VOLUME:
         str="TRADE_RETCODE_LIMIT_VOLUME(Достигнут лимит на объем ордеров и позиций для данного символа)";
         break;
      case TRADE_RETCODE_INVALID_ORDER:
         str="TRADE_RETCODE_INVALID_ORDER:Неверный или запрещённый тип ордера)";
         break;
      case TRADE_RETCODE_POSITION_CLOSED:
         str="TRADE_RETCODE_POSITION_CLOSED:Позиция с указанным POSITION_IDENTIFIER уже закрыта)";
         break;
      case TRADE_RETCODE_INVALID_CLOSE_VOLUME:
         str="TRADE_RETCODE_INVALID_CLOSE_VOLUME(Закрываемый объем превышает текущий объем позиции)";
         break;
      case TRADE_RETCODE_CLOSE_ORDER_EXIST:
         str="TRADE_RETCODE_CLOSE_ORDER_EXIST(Для указанной позиции уже есть ордер на закрытие)";
         break;
      case TRADE_RETCODE_LIMIT_POSITIONS:
         str="TRADE_RETCODE_LIMIT_POSITIONS(Количество открытых позиций, которое можно одновременно иметь на счете, может быть ограничено настройками сервера)";
         break;
      case TRADE_RETCODE_REJECT_CANCEL:
         str="TRADE_RETCODE_REJECT_CANCEL(Запрос на активацию отложенного ордера отклонен, а сам ордер отменен)";
         break;
      case TRADE_RETCODE_LONG_ONLY:
         str="TRADE_RETCODE_LONG_ONLY(Запрос отклонен, так как на символе установлено правило \"Разрешены только длинные позиции\")";
         break;
      case TRADE_RETCODE_SHORT_ONLY:
         str="TRADE_RETCODE_SHORT_ONLY(Запрос отклонен, так как на символе установлено правило \"Разрешены только короткие позиции\")";
         break;
      case TRADE_RETCODE_CLOSE_ONLY:
         str="TRADE_RETCODE_CLOSE_ONLY(Запрос отклонен, так как на символе установлено правило \"Разрешено только закрывать существующие позиции\")";
         break;
      case TRADE_RETCODE_FIFO_CLOSE:
         str="TRADE_RETCODE_FIFO_CLOSE(Запрос отклонен, так как для торгового счета установлено правило \"Разрешено закрывать существующие позиции только по правилу FIFO\")";
         break;
      case TRADE_RETCODE_HEDGE_PROHIBITED:
         str="TRADE_RETCODE_HEDGE_PROHIBITED(Запрос отклонен, так как для торгового счета установлено правило \"Запрещено открывать встречные позиции по одному символу\")";
         break;
      //case : str=""; break;
      //case : str=""; break;
      //case : str=""; break;
      //case : str=""; break;
      default:
         str="Неизвестный результат";
     }
//----
   return(str);
  }
 
Artyom Trishkin:

Les gens ont donc demandé l'accès à la boîte noire - ils l'ont obtenu.
Maintenant, vous devez faire la synchronisation vous-même. Demandé ? Ils l'ont fait. L'ont-ils fait ? Ils l'ont fait. C'est bon ? Ils ont dit que ce serait bien. Une fois qu'il a été donné, il est devenu mauvais.

1. Je ne l'ai pas demandé.

2. personne n'a dit que le prix serait l'intégrité des données, ce qui est beaucoup plus important.

au lieu d'une démagogie nue comme "notre faute", pouvez-vous proposer une solution sans béquilles ?

 
Rashid Umarov:

Trouvé dans kodobase et ajouté les derniers codes

J'ai fait le même code en une demi-heure à partir de l'aide ME - j'ai ouvert les codes d'erreur, j'ai mis la souris en surbrillance, j'ai fait Ctrl+C , j'ai créé une page Excel vide, j'ai fait Ctrl+V et j'ai ajouté des colonnes avec case : et des guillemets inversés.

puis Ctrl+C+Ctrl+V dans ME

ok, apparemment "endurer des difficultés" n'est pas juste un article du manuel militaire, c'est plus comme notre mentalité

 
Andrei Trukhanovich:

1. Je ne l'ai pas demandé.

2. personne n'a dit que le prix serait l'intégrité des données, ce qui est bien plus important.

Au lieu de la démagogie du "blâmez-vous", pouvez-vous proposer une solution sans béquilles ?

Je vais probablement le proposer. Mais beaucoup plus tard. En raison de circonstances subjectives. Malheureusement. En attendant, considérez-vous comme un démagogue. Pas interdit.
 
Igor Makanu:

J'ai fait le même code en une demi-heure à partir de l'aide ME - j'ai ouvert les codes d'erreur, j'ai mis la souris en surbrillance, j'ai fait Ctrl+C , j'ai créé une page Excel vide, j'ai fait Ctrl+V et j'ai ajouté des colonnes avec la casse : et des guillemets inversés.

puis Ctrl+C+Ctrl+V dans ME

ok, apparemment "endurer des difficultés" n'est pas juste un article du manuel militaire, c'est plus notre mentalité

En russe ? En espagnol ? En anglais ? Laquelle ?