Добре дошли в Свободен Български ФОРЕКС форум.
Резултати от 1 до 3 от общо 3
  1. #1
    Потребител
    Регистриран
    28.04.2020
    Мнения
    66

    Примерен код за MetaTrader5

    Знам, че много колеги минават на MetaТrader5 или поне опитват да си препишат стратегиите от МТ4 на МТ5. Появяват се много проблеми, тъй като освен че терминологията на МТ5 е различна, има и ред технически проблеми. Реших докато си помагам с моите хора, да поствам и тук код който решава конкретни проблеми по МТ5. В случая ще покажа как се извлича типа на разрешените поръчки към сървъра за конкретен Symbol, като стойностите са ORDER_FILLING_FOK, ORDER_FILLING_IOC или ORDER_FILLING_RETURN. Само една от трите е възможната. Проблемът е, че в общия случай всеки опит да се вземе тази стойност, връща неверен резултат, най-вероятно защото брокерите не си дават труда да зададат тази настройка така, че да е видима за скрипт/робот. Другия вариант е просто да е бъг на Метакуотс, не знам коя е истината. Това не позволява да се напише универсален код, който да работи при всички брокери, ами за всеки брокер на принципа на пробата и грешката, да се търси верния тип поръчки. Та да се занимаваме и губиме времето с глупости, вместо да си гледаме търговските стратегии. Накратко: Не стига, че има само три типа поръчки, ами дори не можеш да извлечеш вярната стойност по техния начин, както са го дали в докуметацията. За пример мога да ви дам, че във FIX протокола може да се прати и инструкция към всеки ордер AON (ALL_OR_NONE), като разликата с FOK (FILL_OR_KILL) е, че ако няма наличен насрещен достатъчен обем за да се изпълни изцяло, ордера не се канселира (премахва), ами си стои докато не се появи достатъчно такова насрещно количество. Нормалният начин да се вземе тази стойност е чрез
    Код:
    SymbolInfoInteger(_Symbol,SYMBOL_FILLING_MODE);
    Ако отворите от стандартната библиотека на МТ5, класа дето те са го писали CSymbolInfo (в Include\Trade\SymbolInfo.mqh), стойността се извлича точно така! Което означава, че техният клас ПРОСТО НЕ РАБОТИ! И не става за ползване. За това давам примерен код на скрипт, в който има функция проверяваща с цикъл, коя е вярната стойност която Терминала би приел и процедирал при изпращане на поръчка. С леки промени може да си я интегрирате във вашия код при подготовка на структурата MqlTradeRequest за изпращане на поръчка.
    За неопитните колеги: В Едитора натискате бутона "Нов" и от Визарда избирате "Script", давате му име, например Proba_GetSymbolOrderTypeFill.mq5 и после бутона "Край". Копирате кода по-долу в тялото на скрипта и го компилирате. После ще го видите в Навигатора на Терминала в секция "Скриптове". Задействате го с двоен клик, той се изпълнява еднократно върху активната графика в момента и веднага сам се деинсталира.
    Забележка: Трябва да имате пари в акаунта, достатъчни за откриване на позиция с минималния възможен обем, иначе ще видите грешка в логовете в секция "Експерти". Никаква реална поръчка няма да бъде изпратена към сървъра, скрипта не търгува!


    Код:
    //+------------------------------------------------------------------+
    //|                                 Proba_GetSymbolOrderTypeFill.mq5 |
    //|                        Copyright 2020, MetaQuotes Software Corp. |
    //|                                             https://www.mql5.com |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2020, MetaQuotes Software Corp."
    #property link      "https://www.mql5.com"
    #property version   "1.00"
    
    
    string LastErrorLog;
    
    
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart()
    {
       long TypeFill;
       ENUM_ORDER_TYPE_FILLING CheckTypeFill;
       
       if (CheckSymbolOrdersFillingType(TypeFill, CheckTypeFill) > 0)
       {
          string strTypeFill;
          
          if (TypeFill >= 0 && TypeFill <= 2) strTypeFill = EnumToString((ENUM_ORDER_TYPE_FILLING)TypeFill);
          else strTypeFill = "";
          
                Alert("Извлечена стойност за ORDER_TYPE_FILLING = ",strTypeFill," [",TypeFill,"]","\nРазрешения тип поръчки установен опитно = ",EnumToString(CheckTypeFill)," [",(int)CheckTypeFill,"]"); 
    
       }   
    }
    //+------------------------------------------------------------------+
    
    
    int CheckSymbolOrdersFillingType(long &TypeFill, ENUM_ORDER_TYPE_FILLING &checkTypeFill)
    {
       // Тука в общия случай връща невярна стойност, извличаме го като цяло число за бъдещо сравнение след като направим и проби
       // кой е истинския разрешен тип поръчки от трите възможни ORDER_FILLING_FOK, ORDER_FILLING_IOC или ORDER_FILLING_RETURN:
       if (!SymbolInfoInteger(_Symbol,SYMBOL_FILLING_MODE,TypeFill)) { Print("Вътрешна грешка във функцията ",__FUNCTION__,"() !"); return(-1); }
    
    
       //------
       
       // Правим проби с цикъл, за да видим кой е разрешения тип поръчки за съответния Symbol. Създаваме и попълваме с данни двете задължителни 
       // структури за изпращане на поръчка, като за пробата използване минималния възможен обем за влизане. Пробата е за пазарна BUY поръчка, 
       // не е необходимо да се задава цена с request.price при пазарни поръчки:
       MqlTradeRequest request = {0}; 
       MqlTradeCheckResult checkResult = {0};
       bool flagOrdersFillTypeOK = false;
       
       request.symbol = _Symbol;
       request.type = ORDER_TYPE_BUY;
       request.action = TRADE_ACTION_DEAL;
       if (!SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN,request.volume)) { Print("Вътрешна грешка във функцията ",__FUNCTION__,"() !"); return(-1); }
       
       for (int f = 0; f < 3; f++)
       {
          request.type_filling = (ENUM_ORDER_TYPE_FILLING)f;
          
          // Ако OrderCheck() върне true, значи в този етап от цикъла сме попълнили полето request.type с правилната стойност 
          // и  излизаме от цикъла, след като сме си запазили тази стойност в checkTypeFill. Друго не ни трябва, самият резултат който се записва 
          // в структурата checkResult е без значение.       
          if (OrderCheck(request,checkResult)) { checkTypeFill = (ENUM_ORDER_TYPE_FILLING)f; flagOrdersFillTypeOK = true; break; }                          
       }
       
       if (!flagOrdersFillTypeOK ) 
          {
             // Забележка: Трябва да има пари в тествания акаунт, иначе винаги ще получавате тази грешка:
             StringConcatenate(LastErrorLog, "Вътрешна грешка: Не е разпознат типът на изпълнение на поръчките за ",_Symbol," във функцията ",__FUNCTION__,"() !"); 
             Print(LastErrorLog); 
             
             return(-1);
          } 
       
       return(1);
    }
    
    
    //----------------------------------------------------------------------------------------------------------------------

    При мене го пробвах на четири реални акаунта и при всичките извлечената стойност беше неправилна. Ето снимка от настоящия ми МТ5 Брокер Just2trade.online, връща стойност [3], което е напълно невалидна стойност, тъй като се явява 4-та поред. А валидните стойности са само три: 0, 1 и 2. Това е засега, дано да съм бил полезен на някого.


    Щракнете върху изображението за по-голям размер

Име:	j2t_SymbolOrderType.png
Прегледи:      19
Размер:	19.9 KB
ID:	10316

  2. #2
    Благодаря за информацията. Ценна е. Досега не съм търгувал на МТ5, но когато пиша експерти, опитвам се така да направя кода, че да е универсален за двете платформи. До търговските операции обаче все още не съм стигал, и затова този проблем не го знаех.

    Според мене този скрипт трябва да се направи на клас, за да може да се влага във всеки един експерт. Също така не е задължително да се прави със случаен ордер. Може да се заложи като логика в класа за търговски операции, и да се пробва директно с реален ордер. И ако не стане с единия тип, да пробва с другия и след това с третия и след това да се запоми кой работи.

    Той проблемът е, че за всеки един символ може да е различно, и освен това може да се променя с времето. Затова и аз си мисля, че ръчен скрипт не е най-добрата идея. Аз лично ще се опитам да го заложа в кода на търговския клас, така че винаги да работи правилно.

    Също така ми е много любопитно как са се справили с проблема Strategy Quant. Този продукт прави МТ4 и MT5 експерти, и те винаги работят правилно. Може би този проблем вече са го разрешили. Доколкото знам, ползват няколко хиляди реда готов MT5 код, писан от някой друг. Мисля че се казваше Ордер Reliable, но може и да греша.

  3. #3
    Потребител
    Регистриран
    28.04.2020
    Мнения
    66
    То при мене е в клас, който извлича пълно инфо за Символа който му се подаде като параметър на конструктора. Просто тука в скрипта съм отделил метода, който проверява какви са възможните типове поръчки за конкретния Символ. Впечатленията ми са, че никой не ги променя с времето. Както ги е настроил в началото персонала на брокера, така остават. Но разбира се с OnTimer() на всяка секунда се проверява да няма промени за всички извлечени параметри. Най-вече е важно да се проверява за промени в марджин изискванията, защото някой път са драстични и неочаквани. Например при читавите акции докато е отворен пазара имам ливъридж 1:20, ама като затвори пада на 1:5. А имам подозрения, че ако се очаква силна волатилност, може без предупреждение пак да го намалят (ливъриджа). Така много ме издразниха FxOpen като почна големия срут през март. На 16-март следобяд пратиха мейл, че от 17-ти вдигат марджина 5 пъти! И след полунощ вече беше вдигнат. При мене от 1:500 падна на 1:100. Добре че нямах дебели позиции иначе гушвах марджин кол-а. За няколко часа как да реагираш иначе? Като се затвориха позициите, изтеглих си парите и не мисля да се връщам повече. Та тъй, за всякакви изненадки трябва да се внимава.

    Специално в случая, имай предвид че OrderCheck() само проверява валидността на данните в подготвената структура и това е достатъчно, но ще върне true дори когато търговията не е разрешена и реално никакъв ордер не може да се изпрати. Метакуотска му работа, 'ко да прайш.

 

 

Информация за темата

Потребители разглеждащи тази тема

В момента има 1 потребител (и), разглеждащ (и) тази тема. (0 потребител (и) и 1 гост (и))

Разрешения за писане

  • Вие не може да да публикувате нови теми
  • Вие не може да публикувате мнения
  • Вие не може да публикувате прикачени файлове
  • Вие не може да редактирате вашите мнения
  •