伟大而可怕的MT4永远(或如何制定过渡策略) - 页 23

 

它似乎是这样工作的。

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

但它非常慢,而且不是一个很好的解决方案。

 
Igor Makanu:

它似乎是这样工作的。

但它非常慢,而且不是一个很好的解决方案。

你几乎已经做出了这个选择。

关于交易、自动交易系统和交易策略测试的论坛

伟大而可怕的永远的MT4(或如何制定迁移策略)

fxsaber, 2021.05.09 00:36

你可以使用这个条件。

while (OrdersTotal() + PositionsTotal < 100)
 

一般来说,我们需要开发人员提供某种同步的RefreshPositions(),它将可靠地从服务器返回位置+订单的状态。

然后,需要的人异步发送命令,不需要的人在程序的主体中等待服务器的回答。

 
Ihor Herasko:

这就是问题所在,它确实如此。当脚本运行结束时,会有一个或两个位置被挂起(取决于代码中插入了多少个印刷品)。

代码。

结果。

为了使画面更完整,将文章中的交易事件监听器https://www.mql5.com/ru/articles/2513,添加到相邻的图表中

要查看事件的顺序

//+------------------------------------------------------------------+
//|                                     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

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

有多少订单是真正送到那里的

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

我认为,OnTradeTransaction()也不能保证任何事情,事件的顺序不能保证,信息传递到终端本身也不能保证--我指的是在互联网供应商不是最可靠的情况下。

没有机制来控制OnTradeTransaction(),或者我已经或没有严格按照顺序收到所有事件。


PZY: 我希望一些不太忙的MQ程序员能抽出2个小时来写一个函数,返回错误代码的文本描述。 那就太好了,在MQL5中可以少写一些,在MT4中也不需要--让他们手动来做。

;)

 

在codobase中找到,并添加了最新的代码

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

所以人们要求进入黑匣子--他们得到了。
现在你必须自己进行同步。问了吗?他们做到了。他们有吗?他们做到了。它好吗?他们说,这将是很好的。一旦给了,就变坏了。

1.我没有要求这样做。

2.没有人说价格会是数据的完整性,这一点要重要得多。

而不是像 "我们的错 "这样赤裸裸的蛊惑人心,你能不能提供一个没有拐杖的解决方案?

 
Rashid Umarov:

在kodobase中找到并添加了最新的代码

我在半小时内从ME的帮助下完成了同样的代码--打开错误代码,突出显示鼠标,Ctrl+C ,创建一个空的Excel页面,Ctrl+V,用case:和倒置的逗号添加列

然后在ME中Ctrl+ C +Ctrl+V

好吧,显然,"忍受困难 "不仅仅是军事手册中的一条,它更像是我们的心态。

 
Andrei Trukhanovich:

1.我没有要求这样做。

2.没有人说价格会是数据的完整性,这一点要重要得多。

与其说是 "责备自己 "的蛊惑人心,你能不能提出一个没有拐杖的解决方案?

我可能会提出这个建议。但要晚得多。由于主观情况。不幸的是。同时,请将自己视为一个煽动者。不禁止的。
 
Igor Makanu:

我在半小时内从ME的帮助下完成了同样的代码--打开错误代码,突出显示鼠标,Ctrl+C ,创建一个空的Excel页面,Ctrl+V,用case:和倒置的逗号添加列

然后在ME中Ctrl+ C +Ctrl+V

好吧,显然,"忍受困难 "不仅仅是军事手册中的一条,它更像是我们的心态。

用俄语?用西班牙语?英语?哪一个?