Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2253

 
Roman Shiredchenko #:

О! Спс. Разберу код.

Есть вариант для mql5? (Общий подход)

Нужен цикл для суммирования цены открытия (нахождения средней цены по годам) - одинаковых дней  например по 3-м или 5-ти годам.

По сути нужен оптимальный вариант цикла перебора дней по годам для суммирования их цен открытий (закрытий можно) (по соответствующим дням (одинаковым) по годам) - для нахождения средней цены открытия или закрытия дня по например 3 или 5 годам - для примера.

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

 
JRandomTrader #:

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

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

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

 
Roman Shiredchenko #:
Как взять цены например, 10 авг сего года, прошлого и позапрошлого?
short   day     = 10;
short   mon     = 8;
short   year    = 2023;
short   days    = 3;
/********************Script program start function*******************/
void OnStart()
 {
  MqlRates rates[1];
  datetime date = 0;
  double ma = 0.0;
  for(short i = days; (bool)i--;)
   {
    date = StringToTime((string)day+"."+(string)mon+"."+string(year-i));
//    CopyRates(_Symbol, PERIOD_D1, date-PeriodSeconds(PERIOD_D1), date, rates);
    CopyRates(_Symbol, PERIOD_D1, date, 1, rates);
    printf("Дата %s Price open %s ", TimeToString(date, TIME_DATE), DoubleToString(rates[0].open, _Digits));
    ma += rates[0].open;
   }
   Print("Средняя цена = ", DoubleToString(ma/days, _Digits));
 }/******************************************************************/

Результат

2023.08.29 10:35:45.342 !!0 (GBPUSD,M1) Дата 2021.08.10 Price open 1.38692 
2023.08.29 10:35:45.342 !!0 (GBPUSD,M1) Дата 2022.08.10 Price open 1.20770 
2023.08.29 10:35:45.342 !!0 (GBPUSD,M1) Дата 2023.08.10 Price open 1.27446 
2023.08.29 10:35:45.342 !!0 (GBPUSD,M1) Средняя цена = 1.28969
Файлы:
6k0.mq5  3 kb
 
Artyom Trishkin #:

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

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

Я не про перебор рассчитываемых баров в индикаторе, а про перебор баров для поиска данных для расчёта - т.е., для поиска баров, отстоящих ровно на n лет от текущего. Функция StringToTime гораздо более "дорогая", чем TimeToStruct, стоит по возможности ограничить её использование, особенно для критичного по времени/загрузке проца кода.

 
Alexey Viktorov #:
...

О! Спс за подход. Вечером вкурю....

 
Tretyakov Rostyslav #:

Исправьте эту строку

Спасибо, исправил...

Подскажите, пожалуйста, ваш блок:

datetime GetLastProfitDay() 
  {
   int i=OrdersTotal()-1;
   datetime t=0, last=0;
   double res=0;
   for(int pos=i;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol()==_Symbol&&OrderMagicNumber()==Magic)
           {
            res=OrderProfit()+OrderCommission()+OrderSwap();
            if(res>0&&OrderCloseTime()>t)
              {
               t=OrderCloseTime(); last=StringToTime(OrderCloseTime(TimeCurrent(),TIME_DATE))+PeriodSeconds(PERIOD_D1);
              } 
           }
        }
     }
   return(last);
  }

определяет день, когда был достигнут профит, и далее идет сравнение с текущей датой?

Но, я все же не могу понять, как это все совместить воедино.

Мой блок кода:

bool isCloseLastPosByTake(string sy="", int op=-1, int mn=-1) 
{
  datetime t;
  double   ocp, otp;
  int      dg, i, j=-1, k=OrdersHistoryTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++)
   {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) 
    {
      if (OrderSymbol()==sy || sy=="") 
      {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) 
        {
          if (op<0 || OrderType()==op) 
          {
            if (mn<0 || OrderMagicNumber()==mn) 
            {
              if (t<OrderCloseTime())
              {
             
                t=OrderCloseTime();
                j=i;
              
              }
            }
          }
        }
      }
    }
  }
  if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)) 
  {
    dg=MarketInfo(sy, MODE_DIGITS);
    if (dg==0) if (StringFind(OrderSymbol(), "JPY")<0) dg=5; else dg=3;
    ocp=NormalizeDouble(OrderClosePrice(), dg);
    otp=NormalizeDouble(OrderTakeProfit(), dg);
    if (ocp==otp) return(True);
  }
  return(False);

}

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

Спасибо!

 
Alex8888888888 #:

Спасибо, исправил...

Подскажите, пожалуйста, ваш блок:

определяет день, когда был достигнут профит, и далее идет сравнение с текущей датой?

Но, я все же не могу понять, как это все совместить воедино.

Мой блок кода:

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

Спасибо!

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

А здесь уже идет сравнение в текущим временем

if(TimeCurrent()>GetLastProfitDay())
и если текущее время больше - значит можно торговать.
 
Alex8888888888 #:

Спасибо, исправил...

Исправьте еще одну ошибку

int i=OrdersHistoryTotal()-1;
 
К сожалению, не работает.... после получения профита, продолжает открывать сделки до конца дня....
 
Alex8888888888 #:
К сожалению, не работает.... после получения профита, продолжает открывать сделки до конца дня....

Вы что-то не так прописали.

Все работает

2023.08.29 13:32:30.148 2023.08.02 20:45:00  B_GOLICIN GBPUSD,M15: Торговля запрещена
2023.08.29 13:32:30.058 2023.08.02 20:30:00  B_GOLICIN GBPUSD,M15: 2023.08.03 00:00:00
2023.08.29 13:32:30.058 2023.08.02 20:30:00  B_GOLICIN GBPUSD,M15: Торговля запрещена
2023.08.29 13:32:29.983 2023.08.02 20:15:00  B_GOLICIN GBPUSD,M15: 2023.08.03 00:00:00
Причина обращения: