/*!
\brief Текущий фьючерсный контракт
\param const string a_name - шаблон имени фьючерса
\param const datetime a_date - дата определяемого тикера
\return тикер текущего фьючерса
*/
static string CCheck::CurrFutures(const string a_name,const datetime a_date/*=0*/) {
string _ticker = NULL;
MqlDateTime _time = {0};
string _short_name = a_name;
datetime _curr_t = 0;
if(a_date > 0) {
_curr_t = a_date;
TimeToStruct(_curr_t, _time);
} else {
_curr_t = TimeCurrent(_time);
}
int _year = _time.year;
int _mon = _time.mon;
for(int i = 0; i < 12; ++i) {
if(_mon > 12) {
_mon=1;
_year++;
}
_ticker = StringFormat("%s-%d.%d", _short_name, _mon, _year%100);
if(SymbolSelect(_ticker, true))
if(SymbolInfoInteger(_ticker, SYMBOL_EXPIRATION_TIME) > _curr_t)
break;
_mon++;
_ticker = NULL;
}
//---
return _ticker;
}
/*!
\brief Следующий фьючерсный контракт
\param const string a_name - шаблон имени фьючерса
\param const datetime a_date - дата определяемого тикера
\return тикер текущего фьючерса
*/
static string CCheck::NextFutures(string a_name,const datetime a_date/*=0*/) {
string _ticker = NULL;
MqlDateTime _time = {0};
string _short_name = a_name;
datetime _curr_t = 0;
datetime _curr_t2 = 0;
if(a_date > 0) {
_curr_t = a_date;
TimeToStruct(_curr_t, _time);
} else {
_curr_t = TimeCurrent(_time);
}
int _year = _time.year;
int _mon = _time.mon;
for(int i = 0; i < 12; ++i) {
if(_mon > 12) {
_mon = 1;
_year++;
}
_ticker = StringFormat("%s-%d.%d", _short_name, _mon, _year%100);
if(SymbolSelect(_ticker, true)) {
int _expirat = (int)SymbolInfoInteger(_ticker, SYMBOL_EXPIRATION_TIME);
Print("expirate: ", (datetime)_expirat);
if(_curr_t2 == 0)
if(_expirat > _curr_t) {
_curr_t2 = _expirat;
_mon++;
continue;
}
if(_curr_t2 != 0)
if(_expirat > _curr_t2)
break;
}
_mon++;
_ticker = NULL;
}
//---
return _ticker;
}
/*!
\brief Предыдущий фьючерсный контракт
\param const string a_name - шаблон имени фьючерса
\param const datetime a_date - дата определяемого тикера
\return тикер текущего фьючерса
*/
static string CCheck::prevFutures(string a_name,const datetime a_date/*=0*/) {
string _ticker = NULL;
MqlDateTime _time = {0};
string _short_name = a_name;
datetime _curr_t = 0;
if(a_date > 0) {
_curr_t = a_date;
TimeToStruct(_curr_t, _time);
} else {
_curr_t = TimeCurrent(_time);
}
int _year = _time.year;
int _mon = _time.mon;
for(int i = 0; i < 12; ++i) {
if(_mon < 1) {
_mon = 12;
_year--;
}
_ticker = StringFormat("%s-%d.%d", _short_name, _mon, _year%100);
if(SymbolSelect(_ticker, true))
if(SymbolInfoInteger(_ticker, SYMBOL_EXPIRATION_TIME) < _curr_t)
break;
_mon--;
_ticker = NULL;
}
//---
return _ticker;
}
/*!
\break Праздники
\param const datetime a_time - корректируемое время
\param const bool a_flag - флаг возврата даты: true следующий после праздников день, false предыдущий к праздникам день
\remark Дата возвращается как начало суток, т.е. с 00:00:00 даты
*/
static datetime CCheck::CorrectHolidays(const datetime a_time,const bool a_flag) {
int _day = 86400;
datetime _rest = 0;
datetime _holidays[] = { D'2017.11.06 00:00', D'2017.12.29 19:00', D'2017.12.30 00:00',
D'2017.12.31 00:00', D'2018.01.01 00:00', D'2018.01.02 00:00',
D'2018.01.06 00:00', D'2018.01.07 00:00', D'2018.01.08 00:00',
D'2018.02.23 00:00', D'2018.03.08 00:00', D'2018.03.10 00:00',
D'2018.03.11 00:00', D'2018.04.29 00:00', D'2018.05.01 00:00',
D'2018.05.05 00:00', D'2018.05.06 00:00', D'2018.05.09 00:00',
D'2018.06.10 00:00', D'2018.06.12 00:00', D'2018.11.05 00:00' };
for(int i = 0, _size = ArraySize(_holidays); i < _size; ++i) {
if(_holidays%_day > 0)
_rest = _holidays%_day;
else
_rest = _day;
if(a_time >= _holidays && a_time < _holidays + _rest)
if(a_flag) return CorrectHolidays(_holidays + _rest, a_flag);
else return CorrectHolidays(_holidays - _rest, a_flag);
}
//---
return a_time;
}