Изучаем язык программирования MQL4

UZver

Активный участник
Ну а как по другому -
1) вначале формируем идею и задание
2) делаем математическое описание, предполагающее однозначность решения
3) а затем выбираем средства для реализации в коде
или иначе получаем многовариантность в ответах
Что мы на текущей стади и получили
1) Длина серии зависит от необходимости учитывать вариант C=О,
2) Количество серий в результате зависит от количества свечей в серии N=6 или N>=6, при чем на N>=6 то же несколько вариантов.
 

gravity

Местный знаток
В логике (A && B) то же самое что (!A || !B). Иногда полезно так перевернуть. Вот вариант:
Создать 2 флага, один свечи вверх, второй свечи вниз и сразу их поднять. Допустим надо 3 свечи подряд. Тогда создаём цикл на 3 свечи, перебираем их. Если свеча не вверх, сбрасываем флаг вверх, если свеча не вниз, сбрасываем флаг вниз. А если перебрали 3 бара, а флаг вверх не сброшен, значит все 3 свечи подряд вверх, а если флаг вниз не сброшен, значит вниз.
Остаётся добавить цикл перебора всех баров истории и счётчики найденных комбинаций.
Этот простенький пример я так и не смог решить. Не понял как создать цикл для перебора 3х баров.

И по задаче "советник на МА" у Домовенка все нормально,
Вход я сделал не на основании состояния машек на 0 и 1 барах. А на состоянии машек на 1 баре и положения цены относительно машки. Кажется большого отличия быть не должно, а код чуть меньше стал.
а у меня ,оказывается, реализация неправильная. И отличие довольно таки заметное)

Главная цель таких задач – научить начинающего программиста свободно плавать в океане знаний.
Надеюсь на продолжение темы.
 

Ugar

Гуру форума
Чё то набросал
int bars=3;
bool Up=true, Dn=true;
for(int i=1; i<=3; i++)
{
if(Close-Open<0.5*_Point)Up=false;
if(Open-Close<0.5*_Point)Dn=false;
if(!Up && !Dn)break;
}
 

ZenFX

Почетный гражданин
Нука, робят, наковыряйте такую штуку, задаем количество свечей на истории, скрипт или индюкатор или советник, работает на том инструменте, на том таймфрейме куда его накинули.
Показывает : количество серий из однонаправленных свечей от 1 до N (N максимальная серия на данном промежутке)). Свеча с нулевым телом считается свечой продолжающей серию (ибо изменение цены на данном отрезке не произошло). Результаты можно отобразить в процентах ). Да я и сам напишу, но НЕАХОТА ))), а так-то полезно для статистики, общей информации и развития. НЕ хотите можете не писать ), правописание кода проверять не буду ). ТОБИШЬ : Серия из 1 свечи - X раз, серия из 2 свечей - Y раз, серия из N свечей - Z раз ))).

P.S. Для программистов (начинающих) - задача подсчета "счастливых" билетов (сумма первых 3 чисел равна сумме вторых 3 чисел ), в пачке автобуса (номер из 9 чисел ), и билетов "ко встрече", где сумма 3 первых чисел на 1 больше или меньше суммы вторых трёх чисел , или сумма вторых 3 чисел на 1 больше или меньше суммы первых 3 чисел), результат ессесно можно отобразить в процентах )))). Где - нигде, а пригодицо ).
 
Последнее редактирование:

ZenFX

Почетный гражданин
Ну вот в общем я сам наковырял тут )), ничо не проверял, посмотрел, вроде похоже )), если кому надо - допилите ). Ну сомневаюсь конечно в пользе подсчета серий, ну да и ладно ). В качестве примера для начинающих программистов MQL сойдет, думаю. В тему случайно попал, почитал, и решил что надо ТАК )). Удачи в изучении MQL, в любом случае это полезно ).
 

Вложения

BorisSedov

Активный участник
Предлагаю подробно разобрать один важнейший аспект в программировании.

Функция (процедура).

В теме уже были приведены некоторые функции.
Сейчас мы научимся создавать свои (пользовательские) функции, которые выполняют нужные нам действия.

Для начала нужно изучить следующий раздел справочника –
Справочник MQL4 / Основы языка / Функции

Напишите функцию, которая на вход принимает значение MagicNumber (уникальный идентификатор ордера).
Функция должна вернуть суммарную прибыль по всем позициям с соответствующим идентификатором на текущем счете.
Значение прибыли для открытой позиции получать следующим образом –
C++:
Expand Collapse Copy
Profit = OrderProfit() + OrderSwap() + OrderCommission()
 

gravity

Местный знаток
Предлагаю подробно разобрать один важнейший аспект в программировании.

Функция (процедура).

В теме уже были приведены некоторые функции.
Сейчас мы научимся создавать свои (пользовательские) функции, которые выполняют нужные нам действия.

Для начала нужно изучить следующий раздел справочника –
Справочник MQL4 / Основы языка / Функции

Напишите функцию, которая на вход принимает значение MagicNumber (уникальный идентификатор ордера).
Функция должна вернуть суммарную прибыль по всем позициям с соответствующим идентификатором на текущем счете.
Значение прибыли для открытой позиции получать следующим образом –
C++:
Expand Collapse Copy
Profit = OrderProfit() + OrderSwap() + OrderCommission()
Сделал какую-то поделку используя сторонний код. Завтра выложу что получилось.
 

AlexeyVik

Программист mql4 mql5
Да, уж...
Прочёл аж 287 сообщений и ничего полезного для новичков. Ну, или почти ничего...
В одном из сообщений Андрей говорил о беспорядочной последовательности проверки условий. Так вот хочу вас заверить, что последовательность была всегда. Я не знаю когда были внесены изменения в проверку условий функции if(), но изменения такие:
Было: Независимо от результата проверок каждого из условий проверялись ВСЕ условия перечисленные в if()
C++:
Expand Collapse Copy
if(условие_1 && условие_2 && условие_3)
то-есть если условие_1 не выполнено, условие_2 и условие_3 будут проверяться.
Стало: Если одно из условий НЕ выполнено, то дальнейшая проверка не выполняется
C++:
Expand Collapse Copy
if(условие_1 && условие_2 && условие_3)
то-есть если условие_1 Не выполнено, то условие_2 и условие_3 проверяться НЕ будут.
или, если условие_1 выполнено, проверяется условие_ 2 и если оно НЕ выполнено, то условие_ 3 проверяться не будет.

И ещё хочу посоветовать новичкам научиться читать документацию, справочник по языку. К примеру обо всём что я написал можно найти в справочнике. Справочник разбит на разделы. Начните с раздела "Основы языка". Там вы найдёте всё о чем говорил Борис в первом сообщении темы. Дальше достаточно ознакомиться со списком функций в каждом разделе. Какие функции есть в наличии, что они выполняют, что они возвращают. Потом при написании кода вы всегда вспомните, что для решения поставленной задачи что-то похожее встречалось в документации. Дальше всё просто. Находите необходимое и по образцу или примеру можете писать что-то своё.
 

gravity

Местный знаток
Предлагаю подробно разобрать один важнейший аспект в программировании.

Функция (процедура).

В теме уже были приведены некоторые функции.
Сейчас мы научимся создавать свои (пользовательские) функции, которые выполняют нужные нам действия.

Для начала нужно изучить следующий раздел справочника –
Справочник MQL4 / Основы языка / Функции

Напишите функцию, которая на вход принимает значение MagicNumber (уникальный идентификатор ордера).
Функция должна вернуть суммарную прибыль по всем позициям с соответствующим идентификатором на текущем счете.
Значение прибыли для открытой позиции получать следующим образом –
C++:
Expand Collapse Copy
Profit = OrderProfit() + OrderSwap() + OrderCommission()
C++:
Expand Collapse Copy
//+------------------------------------------------------------------+
//|                                                    Магик_111.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// https://forexsystemsru.com/threads/izuchaem-jazyk-programmirovanija-mql4.87869/post-1489322
// Напишите функцию, которая на вход принимает значение MagicNumber (уникальный идентификатор ордера).
// Функция должна вернуть суммарную прибыль по всем позициям с соответствующим идентификатором на текущем счете.

//+------------------------------------------------------------------+

input int                Magic         = 12345;       // Летающий слоник

//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//+------------------------------------------------------------------+
// Условия открытия ордеров для проверки работы Безубытка            |
//+------------------------------------------------------------------+

   if(OrdersTotal()<=1) // если оредров меньше 1го
   {
      int ticket = OrderSend(Symbol(), OP_BUY, 0.01, Ask, 0, 0, 0, "Покупка", Magic, 0, Blue);//открываем BAY
   }
   if(OrdersTotal()<5) // если ордеров меньше 5и
   {
      int ticket = OrderSend(Symbol(), OP_SELL, 0.05, Bid, 0, 0, 0, "Продажа", 777, 0, Red);//открываем SELL
   }

//+------------------------------------------------------------------+

   double op = CalculateProfit(OrderMagicNumber());                      // присваиваем переменной значение функции, передаем ма

  }

//+------------------------------------------------------------------+
//  Считаем профит открытых ордеров
//+------------------------------------------------------------------+

double CalculateProfit(int magic)                                        // Название функции
{
   double Profit = 0.0;                                                  // Задаем значение переменной Profit равное 0
   for (int i=OrdersTotal()-1; i>=0; i--)                                // цикл - определеяем общее количество открытых ордеров
   {
      if (OrderSelect(i, SELECT_BY_POS))                                 // выбираем ордер для дальнейшей работы
      {
         if (/*OrderSymbol() == Symbol() && */                           // проверяем совпадает ли символ ордера с символом графика на котором установлен советник
               magic == Magic)                                           // проверяем совпадение магик номера ордера с магиком советника
         {
            if (OrderType() == OP_BUY || OrderType() == OP_SELL)         // проверяем являются ли ордера, рыночными ордерами на покупку или продажу
            {
               Profit += (OrderProfit() + OrderSwap() + OrderCommission());// суммируем профиты всех выбранных ордеров c учетом свопа и комиссии
            }
         }
      }
   } return(Profit);                                                     // возвращем функции значение суммарного профита
   Print("Профит = ", DoubleToString(Profit));
}
//+------------------------------------------------------------------+
Попытка. Не разобрался.
 

AlexeyVik

Программист mql4 mql5
Вот, к стати, Влад. Нет желания искать ваш диалог с Борисом о применении операции %. То-есть остаток от деления. Хочу сказать где я этим пользуюсь.
Раньше, когда часто встречались ДЦ с котировками 2 и 4 знака, вместо if(_Digits == 3 || _Digits == 5) использовал if(_Digits%2 == 1) это равнозначные условия. Сейчас эта необходимость отпала. Осталось только "отсеивание" позиций по типу, в направлении на север в одну кучку, а все в направлении на йух в другую. Не то чтобы в прямом смысле в кучку, а применить какое-то действие к любому, в зависимости от направленности. Точно так-же if(OrderType()%2 == 0) это значит ордер в направлении на север. В mql5 эта необходимость встречается чуток почаще чем в mql4.

Вспомнил об этом в связи с тем, что начали встречаться ДЦ с ограничениями открытых позиций и отложенных ордеров в одном направлении. Даже автовалидатор на _mql5.com настроили с проверкой. Пришлось писать...
 

gravity

Местный знаток
Исправь строки:
Код:
Expand Collapse Copy
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
//----
if(OrderSymbol()==_Symbol && OrderMagicNumber()==magic)
Спасибо, поменял.

1) Да, MODE_TRADES пропустил.
2) Проверку на символ сам закомментил, потому что в условии задания ничего про символ не сказано. Только магик.
3) Почему принт не выводит в журнале не понимаю. Исправил.
4) И вообще весь код накидал наугад скорее, не понял, что и куда там должно передаваться. Объясните, кто может. А пока пойду читать справочник, может найду чего.
C++:
Expand Collapse Copy
//+------------------------------------------------------------------+
//|                                                    Магик_111.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// https://forexsystemsru.com/threads/izuchaem-jazyk-programmirovanija-mql4.87869/post-1489322
// Напишите функцию, которая на вход принимает значение MagicNumber (уникальный идентификатор ордера).
// Функция должна вернуть суммарную прибыль по всем позициям с соответствующим идентификатором на текущем счете.

//+------------------------------------------------------------------+

input int                Magic         = 12345;       // Летающий слоник

//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
  
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
 
//+------------------------------------------------------------------+
// Условия открытия ордеров для проверки работы Безубытка            |
//+------------------------------------------------------------------+

   if(OrdersTotal()<=1) // если оредров меньше 1го
   {
      int ticket = OrderSend(Symbol(), OP_BUY, 0.01, Ask, 0, 0, 0, "Покупка", Magic, 0, Blue);//открываем BAY
   }
   if(OrdersTotal()<5) // если ордеров меньше 5и
   {
      int ticket = OrderSend(Symbol(), OP_SELL, 0.05, Bid, 0, 0, 0, "Продажа", 777, 0, Red);//открываем SELL
   }

//+------------------------------------------------------------------+

   double op = CalculateProfit(OrderMagicNumber());                      // присваиваем переменной значение функции, передаем магик
  
  } 

//+------------------------------------------------------------------+
//  Считаем профит открытых ордеров
//+------------------------------------------------------------------+

double CalculateProfit(int magic)                                        // Название функции
{
   double Profit = 0.0;                                                  // Задаем значение переменной Profit равное 0
   for (int i=OrdersTotal()-1; i>=0; i--)                                // цикл - определеяем общее количество открытых ордеров
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))                       // выбираем ордер для дальнейшей работы
      {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==magic)
         //if (/*OrderSymbol() == Symbol() && */                         // проверяем совпадает ли символ ордера с символом графика на котором установлен советник
         //      magic == Magic)                                         // проверяем совпадение магик номера ордера с магиком советника
         {
            if (OrderType() == OP_BUY || OrderType() == OP_SELL)         // проверяем являются ли ордера, рыночными ордерами на покупку или продажу
            {
               Profit += (OrderProfit() + OrderSwap() + OrderCommission());// суммируем профиты всех выбранных ордеров c учетом свопа и комиссии
            }
         }
      }
   } Print("Профит = ", DoubleToString(Profit));
   return(Profit);                                                     // возвращем функции значение суммарного профита
  
}
//+------------------------------------------------------------------+
 
Последнее редактирование:

vladradon

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

gravity

Местный знаток
Спасибо, поменял.

1) Да, MODE_TRADES пропустил.
2) Проверку на символ сам закомментил, потому что в условии задания ничего про символ не сказано. Только магик.
3) Почему принт не выводит в журнале не понимаю. Исправил.
4) И вообще весь код накидал наугад скорее, не понял, что и куда там должно передаваться. Объясните, кто может. А пока пойду читать справочник, может найду чего.
C++:
Expand Collapse Copy
//+------------------------------------------------------------------+
//|                                                    Магик_111.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// https://forexsystemsru.com/threads/izuchaem-jazyk-programmirovanija-mql4.87869/post-1489322
// Напишите функцию, которая на вход принимает значение MagicNumber (уникальный идентификатор ордера).
// Функция должна вернуть суммарную прибыль по всем позициям с соответствующим идентификатором на текущем счете.

//+------------------------------------------------------------------+

input int                Magic         = 12345;       // Летающий слоник

//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
 
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//+------------------------------------------------------------------+
// Условия открытия ордеров для проверки работы Безубытка            |
//+------------------------------------------------------------------+

   if(OrdersTotal()<=1) // если оредров меньше 1го
   {
      int ticket = OrderSend(Symbol(), OP_BUY, 0.01, Ask, 0, 0, 0, "Покупка", Magic, 0, Blue);//открываем BAY
   }
   if(OrdersTotal()<5) // если ордеров меньше 5и
   {
      int ticket = OrderSend(Symbol(), OP_SELL, 0.05, Bid, 0, 0, 0, "Продажа", 777, 0, Red);//открываем SELL
   }

//+------------------------------------------------------------------+

   double op = CalculateProfit(OrderMagicNumber());                      // присваиваем переменной значение функции, передаем магик
 
  }

//+------------------------------------------------------------------+
//  Считаем профит открытых ордеров
//+------------------------------------------------------------------+

double CalculateProfit(int magic)                                        // Название функции
{
   double Profit = 0.0;                                                  // Задаем значение переменной Profit равное 0
   for (int i=OrdersTotal()-1; i>=0; i--)                                // цикл - определеяем общее количество открытых ордеров
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))                       // выбираем ордер для дальнейшей работы
      {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==magic)
         //if (/*OrderSymbol() == Symbol() && */                         // проверяем совпадает ли символ ордера с символом графика на котором установлен советник
         //      magic == Magic)                                         // проверяем совпадение магик номера ордера с магиком советника
         {
            if (OrderType() == OP_BUY || OrderType() == OP_SELL)         // проверяем являются ли ордера, рыночными ордерами на покупку или продажу
            {
               Profit += (OrderProfit() + OrderSwap() + OrderCommission());// суммируем профиты всех выбранных ордеров c учетом свопа и комиссии
            }
         }
      }
   } Print("Профит = ", DoubleToString(Profit));
   return(Profit);                                                     // возвращем функции значение суммарного профита
 
}
//+------------------------------------------------------------------+
Почитал, так что ли получается?
Вызываем функцию CalculateProfit с параметром OrderMagicNumber(). Значение этого параметра, которое равно магику выбранного ордера, передается(копируется) в параметр magic в описании функции CalculateProfit.
Получается что OrderMagicNumber() = magic.
А вот зачем тогда нужна проверка вот этого условия OrderMagicNumber()==magic, ведь они и так равны?
Потом мы вычисляем внутри функции значение профита и с помощью return возвращаем это значение функции CalculateProfit.
В итоге у нас получится double op = CalculateProfit = Profit.

Так? Что-то тут не сходится по моему. Понять не могу.
 

Вложения

  • Screenshot_1.jpg
    Screenshot_1.jpg
    66,5 КБ · Просмотры: 14

vladradon

Программист
А вот зачем тогда нужна проверка вот этого условия OrderMagicNumber()==magic
Нет, параметр magic - это параметр, который мы задаем как входной и который выставляется ордерам нашего сова, а OrderMagicNumber() - функция, которая возвращает магик выбранного на данный момент ордера. Ордера могут быть ручные с 0-м магиком или с другим магиком. Вот поэтому мы сравниваем если (OrderMagicNumber()==magic ) - продолжаем, если нет - переходим к следующему ордеру. В остальном все верно.
 

gravity

Местный знаток
Нет, параметр magic - это параметр, который мы задаем как входной и который выставляется ордерам нашего сова, а OrderMagicNumber() - функция, которая возвращает магик выбранного на данный момент ордера. Ордера могут быть ручные с 0-м магиком или с другим магиком. Вот поэтому мы сравниваем если (OrderMagicNumber()==magic ) - продолжаем, если нет - переходим к следующему ордеру. В остальном все верно.
Спасибо! Но я все равно не понял логику. Если magic - это входной параметр, значит должно быть чтобы Magic = magic = 12345;

Тогда в этой строке вместо OrderMagicNumber() должно быть Magic?

Screenshot_3.jpg
 

Вложения

  • Screenshot_2.jpg
    Screenshot_2.jpg
    69 КБ · Просмотры: 10

vladradon

Программист
Тогда в этой строке вместо OrderMagicNumber() должно быть Magic?
Нет! OrderMagicNumber() возвращает магик ВЫБРАННОГО функцией OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ордера. В терминале может быть открыто много ордеров с разными магиками и мы в цикле все их перебираем. В каждом проходе цикла мы выбираем ордер по порядку - переменная i, и сравниваем его магик, который возвращает функция OrderMagicNumber(), с нашим магиком magic, который передается функции подсчета профита и равен Magic.
 

gravity

Местный знаток
Нет! OrderMagicNumber() возвращает магик ВЫБРАННОГО функцией OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ордера. В терминале может быть открыто много ордеров с разными магиками и мы в цикле все их перебираем. В каждом проходе цикла мы выбираем ордер по порядку - переменная i, и сравниваем его магик, который возвращает функция OrderMagicNumber(), с нашим магиком magic, который передается функции подсчета профита и равен Magic.
vladradon ценю ваши объяснения, но я не понимаю)
То что в цикле for перебираем все ордера на счете с помощью функции OrdersTotal();
это я понимаю. И что сравниваем магики всех этих ордеров тоже понимаю.
Чего не понимаю, так это того, в каком месте значение magic стало равно Magic.
 

vladradon

Программист
Чего не понимаю, так это того, в каком месте значение magic стало равно Magic.
Пропустил эту строку. Так бывает, когда пишешь код, смотришь сериал по телеку и пытаешься ответить на вопрос одновременно. :ROFLMAO:Правильно:
double op = CalculateProfit(Magic);
в скобках передаем входной параметр = Magic.
 
Последнее редактирование:

vladradon

Программист
Вот, к стати, Влад. Нет желания искать ваш диалог с Борисом о применении операции %. То-есть остаток от деления. Хочу сказать где я этим пользуюсь.
Я спорил с тем, что подобные функции, которые редко используются, не нужно задавать в начале обучения - нужны самые часто используемые в практике - научатся основам - с остальным сами разберутся.
 
Верх