MT5 ist für Programmierer, nicht für Trader - Seite 17

 
Andrey F. Zelinsky:

Die Zeiten, in denen ein Programmierer, bevor er C erlernte, Maschinenbefehle, Assembler, Fortran, PL/1, Pascal und viele andere Dinge durchlief, sind lange vorbei - alles ohne Lehrbücher, ohne richtige Erklärung, wie Volchansky oben sagte, mit einer in krummen Buchstaben ausgedruckten Dokumentation.

Dies ist die Zeit der komplexen multifunktionalen Anwendungssysteme - mit einer eingebetteten Anwendungsprogrammiersprache - und die Aufgabe dieser Sprache ist es, das Anwendungsterminal den Anwendungsnutzern zur Verfügung zu stellen, die, ohne sich in die Programmierung vertiefen zu müssen, diese Terminalsprache in kurzer Zeit erlernen und nutzen können.


Ich bin einverstanden! Richtig formuliert. Das Handelsterminal sollte den Handel erleichtern.

 
ILNUR777:
An wem orientieren Sie sich? Als Gesicht des Unternehmens ist es nicht nett, wenn Sie in Trolling abgleiten. Sie haben bereits geschrieben, dass selbst diejenigen, die Erfahrung mit MT4 haben, Schwierigkeiten haben. Und sie brauchen es nicht.

Siehst du Trolling?

Ich habe schon oft geschrieben, dass es viele Möglichkeiten gibt, einen Test-EA für Ihre Strategie zu schreiben.

Ich habe sogar einen Link zur Hilfe angegeben. Aber wenn wir anfangen würden, Fragen zur Hilfe zu stellen, würden wir sehen, dass wir an dieser Art von Wissen interessiert sind. Aber es wurde immer wieder darauf hingewiesen, wie schlecht alles ist.

Deshalb sage ich - vielleicht die Generation, die wir jetzt haben - 18 Jahre alt, Eltern-Schwiegertochter müssen ein Auto kaufen, 21 - ein Haus kaufen. Aber zu studieren - nein, warum?

 
Mickey Moose:

Wie kompliziert ist der Assembler? Ich brauche seine Funktionen

Warum? Schreiben Sie es in µl5. Es ist einfach und unkompliziert.
 
Artyom Trishkin:

Denn noch vor 10 Jahren haben Anfänger in diesem Forum ganz andere Fragen gestellt - viel komplizierter und interessanter.

Übrigens, die heutigen Fragen in MQL4 sind viel informativer als in MQL5. Der Grund liegt auf der Hand und ist nicht das Alter der MQL-Versionen.

 
Alexey Viktorov:

Nein, das weiß ich nicht. Wie meinen Sie das?

Alexey, ich kann dir jetzt wirklich kein Beispiel nennen. Aber Sie experimentieren gerne - lassen Sie es laufen und sehen Sie, was es mit verschiedenen Eingabedaten ergibt.

Es fällt mir nur schwer, mich jetzt daran zu erinnern und danach zu suchen.

Nun, fxsaber gab ein Beispiel (ich habe es für mich geändert), vergleichen Sie den Code:

//+------------------------------------------------------------------+
//| Возвращает смещение бара таймфрейма по времени                   |
//+------------------------------------------------------------------+
int CTimes::BarShift(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const datetime time) const
  {
   int res=WRONG_VALUE;
   datetime last_bar;
   if(::SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE,last_bar)){
      if(time>last_bar) res=0;
      else{
         const int shift=::Bars(symbol_name,timeframe,time,last_bar);
         if(shift>0) res=shift-1;
         }
      }
   return(res);
  }
//+------------------------------------------------------------------+

Hier können Sie sehen, unter welchen Bedingungen Bars() ein Foul zurückgibt.

 
fxsaber:

Das erste, was ein Anfänger schreibt, ist ein Handelsskript. Der zweite ist ein einfacher Indikator. Der dritte - ein einfacher Expert Advisor.

Schon die erste Stufe in MQL4 ist schneller als in MQL5.

Ein Handelsskript? Warum nicht ein Expert Advisor oder sogar ein Ersatz für die Standardbibliothek?

Meiner Meinung nach ist das Schreiben eines Handelsskripts eine klare Aufgabe für Fortgeschrittene und keinesfalls für einen Anfänger geeignet.

Ein Anfänger sollte sich zunächst auf die einfachste Zeilenausgabe beschränken. Dann - ein einfacher Indikator. Und erst dann können Sie Indikatoren und Handelsfunktionen abfragen.

 
Mickey Moose:

Wie kompliziert ist der Assembler? Ich brauche seine Funktionen.

Welche Funktionen?

Assembler ist zu spezifisch, um zu sagen: "Ich brauche seine Funktionen".

 

Ein neues Beispiel zum Thema, was die SB an Neulinge im Forum verkauft und warum es selbst weit entfernte Faulpelze sehr schwer haben. Heute habe ich eine sehr konstruktive Frage zu MQL5 erhalten, ohne zu jammern.

Dies ist das Forum für Handel, automatisierte Handelssysteme und das Testen von Handelsstrategien

Wanzen, Wanzen, Fragen

damirqa, 2018.01.09 12:14

Hallo! Ich habe das Studium von MQL5 aufhttps://www.mql5.com/ru/articles/100 begonnen. Ich habe es versucht und erhielt die Fehlermeldung 4756. Ich habe in der Dokumentation nachgeschaut und es war nicht besser. Ich dachte, ich beginne mit etwas Einfachem (Warnung/Drucken...). Eine der wichtigsten Funktionen ist OrderSend. Ich habe angefangen, das Forum/die Dokumentation zu durchsuchen, wie man OrderSend verwendet. Ich habe diesen Artikelhttps://www.mql5.com/ru/docs/constants/tradingconstants/enum_trade_request_actions gefundenund den Code für die Eröffnung einer Kaufposition gefunden. Ich habe Fehler 4756 und Retcode 10030. Ich habe verstanden, dass 10030 - es ist die OrderSend-Eigenschaft, aber ich habe nicht verstanden, wie diese Eigenschaft verwendet werden sollte (ich habe mir den Code von jemand anderem angesehen) und wofür sie hauptsächlich verwendet wird. Dann öffnete ichhttps://www.mql5.com/ru/docs/trading/ordersend, kopierte den Code, führte ihn aus und er funktionierte einwandfrei.
Aber ich verstehe immer noch nicht, warum der Fehler 4756 auftritt und wie man ihn loswerden kann, ebenso wie den Fehler 10030.

Ich habe mir den Code zwischen

void OnTick(){
      //--- объявление и инициализация запроса и результата
      MqlTradeRequest request={0};
      MqlTradeResult  result={0};
      //--- параметры запроса
      request.action   =TRADE_ACTION_DEAL;                     // тип торговой операции
      request.symbol   =Symbol();                              // символ
      request.volume   =0.1;                                   // объем в 0.1 лот
      request.type     =ORDER_TYPE_BUY;                        // тип ордера
      request.price    =SymbolInfoDouble(Symbol(),SYMBOL_ASK); // цена для открытия
      request.deviation=5;                                     // допустимое отклонение от цены
      request.magic    =EXPERT_MAGIC;                          // MagicNumber ордера
      //--- отправка запроса
      if(!OrderSend(request,result))
         PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
         Alert(GetLastError());
      //--- информация об операции
      PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
   }

und diese.

uint SendRandomPendingOrder(long const magic_number) 
  { 
//--- готовим запрос 
   MqlTradeRequest request={0}; 
   request.action=TRADE_ACTION_PENDING;         // установка отложенного ордера 
   request.magic=magic_number;                  // ORDER_MAGIC 
   request.symbol=_Symbol;                      // инструмент 
   request.volume=0.1;                          // объем в 0.1 лот 
   request.sl=0;                                // Stop Loss не указан 
   request.tp=0;                                // Take Profit не указан    
//--- сформируем тип ордера 
   request.type=GetRandomType();                // тип ордера 
//---сформируем цену для отложенного ордера 
   request.price=GetRandomPrice(request.type);  // цена для открытия 
//--- отправим торговый приказ 
   MqlTradeResult result={0}; 
   OrderSend(request,result); 
//--- выведем в лог ответ сервера   
   Print(__FUNCTION__,":",result.comment); 
   if(result.retcode==10016) Print(result.bid,result.ask,result.price); 
//--- вернем код ответа торгового сервера 
   return result.retcode; 
  } 

Sie scheinen mir fast identisch zu sein, ich sehe die Stellen nicht, an denen diese Fehler auftreten (4756 und 10030). Zeigen Sie mit dem Finger und erklären Sie bitte


Antwort des Moderators

Forum über Handel, automatische Handelssysteme und Strategietester

Fehler, Irrtümer, Fragen

Wladimir Karputow, 2018.01.09 12:20


Verwenden Sie die Handelsklasse CTrade - so machen Sie garantiert so wenig Fehler wie möglich.

Beispiel für das Senden eines Handelsauftrags zur Eröffnung eines Kaufs:


Das hat wahrscheinlich dazu beigetragen, die Sache zu klären. Aber in Wirklichkeit hat der Neuling ein sehr ernstes Problem.

Das heißt, Sie müssen die Links zu dem betreffenden Thema lesen. In SB wird dies durch einen wunderbaren Ort gelöst. D.h. beim Schreiben des einfachsten Handelsskripts (das erste Programm eines jeden Anfängers) ist es fast ein Kinderspiel.

 
George Merts:

Skript für den Handel Warum nicht ein Expert Advisor oder sogar ein Ersatz für die Standardbibliothek?

Meiner Meinung nach ist das Schreiben eines Handelsskripts eine eindeutige Aufgabe für Fortgeschrittene und keinesfalls für einen Anfänger geeignet.

Ein Anfänger sollte sich zunächst auf die einfachste Zeilenausgabe beschränken. Dann - ein einfacher Indikator. Und erst dann können Sie Indikatoren und Handelsfunktionen abfragen.

Ich habe sofort mit Multicurrency MTF Expert Advisor begonnen. Und ich habe mich in der Neulingsabteilung wohl gefühlt. Und ich habe nicht zu viele Fragen gestellt - ich habe ja irgendwo Hilfe und ein Gehirn...

 

Oh, und übrigens, über iBarsShift.

Hier ist mein Gegenstück Funktion (CTSTime ist eine Zeitreihe Klasse), ich denke, es ist ein bisschen kompliziert für Neulinge, auch mit den Kommentaren. Es fehlt also wirklich an SB:

// Функция ищет бар, внутри которого находится указанный момент.
// Если такой бар найден - возвращается true и ссылка rIdx устанавливает нужное значение 
// Если такой бар не найден - возвращается false и ссылка rIdx устанавливает значение на ближайший индекс,
// время которого меньше, требуемого.
// При недостаточности буффера функция возвращает false, ссылка устанавливается на отрицательное значение.   
// NOTE !!! ненаступивший момент может лежать внутри нулевого бара, в этом случае вернется true,
// даже если фактически данный момент еще не наступил. false вернется только если данный момент лежит позже
// нулевого бара. 
// Если искомый момент находится раньше самого раннего бара, возвращается false и  rIdx = INT_MAX

bool CTSTime::FindIdxOf(datetime dtMomentToFind,int& rIdx)
{
   ASSERT(dtMomentToFind > MIN_DATETIME && dtMomentToFind < NEVER_EXPIRES);

   // Пока найденный индекс - невалиден.
   rIdx = WRONG_VALUE;

   // Если данных нет - возвращаем отрицательный результат поиска.
   if(GetTSSize() == 0)
      return(false);

   // Найдем продолжительность текущего бара
   int iSecondsInBar = PeriodSeconds(m_etTimeframe);
   
   ASSERT(iSecondsInBar >= SECS_IN_MINUTE);

   datetime dtMomentOfZeroBar = GetTime(0);
   datetime dtMomentOfLastBar = GetTime(GetTSSize()-1);
   
   // Искомый момент лежит внутри или позже, чем нулевой бар ?  
   if(dtMomentToFind >= dtMomentOfZeroBar)   
      {
      rIdx = 0;
      
      // Искомый момент лежит на открытии минус первого бара или позже ?  
      if(dtMomentToFind >= dtMomentOfZeroBar + iSecondsInBar) 
         return (false);   // Искомый момент лежит после нулевого бара. 
      
      // Искомый момент лежит внутри нулевого бара.
      return(true);               
      };
      
   // Здесь ясно, что искомый момент был ранее нулевого бара. 
   
   // Проверим, может быть искомый момент лежит раньше последнего бара ? 
   if(dtMomentToFind < dtMomentOfLastBar)
      {
      // Увы, такого раннего момента в таймсерии нет. 
      // Возвращаем самый большой индекс бара, какой можем возвратить
      // (Потому, что бара со временем меньше требуемого - в таймсерии нет).
      rIdx = INT_MAX;
      return(false);
      };

   // Здесь ясно, что искомый момент был позже начала самого раннего бара, но раньше начала самого нового бара.

   ASSERT(GetTSSize()  > 1);  // Проверим, размер буффера должен быть минимум два бара. (Иначе условие не выполняется, что искомый момент был позже начала самого раннего бара, но раньше начала самого нового бара, не выполняется)

   // Ищем примерно, где был данный момент.
   ASSERT(dtMomentOfZeroBar > dtMomentToFind);
   ASSERT(dtMomentOfZeroBar > dtMomentOfLastBar);
   
   ulong ulSecFromSearchToLatest = dtMomentOfZeroBar - dtMomentToFind;   
   ulong ulSecFromEarlestToLatest = dtMomentOfZeroBar - dtMomentOfLastBar;
   
   ASSERT(ulSecFromEarlestToLatest > ulSecFromSearchToLatest);
    
   double dResIdx = (double)ulSecFromSearchToLatest*(double)(GetTSSize()-1)/(double)ulSecFromEarlestToLatest;
   
   ASSERT(dResIdx <INT_MAX && dResIdx >= 0);
   
   int iResIdx = (int)MathRound(dResIdx);
   
   ASSERT(iResIdx >= 0 && iResIdx<(int)GetTSSize());   // По идее, мы должны уложиться в этот диапазон.
   
   // Поскольку мы исследуем минимум два бара (текущий и следующий),
   // Текущий бар не должен быть нулевым.
   // Поскольку случай с буффером в один бар у нас был отсеян раньше, мы не должны получить ошибку.
   
   if(iResIdx == 0)  
      iResIdx = 1;

   // Получен приблизительный индекс (uiResIdx).
   
   // Уточняем. Берем два бара, текущий и следующий.
   datetime dtResMoment;
   datetime dtNextMoment;
   
   
   dtResMoment = GetTime(iResIdx);
   dtNextMoment = GetTime(iResIdx-1);
   
   int iShift = 0;
   bool bUp = false;
   bool bDown = false;
   
   do
      {
      if(dtResMoment > dtMomentToFind)       // Если искомый момент раньше начала первого бара
         {
         iShift = 1;                         // Возьмем на один бар раньше.
         bUp = true;                         // Запомним направление
         }
      else                                   // Иначе - Искомый момент равен или позже начала первого бара. 
         {
         if(dtNextMoment <= dtMomentToFind)  // Если искомый момент больше или равен началу второго бара
            {
            iShift = -1;                     // Возьмем на один бар позже
            bDown = true;                    // Запомним направление
            }
         else                          // Иначе - искомый момент равен или позже начала перого бара и раньше начала  второго бара   
            {         
            iShift = 0;                // То есть, можно выходить из цикла коррекции.
            }
         }  

      iResIdx += iShift;               // Смещаемся

      if(iResIdx > (int)GetTSSize() || iResIdx <= 0) // Проверим на допустимый диапазон
         {
         ASSERT(false);    // В серии недостаточно данных (мал буффер)
         rIdx = INT_MAX;
         return(false);
         };
                  
      dtResMoment = GetTime(iResIdx);  // Запрашиваем новые данные 
      dtNextMoment = GetTime(iResIdx-1);
            
      if(bUp == true && bDown == true) // Контроль направления коррекции
         {
         ASSERT(false);                // Сменилось направление коррекции !!!
         iShift = 0;
         }           
      }
   while(iShift != 0);
   
   // В этой точке искомый момент равен или позже начала перого бара и раньше начала  второго бара.
   // Проверим, может быть, искомый момент позже конца первого бара, но раньше начала второго бара 
   // (между барами разрыв, и искомый момент находится именно там)
   
   // Ясно, что ссылка должна показывать на первый бар в любом случае 
   
   rIdx = iResIdx;
   
   if(dtMomentToFind >= dtResMoment+iSecondsInBar)
      // Действительно, искомый момент - внутри разрыва между барами.
      return(false);
   
   return(true);         
};      


Grund der Beschwerde: