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

 
MakarFX

благодарю за ответ, костыльное и неплохое решение, но с точки зрения моей идеи оно работает немного некорректно, так как баланс плавает, наверное он это делает не мгновенно и в некоторых случаях мои ордера начали по какой-то причине закрываться с минусом. Но прирост пошел как надо, но и просадка с теми минусами повырастала. Я плюнул на все и решил задать вручную лимиты выторга, придется так подстраивать ежедневно. 

 
Порт-моне тв:

благодарю за ответ, костыльное и неплохое решение, но с точки зрения моей идеи оно работает немного некорректно, так как баланс плавает, наверное он это делает не мгновенно и в некоторых случаях мои ордера начали по какой-то причине закрываться с минусом. Но прирост пошел как надо, но и просадка с теми минусами повырастала. Я плюнул на все и решил задать вручную лимиты выторга, придется так подстраивать ежедневно. 

Функция работает корректно.

Попробуй так

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

sb1 = StartBalance();
................

//+--------------------------------------------------------------------------------------------------------------------+
//|  Баланс на начало периода                                                                                          |
//+--------------------------------------------------------------------------------------------------------------------+
double StartBalance()
  { double b = 0;
   if(AccountBalance()>0) {b = AccountBalance()-DayProfit();}
   return(b);
  }
//+--------------------------------------------------------------------------------------------------------------------+
//|  Суммарный профит на начало периода                                                                                |
//+--------------------------------------------------------------------------------------------------------------------+
double DayProfit()
  { double p = 0; datetime st=iTime(_Symbol,PERIOD_D1,0);
   for(int pos=OrdersHistoryTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS,MODE_HISTORY)==true)
        {
         if(OrderSymbol() == _Symbol)
           { 
            if(OrderCloseTime()>=st){p+=OrderProfit()+OrderSwap()+OrderCommission();}
           }
        }
     }
   return(p);
  }
//+--------------------------------------------------------------------------------------------------------------------+

и добавь в функцию закрытия ордеров обновление баланса

   if(OrderClose(бла бла бла))
     {
      StartBalance(); Print("Order Close");
     }
 
Maxim Kuznetsov:

ловить смену дня и рассчитывать значение баланса на этот момент.

не зря-же говорили что "возьмите подходящий индикатор" - это не уложится в пару строчек кода. Там довольно ёмкий алгоритм.

поймать смену дня легко, "известный номер дня сейчас не равен номеру дня ранее", а вот дальше сложности


Алг. " посчитать баланс на момент D" (без учёта снятий/пополнений и некоторым багом про свопы и комиссии)

Баланс:=текущий баланс счёта. Тот который AccountBalance()

По всем закрытым рыночным ордерам в истории:

если время закрытия попадает между D и текущим моментом, Баланс -= OrderProfit()+OrderSwap()+OrderCommision();

по завершению перебора, Баланс есть искомое значение..

НО, комиссия взимается (то есть влияет на линию баланса) при открытии, а мы её учтём при закрытии и свопы берутся при перемене дня, а мы учтём опять-же лишь при закрытии

и при большой глубине D, есть шанс в переборе не получить все требуемые ордера

 
Порт-моне тв:

благодарю за ответ, костыльное и неплохое решение, но с точки зрения моей идеи оно работает немного некорректно, так как баланс плавает, наверное он это делает не мгновенно и в некоторых случаях мои ордера начали по какой-то причине закрываться с минусом. Но прирост пошел как надо, но и просадка с теми минусами повырастала. Я плюнул на все и решил задать вручную лимиты выторга, придется так подстраивать ежедневно. 

Я уже заблудился в ваших пожеланиях и советах вам… Поэтому возможно мой совет совсем не в тему, ну уж извиняйте…

Я так понимаю, надо на начало дня зафиксировать баланс и в течении дня считать прибыль\потери с соответствии с которыми надо принять решение о продолжении торговли…

Так вот решение

datetime dayTime;
double dayBalance;
// Дальше в функции OnTick()
if(dayTime != iTime(_Symbol, PERIOD_D1, 0);
 {
  dayBalance = AccountInfoDouble(ACCOUNT_BALANCE));
  dayTime = iTime(_Symbol, PERIOD_D1, 0);
 }
// Дальше текущий баланс можно сравнивать с балансом на начало дня…
// В начале следующего дня в переменной dayBalance будет другое значение баланса…

Если в течении дня будет перезапуск советника, то в OnInit() надо предусмотреть подсчёт прибыли\убытков сегодняшних ордеров с учётом свопов и комиссий и высчитать баланс на начало дня.

Я верю в способности Макара, он может всё это показать уже в коде…

 

Здравствуйте. Подскажите, пожалуйста.

Как определить номер текущего бара с начала суток?

Спасибо.

 
prom18:

Здравствуйте. Подскажите, пожалуйста.

Как определить номер текущего бара с начала суток?

Спасибо.

      double BarNumber=NormalizeDouble((TimeCurrent()-iTime(_Symbol,PERIOD_D1,0))/60/Period()+0.5,0);

это текущий бар, если последний закрытый, то -0,5

 
MakarFX:

это текущий бар, если последний закрытый, то -0,5

Спасибо. Попробую.

 
MakarFX:

это текущий бар, если последний закрытый, то -0,5

на минутках и экзотах будет сбоить.

кол-во баров != число_отсчётов

бары пропускаются просто на раз, за 15 мин может быть 12 минутных баров

лучше использовать штатную iBarShift() 

 
Maxim Kuznetsov:

лучше использовать штатную iBarShift() 

Я не знаю как(

 
MakarFX:

Я не знаю как(

Функция    

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 26.02.2008                                                     |
//|  Описание : Возвращает реальный номер бара от начала суток.                |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (NULL или "" - текущий символ)          |
//|    tf - таймфрейм                  (          0 - текущий таймфрейм)       |
//|    dt - дата и время открытия бара (          0 - текущее время)           |
//+----------------------------------------------------------------------------+
int iBarOfDayReal(string sy="", int tf=0, datetime dt=0) {
  if (sy=="" || sy=="0") sy=Symbol();
  if (tf<=0) tf=Period();
  if (dt<=0) dt=TimeCurrent();
  if (tf>PERIOD_D1) {
    Print("iBarOfDayReal(): Таймфрейм должен быть меньше или равен D1");
    return(0);
  }

  int cd=TimeDay(dt);                       // текущий день месяца
  int nb=iBarShift(sy, tf, dt, False);      // номер текущего бара
  int bd=0;                                 // номер бара от начала суток

  while(TimeDay(iTime(sy, tf, nb))==cd) {
    nb++;
    bd++;
  }

  return(bd);
}


 

Причина обращения: