La gran y terrible MT4 para siempre (o cómo hacer una estrategia de transición) - página 23

 

parece que funciona así:

#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;
   }
}

pero es muy lento, y no es una solución muy buena.

 
Igor Makanu:

parece que funciona así:

pero es muy lento, y no es una solución muy buena.

Usted ha hecho casi esa opción.

 

En general, necesitamos algún tipo de RefreshPositions() sincrónico por parte de los desarrolladores que devuelva de forma fiable desde el servidor el estado de las posiciones + órdenes

Entonces el que lo necesita envía las órdenes de forma asíncrona, y el que no lo necesita espera la respuesta del servidor en el cuerpo del programa.

 
Ihor Herasko:

Esa es la cuestión, lo hizo. Cuando el script termina de ejecutarse, una o dos posiciones quedan colgadas (dependiendo de cuántas impresiones se inserten en el código).

Código:

Resultado:

Para completar el cuadro, añada el escuchador de eventos comerciales del artículo https://www.mql5.com/ru/articles/2513 al gráfico adyacente

Para ver el orden de los acontecimientos

//+------------------------------------------------------------------+
//|                                     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 solicitud que debe establecer el terminal cuando se envíe la orden

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

¿Cuántos pedidos se envían realmente allí?

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

imho, OnTradeTransaction() tampoco garantiza nada, la secuencia de eventos no está garantizada, así como la entrega de información al propio terminal - me refiero al caso con proveedores de internet no muy fiables

no hay ningún mecanismo para controlar OnTradeTransaction(), o he recibido o no todos los eventos en estricta secuencia


PZY: Me gustaría que algún programador de MQ no muy ocupado pudiera encontrar 2 horas para escribir una función que devuelva una descripción de texto del código de error. Eso sería genial, y habría menos escritura en MQL5 y no sería necesario en MT4 - que lo hagan manualmente

;)

 

Encontrado en codobase y los últimos códigos añadidos

//+------------------------------------------------------------------+
//| Возврат стрингового результата торговой операции по его коду     |
//+------------------------------------------------------------------+
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:

Así que la gente pidió acceso a la caja negra y lo consiguió.
Ahora tienes que hacer la sincronización tú mismo. ¿Preguntado? Lo hicieron. ¿Lo hicieron? Lo hicieron. ¿Es bueno? Dijeron que sería bueno. Una vez que se dio, se convirtió en algo malo.

1. Yo no lo he pedido.

2. nadie dijo que el precio sería la integridad de los datos, que es mucho más importante.

en lugar de demagogia desnuda como "nuestra culpa", ¿puede ofrecer una solución sin muletas?

 
Rashid Umarov:

Encontrado en kodobase y añadido los últimos códigos

Hice el mismo código en media hora desde la ayuda de ME - abrí los códigos de error, resalté el ratón, Ctrl+C , creé una página de Excel vacía, Ctrl+V y añadí columnas con case: y comillas

luego Ctrl+C+Ctrl+V en ME

Vale, aparentemente "soportar las dificultades" no es sólo un artículo del manual militar, es más bien nuestra mentalidad

 
Andrei Trukhanovich:

1. Yo no lo he pedido.

2. nadie dijo que el precio sería la integridad de los datos, que es mucho más importante.

En lugar de la demagogia de "echarse la culpa", ¿puede sugerir una solución sin muletas?

Probablemente lo proponga. Pero mucho más tarde. Debido a circunstancias subjetivas. Desgraciadamente. Mientras tanto, considérese un demagogo. No está prohibido.
 
Igor Makanu:

Hice el mismo código en media hora desde la ayuda de ME - abrí los códigos de error, resalté el ratón, Ctrl+C , creé una página de Excel vacía, Ctrl+V y añadí columnas con case: y comillas

luego Ctrl+C+Ctrl+V en ME

Vale, aparentemente "soportar las dificultades" no es sólo un artículo del manual militar, es más bien nuestra mentalidad

¿En ruso? ¿En español? ¿Inglés? ¿Cuál?
Razón de la queja: