Страница 1 из 2
Доступ к другим TimeFrame
Добавлено: Чт фев 04, 2010 12:22 pm
MKrymsky
Как можно получить данные по другим таймфреймам внутри индикатора?
Пример: я хочу чтобы у меня на 5-минутках рисовались значения High предыдущего бара из часовиков.
Конструкция:
H1High[Index]:= iHigh(Symbol(), PERIOD_H1, Index);
H1Low[Index]:= iHigh(Symbol(), PERIOD_H1, Index);
выдает неправильные значения.
Процедура, которая описана в Helpе:
iHigh(Symbol(), 60, Index);
не работает:
[Error]: Incompatible types: 'TTimeframe' and 'Integer'
Заранее благодарю!
Добавлено: Вс фев 07, 2010 2:03 pm
duh
Таймфрейм д.б. указан цифрой наверное - 60, а индекс предыдущего бара на часовиках всегда равен 1, поэтому надо как-то так:
H1High[Index]:= iHigh(Symbol(), 60, 1);
H1Low[Index]:= iHigh(Symbol(), 60, 1); \\ Логическая ошибка - не High а Low
А неправильные значения и ошибки скорее всего из-за того что и справа и слева использовали один и тот же Index. Обязательно учитывайте, что Index на пятиминутках отличается от Index на часовиках, в индикаторе Index соответствует тому таймфрейму на котором добавлен индикатор, на других таймфреймах своя нумерация, поэтому на часовиках ставьте 1 - это и есть предыдущий (завершенный) часовой бар.
Добавлено: Вс фев 07, 2010 2:20 pm
duh
И еще, если решите построить этот индикатор на исторических данных, то 1 не покатит, 1 покатит только при появлении новых баров, для истории придется высчитывать соответствие между номерами баров на пятиминутках и часовиках. К сожалению такой функции встроенной нет.
Добавлено: Пн фев 08, 2010 1:31 pm
MKrymsky
duh писал(а):Таймфрейм д.б. указан цифрой наверное - 60, а индекс предыдущего бара на часовиках всегда равен 1, поэтому надо как-то так:
H1High[Index]:= iHigh(Symbol(), 60, 1);
Дело в том, что как раз при использовании цифры "60" вместо константы "PERIOD_H1" типа TTimeFrame и появляется ошибка "Incompatible types".
Т.е. Delphi ругается именно на использование цифры "60".
Может разработчики могут что-нибудь прояснить?
Спасибо.
Добавлено: Пн фев 08, 2010 3:28 pm
duh
MKrymsky писал(а):duh писал(а):Таймфрейм д.б. указан цифрой наверное - 60, а индекс предыдущего бара на часовиках всегда равен 1, поэтому надо как-то так:
H1High[Index]:= iHigh(Symbol(), 60, 1);
Дело в том, что как раз при использовании цифры "60" вместо константы "PERIOD_H1" типа TTimeFrame и появляется ошибка "Incompatible types".
Т.е. Delphi ругается именно на использование цифры "60".
Может разработчики могут что-нибудь прояснить?
Спасибо.
Думаю что ошибка не в этом, был у меня простенький индюк, специально поставил сейчас константу, все работает, ищите ошибку в другом. Там без разницы что использовать константу или переменную типа int.
Добавлено: Пн фев 08, 2010 3:33 pm
duh
Вобще, что за тип такой "TTimeframe" - у меня вообще такого нет (искал поиском по справке), скорее всего вы что-то обозвали типом "TTimeframe", а требуется тип "int", вот и ругается, копируйте весь текст индюка, а там посмотрим, я правда в С++, но м.б. другие посмотрят.
констана PERIOD_H1 тоже вроде int была раньше, м.б. у вас программа старая а справка новая, сейчас вроде константы PERIOD_H1 и прочее не используются
Добавлено: Пн фев 08, 2010 4:03 pm
MKrymsky
duh писал(а):Вобще, что за тип такой "TTimeframe" - у меня вообще такого нет (искал поиском по справке), скорее всего вы что-то обозвали типом "TTimeframe", а требуется тип "int", вот и ругается
Извините за нескромный вопрос: у Вас Delphi установлен? У Вас не ругается на такую команду?:
c := iClose('USDJPY',
15, 10);
Объясню, почему спрашиваю.
Я прописываю в тексте индикатора то, что скопировал из "Help"a (ForexTester 2/ Помощь / Интерфейс Индикаторов / функция iHigh):
"var c: double;
c := iClose('USDJPY',
15, 10);"
на что мне компилятор ругается:
"[Error] : Incompatible types: TTimeframe' and 'Integer'"
Ищу в Delphi декларацию функции iHigh() и нахожу его в модуле IndicatorInterfaceUnit.pas:
"{-----Get high value---------------------------------------------------------}
function iHigh(Symbol: string; TimeFrame:
TTimeframe; shift: longword): double;"
Далее ищу декларацию типа TTimeFrame и нахожу в том же модуле:
" // timeframe
TTimeframe =
(PERIOD_M1 = 0,
PERIOD_M5 = 1,
PERIOD_M15 = 2,
PERIOD_H1 = 3,
PERIOD_H4 = 4,
PERIOD_D1 = 5,
PERIOD_W1 = 6);"
Изменяю в тексте индикатора
c := iClose('USDJPY',
15, 10); на
c := iClose('USDJPY',
PERIOD_M15, 10);
компилятор перестает ругаться. Индикатор компилируется, рисует линию в ФТестере, но выдает явно неправильные значения.
Вот про это я, собственно, и спрашивал. Есть идеи?
Спасибо.
Добавлено: Пн фев 08, 2010 4:23 pm
duh
Я же написал что я С++ юзаю он ни на что не ругается, так же и в делфи должно быть.
У меня никакого типа TTimeframe нет нигде - искал и в справках и в файлах АPI стратегий и индикаторов.
У меня есть файлы АPI текстовые для Делфи, я там поискал, там тоже нет никакого типа TTimeframe!!! М.б. вы не те файлы АPI используете, м.б. от старой версии программы, возьмите новые из папки с программой.
Добавлено: Пн фев 08, 2010 4:31 pm
MKrymsky
duh писал(а):... копируйте весь текст индюка, а там посмотрим, я правда в С++, но м.б. другие посмотрят...
Индюк забыл прилепить.
В аттаче индюк и то, что он показывает.
Добавлено: Пн фев 08, 2010 4:32 pm
duh
Вот копирую из API для делфи,
в самом начале:
//----------------------------------------------------------------------------
// Indicator interface unit ver 1.8, ForexTester (c) Koshelev M.A.
//
// What's new:
//
// ver 1.8
............. далее функция
function iHigh(Symbol: string; TimeFrame: integer; index: integer): double;
.............
Поэтому у вас видимо старый API
Добавлено: Пн фев 08, 2010 4:36 pm
duh
Файл индюка пока не смотрю, м.б. поможет использование нового API
смотрите в папке ForexTester2\Examples\Indicators\Delphi
Добавлено: Пн фев 08, 2010 4:44 pm
duh
Еще как вариант - у вас правильный API (соответствующий программе), но хелп от нового API. Короче вам надо проверить соответствие между версией программы, API и хелпом к API
А что на картинке, так если не правильно рисует - это м.б. ваша логическая ошибка.
Вот у меня прога версии 2.4.2, API версии 1.8 для делфи и 1.7 для с++, ну а хелп из программы вызываю
Добавлено: Пн фев 08, 2010 4:47 pm
MKrymsky
duh писал(а):Я же написал что я С++ юзаю он ни на что не ругается, так же и в делфи должно быть.
У меня никакого типа TTimeframe нет нигде - искал и в справках и в файлах АPI стратегий и индикаторов.
У меня есть файлы АPI текстовые для Делфи, я там поискал, там тоже нет никакого типа TTimeframe!!! М.б. вы не те файлы АPI используете, м.б. от старой версии программы, возьмите новые из папки с программой.
Вы абсолютно правы. У меня старый IndicatorInterfaceUnit.pas оказался.
Заменил его на новый. Компилятор ругаться перестал на целочисленные значения в параметре TimeFrame оператора iHigh(). Теперь равнозначно проходят и "15" и "PERIOD_M15".
Правда это не помогло в правильности значений индикатора. На графике все равно получаются те же самые невразумительные значения! (Картинка в предыдущем посте).
Еще раз спасибо!
Добавлено: Пн фев 08, 2010 4:50 pm
duh
MKrymsky писал(а):duh писал(а):Я же написал что я С++ юзаю он ни на что не ругается, так же и в делфи должно быть.
У меня никакого типа TTimeframe нет нигде - искал и в справках и в файлах АPI стратегий и индикаторов.
У меня есть файлы АPI текстовые для Делфи, я там поискал, там тоже нет никакого типа TTimeframe!!! М.б. вы не те файлы АPI используете, м.б. от старой версии программы, возьмите новые из папки с программой.
Вы абсолютно правы. У меня старый IndicatorInterfaceUnit.pas оказался.
Заменил его на новый. Компилятор ругаться перестал на целочисленные значения в параметре TimeFrame оператора iHigh(). Теперь равнозначно проходят и "15" и "PERIOD_M15".
Правда это не помогло в правильности значений индикатора. На графике все равно получаются те же самые невразумительные значения! (Картинка в предыдущем посте).
Еще раз спасибо!
Я там ответил выше, как уже написал, что неправильные значения - это ваша логическая ошибка - надо логику проверять в программе.
Добавлено: Пн фев 08, 2010 4:53 pm
duh
А как правильно по замыслу должно рисовать, кидайте текст индюка, если не сильно сложно то гляну, но делфи я не знаю.
Добавлено: Пн фев 08, 2010 5:05 pm
MKrymsky
duh писал(а):А как правильно по замыслу должно рисовать, кидайте текст индюка, если не сильно сложно то гляну, но делфи я не знаю.
Да собственно хотелось простейший индикатор сделать наподобие PivotPoint, только чтобы High, Low и Close брались не с предыдущего дня, а с предыдущего часа. Но на первом же шаге (High от H1) застопорился. Конечно можно в индюке прописать поиск хай предыдущего часа в явном виде по текущему таймфрейму. Но это как-то несолидно, коль уж есть специальные функции работы с таймфреймами. Но вот видно знаний еще не хватает.
Заранее вас благодарю, если намекнете как лучше найти High по H1 на меньшем таймфрейме.
Добавлено: Пн фев 08, 2010 5:29 pm
duh
MKrymsky писал(а):duh писал(а):А как правильно по замыслу должно рисовать, кидайте текст индюка, если не сильно сложно то гляну, но делфи я не знаю.
Да собственно хотелось простейший индикатор сделать наподобие PivotPoint, только чтобы High, Low и Close брались не с предыдущего дня, а с предыдущего часа. Но на первом же шаге (High от H1) застопорился. Конечно можно в индюке прописать поиск хай предыдущего часа в явном виде по текущему таймфрейму. Но это как-то несолидно, коль уж есть специальные функции работы с таймфреймами. Но вот видно знаний еще не хватает.
Заранее вас благодарю, если намекнете как лучше найти High по H1 на меньшем таймфрейме.
А при чем здесь знания - встроенной функции такой нету, что бы выдавала номер бара на другом таймфрейме по индексу на текущем.
Но это не очень сложно написать, я давно такую функцию хотел написать, так как все абы как подобное организовывал, ну и вчера после вашего поста сел да написал что бы больше не мучаться
Так и быть, сейчас я ее куда - нибудь вставлю, проверю на логические ошибки и сюда закопирую, на делфи сами перепишите, в принципе там все понятно - несколько срок кода.
Функция по заданному времени ищет индекс бара на указанном таймфрейме методом дихотомии, должна находить примерно итераций за 20-30 бар на минутках из истории за 10 лет (наверное будет долго лопатить минутки, лучше ниже пятимиуток не опускаться), т.е. если вам надо найти индекс бара на любом таймфрейме который соответствует бару на рабочем интервале, просто определяете время этого бара на рабочем интервале и вызываете функцию.
Но ладно, сейчас (через часик).
Добавлено: Пн фев 08, 2010 6:29 pm
duh
Код: Выделить всё
// Функция по таймфрейму и времени найдет номер бара
// ts - время
// tf - таймфрейм
// log - символ инструмента
int ftib(PChar log, int tf, TDateTime ts);
int ftib(PChar log, int tf, TDateTime ts)
{
int ibar = -1;
int nbar = iBars(log, tf);
if(iTime(log, tf, 0) <= ts) ibar = 0;
if(iTime(log, tf, nbar - 1) == ts) ibar = nbar - 1;
int ia = 0, ix = 0, ib = 0;
TDateTime tx = 0.0;
ia = nbar - 1; ib = 0; ix = (ia + ib) / 2; tx = iTime(log, tf, ix);
while(ibar < 0)
{
if(tx == ts)
{
ibar = ix;
}
else
{
if(tx < ts) ia = ix;
if(ts < tx) ib = ix;
ix = (ia + ib) / 2;
tx = iTime(log, tf, ix);
if((ia - ib) <= 1) ibar = ia;
}
}
return ibar;
}
Ну вот собственно код, правда на истории он работает ОООчень медленно, так как на каждый поиск надо 20-30 итераций, я попробовал на пятиминутках рисовать хаи часовиков, так на один год истории уходит примерно минута, если еще и лоу добавить то две минуты будет уходить (еще от мощности компа конечно зависит), можно ускорить значительно т.к. у нас интервалы временные баров постоянные и если высчитывать пропорции, то можно сразу сократить область поиска, но это поопзже сделаю. В принципе в динамике не должно тормозить, а на истории один раз подождал и все, если история не очень длинная то не долго ждать.
Под делфи перепишите, вроде ничего сложного и все д.б. понятно обращаю внимание только на выражение ix = (ia + ib) / 2; - встречается в функции два раза, в С++ его результатом всегда будет целое число - если не делится на цело, то автоматом приводится к целому а дробная часть отбрасывается, если в делфи надо это явно указывать то учтите это.
Функция вернет номе бара на указанном таймфрейме.
В вашем случае будет так:
iHigh(Symbol(), tf, (ftib(Symbol(), tf, Time(index)) + 1) );
вернет хай предыдущего часового бара (подразумевается что tf = 60),
а выражение ftib(Symbol(), tf, Time(index)) + 1 - это и есть предыдущий часовой бар, т.е. индекс предыдущего бара всегда на единицу больше текущего, поэтому сначала при помощи указанной функции ftib ищется индекс текущего часового бара, и прибавляется к найденному значению 1, ну а Time(index) - это время на рабочем интервале, например последнего пятиминутного бара (можно iTime использовать).
Если будете использовать в динамике, то делайте вычисление для каждого пятиминутного бара только один раз, иначе если на каждом тике будет итерации проводить, то может тормозить будет
Сейчас попробую усовершенствовать для ускорения через сокращение области поиска, полностью опираться на постоянство интервалов не приходится, так как часто пропуски в истории встречаются, поэтому надо попытаться сократить область поиска и также методом дихотомии "добить".
Добавлено: Пн фев 08, 2010 6:35 pm
duh
Еще если будете решать вашу задачу, то учтите, что для самого старого пятиминутного бара нет предыдущего часового (история ведь только началась) поэтому прибавив единицу к найденному номеру часового бара вы выскакиваете за исторический диапазон, поэтому начинайте обработку пропустив пару десятков пятиминутных баров или обрабатывайте эту ситуацию по другому, например сравнивая с количеством часовых баров.
Добавлено: Пн фев 08, 2010 7:31 pm
MKrymsky
To duh:
Огромное спасибо! Буду разбираться. Если что получится, выложу тут.
Добавлено: Пн фев 08, 2010 8:27 pm
duh
Сейчас немного переделал алгоритм, завел поиск методом перебора, где начальная стартовая точка определяется с учетом временных и индексных интервалов, получилось ускорение по сравнению с предыдущей функцией примерно в три раза (т.е. год будет прорисовывать секунд 20 на моем компе - в задаче которую я рассмотрел с временными таймфреймами - 5 минут - 60 минут).
Код: Выделить всё
// Функция по таймфрейму и времени найдет номер бара, используется метод перебора и соотношения временных и индексных интервалов
// ts - время
// tf - таймфрейм
// log - символ инструмента
int ftibp(PChar log, int tf, TDateTime ts);
int ftibp(PChar log, int tf, TDateTime ts)
{
int ibar = -1;
int nbar = iBars(log, tf);
if(iTime(log, tf, 0) <= ts) ibar = 0;
if(iTime(log, tf, nbar - 1) == ts) ibar = nbar - 1;
int ia = 0, ix = 0, ib = 0, ixstart = 0;
TDateTime ta = 0.0, tx = 0.0, tb = 0.0, txstart = 0.0;
ia = nbar - 1; ib = 0; ta = iTime(log, tf, ia); tb = iTime(log, tf, ib);
ixstart = ( ia - ( (ia - ib) * ( (ts - ta) / (tb - ta) ) ) ); txstart = iTime(log, tf, ixstart);
int step = 0;
if(ts < txstart) step = 1; else step = -1;
for(int i = ixstart; ibar < 0; i = i + step)
{
ix = i;
tx = iTime(log, tf, ix);
if(step == 1)
{
if(tx <= ts) ibar = ix;
}
else
{
if(tx > ts) ibar = ix + 1;
if(tx == ts) ibar = ix;
}
}
return ibar;
}
Завтра подумаю как совместить учет временных и индексных интервалов с методом дихотомии (в идеале золотого сечения) - еще можно будет получить ускорение
Добавлено: Пн фев 08, 2010 8:35 pm
duh
При переводе в делфи учтите что выражние ixstart = ( ia - ( (ia - ib) * ( (ts - ta) / (tb - ta) ) ) ); должно быть пиведено к int (в с++ это автоматом делается).
Добавлено: Вс апр 11, 2010 3:15 pm
duh
Появлась новая функция iBarShift, которая по времени определяет номер бара, потестировал ее, быстродействие не очень, фактически комфортно работать только с ТФ больше часа, если последовательно для каждого часа бращаться к пятиминуткам для всей истории, то на моем компе более 3-х минут историю прогоняет, ... к минуткам почти 4 минуты - дождаться можно, но при тестировании не очень удобно, если последовательно обращаться с мелких ТФ, то вообще не рельно дождаться.
В данный момент у меня есть функция которая летает почти на любых парах интервалов, если кому надо (м.б. разработчикам алгоритм интересен), то могу выложить, проблемы начинаются только если работать с интервалами менее 5 минут, например с пятиминуток лезть на минутки или наоборот. Эта фунция часто работает в разы, а иногда на порядок быстрее iBarShift.
А разработчикам предлагаю еще ввести один не обязательный параметр в функцию iBarShift - индекс предыдущего найденного бара и если он указан, то отталкиваться в поисках от него, что позволит значительно ускорить процесс поиска для случаев, когда последовательно перебираются все бары.
Добавлено: Вс апр 11, 2010 5:21 pm
Terranin
duh писал(а):Появлась новая функция iBarShift, которая по времени определяет номер бара, потестировал ее, быстродействие не очень, фактически комфортно работать только с ТФ больше часа, если последовательно для каждого часа бращаться к пятиминуткам для всей истории, то на моем компе более 3-х минут историю прогоняет, ... к минуткам почти 4 минуты - дождаться можно, но при тестировании не очень удобно, если последовательно обращаться с мелких ТФ, то вообще не рельно дождаться.
В данный момент у меня есть функция которая летает почти на любых парах интервалов, если кому надо (м.б. разработчикам алгоритм интересен), то могу выложить, проблемы начинаются только если работать с интервалами менее 5 минут, например с пятиминуток лезть на минутки или наоборот. Эта фунция часто работает в разы, а иногда на порядок быстрее iBarShift.
А разработчикам предлагаю еще ввести один не обязательный параметр в функцию iBarShift - индекс предыдущего найденного бара и если он указан, то отталкиваться в поисках от него, что позволит значительно ускорить процесс поиска для случаев, когда последовательно перебираются все бары.
Опишите алгоритм, посмотрим. В данный момент функция работает методом деления отрезков времени на 2.
Добавлено: Вс апр 11, 2010 6:48 pm
duh
Понятно, что метод дихотомии (деления отрезков пополам) - это основной метод.
Забыл написать, что если использовать в функции индекс предыдущего найденного бара, то именно в этом случае должен быть задействован метод перебора - так гораздо быстрее, метод дихотомии здесь не даст сильного ускорения.
Ниже будет функция с пояснениями, я сначала тоже писал функцию которая по времени ищет бар на указанном таймфрейме (они выше представлены), но потом оказалось что надо передавать не время а индекс бара, тогда можно более точно определить начальные точки.
Итак, вкратце алгоритм такой:
- если в функцию передается индекс предыдущего найденного бара (iy), то она берет его за начальную точку и методом последовательного перебора находит требуемый индекс бара (работает очень быстро даже с минутками если надо последовательно прогонять всю историю)
- если не передается предыдущий индекс бара, то будет использован метод дихотомии по индексам баров, для этого определяется начальный диапазон индексов в котором будут проводиться поиски,
-- первая точка диапазона определяется исходя из соотношения индексов (именно поэтому в функцию передается индекс бара а не время, время конечно тоже используется, но именно соотношения индексов позволяют очень точно определить первую точку, соотношения времен дают большую погрешность)
соотношение простое, обычная пропорция - (ix1+1)/(ibar1+1) = (i2+1)/(i1+1), где ix1 и ibar1 - индксы баров, ibar1 известен (если добавлено +1, то это получается количество баров в отрезке от нулевого бара до бара с соответствующим индексом) в программе отсюда выражается ix1 - это первая точка диапазона, i1 и i2 с прибавленной еденичкой - это количество баров всего на таймфреймах
-- вторая точка определяется по разности между временем входного бара и временем бара ix1 в первой точке, выражение такое:
ix2 = (ix1+1) +- 1440*(tx1-ts)/tf, где (+- - это плюс или минус в зависимости от положения входного времени и tx1) ix2 - индекс бара или вторая точка дипазона, tx1 - время бара ix1, ts - это известное время входного бара, (tx1-ts) их разность, логика такая, если разность по времени поделить на таймфрейм tf (так как tf в минутах, то еще умножаем на 1440 - переводим время в минуты), получим максимальное количество баров в случае отсутствия пропусков в истории, так как пропуски есть, то добавив (или отняв) полученную величину от (ix1+1) мы получим вторую точку диапазона а искомый индекс будет находиться в нем. (ix1+1) - плюс один - это что бы из-за всяких округлений не выскочить за диапазон случайно, так сказать расширили диапазон.
-- после всего этого имеем индексы баров ix1 и ix2 - диапазон в котором методом дихотомии надо найти искомый индекс бара