Der große und schreckliche MT4 für immer (oder wie man einen Übergang strategisch plant) - Seite 23

 

Es scheint folgendermaßen zu funktionieren:

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

aber es ist sehr langsam und keine besonders gute Lösung.

 
Igor Makanu:

Es scheint folgendermaßen zu funktionieren:

aber es ist sehr langsam und keine besonders gute Lösung.

Sie haben fast diese Möglichkeit geschaffen.

 

Generell benötigen wir von den Entwicklern eine Art synchrones RefreshPositions(), das zuverlässig den Stand der Positionen + Aufträge vom Server zurückliefert

Dann sendet derjenige, der es braucht, die Aufträge asynchron, und derjenige, der es nicht braucht, wartet im Hauptteil des Programms auf die Antwort des Servers.

 
Ihor Herasko:

Das ist es ja, das war es. Wenn das Skript zu Ende ist, bleiben ein oder zwei Positionen hängen (je nachdem, wie viele Drucke in den Code eingefügt wurden).

Code:

Ergebnis:

Um das Bild zu vervollständigen, fügen Sie den Handelsereignis-Listener aus dem Artikel https://www.mql5.com/ru/articles/2513 in das nebenstehende Diagramm ein

Um die Reihenfolge der Ereignisse zu sehen

//+------------------------------------------------------------------+
//|                                     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 output - Request ID, die vom Terminal beim Absenden der Bestellung gesetzt wird

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

Wie viele Aufträge werden wirklich dorthin geschickt?

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

Imho garantiert OnTradeTransaction() auch nichts, die Abfolge der Ereignisse ist nicht garantiert, ebenso wenig wie die Zustellung der Informationen an das Terminal selbst - ich meine den Fall mit nicht den zuverlässigsten Internet-Providern

es gibt keinen Mechanismus zur Steuerung von OnTradeTransaction(), oder ich habe alle Ereignisse in strikter Reihenfolge erhalten oder nicht


PZY: Ich wünschte, ein nicht allzu beschäftigter MQ-Programmierer könnte 2 Stunden Zeit finden, um eine Funktion zu schreiben, die eine Textbeschreibung des Fehlercodes zurückgibt. Das wäre großartig, und es gäbe weniger Schreibarbeit in MQL5 und keinen Bedarf in MT4 - lassen Sie sie es manuell tun

;)

 

In der Codobase gefunden und die neuesten Codes hinzugefügt

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

Also verlangten die Leute Zugang zur Blackbox - und sie bekamen ihn.
Jetzt müssen Sie die Synchronisierung selbst vornehmen. Gefragt? Das taten sie. Haben sie? Das taten sie. Ist es gut? Sie sagten, es würde gut sein. Sobald sie gegeben war, wurde sie schlecht.

1. ich habe nicht darum gebeten.

2. Niemand hat gesagt, dass der Preis die Datenintegrität sein würde, die viel wichtiger ist.

Können Sie statt nackter Demagogie wie "es ist unsere Schuld" eine Lösung ohne Krücken anbieten?

 
Rashid Umarov:

In kodobase gefunden und die neuesten Codes hinzugefügt

Ich habe den gleichen Code in einer halben Stunde mit der ME-Hilfe erstellt - ich habe die Fehlercodes geöffnet, die Maus markiert, Strg+C gedrückt, eine leere Excel-Seite erstellt, Strg+V gedrückt und Spalten mit Groß- und Kleinschreibung und Anführungszeichen hinzugefügt

dann Strg+C+Strg+V in ME

Okay, offenbar ist "Härte ertragen" nicht nur ein Artikel aus dem Militärhandbuch, sondern eher unsere Mentalität

 
Andrei Trukhanovich:

1. ich habe nicht darum gebeten.

2. Niemand hat gesagt, dass der Preis die Datenintegrität sein würde, die viel wichtiger ist.

Können Sie anstelle der "Selbst schuld"-Demagogie eine Lösung ohne Krücken vorschlagen?

Das werde ich wahrscheinlich tun. Aber viel später. Aufgrund subjektiver Umstände. Leider. In der Zwischenzeit können Sie sich als Demagoge betrachten. Nicht verboten.
 
Igor Makanu:

Ich habe den gleichen Code in einer halben Stunde mit der ME-Hilfe erstellt - ich habe die Fehlercodes geöffnet, die Maus markiert, Strg+C gedrückt, eine leere Excel-Seite erstellt, Strg+V gedrückt und Spalten mit Groß- und Kleinschreibung und Anführungszeichen hinzugefügt.

dann Strg+C+Strg+V in ME

Okay, offenbar ist "Härte ertragen" nicht nur ein Artikel aus dem Militärhandbuch, sondern eher unsere Mentalität

Auf Russisch? Auf Spanisch? Englisch? Welcher ist es?