А вообще не зачем велосипед изобретать, см. прицеп, там библиотека тралов от Ю.Дзюбана. Всё работает, проверял. Правь, если надо под свои нужды любые виды тралов и всё!
доброго время суток. у меня тут очень странное дело не поможете. Я тестирую советника на историй с 2004 по 2012 и результат один, положительный, а потом делаю тест на периоде с 2009 по 2012 и он просто совершенно другой. большое количество ордеров, более 20000 за период 8 лет. когда при тесте большом, то по гистограмме прибыльности видно что с 2009 по 2012 прибыль чистая и красивая а когда тестируешь любое расстояние меньше 2009 то просто ХАОС. вы случайно не в курсе что это может быть. Заранее спасибо ребята :)
Подскажите, как вытягивать значения из индикатора зиг-заг? Как вообще это реализуется? Т.е. если я хочу подхватить определённый экстремум, а не только последний.
Вот, например, я щяс это зиг-заг хочу прикрутить к своему эксперту:
#property copyright "Scriptong"#property link "http://autograf.dp.ua"#property indicator_chart_window // Индикатор выводится в окне графика#property indicator_buffers 1// используется 1 буфер индикатора#property indicator_color1 Blue // Цвет отображения данных 1-го буфера#property indicator_width1 1// Толщина линий 1-го буфераdouble ZZBuf[]; // Буфер экстремумовdouble UpDnBuf[]; // Буфер признака текущего тренда#define NO_TREND 0// Нет тренда#define TREND_UP 1// Восходящий тренд#define TREND_DOWN -1// Нисходящий тренд //+-------------------------------------------------------------------------------------+//| Custom indicator initialization function |//+-------------------------------------------------------------------------------------+int init()
{
IndicatorBuffers(2);
// - 1 - == Проверка корректности значений настроечных параметров индикатора ============string name = WindowExpertName();
// - 1 - == Окончание блока =============================================================// - 2 - == Связывание буферов с индексами, определение стилей ==========================SetIndexBuffer(0, ZZBuf); // Первый буфер - экстремумы
SetIndexStyle(0, DRAW_SECTION); // В виде линии между непустыми..// ..значениямиSetIndexBuffer(1, UpDnBuf); // Второй буфер - признак тренда
SetIndexStyle(1, DRAW_NONE); // Не отображается// - 2 - == Окончание блока =============================================================return(0);
}
//+-------------------------------------------------------------------------------------+//| Custom indicator deinitialization function |//+-------------------------------------------------------------------------------------+int deinit()
{
return(0);
}
//+-------------------------------------------------------------------------------------+//| Определение индекса бара, с которого необходимо производить перерасчет |//+-------------------------------------------------------------------------------------+int GetRecalcIndex()
{
int counted_bars = IndicatorCounted();
if (counted_bars == 0) // Кол-во посчитанных баров - 0. Будут
{ // ..пересчитаны все буфера с самого..ArrayInitialize(ZZBuf, EMPTY_VALUE); // ..начала. Очистка буферовArrayInitialize(UpDnBuf, 0);
return(Bars - 2); // Начинаем со второго бара истории
}
return(Bars - counted_bars - 1); // Начинаем с нового бара
}
//+-------------------------------------------------------------------------------------+//| Определение тенденции по соотношению указанной и предыдущей свечей |//+-------------------------------------------------------------------------------------+int GetTrend(int index)
{
// - 1 - == Закрытие новой свечи выше максимума предыдущей ==============================if (Close[index] > High[index+1])
return(TREND_UP); // Рост// - 1 - == Окончание блока =============================================================// - 2 - == Закрытие новой свечи ниже минимума предыдущей ===============================if (Close[index] < Low[index+1])
return(TREND_DOWN); // Падение// - 2 - == Окончание блока =============================================================return(NO_TREND); // Если свеча не пробита - нет тренда
}
//+-------------------------------------------------------------------------------------+//| Поиск последнего элемента ZZBuf с непустым значением |//+-------------------------------------------------------------------------------------+int GetLastIndexNoEmptyValue(int index)
{
while (ZZBuf[index] == EMPTY_VALUE && index < Bars)// Поиск по графику справа налево
index++; // Пока не будет найден экстремум или// ..пока не достигнем конца историиreturn(index); // Индекс бара с непустым значением..// ..зиг-зага
}
//+-------------------------------------------------------------------------------------+//| Сравнение последнего максимума с новым максимумом |//+-------------------------------------------------------------------------------------+void CheckHigh(int index)
{
int cnt = GetLastIndexNoEmptyValue(index); // Найдем последний непустой элемент..// ..зиг-загаif (cnt == Bars) // Если элемент не найден (достигнут..
{ // ..конец истории), то максимумом..
ZZBuf[index] = High[index]; // ..считается текущий максимумreturn;
}
if (High[index] > ZZBuf[cnt]) // Элемент найден. Сравним его..
{ // ..значение с новым максимумом. Если
ZZBuf[cnt] = EMPTY_VALUE; // ..новый максимум выше, то..
ZZBuf[index] = High[index]; // ..предыдущий максимум уничтожается,// ..а новый сохраняется
}
}
//+-------------------------------------------------------------------------------------+//| Сравнение последнего минимума с новым минимумом |//+-------------------------------------------------------------------------------------+void CheckLow(int index)
{
int cnt = GetLastIndexNoEmptyValue(index); // Найдем последний непустой элемент..// ..зиг-загаif (cnt == Bars) // Если элемент не найден (достигнут..
{ // ..конец истории), то минимумом..
ZZBuf[index] = Low[index]; // ..считается текущий минимумreturn;
}
if (Low[index] < ZZBuf[cnt]) // Элемент найден. Сравним его..
{ // ..значение с новым минимумом. Если
ZZBuf[cnt] = EMPTY_VALUE; // ..новый минимум ниже, то..
ZZBuf[index] = Low[index]; // ..предыдущий минимум уничтожается,// ..а новый сохраняется
}
}
//+-------------------------------------------------------------------------------------+//| Смена тренда или его продолжение при отсутствии нового сигнала |//+-------------------------------------------------------------------------------------+void TrendChange(int trend, int i)
{
// - 1 - == Тренд изменился с нисходящего на восходящий =================================
UpDnBuf[i] = trend; // Сохранение признака направленияif (trend == TREND_UP) // Тренд изменился на восходящий
{
CheckLow(i); // Проверка появления нового минимумаif (ZZBuf[i] != EMPTY_VALUE) // Если минимум обновлен, то максимум
ZZBuf[i-1] = High[i]; // ..переносим на следующий барelse// Если минимум не обновлен, то..
ZZBuf[i] = High[i]; // ..максимум отображается на текущемreturn; // ..баре
}
// - 1 - == Окончание блока =============================================================// - 2 - == Тренд изменился с восходящего на нисходящий =================================
CheckHigh(i); // Проверка появления нового максимумаif (ZZBuf[i] != EMPTY_VALUE) // Если максимум обновлен, то минимум
ZZBuf[i-1] = Low[i]; // ..отображается на следующем бареelse// Если максимум не обновлен, то..
ZZBuf[i] = Low[i]; // ..минимум отображается на текущем..// ..баре// - 2 - == Окончание блока =============================================================
}
//+-------------------------------------------------------------------------------------+//| Расчет значений индикатора |//+-------------------------------------------------------------------------------------+void ZigZag(int limit)
{
for (int i = limit; i > 0; i--) // По всем новым барам
{
int trend = GetTrend(i); // Получение направления на баре iif (trend != UpDnBuf[i+1] && trend != 0) // Направление на текущем баре..
{ // ..отличается от направления на..
TrendChange(trend, i); // ..предыдущем баре.continue;
}
UpDnBuf[i] = UpDnBuf[i+1]; // Направление не изменяетсяif (UpDnBuf[i] == TREND_UP) // Сохранение восходящего тренда
{
CheckHigh(i); // Обновление максимумаcontinue;
}
if (UpDnBuf[i] == TREND_DOWN) // Сохранение нисходящего тренда
CheckLow(i); // Обновление минимума
}
}
//+-------------------------------------------------------------------------------------+//| Custom indicator iteration function |//+-------------------------------------------------------------------------------------+int start()
{
int limit = GetRecalcIndex(); // Определим первый расчетный бар
ZigZag(limit); // Расчет значений индикатораreturn(0);
}
То что нужно воспользоваться функцией iCustom как это обычно и делается для обращения к пользовательскому индюку я понимаю, но как цеплять вершины это вопрос...
Мигает, становится прерывистый, и как лазер совсем, короче.
Классно!
По вопросу - разбери трал учебника от и до. Найдёшь ответ!
А вообще не зачем велосипед изобретать, см. прицеп, там библиотека тралов от Ю.Дзюбана. Всё работает, проверял. Правь, если надо под свои нужды любые виды тралов и всё!
<Ctrl+D>
Почему не отображается?
Потому, что короткое имя может быть присвоено только индикатору, отображаемому в дополнительном окне.
Точнее, присвоить его никто не запрещает любому индикатору, но для 0-го окна не предусмотрено отображение этого имени ни в одном из окон терминала.
Потому, что короткое имя может быть присвоено только индикатору, отображаемому в дополнительном окне.
Точнее, присвоить его никто не запрещает любому индикатору, но для 0-го окна не предусмотрено отображение этого имени ни в одном из окон терминала.
спасибо..
Я Димку видел! На ТOYOTA-BB катается. Просил передать Белорусскому другу, что вопрос" можно , нельзя ". Можно и не спрашивать.
"BB" - это BabyBaby для 14 лет?!

Подскажите, как вытягивать значения из индикатора зиг-заг? Как вообще это реализуется? Т.е. если я хочу подхватить определённый экстремум, а не только последний.
Вот, например, я щяс это зиг-заг хочу прикрутить к своему эксперту:
То что нужно воспользоваться функцией iCustom как это обычно и делается для обращения к пользовательскому индюку я понимаю, но как цеплять вершины это вопрос...