Код: Выделить всё
// Функция по таймфрейму и индексу бара найдет номер бара на указанном таймфрейме
// Используется метод дихотомии и соотношения индексных интервалов для задания начальной точки
// log - символ инструмента
// tf1 - таймфрейм на котором имеем бар с индексом ibar1
// ibar1 - индекс бара
// tf2 - таймфрейм на котором ищем индекс бара соответствующий бару ibar1
// iy - предыдущий найденный бар (для ускорения и поиском методом перебора), если меньше 0, то ускорения нет
int ftib5(PChar, int , int, int, int);
int ftib5(PChar log, int tf1, int ibar1, int tf2, int iy)
{
int i1 = iBars(log, tf1) - 1, i2 = iBars(log, tf2) - 1; // Индексы последнего бара
double tbar1 = iTime(log, tf1, ibar1), tbar2 = iTime(log, tf2, 0);
if(tbar2 <= tbar1) return 0; // Законченный временной интервал у текущего бара отсутсвует и он выходит за пределы временного диапазона, поэтому надо проверять текущий бар отдельно
if(iy > -1) // В случае если задан предыдущий индекс, то используется метод перебора от предыдущего индекса
{
int ibar2 = 0;
if(iy > i2) ibar2 = i2; else ibar2 = iy;
tbar2 = iTime(log, tf2, ibar2);
int v = 1;
if(tbar1 > tbar2) v = -1;
while(true)
{
if(tbar1 == tbar2) return ibar2;
if(v == 1 && tbar1 > tbar2) return ibar2;
if(v == -1 && tbar1 < tbar2) return (ibar2 + 1);
ibar2 = ibar2 + v;
tbar2 = iTime(log, tf2, ibar2);
}
}
else // Если не задан предыдущий индекс, то используется метод дихотомии
{
int tf = tf2; // Таймфрейм на котором ищем индекс бара
int ia = 0, ib = 0, ix = 0, ix1 = 0, ix2 = 0; // Индексы баров
double ts = tbar1; // Время входящего бара
double ta = 0.0, tb = 0.0, tx = 0.0, tx1 = 0.0, tx2 = 0.0; // Времена соответствующее барам ia, ib, ix, ix1 и ix2
ix1 = (int) ( (((double)(i2+1)/(double)(i1+1)) * (double)(ibar1+1)) - 1 ); // Вычисление первой начальной точки
if(ix1 > i2) ix1 = i2; if(ix1 < 0) ix1 = 0; // Проверка на выход за пределы истории
tx1 = iTime(log, tf, ix1);
if(ts == tx1) return ix1; // Проверка на равенство
if(ts < tx1)
{
ix2 = (int) ( (double)(ix1+1) + (((tx1 - ts) * 1440.0 ) / (double)tf) ); // Вычисление второй начальной границы интервала
if(ix2 > i2) ix2 = i2; // Проверка на выход за пределы истории
tx2 = iTime(log, tf, ix2);
ia = ix2; ib = ix1;
ta = tx2; tb = tx1;
}
else
{
ix2 = (int) ( (double)(ix1-1) - (((ts - tx1) * 1440.0 ) / (double)tf) ); // Вычисление второй начальной границы интервала
if(ix2 < 0) ix2 = 0; // Проверка на выход за пределы истории
tx2 = iTime(log, tf, ix2);
ia = ix1; ib = ix2;
ta = tx1; tb = tx2;
}
if(ts == tx2) return ix2; // Проверка на равенство
ix = (int) ( (ia + ib) / 2 ); tx = iTime(log, tf, ix); // Задание начальных данных
while(true) // Цикл
{
if(tx == ts) return ix;
if(ts < tx) ib = ix; else ia = ix;
if((ia - ib) <= 1) return ia; // Если интервал сошелся, то искомое время в диапазоне бара с индексом ia
ix = (int) ( (ia + ib) / 2 );
tx = iTime(log, tf, ix);
}
}
return -1;
}