Полезно MQL: примеры и готовые рецепты

Тема в разделе "В помощь трейдеру", создана пользователем loopsider, 7 Сентябрь 2014.

  1. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    В этой ветке буду складывать полезные наработки на MQL. В сети есть много чего, но если что-то конкретное нужно, то ни в жизнь не найдешь.

    Вот мегаполезная библиотека для работы с цветами. В частности, содержит функции конвертации MQL типа color в RGB, HSV и все переходы между ними. А также многое другое. Документация здесь Пожалуйста, войдите или зарегистрируйтесь для просмотра ссылок
     

    Вложения:

    Admin103, Kozubus и bellduke нравится это.
  2. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    А вот интересный пример того, как закрасить пространство между двумя линиями индикатора.
    aaa.PNG
    Автор: mladen c forex-tsd
    Так сразу не догадаешься как такую штуку сделать...
     

    Вложения:

    Последнее редактирование: 7 Сентябрь 2014
    Hannay, Klaus Lebentz и bellduke нравится это.
  3. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Периодически возникает потребность отрисовать линию индикатора прямо из советника. Как это сделать? Советник может использовать любой индикатор, с этим нет проблем. А вот чтобы нарисовать на графике те линии, что он получает - стандартных средств для этого в MQL нет. Приходится извращаться.
    Видимо, наилучшее решение - рисовать кривую из эксперта с помощью трендовых линий. Получается вполне натурально
    aaaa.PNG
    Пример советника прилагаю. Код мой.
     

    Вложения:

  4. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Интересный вопрос: как советнику получить список всех символов, доступных в окне Обзор рынка? Прилагаемый скрипт демонстрирует решение. Он читает список всех инструментов из системного файла МТ symbols.sel и пишет список в журнал те из них, по которым разрешена торговля.
    Автор: hrenfx
    Более подробно вопрос рассмотрен здесь Пожалуйста, войдите или зарегистрируйтесь для просмотра ссылок
     

    Вложения:

    Последнее редактирование: 23 Октябрь 2014
    Andre_KMS нравится это.
  5. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Простейший пример того, как в mql4 можно работать с кнопками. Создать кнопку, проверить статус (нажата/не нажата), отжать кнопку если нажата, выполнить соответствующее действие. Советник выводит на экран кнопку и прямоугольник
    but1.PNG
    Если на кнопку нажать, советник уберет прямоугольник
    but2.PNG
    Еще раз нажать - опять выведет, и т.д.
     

    Вложения:

    • Button_test.mq4
      Размер файла:
      8,6 КБ
      Просмотров:
      105
    Admin103, momcom, Starky и 3 другим нравится это.
  6. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Еще один пример работы с графикой. Советник заливает график вот таким симпатичным градиентом
    gradient.PNG
     

    Вложения:

    • gradient.mq4
      Размер файла:
      2,1 КБ
      Просмотров:
      30
    Ducat, Hannay, Andre_KMS и 6 другим нравится это.
  7. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как сделать выпадающий список в настройках советника/скрипта/индикатора?
    Одно из мегаполезных свойств обновленного языка MQL4 (MQL4++).

    Пример 1.
    В коде прописываем
    Код:
    input ENUM_APPLIED_PRICE   AppliedPrice   = PRICE_CLOSE;
    В результате получаем выпадающий список, соответствующий перечислению ENUM_APPLIED_PRICE
    a1.PNG

    Пример 2.
    Создаем пользовательский тип-перечесление DayOfWeek и задаем перменную Day этого типа
    Код:
    enum DayOfWeek
    {
       Понедельник,
       Вторник,
       Среда,
       Четверг,
       Пятница,
       Суббота,
       Воскресенье
    };
    input DayOfWeek Day;
    В резльтате получаем выпадающий список в настройках
    a2.PNG
     
    zz7z, Admin103, momcom и 5 другим нравится это.
  8. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как эмулировать приход тика для индикаторов, экспертов и в оффлайн графиках?

    Проблема имитации тиков возникает во-первых, при создании оффлайновых графиков (например, Пожалуйста, войдите или зарегистрируйтесь для просмотра ссылок) - для того, чтобы на них можно было "вешать" советники - а во-вторых, при запуске советников на выходных (т.к. советнику для старта как правило необходим приход тика).

    Задача решается использованием недокументированной, но хорошо известной в узких кругах особенности МТ4. Фишка заключается в том, что посылка определенных команд через импортированную стандартную Win32 функцию PostMessage приводит к некоторым эффектам, часть из которых оказываются полезными. В частности, эмуляция тика.

    Вот код скрипта, который выполняет однократную посылку тика на график (для билдов 600+)
    Код:
    #include <WinUser32.mqh>
    #import "user32.dll"
       int RegisterWindowMessageW(string a0);
    #import
    
    void start() {
       int message = RegisterWindowMessageW("MetaTrader4_Internal_Message");
       int hwd = WindowHandle(Symbol(), Period());
       PostMessageW(hwd, message, 2, 1);
    }
    
    Все гениальное просто, не правда ли? :)
     
    forexfox, Admin103, momcom и 3 другим нравится это.
  9. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как программно имитировать нажатие клавиши (комбинации клавиш) на клавиатуре?

    Очень просто, тоже через PostMessage. Вот пример скрипта, который нажимает клавишу HOME:
    Код:
    #include <WinUser32.mqh>
    #define VK_HOME   0x24
    void start() {
       int handle=WindowHandle(Symbol(),Period());
       PostMessageA(handle,WM_KEYDOWN,VK_HOME,0);
    }
    

    Чуть более сложный вариант, который использует системную функцию keybd_event из системной виндовой библиотеки user32.dll. Вот код скрипта, который "нажимает" сочетание клавиш Ctrl+буква или Alt+буква. С настройками по умолчанию нажимается Ctrl+T.
    Код:
    #import "user32.dll"
    // Функция keybd_event синтезирует нажатие клавиши. Система может использовать такое синтезируемое нажатие клавиши, чтобы создать сообщение WM_KEYUP или WM_KEYDOWN.
    // Вызывает функцию keybd_event программа обработки прерываний драйвера клавиатуры.
    void     keybd_event(int bVk,          // Определяет код виртуальной клавиши. Код должен быть значением в диапазоне от 1 до 254.
                          int bScan,        // Этот параметр не используется (Scan = 0x45).
                          int dwFlags,      // Определяет различные виды операций функции. Этот параметр может состоять из одного или нескольких ниже следующих  значений.
                                            // KEYEVENTF_EXTENDEDKEY    - Если он установлен, скэн-коду предшествует префиксный байт, имеющий значение 0xE0 (224).
                                            // KEYEVENTF_KEYUP          - Если он установлен, клавиша была отпущена. Если не установлен, клавиша была нажата.
                          int dwExtraInfo); // Определяет дополнительное значение, связанное с нажатием клавиши.
                                            // Моделируем нажатие клавиши:                        keybd_event (VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY|0, 0);
                                            // Моделируем возврат клавиши в не нажатое состояние: keybd_event (VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP, 0);
    #import
    
    #define PAUSE 10
    #define VK_MENU 0x12 //ALT key
    #define VK_CONTROL 0x11 //CTRL key
    
    #property show_inputs
    extern   int     CtrlAlt=0;   // Первая клавиша: 0 - Ctrl, 1 - Alt
    extern   string  Key="T";     // Вторая клавиша
    
    void start() {
        int FirstKey=VK_CONTROL;
        if(CtrlAlt==1)FirstKey=VK_MENU;
        int SecondKey=StringGetChar(Key,0);
        keybd_event(FirstKey,0,0,0);
        Sleep(PAUSE);
        keybd_event(SecondKey,0,0,0);
        Sleep(PAUSE);
        keybd_event(SecondKey,0,2,0);
        Sleep(PAUSE);
        keybd_event(FirstKey,0,2,0);
    }
    Интересно, что подобную комбинацию клавиш можно присвоить, например, какому-нибудь скрипту - и тогда ваш советник или индикатор сможет программно вызывать скрипт.
     
    Последнее редактирование: 14 Декабрь 2014
    Admin103 нравится это.
  10. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как сделать советник, работающий без тиков?

    Как все наверное знают, советник, прикрепленный к графику, выполняет какое-то действие только когда на график приходит очередной тик (новая цена). Если тика нет, советник ничего не делает. В некоторых случаях это проблема. Например, если у вас советник мультивалютный - ведь реагировать он будет только на тики той валютной пары, на график которой он прикреплен. А по другим парам цена может сильно измениться - советник не сможет это отследить.

    Раньше с этой проблемой боролись, зацикливая советник и прерывая его работу после каждого цикла на некоторое время с помощью паузы Sleep(). Этот способ имеет тот недостаток, что Sleep(), хоть и ничего не делает, а процессор грузит. Если ресурсы ограничены (как, например, на ВПС), то это плохо.

    В новой редакции MQL4 наконец появился стандартный механизм для реализации таких советников. Вот пример советника, который запускается без тиков с частотой, заданной в настройках.
    Код:
    extern int PauseMilliSec = 50; // pause in milliseconds
    int time;
    void OnInit() {
       EventSetMillisecondTimer(PauseMilliSec);
       time = GetTickCount();
    }
    void OnTimer() {
       int time0 = GetTickCount();
       Print("new timer event; ",(time0-time)," msec passed.");
       time = time0;
    }
    void DeInit() {
       EventKillTimer();
    }
    
    Проверяем: вешаем на любой график (сегодня суббота и тиков нет) и в журнале видим поток записей с промежутком примерно 60 мсек
    Capture.PNG
     
    Admin103, momcom, Klaus Lebentz и 2 другим нравится это.
  11. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как сделать оптимизацию в тестере стратегий по другому критерию?

    Не секрет, что при оптимизации в тестере стратегий выводятся только несколько параметров, по которым можно анализировать и отбирать результаты (прибыль, просадка, прибыльность, матожидание, количество сделок - и все). В частности, среди стандартных параметров отсутствует показатель восстановления (= отношение прибыли к максимальной просадке), который является важным критерием для оценки результативности мартингейловых советников. К счастью, в новой редакции MQL4 ничего не стоит сделать свой критерий оптимизации в тестере.

    Возьмем для примера советник MovingAverage, который есть в стандартной поставке МТ, и вставим в него показатель восстановления в качестве критерия оптимизации. Чтобы получить показатель восстановления, нам надо знать общую прибыль и максимальную просадку.
    Добавляем в общие переменные
    Код:
    double AccountBalanceStart; // начальный баланс
    double maxBalance;  // максимальный балланс
    double maxDrawdown = 0; // максимальная просадка
    
    инициализацию
    Код:
    void init() {
       AccountBalanceStart = AccountBalance();
       maxBalance = AccountBalance();
    }
    На каждом тике обновляем значения максимального балланса и просадки
    Код:
       if (AccountBalance() > maxBalance) maxBalance = AccountBalance();
       if (AccountEquity()-maxBalance < maxDrawdown) maxDrawdown = AccountEquity()-maxBalance;
    
    И самое главное - добавляем функцию OnTester(), которая возвращает вычисленный коэффициент восстановления. Эта функция автоматически вызывается МТ при выполнении совеника в тестере стратегий.
    Код:
    double OnTester() {
       double result = 0;
       if (maxDrawdown != 0) result = (AccountBalance() - AccountBalanceStart)/(-maxDrawdown);
       return(NormalizeDouble(result,3));
    }
    Ну вот и все. Компилируем, запускаем в тестере в режиме оптимизации -- и в списке параметров отчета появляется новая графа "Результат OnTester", который и есть наш любимый коэффициент восстановления.
    Capture.PNG
    Модифицированный советник MovingAverage прилагается.

    ======================================
    Добавлено 06.04.15:

    Мое внимание обратили на то, что указанный критерий оптимизации в тестере можно реализовать гораздо проще с помощью стандартной функции TesterStatistics:
    Код:
    double GetRecoveryFactor( void )
    {
      double Res = 0;
      double MaxDD = TesterStatistics(STAT_EQUITY_DD);
      if (MaxDD != 0)
       Res = TesterStatistics(STAT_PROFIT) / MaxDD;
    
      return(Res);
    }
    
    double OnTester( void )
    {
      return(GetRecoveryFactor());
    }
     

    Вложения:

    Последнее редактирование: 7 Апрель 2015
    Admin103, termit, momcom и ещё 1-му нравится это.
  12. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как автоматически получить префикс и суффикс валютных пар в терминале МТ?

    Элегантное решение от mladen на форекс тсд. Советник просматривает все символы в Обзоре рынка (а точнее, в файле symbols.raw), ищет там символ EURUSD и выделяет префикс и суффикс. Вот код функции getPrefixSuffix, которая возвращает префикс и суффикс.
    Код:
    #define sectorSize  1936
    #define HFILE_ERROR -1
    void getPrefixSuffix(string& prefix, string& suffix)
    {
       int fileHandle = FileOpenHistory("symbols.raw",FILE_BIN|FILE_READ);
       if (fileHandle == HFILE_ERROR) return;
       prefix=""; suffix="";
       for(int i=0;; i++)
       {
          FileSeek(fileHandle, sectorSize*i, SEEK_SET); 
          if (FileIsEnding(fileHandle)) { prefix="err"; break; }
          string symbolName = FileReadString(fileHandle,12);
          symbolName = StringSubstr(symbolName, 0);
          int pos = StringFind(symbolName,"EURUSD",0);
          if (pos > -1)
                 {
                    if (pos>0)                         prefix = StringSubstr(symbolName,0,pos);
                    if ((pos+6)<StringLen(symbolName)) suffix = StringSubstr(symbolName,(pos+6),0);
                    break;
                 }   
       }
       if (fileHandle>-1) FileClose(fileHandle);
    }  
     
    Admin103, Klaus Lebentz, Andre_KMS и ещё 1-му нравится это.
  13. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    В продолжение простейших примеров работы с кнопками в обновленном MQL4. Первый пример приведен Пожалуйста, войдите или зарегистрируйтесь для просмотра ссылок.
    Этот пример отличается от предыдущего тем что
    1. Кнопка реагирует на нажатие сразу же а не на следующем тике,
    2. Квадрат, который выводится/убирается кнопкой можно подхватывать мышкой и передвигать по графику. Capture.PNG
     

    Вложения:

    Admin103, termit и ddos1 нравится это.
  14. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как программно нажать кнопку автоторговли (= разрешить/запретить торговлю советников в терминале)?

    Скрипт, который нажимает/отжимает кнопку автоторговли.
    Код:
    #include <WinUser32.mqh>
    
    #import "user32.dll"
    // Считывает описатель оpгана упpавления, содеpжащийся в указанном блоке диалога. Возвpащаемое значение: идентификатоp оpгана упpавления; 0 - если указанный оpган упpавления не существует.
    int      GetDlgItem(int hDlg,        // Блок диалога, содеpжащий оpган упpавления.
                         int nIDDlgItem); // Идентификатоp оpгана упpавления.
    // Возвращает идентификатор hierarchyid, представляющий n-го предка данного элемента.
    int      GetAncestor(int hWnd,      // Идентификатоp окна.
                          int gaFlags);  // Уровень окна от текущего окна (1, 2, 3...).
    int      SendMessageA(int  hWnd,      // Окно, пpинимающее сообщение или $FFFF для посылки всем всплывающим окнам в системе.
                           int  Msg,       // Тип сообщения.
                           int  wParam,    // Дополнительная инфоpмация о сообщении.
                           int& lParam[]); // Дополнительная инфоpмация о сообщении.
                      
    #import
    
    void start() {
       if (IsExpertEnabled()) ExpertEnabled (false);
          else ExpertEnabled (true);
    }
    
    // Функция включения/отключения эксперта.
    void ExpertEnabled (bool Switch) // TRUE - включить эксперт, FALSE - отключить эксперт.
    {
      int HandlWindow = WindowHandle (Symbol(), Period()); // Системный дескриптор окна.
      int HandlMT4;        // Системный дескриптор окна МТ4.
      int HandlToolbar;    // Системный дескриптор окна инструментов.
    
      int    ArIntTemp[1]; // Временный массив.
      //----
      if ((Switch && !IsExpertEnabled()) || (!Switch && IsExpertEnabled()) )  {
         HandlMT4 = GetAncestor (HandlWindow, 2); 
         HandlToolbar = GetDlgItem (HandlMT4, 0x63);
         ArIntTemp[0] = HandlToolbar;
         SendMessageA (HandlMT4, WM_COMMAND, 33020, ArIntTemp);
      }
    }
     

    Вложения:

    Последнее редактирование: 23 Июнь 2015
    Kasik и Dmitri нравится это.
  15. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Простой способ вывода текста на экран
    Альтернатива Comment'у, который выглядит совсем уж отвратно.
    От Andy_Kon на mql4 форуме
    В самом начале
    Код:
    string $txt_msg;
    там где нужно
    Код:
    $txt_msg=$txt_msg+" ТЕКСТ ";
    в самом конце
    Код:
    if($txt_msg!=""){
       if(ObjectFind("txt_msg")!= 0) {
          ObjectCreate("txt_msg", OBJ_LABEL, 0, 0, 0);
          ObjectSet("txt_msg", OBJPROP_CORNER, 0);
          ObjectSet("txt_msg", OBJPROP_XDISTANCE, 0);
          ObjectSet("txt_msg", OBJPROP_YDISTANCE, 12);
       }
       ObjectSetText("txt_msg", $txt_msg, 8, "Tahoma", Yellow);
    } else {
       ObjectDelete("txt_msg");
    }
     
    Admin103 и Klaus Lebentz нравится это.
  16. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Перевод "старых пунктов" в "новые пункты" для 4-х значных и 5-значных брокеров
    Не представляет никаких сложностей если торговать только валютными парами. А вот если торговать разными инстументами, разобраться надо или нет домножать размер пункта на 10 немного сложнее. Вот вариант
    Код:
    bool AdditionalDigit = MarketInfo(Symbol(), MODE_MARGINCALCMODE) == 0 && MarketInfo(Symbol(), MODE_PROFITCALCMODE) == 0 && Digits % 2 == 1;
    if (AdditionalDigit) point = MarketInfo(Symbol(), MODE_POINT)*10;
       else point = MarketInfo(Symbol(), MODE_POINT);
    
     
    jeniacomru и Klaus Lebentz нравится это.
  17. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Пример работы с графиками в терминале
    Закрываем все графики кроме того, на который брошен скрипт. Элементарно...
    Код:
    void OnStart(){
       long curr = ChartFirst();     
       while(curr != -1) {
          if (curr != ChartID()) ChartClose(curr);
          curr = ChartNext(curr);
       }
    }
    
     
    Klaus Lebentz нравится это.
  18. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как вычислить залог (маржу) для открытия ордера по заданной валютной паре?
    Просто:
    Код:
    One_Lot = MarketInfo(Symbol(),MODE_MARGINREQUIRED); // маржа для открытия 1 лота по текущему символу
    А вот узнать, как именно вычисляется залог можно из приведенного ниже кода
    Код:
    //+------------------------------------------------------------------+
    //|                                              MarginCalculate.mq4 |
    //|                      Copyright © 2006, MetaQuotes Software Corp. |
    //|                                        http://www.metaquotes.net |
    //+------------------------------------------------------------------+
    #property copyright "Copyright © 2006, MetaQuotes Software Corp."
    #property link      "http://www.metaquotes.net"
    //+------------------------------------------------------------------+
    //| Очень простая функция расчета маржи для форексных символов.      |
    //| Расчет автоматически идет в базовой валюте счета и не работает   |
    //| для сложных видов курсов, которые не имеют прямого пересчета     |
    //| в базовую валюту торгового счета.                                |
    //+------------------------------------------------------------------+
    double MarginCalculate(string symbol,double volume)
      {
       string first   =StringSubstr(symbol,0,3);         // первый символ,    например EUR
       string second  =StringSubstr(symbol,3,3);         // второй символ,    например USD
       string currency=AccountCurrency();                // валюта депозита,  например USD
       double leverage=AccountLeverage();                // кредитное плечо,  например 100
       double contract=MarketInfo(symbol,MODE_LOTSIZE);  // размер контракта, например 100000
       double bid     =MarketInfo(symbol,MODE_BID);      // цена бид
    //---- допускаем только стандартные форексные символы XXXYYY
       if(StringLen(symbol)!=6)
         {
          Print("MarginCalculate: '",symbol,"' must be standard forex symbol XXXYYY");
          return(0.0);
         }
    //---- проверка наличия данных
       if(bid<=0 || contract<=0)
         {
          Print("MarginCalculate: no market information for '",symbol,"'");
          return(0.0);
         }
    //---- проверяем самые простые варианты - без кроссов
       if(first==currency)   return(contract*volume/leverage);           // USDxxx
       if(second==currency)  return(contract*bid*volume/leverage);       // xxxUSD
    //---- проверяем обычные кроссы, ищем прямое преобразование через валюту депозита
       string base=currency+first;                                       // USDxxx
       if(MarketInfo(base,MODE_BID)>0) return(contract/MarketInfo(base,MODE_BID)*volume/leverage);
    //---- попробуем наоборот
       base=first+currency;                                              // xxxUSD
       if(MarketInfo(base,MODE_BID)>0) return(contract*MarketInfo(base,MODE_BID)*volume/leverage);
    //---- нет возможности прямого перерасчета
       Print("MarginCalculate: can not convert '",symbol,"'");
       return(0.0);
      }
    //+------------------------------------------------------------------+
    //| script program start function                                    |
    //+------------------------------------------------------------------+
    int start()
      {
    //----
       Print("Margin EURUSD: ",MarginCalculate("EURUSD",1.0));
       Print("Margin USDCHF: ",MarginCalculate("USDCHF",1.0));
       Print("Margin GBPCHF: ",MarginCalculate("GBPCHF",1.0));
       Print("Margin CHFJPY: ",MarginCalculate("CHFJPY",1.0));
    //----
       return(0);
      }
    //+------------------------------------------------------------------+
     
    Последнее редактирование: 25 Октябрь 2015
    Klaus Lebentz, Kasik, Pythoha и 2 другим нравится это.
  19. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Как сделать скриншоты всех сделок советника в тестере?
    Очень полезная штука - прогоняешь советник в тестере, а потом спокойно рассматриваешь все входы и выходы по сделкам.
    Логика приведенного ниже кода очень проста: отслеживаем количество ордеров в рынке, если оно изменилось (значит, сделка либо открылась, либо закрылась), делаем скриншот. Все скриншоты лежат в папке tester\files и пронумерованы по порядку.
    Код:
    int total_buy = 0;
    int total_sell = 0;
    int counter = 0;
    void start {
       ...
       любой код
       ....
       int total_buy_ = total_buy;
       int total_sell_ = total_sell;
       total_buy = 0;
       total_sell = 0;
       for (int cnt = OrdersTotal() - 1; cnt >= 0; cnt--) {
          if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) {
             if (OrderType() == OP_BUY) total_buy++;
                else if (OrderType() == OP_SELL) total_sell++;
          }
       }
       if (total_buy_ != total_buy || total_sell_ != total_sell) {
          WindowScreenShot("MyEA"+Symbol()+counter+".gif",1024,768,-1,2,1);
          Print("Screenshot #",counter);
          counter++;
       }
    }
     
    Admin103, Klaus Lebentz и Сергей Иванов нравится это.
  20. loopsider

    loopsider Бывалый Команда форума Модератор

    Регистрация:
    13 Ноябрь 2013
    Сообщения:
    4.170
    Симпатии:
    3.812
    Баллы:
    435
    Пол:
    Мужской
    Простой способ программного вызова скрипта
    Автор Scriptong
    Код:
    #define MT4_MESSAGE "MetaTrader4_Internal_Message"
    #define TA_SCRIPT_NAME "<имя скрипта>"
    
    #import "user32.dll"
      int RegisterWindowMessageA(uchar &lParam[]);
      int SendMessageA(int hWnd, int Msg, int wParam, char &lParam[]);
    #import
    
    ...
        char buf[];
        StringToCharArray(MT4_MESSAGE, buf);
        int MT4InternalMsg = RegisterWindowMessageA(buf);
        StringToCharArray(TA_SCRIPT_NAME, buf);
      
        int hwnd = WindowHandle("<символ>", <таймфрейм>);
        if (hwnd < 0)
        {
          Alert("Заданное окно для запуска скрипта не найдено.");
          return;
        }
      
        SendMessageA(hwnd, MT4InternalMsg, 16, buf);      
     
    Последнее редактирование: 16 Март 2016
    Klaus Lebentz нравится это.

.

Поделиться этой страницей

translate