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

BorisSedov

Активный участник
Покажите как напишите Вы. Может получится лучше?
Мой вариант.
C++:
Expand Collapse Copy
#property strict
#property script_show_inputs

input int k = 1;

bool m[];

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
if(k<1 || k>51000000) {Print("k - ?"); return;}

int i,n,s,c;

if(k<=4) {n=10; s=n/10; c=0;}
else if(k<=25) {n=100; s=n/10; c=4;}
else if(k<=168) {n=1000; s=n/10; c=25;}
else if(k<=1229) {n=10000; s=n/10; c=168;}
else if(k<=9592) {n=100000; s=n/10; c=1229;}
else if(k<=78498) {n=1000000; s=n/10; c=9592;}
else if(k<=664579) {n=10000000; s=n/10; c=78498;}
else if(k<=5761455) {n=100000000; s=n/10; c=664579;}
else if(k<=50847534) {n=1000000000; s=n/10; c=5761455;}
else {n=1003162753; s=1000000000; c=50847534;}

fE(n);

for(i=s+1; i<=n; i++)
   {
   if(m[i])
      {
      c++;
      if(c==k) break;
      }
   }

Print("Результат: ",i);
}
//+------------------------------------------------------------------+

void fE(int n)
{
int i,s,p;

ArrayResize(m,n+1);
ArrayInitialize(m,false);

m[2]=true;
m[3]=true;

for(i=5; i<=n; i+=6) m[i]=true;
for(i=7; i<=n; i+=6) m[i]=true;
for(i=9; i<=n; i+=6) m[i]=false;

for(s=5; s*s<=n;)
   {
   if(m[s])
      {
      p=s*2;
      for(i=s*s; i<=n; i+=p) m[i]=false;
      }
   s+=2;
   if(m[s])
      {
      p=s*2;
      for(i=s*s; i<=n; i+=p) m[i]=false;
      }
   s+=4;
   }
}
C++:
Expand Collapse Copy
2019.06.27 17:55:00.444    test9 EURUSD,H1: Результат: 1299709
2019.06.27 17:55:00.335    test9 EURUSD,H1: initialized
2019.06.27 17:55:00.304    test9 EURUSD,H1 inputs: k=100000;
C++:
Expand Collapse Copy
2019.06.27 17:51:22.631    test9 EURUSD,H1: Результат: 998555221
2019.06.27 17:51:00.756    test9 EURUSD,H1: initialized
2019.06.27 17:51:00.722    test9 EURUSD,H1 inputs: k=50777999;
 
  • Like
Реакции: Ugar

Ugar

Гуру форума
Отлично. Кто нибудь из изучающий здесь программирование сможет понять устройство Вашего скрипта?
Мой скрипт наверняка поймут.
Либо Вы этой задачей решили поучить меня. Либо объяснить всем что пора вспоминать математику. А практический пример показывающий надобность этой задачи в построении торговой системы есть?
 

BorisSedov

Активный участник
Отлично. Кто нибудь из изучающий здесь программирование сможет понять устройство Вашего скрипта?
Мой скрипт наверняка поймут.
Либо Вы этой задачей решили поучить меня. Либо объяснить всем что пора вспоминать математику. А практический пример показывающий надобность этой задачи в построении торговой системы есть?
Эта задача была рассчитана на программиста с глубоким пониманием процессов, надеялся увидеть красивое решение, но получилось то, что получилось.
Начинающим, такие задачи решать еще очень рано. Мы будем двигаться постепенно, шаг за шагом.
У нас уже есть определенный прогресс, и я уверен, что те кто продолжит занятия, в скором времени научится разрабатывать собственные советники и индикаторы, которые помогут в реальной работе. При решении задач в процессе обучения, есть только одна цель и польза – это получение навыков программирования.
 

BorisSedov

Активный участник
Следующая задача.
Нужно написать скрипт, который сначала проверяет наличие открытых ордеров на счете, и если открытых ордеров нет – открывает один ордер Buy. Если в момент запуска скрипта, на счете уже есть открытый ордер/ордера, то новый открываться не должен. Уровни СтопЛосс и ТейкПрофит устанавливать не нужно.
 

Ugar

Гуру форума
Эта задача была рассчитана на программиста с глубоким пониманием процессов, надеялся увидеть красивое решение, но получилось то, что получилось.
Начинающим, такие задачи решать еще очень рано. Мы будем двигаться постепенно, шаг за шагом.
У нас уже есть определенный прогресс, и я уверен, что те кто продолжит занятия, в скором времени научится разрабатывать собственные советники и индикаторы, которые помогут в реальной работе. При решении задач в процессе обучения, есть только одна цель и польза – это получение навыков программирования.
Я думал что здесь учат новичков как наипростейшим способом запрограммировать торговую идею. Я написал скрипт, который сможет понять новичёк. А эта задача была что бы поучить меня, даже не программированию, а математике. Как оптимально решать бесполезные задачи, все уже поняли. Пора бы переходить к функциям.
Без них не получится открыть ордер, тем более узнать есть ли открытые ордера.
 

Ugar

Гуру форума
Следующая задача.
Нужно написать скрипт, который сначала проверяет наличие открытых ордеров на счете, и если открытых ордеров нет – открывает один ордер Buy. Если в момент запуска скрипта, на счете уже есть открытый ордер/ордера, то новый открываться не должен. Уровни СтопЛосс и ТейкПрофит устанавливать не нужно.
Это для кого задача, для меня или для новичков изучающих язык по этой ветке? Если для для новичков, то надо сначала объяснить понятие функции.
 

DomovenokBrest

♔♕♖♗♘♙
Пытаюсь научиться давно лет 7 - 8... результат 0! Утверждал и утверждаю, не может человек которого ни когда не учили программированию взять почитать "учебник", документацию или справку и начать писать программы...
Мне 52. Программирование никогда не изучал. Ну может фортран или бэйсик (уже не помню) в институте не профильном программированию. Начал ковырять программы года 3-4 назад, когда надоело просить сделать простейшие телодвижения: вывести настройки толщины линии, исправить ошибку и т.д. Программистом не стал. Делаю ошибки и сейчас. Что получил - немного самостоятельности в обращении с кодом, читаю код в "своих рамках", создаю те программы, до которых дорос.
 

DomovenokBrest

♔♕♖♗♘♙
Следующая задача.
Нужно написать скрипт который подсчитает количество баров на графике, у которых –
Open=Close
или
High=Close
или
Low=Close
или
High=Open
или
Low=Open
Если хотя бы одно из перечисленных условий для конкретного бара выполняется, то учитываем этот бар при подсчете.

(у меня таких баров нашлось 12 630 из 100 000).
Как то так:

C++:
Expand Collapse Copy
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Нужно написать скрипт который подсчитает количество баров на графике, у которых –
// Open=Close
// или
// High=Close
// или
// Low=Close
// или
// High=Open
// или
// Low=Open
// Если хотя бы одно из перечисленных условий для конкретного бара выполняется, то учитываем этот бар при подсчете.

// (у меня таких баров нашлось 12 630 из 100 000).
   {
int i, total, n=0; // Объявлены переменные, i, n переменной n сразу же присвоено значение 0.

total=Bars;


for(i=total-1; i>0; i--) // Сразу присвоено значение Bars-1 переменной i. После этого проверено условие что i>0,
   {                    // если это так, то выполняется один раз все, что написано внутри тела цикла.
   if((Close[i]==Open[i]) || (High[i]==Close[i]) || (Low[i]==Close[i]) || (High[i]==Open[i]) || (Low[i]==Open[i]) ) // Если одно из условий выполняется, то
      {                
      n++;              // В теле условия суммируются все подходящие цены и подсчитывается количество подходящих баров.
      Print(n);  // Выводится результат.
      }                
   }                                


}

у меня таких баров нашлось 15552
 

BorisSedov

Активный участник
Это для кого задача, для меня или для новичков изучающих язык по этой ветке? Если для новичков, то надо сначала объяснить понятие функции.
Если у вас есть интерес и желание, то мы будем только рады вашему участию в теме. :)
 

Ugar

Гуру форума
Функция это программа. В неё передаются аргуметны, Она с ними что то делает и возвращает рузультат.
Аргументы передаются в строго определённом порядке. Функции могут не иметь аргументов, тогда данные она выполняет свой код и что то возвращает. Функция может ничего не возвращать, тогда она просто выполняет свой код.
В языке программирования уже есть множество функций, их можно использовать. Но можно написать свою, такая называется пользовательской. Пользовательские можно разобрать позже.
Пока можно научиться вызывать функции из языка программирования.
В справочнике есть функция
void Print(
argument, // первое значение
... // последующие значения
);
Здесь void означает что она ничего не возвращает. Дальше идёт имя функции. Дальше идут круглые скобки. Внутри этих круглых скобок аргуметны разделяемые запятыми.
Вызываем функцию без указания типа возвращаемых данных.
Ещё пример
double NormalizeDouble(
double value, // нормализуемое число
int digits // кол-во знаков после запятой
);
Здесь double означает что функция возвращает дробное значение.
Вызываем, например присваивая возвращаемое в переменную.
double a=NormalizeDouble(0.254821212121,4);

Пример функции без аргументов
bool IsTesting();
Вызываем
bool test= IsTesting();
или
if(IsTesting())Print("Советник работет в тестере");


Зубрить все функции, тем более их аргументы не обязательно. Достаточно выделить имя функции и нажать F1. Справочник отобразит информацию об этой функции. Что она делает, возвращает и какие аргументы.
 
Последнее редактирование:

Ugar

Гуру форума
MQL языки событийные. То есть всё начинается с события.
При запуске советника или индикатора, а так же после деинициализации если программа ещё работает, происходит инициализация. При событии инициализации выполняется функция
OnInit()
{
//Всё что будет написано внутри этих скобок будет выполняться при инициализации.
}

Функция OnDeinit() выполняется при деинициализации. О причинах можно узнать в справочнике.
Функция OnTick() выполняется с приходом тика. Чаще всего, основной код советника, находится внутри фигурных скобок этой функции. После выполнения всего что внутри, ожидается новый тик и снова выполняется.
При запуске скрипта выполняется функция OnStart() то есть код внутри фигурных сколбок этой функции. После чего скрипт завершает работу.
Эти функции вызывать не надо, они сами запускаются при своём событии.
 
Последнее редактирование:

BorisSedov

Активный участник
int OrdersTotal();
Возвращает общее количество открытых и отложенных ордеров.

int OrderSend(
string symbol, // символ
int cmd, // торговая операция
double volume, // количество лотов
double price, // цена
int slippage, // проскальзывание
double stoploss, // stop loss
double takeprofit, // take profit
string comment=NULL, // комментарий
int magic=0, // идентификатор
datetime expiration=0, // срок истечения ордера
color arrow_color=clrNONE // цвет
);
Основная функция, используемая для совершения торговых операций или установки отложенного ордера.

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

Ugar

Гуру форума
Вот в этом для меня "логика и технаря" проблема! Не вижу ни логики ни последовательности, ни Учителя который весь этот хаос объяснит...
К сожалению Учителей (с большой буквы) крайне мало, даже в учебных заведениях. Такой учитель не только сам должен знать дисциплину, но и уметь учить. Некоторые "учителя" считают что достаточно самому знать то чему обучают. Не понимают что умение учить, это другое умение. Не редко попадаются "учителя" которые не только не умеют учить, но и сами не знают того чему учат. Методом научного тыка исправил программу и ну давай всех учить.
С учебниками то же проблемы. Их же писали такие же "учителя", часто не умеющие учить. Я помню как когда то давно пытался изучить бейсик для программирования синклера. Только третий купленный мной учебник мне помог.
Так что, было бы желание, хороший учебник, найти возможно, хотя и не просто. С учителями языку MQL сложнее, так как он специфический, его не преподают в вузах, все самоучки. Придётся довольствоваться теми что есть.
 

gravity

Местный знаток
Не редко попадаются "учителя" которые не только не умеют учить, но и сами не знают того чему учат. Методом научного тыка исправил программу и ну давай всех учить.
А это похоже про меня и созданную тему, да :D
Следующая задача.
Нужно написать скрипт, который сначала проверяет наличие открытых ордеров на счете, и если открытых ордеров нет – открывает один ордер Buy. Если в момент запуска скрипта, на счете уже есть открытый ордер/ордера, то новый открываться не должен. Уровни СтопЛосс и ТейкПрофит устанавливать не нужно.
Чтобы решить, пришлось посмотреть это видео с 40-й минуты, почитать справку и поковыряться в советниках.
PHP:
Expand Collapse Copy
void OnStart()
//Нужно написать скрипт, который сначала проверяет наличие открытых ордеров на счете,
//и если открытых ордеров нет – открывает один ордер Buy.
//Если в момент запуска скрипта, на счете уже есть открытый ордер/ордера, то новый открываться не должен.
//Уровни СтопЛосс и ТейкПрофит устанавливать не нужно.


{
  double minlot = MarketInfo(Symbol(),MODE_MINLOT); // узнаем каков минимальный размер лота
  if(OrdersTotal()>0)                               // если есть открытые ордера, то...
    {
     return;                                        //...прекращаем работу скрипта
    }
 
  int ticket;                                       // объявляем переменную ticket и присваиваем ей OrderSend,
                                                    // если так не сделать, то в журнале будет предупреждение
                                                 
  ticket = OrderSend(Symbol(), OP_BUY, minlot , Ask, 5, 0,0, "Ордер на покупку", 0, 0, Blue);// открываем ордер на покупку
  if(ticket<0)  // если ордеров нет, то..
     {
      Print("Ошибка открытия ордера на покупку ",GetLastError()); // ... выводим в журнал сообщение об ошибке
     }
  else
      Print("Ордер на покупку открыт"); // а если ордера есть (ticket>0), то пишем об открытии ордера
}
//+------------------------------------------------------------------+
 
Последнее редактирование:

Ugar

Гуру форума
А это похоже про меня и созданную тему, да :D
Не только. Ничего личного. Периодически появляются такие ветки. Типа " я учусь программировать, давайте учиться вместе". В принципе, обычно автор такой ветки, всё же начинает программировать, более менее уверенно. Даже если все переменные объявлены на глобальном уровне например, но работает же. Делая ошибки и потом делая выводы из них, и есть процесс обучения, даже если он публичный.
Все, кто пишет программы, когда то изучали язык. Не все публично. Но если так проще запоминать, почему бы и нет. Не научится только тот, кто ничего не делает.
 

BorisSedov

Активный участник
Чтобы решить, пришлось посмотреть это видео с 40-й минуты, почитать справку и поковыряться в советниках.
Все верно. (y)

Одно уточнение.
Когда мы используем функцию OrderSend, то результатом ее работы будет номер тикета, который назначен ордеру торговым сервером или -1 в случае неудачи. Этот результат (номер тикета или -1) как раз мы и помещаем в переменную ticket. Важно понимать, что в случае открытия ордера, в этой переменной будет не количество ордеров, а номер тикета. Для чего нужно сохранять этот номер? Для того, чтобы в будущем, по этому номеру можно было найти ордер и выполнять с ним какие-то последующие операции – изменять уровни СтопЛосс и ТейкПрофит, закрывать ордер и т.д.. Считайте номер тикета – "именем ордера" (образно).
 
Верх