Jump to content
Programmer

Общие вопросы по языку MQL

Recommended Posts

AntFX
13 минут назад, nasdaq сказал:

Как остановить оптимизацию из функции OnTester() ?

Остановка оптимизации из эксперта не предусмотрена разработчиками терминала. Функция OnTester нужна для вычисления пользовательского критерия оптимизации, а не управления её ходом


Статистика спредов | ПАММ-корректировщик | Section Divine

אף אדם לא לבד - כולנו איש אחד בלב אחד

Share this post


Link to post
Share on other sites
Pirojoque Project
20 часов назад, torgf сказал:

Вы пишете конкретную дату и время, как взять только время для каждого ЗАКРЫТОГО бара - дня, непонятно.

Не понимаю проблему. Опишите подробней.

Share this post


Link to post
Share on other sites
torgf
48 минут назад, Pirojoque Project сказал:

Не понимаю проблему. Опишите подробней.

11:15 вчера - это iTime(Symbol(), PERIOD_D1, 1) + 15 * 60 + 11 * 3600

Как полям  структуры типа MqlDateTime, присвоить такие  значения - "11:15 вчера"?

Share this post


Link to post
Share on other sites
Pirojoque Project
39 минут назад, torgf сказал:

Как полям  структуры типа MqlDateTime, присвоить такие  значения - "11:15 вчера"?

Вопрос ясен. Очень легко:

MqlDateTime mqltime; // Время-структура
datetime basetime = TimeCurrent(); // Время, от которого будем отсчитывать сдвиг (здесь — текущее время сервера)

TimeToStruct(basetime, mqltime); // Конвертируем базовое время в структуру
mqltime.day--; // Модифицируем структуру (сегодняшний день откручиваем назад на один)
mqltime.hour = 11; // Устанавливаем час
mqltime.min = 15; // Устанавливаем минуту

datetime targettime = StructToTime(mqltime); // Конвертируем время-структуру в искомое время простого формата (вчерашние 11:15)
int n = iBarShift(_Symbol, _Period, targettime); // Получили номер искомого бара (который был вчера в 11:15)

 

  • Upvote 1

Share this post


Link to post
Share on other sites
torgf
1 час назад, Pirojoque Project сказал:

Вопрос ясен. Очень легко:

 

Спасибо.

Количество баров расчёта ограничиваю так

   int limit=rates_total-prev_calculated;
   if(limit>1000)
     {
      limit=1000;//rates_total-20;
     }
//--- Цикл расчёта индикатора
   for(int i=limit; i>=0; i--)
     {
//
     }

 

Как ограничить расчёт индикатора не в барах, а в днях? Например 4 дня, дальше не считать.

Edited by torgf

Share this post


Link to post
Share on other sites
Ugar68

4 дня или 4 дневных бара? Из за выходных есть разница.


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
Pirojoque Project
В 31.07.2018 в 22:50, torgf сказал:

Количество баров расчёта ограничиваю так

Зачем? Полная глубина истории на графике будет посчитана один раз, а затем пересчёт будет производиться только на новых барах (на последнем обычно, если история уже подгружена).

 

В 31.07.2018 в 22:50, torgf сказал:

Как ограничить расчёт индикатора не в барах, а в днях? Например 4 дня, дальше не считать.

С помощью приёма со временем-структурой нужно найти бар, который был 4 дня назад и цикл расчёта индикатора производить от него, а не от limit, как вы это делали.

  • Thanks 1

Share this post


Link to post
Share on other sites
AntFX
В 31.07.2018 в 22:50, torgf сказал:

Как ограничить расчёт индикатора не в барах, а в днях? Например 4 дня, дальше не считать.

limit=iBarShift(Symbol(), Period(), TimeCurrent() - 86400 * 4);

  • Thanks 1

Статистика спредов | ПАММ-корректировщик | Section Divine

אף אדם לא לבד - כולנו איש אחד בלב אחד

Share this post


Link to post
Share on other sites
DVargo

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

Почему бы не вынести все в скрипт или советник. И вызывать построение трендовой по мере надобности - раз в сутки, в час и т.д.

Зачем  эти все лимиты?

Share this post


Link to post
Share on other sites
torgf
11 часов назад, AntFX сказал:

limit=iBarShift(Symbol(), Period(), TimeCurrent() - 86400 * 4);

Не хочет ограничивать, всю историю считает.

//--- Проверка на минимальное колиество баров для расчёта
   if(rates_total<4) return 0;

   int limit=rates_total-prev_calculated;
  
     limit=iBarShift(Symbol(), Period(), TimeCurrent() - 86400 * 4);
//--- Цикл расчёта индикатора
   for(int i=limit; i>=0; i--)
     {
     //
     }

Что не так?

Edited by torgf

Share this post


Link to post
Share on other sites
AntFX
6 минут назад, torgf сказал:

Не хочет ограничивать, всю историю считает.

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

  • Upvote 1

Статистика спредов | ПАММ-корректировщик | Section Divine

אף אדם לא לבד - כולנו איש אחד בלב אחד

Share this post


Link to post
Share on other sites
torgf
8 минут назад, AntFX сказал:

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

Изменила т.ф., Ограничивает. Спасибо.

ENUM_TIMEFRAMES tf=PERIOD_D1;
   if(rates_total<4) return 0;

   int limit=rates_total-prev_calculated;
  
     limit=iBarShift(Symbol(), tf, TimeCurrent() - 86400 * (N_-1));
//--- Цикл расчёта индикатора
   for(int i=limit; i>=0; i--)
     {
     //
     }

 

Share this post


Link to post
Share on other sites
torgf

Как вернуть true, если 4 первых фрактала расположены по возрастанию?

f=iFractals(sy,tf,MODE_UPPER,1);

 

Edited by torgf

Share this post


Link to post
Share on other sites
Ugar68

Надо в цикле перебирать бары в поисках фракталов. Найденные запоминать и сравнивать со следующим найденным.

  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
torgf
9 часов назад, Ugar68 сказал:

Надо в цикле перебирать бары в поисках фракталов. Найденные запоминать и сравнивать со следующим найденным.

Спасибо. Задача на определённом количестве "dofr" баров посчитать фракталы, прибавить единицу и затем убедиться что они  расположены по возрастанию. Первую часть сделала, как теперь построить цикл сравнения этих  kfr_all+1?

попыталась, но не выходит

//+--------------------------------------------
bool f_UPPER(int dofr,int n_)
  {
   int tf=0;//,
   int kfr_all=0;
   string sy=Symbol();
   double f=0,fn=0,old_f=0;
   int    i,kf;

   for(i=n_; i<n_+dofr; i++)
     {
      f=iFractals(sy,tf,MODE_UPPER,i);
      if(f!=0)
        {
         kfr_all++;
        }
     }
//посчиталa фракталы
//сравниваю,если каждый след. фр. больше то true
   int    n=0,con;
   for(int i=n; i<=kfr_all+1; i++)
     {
      fn=iFractals(sy,tf,MODE_UPPER,1);
      if(fn>0)
         n++;
      if(fn>old_f)
        {
         old_f=fn;
         con++;
        }
     }
   if(con==kfr_all)return(true);

   return(false);
  }
//+------------------------------------------------------

 

Share this post


Link to post
Share on other sites
Ugar68

Сравнивать надо найденные фракталы. для этого их надо запомнить все в массиве. Но проще всего это сделать в одном цикле. Тогда запоминать надо только прошлый найденный фрактал.

bool f_UPPER(int dofr,int n_)
   {
   int tf=0;
   int kfr_all=0;
   string sy=Symbol();
   double f=0,fn=0,old_f=0;
   int    i;

   for(i=n_; i<n_+dofr; i++)
     {
      f=iFractals(sy,tf,MODE_UPPER,i);
      if(f>0)//Если фрактал найден
        {
         kfr_all++;//счётчик фракталов
         //Сравнение фрактала с прошлым, если не по возрастанию - выйти вернув false
         if(old_f>0 && old_f<f)return(false);
         old_f=f;
        }
     //Если досчитали до 4 фракталов и не вылетели ранее-выйти вернув true
     if(kfr_all==4)return(true);
     }
   return(false);
   }

Как то так.

  • Upvote 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
torgf
8 часов назад, Ugar68 сказал:

Сравнивать надо найденные фракталы. для этого их надо запомнить все в массиве. Но проще всего это сделать в одном цикле. Тогда запоминать надо только прошлый найденный фрактал.

Как то так.

Спасибо.

Вероятно моя формулировка задачи некорректна. Количество баров и фракталов динамически меняется.

Задача глобально:   между первым и вторым нижними фракталами найти все верхние  фракталы плюс 1 фрактал, то есть участвует в сравнении ещё и первый верхний расположенный за вторым нижним.

Если все расположены по возрастанию=true. Приведённым вами примером могу посчитать только верхние фракталы между первым и вторым нижними. Нужно как то добавить ещё один фрактал )

Share this post


Link to post
Share on other sites
Ugar68

Тогда надо в цикле искать и считать сразу верхние и нижние фракталы. Но критерием для прекращения поиска и возвратом true, будет не досчитал 4 верхних, а досчитал 2 нижних и после 1 верхний.

Критерий прекращения поиска и возврата false - остаётся.

  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
torgf
9 минут назад, Ugar68 сказал:

а досчитал 2 нижних и после 1 верхний.

Здесь у меня ступор. В аргумент "dofr"  я передаю сколько считать, а это как раз до бара на котором второй нижний фрактал, так что верхний за вторым нижним мне не увидеть в таком цикле. 

Share this post


Link to post
Share on other sites
torgf

Не получается, помогите.
Нахожу второй нижний фрактал, запоминаю бар в переменную 1.
От этого бара нахожу первый верхний фрактал, запоминаю бар в переменную 2.
Затем до бара в переменной 2 нахожу верхние фракталы, считаю их количество  и количество возрастающих фракталов. Если их равное количество значит каждый следующий больше, возвращаю true.
Почему всегда true?
 

bool f_UPPER(int n_)
   {
   int tf=0,niznum,verhnum,nbar=0,vbar=0;
   int kfr_all=0,rit_fr=0;
   string sy=Symbol();
   double f=0,fn=0,old_f=0,fl=0,fup=0;
   int    i,k=iBars(sy,tf);
   for(i=n_; i<k; i++)
     {
     fl=iFractals(sy,tf,MODE_LOWER,i);
      if(fl>0)//Если фрактал найден
      {
      nbar++;
      }
      if(nbar==3)//если фрактал второй
        {
        niznum=i;//запомню бар, от него буду искать первы верхний
       //
         break;
        }
     }
     //
   for(i=niznum; i<k; i++)
     {
     fup=iFractals(sy,tf,MODE_UPPER,i);
      if(fup>0)//Если фрактал найден
      {
        verhnum=i;// до этого бара буду искать верхние фракталы
         break;
        }
     }
     
     //
   for(i=n_+2; i<verhnum; i++)
     {
      f=iFractals(sy,tf,MODE_UPPER,i);
      if(f>0)//Если фрактал найден
        {
         kfr_all++;//счётчик фракталов
         //Сравнение фрактала с прошлым, если по возрастанию, то +1
         if(old_f>0 && old_f<f)
         {
         rit_fr++;
         
         }
         old_f=f;
        }
     //Если общее количество найденыx фракталов равно количеству возрастающих, то true
     if(kfr_all==rit_fr)return(true);
     }
   return(false);
   }
//

 

Edited by torgf

Share this post


Link to post
Share on other sites
Ugar68

Зачем так усложнять? Всё можно сделать в одном цикле. Добавить поиск и счётчик нижних фракталов и сделать что бы счётчик верхних начинал работать после того как счётчик нижних досчитал до 2.

bool f_UPPER(int n_)
   {
   int tf=0;
   int CountFUp=0, CountFLow=0;
   string sy=Symbol();
   double f_up=0, f_low=0,fn=0,old_f=0;
   int    i;

   for(i=n_; i<Bars; i++)
     {
      f_up=iFractals(sy,tf,MODE_UPPER,i);
      f_low=iFractals(sy,tf,MODE_LOWER,i);
      if(f_low>0)CountFLow++;//Счётчик нижних фракталов
      if(f_up>0)//Если фрактал найден
        {
         //Если найдено 2 нижних фрактала, считать верхние
         if(CountFLow>=2)CountFUp++;//счётчик верхних фракталов
         //Сравнение фрактала с прошлым, если не по возрастанию - выйти вернув false
         if(old_f>0 && old_f<f_up)return(false);
         old_f=f_up;
        }
     //Если досчитали до 1 фрактал и не вылетели ранее-выйти вернув true
     if(CountFUp==1)return(true);
     }
   return(false);
   }

Как то так.

Edited by Ugar68
  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
torgf
5 часов назад, Ugar68 сказал:

Как то так.

Спасибо.

Share this post


Link to post
Share on other sites
krolix

Здравствуйте, товарищи программисты! Помогите решить такой вопрос:

Имеется такой вот код когда советник завершает работу при достижении заданного процента в настройках (нашел на другом форуме). Подскажите пожалуйста как реализовать данную функцию в советнике? MetaEditor ругается на эту функцию ChekDayProfitByPercent. Google ничего не дал. 


//+------------------------------------------------------------------+
//Функция для проверки заработанного процента
bool ChekDayProfitByPercent(double StartBalanse, uint Percent)
{
bool Result = False;
MqlDateTime CurrentDate;
double DayProfit = 0.0;
int HistoryTotal = OrdersHistoryTotal();

//Формируем текушую дату
TimeToStruct(TimeCurrent(), CurrentDate);
CurrentDate.hour = 0;
CurrentDate.min = 0;
CurrentDate.sec = 0;

//Считаем дневной профит
for(int i = 0; i < HistoryTotal; i++)
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
if(OrderCloseTime() >= StructToTime(CurrentDate))
DayProfit = DayProfit + OrderProfit();
//Сравниваем с заданным процентом
if(DayProfit >= StartBalanse * (Percent / 100.0))
Result = True;
//Выход
return(Result);
}

//Пример использования, Баланс = 100.00 уёв, процент = 10%
if(ChekDayProfitByPercent(100.00, 10)) return;

 

Share this post


Link to post
Share on other sites
sviter

Граждане подскажите правильно ли я делаю!!! Нужно что бы советник торговал когда не вошел за зону 30 или 70, а когда зашел, то не торговал!!! Так правильно сделано?

RSI3 = iRSI(_Symbol, _Period, RSIPeriod, PRICE_CLOSE, 1);
RSI4 = iRSI(_Symbol, _Period, RSIPeriod, PRICE_CLOSE, 2);

bool RSItf = RSI3 > 30 && 30 > RSI4;
if(RSItf == true)
{
}
else
{
ordersend(_Symbol, OP_SELL, lot, Bid, Slippage, 0, 0, NULL, Magic, 0, clrRed);
}
bool RSItf = RSI3 > 70 && 70> RSI4;
if(RSItf == true)
{
}
else
{
ordersend(_Symbol, OP_BUY, lot, Ask, Slippage, 0, 0, NULL, Magic, 0, clrBlue);
}

Share this post


Link to post
Share on other sites
Ugar68

Получается по коду:

Если на сформированном баре индикатор пересёк 30 снизу вверх, он ничего не делает. Всё остальное время от открывает Sell на каждом тике, независимо от того где находится индикатор выше или ниже 30.

Если на сформированном баре индикатор пересёк 70 снизу вверх, он ничего не делает. Всё остальное время от открывает Buy на каждом тике, независимо от того где находится индикатор выше или ниже 70.

1. Для открытия нужно какое то условие, характеризующее точку входа. Или хотя бы запретить открывать если уже есть открытый ордер. Иначе будут открываться сделки на каждом тике.

2. Судя по описанию надо разрешить торговлю когда индикатор находится между 30 и 70.

RSI3 = iRSI(_Symbol, _Period, RSIPeriod, PRICE_CLOSE, 1);

if(RSI3>30 && RSI3<70)
{
if(...)//вместо точек условие для открытия Sell
    {
    OrderSend(_Symbol, OP_SELL, lot, Bid, Slippage, 0, 0, NULL, Magic, 0, clrRed);         
    }
if(...)//вместо точек условие для открытия Buy
    {
    OrderSend(_Symbol, OP_BUY, lot, Ask, Slippage, 0, 0, NULL, Magic, 0, clrBlue);
    }
}

 

 

  • Upvote 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×