Торговая сессия & Котировочная сессия. Вопросы остаются... - страница 2

 

Я пользуюсь вот такой функцией для проверки возможности торговать:

#define MAX_TRADE_SESSIONS 5

bool IsTradeAllowed( string symbol )
{
//---
        if ( SymbolInfoInteger( symbol, SYMBOL_TRADE_MODE ) != SYMBOL_TRADE_MODE_FULL ) return(false);

//---
        MqlDateTime dt;
        datetime t, time = TimeTradeServer( dt );

//--- время торгов
        t = (datetime)SymbolInfoInteger( symbol, SYMBOL_EXPIRATION_TIME );
        if ( t > 0 && time > t ) return(false);

        t = (datetime)SymbolInfoInteger( symbol, SYMBOL_START_TIME );
        if ( t > 0 && time < t ) return(false);

//--- торговые сессии
        datetime today_start = time/(60*60*24);
        today_start*=(60*60*24);

        datetime session_start, session_end, today_seconds = time - today_start;

        for ( int session = 0; session < MAX_TRADE_SESSIONS; session ++ )
        {
                if ( !SymbolInfoSessionTrade( symbol, (ENUM_DAY_OF_WEEK)dt.day_of_week, session, session_start, session_end ) ) break;
                if ( today_seconds >= session_start && today_seconds <= session_end ) return(true);
        }

        return(false);
}

 

Но она не рассчитана на сессии, переходящие через полночь.

 
Andrey Khatimlianskii:

А, кстати, интересный вопрос. Как можно задавать сессии для конкретного дня, залезая на другой день? Если бы они были одинаковыми на все 7 дней — то да. А иначе появляется неоднозначность.

Мне, например, по приведенному скриншоту не понятно, можно ли торговать в пятницу с 00:00 до 00:55, т.к. для нее указан совершенно конкретный интервал 03:05-23:05.

Хотелось бы комментариев разработчиков. 

 

Получается, нужна возможность указывать несколько интервалов для каждого дня или сложная функция парсинга торговых сессий с учетом перехода через дни.

По правильному должны быть возвращены все сессии с правильным временем когда from < to

тогда было бы две сессии каждый день

с 00:00 по 00:55  и

с 03:05 по 00:00 (24:00)

 

А вот это признак from > to заставляет ломать голову как учитывать вчерашний день, и как он заползает на сегодня.

-----------------------------------------------------

Ваш код возьму на заметку, но мне кажется   while(SymbolInfoSessionTrade...  боле правильно чем какое либо ограничение сессий по кол-ву (#define MAX_TRADE_SESSIONS 5)


Вот эти ф-ции в 4-ке  у меня всегда возвращали 0

SymbolInfoInteger( symbol, SYMBOL_EXPIRATION_TIME )

SymbolInfoInteger( symbol, SYMBOL_START_TIME );

 
Dmytro Zelenskyy:

Ваш код возьму на заметку, но мне кажется   while(SymbolInfoSessionTrade...  боле правильно чем какое либо ограничение сессий по кол-ву (#define MAX_TRADE_SESSIONS 5)

Не, лучше ограничить. Ну, или IsStopped проверять.

 

Dmytro Zelenskyy:

Вот эти ф-ции в 4-ке  у меня всегда возвращали 0

SymbolInfoInteger( symbol, SYMBOL_EXPIRATION_TIME )

SymbolInfoInteger( symbol, SYMBOL_START_TIME );

 Они для фьючерсов.

 

Ну что то такое сделал, надо понаблюдать...

Идея такая

- если сегодня не воскресенье, то можно посмотреть вчера сессии

- из всех вчерашних сессий найти ту у которой  from > to, она же будет и последней.

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

- а далее все по if  (TimeCurrent()...

 

Еще прикрепил файлик с ф-цией для наблюдений.

 

bool dz_SymbolInfoSessionTrade02(string symbolF, bool oneF)
{
   int session_indexF=0;
   
   datetime vr_toF=0, vr_fromF=0, fromF=0, toF=0, TimeCurrentDay=0;
   
   //ENUM_DAY_OF_WEEK previous_day_of_weekF = ENUM_DAY_OF_WEEK( TimeDayOfWeek(TimeCurrent() - 24 * 60 * 60) );
      
   
   datetime todayStart = StringToTime(TimeToString(TimeCurrent(), TIME_DATE) );
   
   ENUM_DAY_OF_WEEK day_of_weekF = ENUM_DAY_OF_WEEK(DayOfWeek() );
   
   Print("todayStart= ", todayStart, "   day_of_weekF= ", EnumToString(day_of_weekF) );
   
   
   
   //--------------------------  vr_from  >  vr_to  yesterday
   if(DayOfWeek() - 1 >= 0)
   {
      //fromF = todayStart; // ??? for first trade day.  vr_from  >  vr_to
      
      datetime yesterdayStart = StringToTime(TimeToString(TimeCurrent() - 24 * 60 * 60, TIME_DATE) );
   
      ENUM_DAY_OF_WEEK yesterday_day_of_weekF = ENUM_DAY_OF_WEEK( TimeDayOfWeek(yesterdayStart) );
      
      Print("yesterdayStart= ", yesterdayStart, "   yesterday_day_of_weekF= ", EnumToString(yesterday_day_of_weekF) );
      
      
      //-----  yesterday   ,to
      while(SymbolInfoSessionTrade(symbolF, yesterday_day_of_weekF, session_indexF, vr_fromF, vr_toF) && !IsStopped() )
      {
         if(vr_fromF > vr_toF)
         {
            toF = todayStart + vr_toF;
            
            Print("while vr_fromF > vr_toF. Yesterday_day_of_weekF. Today  toF= ", toF, "   session_indexF= ", session_indexF);
            
            break;
         }
         
         session_indexF++;
      }
      
      
      //--
      //if(fromF != 0 && toF != 0 && TimeCurrent() >= fromF && TimeCurrent() < toF) 
      
      if(TimeCurrent() < toF) 
      {
         //Print("IF vr_fromF > vr_toF  Yesterday_day_of_weekF  fromF= ", fromF, "   toF= ", toF);
         
         Print("IF vr_fromF > vr_toF  Yesterday_day_of_weekF  toF= ", toF);
         
         return(true);
      }      
      
   } // if(DayOfWeek() - 1 >= 0)
   



   //-----  today   ,from  ,to
   session_indexF = 0;
   
   while(SymbolInfoSessionTrade(symbolF, day_of_weekF, session_indexF, vr_fromF, vr_toF) && !IsStopped() )
   {
      fromF = todayStart + vr_fromF;
      
      toF = todayStart + vr_toF;
   
      Print("while Today fromF= ", fromF, "   toF= ", toF, "   session_indexF= ", session_indexF);
  
      if(vr_fromF < vr_toF)
      {
         if(TimeCurrent() >= fromF && TimeCurrent() < toF) 
         {
            Print("IF  vr_fromF < vr_toF   today fromF= ", fromF, "   toF= ", toF, "   session_indexF= ", session_indexF);
            
            return(true);
         }               
      }else
      {
         if(TimeCurrent() >= fromF) 
         {
            Print("IF vr_fromF > vr_toF  today  fromF= ", fromF, "   session_indexF= ", session_indexF);
            
            return(true);
         }
      }
      
      session_indexF++;
   }   


   return(false);
}
Файлы:
0_session07.mq4  10 kb
 

Ну пока все по плану

пятница. Возвраты ф-ций

0 00:05:00.353 0_session07 BRENT-SEP16,M5: IsTradeAllowed(symbolF, TimeCurrent() )= false

0 00:05:00.353 0_session07 BRENT-SEP16,M5: MarketInfo(symbolF, MODE_TRADEALLOWED)= 0.0

0 00:05:00.353 0_session07 BRENT-SEP16,M5: todayStart= 2016.07.22 00:00:00   day_of_weekF= FRIDAY

0 00:05:00.353 0_session07 BRENT-SEP16,M5: yesterdayStart= 2016.07.21 00:00:00   yesterday_day_of_weekF= THURSDAY

0 00:05:00.353 0_session07 BRENT-SEP16,M5: while vr_fromF > vr_toF. Yesterday_day_of_weekF. Today  toF= 2016.07.22 00:55:00   session_indexF= 0

0 00:05:00.353 0_session07 BRENT-SEP16,M5: IF vr_fromF > vr_toF  Yesterday_day_of_weekF  toF= 2016.07.22 00:55:00

0 00:05:00.353 0_session07 BRENT-SEP16,M5: 2016.07.22 00:05:00 ==== dz_SymbolInfoSessionTrade02= true 

 

моя ф-ция разрешила торговать и действительно можно...

0 00:05:38.559 '8715750': order sell market 1.00 BRENT-SEP16 sl: 0.00 tp: 0.00

0 00:05:38.719 '8715750': order was opened : #30289279 sell 1.00 BRENT-SEP16 at 46.04 sl: 0.00 tp: 0.00

0 00:05:44.809 '8715750': close order #30289279 sell 1.00 BRENT-SEP16 at 46.04 sl: 0.00 tp: 0.00 at price 0.00

0 00:05:44.949 '8715750': order #30289279 sell 1.00 BRENT-SEP16 at 46.04 sl: 0.00 tp: 0.00 closed at price 46.09 

 

Надо еще раз проверить понедельник 

 

Понедельник

 

00:52:25.398 0_session07 BRENT-SEP16,M5: INIT IsTradeAllowed()= true

0 00:52:25.398 0_session07 BRENT-SEP16,M5: INIT IsTradeAllowed(symbolF, TimeCurrent() )= false

0 00:52:25.398 0_session07 BRENT-SEP16,M5: INIT MarketInfo(symbolF, MODE_TRADEALLOWED)= 0.0

0 00:52:25.398 0_session07 BRENT-SEP16,M5: todayStart= 2016.07.25 00:00:00   day_of_weekF= MONDAY

0 00:52:25.398 0_session07 BRENT-SEP16,M5: yesterdayStart= 2016.07.24 00:00:00   yesterday_day_of_weekF= SUNDAY

0 00:52:25.398 0_session07 BRENT-SEP16,M5: while Today fromF= 2016.07.25 03:05:00   toF= 2016.07.25 00:55:00   session_indexF= 0

0 00:52:25.398 0_session07 BRENT-SEP16,M5: 2016.07.25 00:52:25 ==== INIT dz_SymbolInfoSessionTrade02= false

 

и ручками подверждаю

0 00:52:40.251 '8715750': order sell market 1.00 BRENT-SEP16 sl: 0.00 tp: 0.00

1 00:52:40.368 '8715750': order sell 1.00 BRENT-SEP16 opening at market sl: 0.00 tp: 0.00 failed [Market is closed]

0 00:52:43.128 '8715750': order buy market 1.00 BRENT-SEP16 sl: 0.00 tp: 0.00

1 00:52:43.257 '8715750': order buy 1.00 BRENT-SEP16 opening at market sl: 0.00 tp: 0.00 failed [Market is closed] 

 

Извините что встреваю, если можно один вопрос:

Сегодня, понедельник, случилось что эти строки

  MqlRates mqlRates[];
  CopyRates(symbol, timeframe, 0, 1, mqlRates);
  datetime tNew = mqlRates[0].time;

// symbol и timeframe параметры функции

выдали что tNew 23 часа пятницы

2016.07.25 00:00:41.299 00 (GBPUSD,M15) GBPUSD TimeCurrent 2016.07.25 00:00:40 tOld 1970.01.01 00:00:00 tNew 2016.07.22 23:00:00

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

Это МТ5, форекс.

 

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

TradeState - переключатель торгового режима эксперта в зависимости от времени - библиотека для MetaTrader 5

 
Vasiliy Sokolov:

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

TradeState - переключатель торгового режима эксперта в зависимости от времени - библиотека для MetaTrader 5

При чем здесь задаваемое время? Функции должны работать.

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

 
Vasiliy Sokolov:

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

TradeState - переключатель торгового режима эксперта в зависимости от времени - библиотека для MetaTrader 5

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