
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Тоже пытался реализовать подобный алгоритм в далеком 2013 году... Правда использовал 7 индикаторов, а Zigzag использовал для формирования вектора обучения НС. Но суть таже - искал реверсные позиции... ничего путного не получалось ни с данными от индикаторов, ни с торговыми сигналами от них... пока случайно не наткнулся на паттерны. Которые в корне изменили мою ТС. Теперь мой алгоритм стал проще:
1. Вычисление паттернов на минутном и часовом таймфрейме, за последний год;
2. Составление словаря переломных моментов (пар "минутный паттерн - часовой паттерн") ;
3. Обучение НС по словарю переломных моментов ( на 150-160 парах);
Вот результат моего подхода:
К недостатки моего подхода:
1) Высокий риск ТС - так как точно нельзя определить значение цены перелома, ТС выставляет 9 отложенных ордеров с лотами: 1, 1, 3, 6, 14, 31, 70, 158, 355;
2) Сложно реализовать алгоритм выхода (трал ТС);
Так что НС можно использовать для торговли, только вот вопрос чему НС обучать...
P/s: под паттернами понимаю паттерны А. Меррилла (M & W) .
Толковый подход. А паттерны описывали просто как положение баров в матрице, без учета фактической дельты цены - только относительное положение?
У меня есть идея, попробовать паттерны индикаторов, но с разным фреймом - первых пять баров анализируем показатели на 5 последних индикаторах, и два показателя для анализа тенденции - анализируем с шагом 10 и при этом учитываем абсолютные изменения.
Про зиг-заг толковая идея, а как пики фильтровали от флэтовых вихляний могли быть ложные точки смены тенденции?
Толковый подход. А паттерны описывали просто как положение баров в матрице, без учета фактической дельты цены - только относительное положение?
У меня есть идея, попробовать паттерны индикаторов, но с разным фреймом - первых пять баров анализируем показатели на 5 последних индикаторах, и два показателя для анализа тенденции - анализируем с шагом 10 и при этом учитываем абсолютные изменения.
Про зиг-заг толковая идея, а как пики фильтровали от флэтовых вихляний могли быть ложные точки смены тенденции?
Я делаю так:
Есть динамический массив который хранит исключительно пары паттернов (я называю его словарь), если пара паттернов попала в словарь второй раз её не записываю; и два массива счетчика старшего таймфрейма и младшего - они считают как часто участвовал паттерн в формировании пар, даже если его не записывали в словарь.
Формирование вектора обучения происходит по словарю, вес отдельного паттерна = счетчик_патерна / максимум_счетчика. Т.е. паттерн который чаще всего участвует в формировании пар равен 1, а все остальные меньше 1. Вот такая табличка получается после обучения НС:
Структура НС: 64 нейрона на входе, 4 внутренних, 1 выход. Т.е. один входной нейрон описывает один паттерн. Сетка обучается за 40-50 минут, ошибка НС не превышает 0,00001.
Таким образом я имею модель которая может предсказывать значимость пар паттернов, даже если раньше её не было в словаре.
С флэтом и ложными пиками борюсь давно, но на уровне расчета ZigZaga. Я немного переделал код стандартного Zigzag, а именно реализовал на его базе процентный ZZ. Пока более или менее потребный код выглядит так:
int MyCExtremum::GetCombiZigzag(const double &high[], // буфер цен high
const double &low[], // буфер цен low
const datetime &time[], // буфер время
int ExtDepth, // глубина поиска экстремумов(первого прохода)
double ExtDeviation,// "пороговое значение": жесткая ступенька + % роста цены
int ExtBackstep // глубина поиска экстремумов(второго прохода)
)
{
//--- value
int shift=0, whatlookfor=0, lasthighpos=0, lastlowpos=0, Deviat=1;
double lasthigh=0.0, lastlow=0.0, percent=0.0;
int rates_total = ArraySize(time); // размер входных таймсерий
int limit = rates_total - ExtDepth; // лимит на расчеты...
//+---------------------------------------------------------------+
//| ОЧЕНЬ ВАЖНАЯ ПРОВЕРКА ВЛИЯЮЩАЯ НА КОРРЕКТНОСТЬ ВЫЧИСЛЕНИЙ! |
//+---------------------------------------------------------------+
if(ArrayIsSeries(high)) ArraySetAsSeries(high,false);
if(ArrayIsSeries(low)) ArraySetAsSeries(low,false);
if(ArrayIsSeries(time)) ArraySetAsSeries(time,false);
//+---------------------------------------------------------------+
//| ПРОВЕРКИ ВХОДНЫХ ПЕРЕМЕННЫХ |
//+---------------------------------------------------------------+
if(rates_total<20)
{
Print(__FUNCTION__," ERROR: the small size of the buffer.");
return(-1);
}
if(ExtDeviation<0 || ExtDeviation>100)
{
Print(__FUNCTION__," ERROR: Is\'not correct a Deviation. The value of Deviation should be in the interval [0..100].");
return(-1);
}
//--- Проверка: Depth and Backstep
if((ExtDepth < ExtBackstep)||(ExtDepth < 2))
{
Print(__FUNCTION__+" ERROR: Is\'not correct a Depth and Backstep. The value of Depth should be greater than Backstep.");
return(-1);
}
//--- готовим буфер ZigzagBuffer[]
if(ArraySize(ZigzagBuffer)>0) ArrayFree(ZigzagBuffer); // Удаляем старые данные
ArrayResize(ZigzagBuffer,rates_total, EXTREMUM_RESERVE);
ArrayFill(ZigzagBuffer,0,rates_total,0.0);
if(ArrayIsSeries(ZigzagBuffer)) ArraySetAsSeries(ZigzagBuffer, false);
//---
if(ArraySize(HighMapBuffer)>0) ArrayFree(HighMapBuffer); // Удаляем старые данные
ArrayResize(HighMapBuffer,rates_total, EXTREMUM_RESERVE);
ArrayFill(HighMapBuffer,0,rates_total,0.0);
if(ArrayIsSeries(HighMapBuffer)) ArraySetAsSeries(HighMapBuffer, false);
//---
if(ArraySize(LowMapBuffer)>0) ArrayFree(LowMapBuffer); // Удаляем старые данные
ArrayResize(LowMapBuffer,rates_total, EXTREMUM_RESERVE);
ArrayFill(LowMapBuffer,0,rates_total,0.0);
if(ArrayIsSeries(LowMapBuffer)) ArraySetAsSeries(LowMapBuffer, false);
//---
if(ArraySize(TimeBuffer)>0) ArrayFree(TimeBuffer); // Удаляем старые данные
ArrayResize(TimeBuffer, rates_total, EXTREMUM_RESERVE);
ArrayFill(TimeBuffer, 0, rates_total, 0);
if(ArrayIsSeries(TimeBuffer)) ArraySetAsSeries(TimeBuffer, false);
//--- корректировка Deviation
if(ExtDeviation < 1)
{
Deviat = 1;
}else
{
Deviat = (int)ExtDeviation;
}
//--- получаем "свежие" минимумы и максимумы
if(GetHighMapZigzag(high,ExtDepth,Deviat,ExtBackstep) < 0) return(0);
if(GetLowMapZigzag(low,ExtDepth,Deviat,ExtBackstep) < 0) return(0);
//--- final rejection
for(shift=ExtDepth;shift<rates_total;shift++)
{
switch(whatlookfor)
{
case Start: // search for peak or lawn
if(lastlow==0 && lasthigh==0)
{
if(HighMapBuffer[shift]!=0)
{
lasthigh=high[shift];
lasthighpos=shift;
whatlookfor=Sill;
ZigzagBuffer[shift]=lasthigh;
TimeBuffer[shift]=time[shift];
}
if(LowMapBuffer[shift]!=0)
{
lastlow=low[shift];
lastlowpos=shift;
whatlookfor=Pike;
ZigzagBuffer[shift]=lastlow;
TimeBuffer[shift]=time[shift];
}
}
break;
case Pike: // search for peak
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
{
//---
ZigzagBuffer[lastlowpos] = 0.0;
TimeBuffer[lastlowpos] = 0;
//---
lastlowpos=shift;
lastlow=LowMapBuffer[shift];
ZigzagBuffer[shift]=lastlow;
TimeBuffer[shift]=time[shift];
//--- Обязательно: покинуть switch
break;
}
//--- Обход "двойственности"
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow)
{
//---
ZigzagBuffer[lastlowpos] = 0.0;
TimeBuffer[lastlowpos] = 0;
//---
lastlowpos=shift;
lastlow=LowMapBuffer[shift];
ZigzagBuffer[shift]=lastlow;
TimeBuffer[shift]=time[shift];
//--- Обязательно: покинуть switch
break;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
//--- Проверка: % роста цены
percent = (HighMapBuffer[shift]-lastlow)/(lastlow/100);
if(percent > ExtDeviation)
{
lasthigh=HighMapBuffer[shift];
lasthighpos=shift;
ZigzagBuffer[shift]=lasthigh;
TimeBuffer[shift]=time[shift];
whatlookfor=Sill;
}
percent = 0.0;
}
break;
case Sill: // search for lawn
if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
{
//---
ZigzagBuffer[lasthighpos] = 0.0;
TimeBuffer[lasthighpos] = 0;
//---
lasthighpos=shift;
lasthigh=HighMapBuffer[shift];
ZigzagBuffer[shift]=lasthigh;
TimeBuffer[shift]=time[shift];
//--- Обязательно: покинуть switch
break;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh)
{
//---
ZigzagBuffer[lasthighpos] = 0.0;
TimeBuffer[lasthighpos] = 0;
//---
lasthighpos=shift;
lasthigh=HighMapBuffer[shift];
ZigzagBuffer[shift]=lasthigh;
TimeBuffer[shift]=time[shift];
//--- Обязательно: покинуть switch
break;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
//--- Проверка: % роста цены
percent = (lasthigh-LowMapBuffer[shift])/(lasthigh/100);
if(percent > ExtDeviation)
{
lastlow=LowMapBuffer[shift];
lastlowpos=shift;
ZigzagBuffer[shift]=lastlow;
TimeBuffer[shift]=time[shift];
whatlookfor=Pike;
}
percent = 0.0;
}
break;
default:
return(-1);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
В файле MyCExtremum - класс для расчета ZigZag...
Толковый подход. А паттерны описывали просто как положение баров в матрице, без учета фактической дельты цены - только относительное положение?
У меня есть идея, попробовать паттерны индикаторов, но с разным фреймом - первых пять баров анализируем показатели на 5 последних индикаторах, и два показателя для анализа тенденции - анализируем с шагом 10 и при этом учитываем абсолютные изменения.
Про зиг-заг толковая идея, а как пики фильтровали от флэтовых вихляний могли быть ложные точки смены тенденции?
Andrey Emelyanov:
Структура НС: 64 нейрона на входе, 4 внутренних, 1 выход. Т.е. один входной нейрон описывает один паттерн.
Я делаю так:
Есть динамический массив который хранит исключительно пары паттернов (я называю его словарь), если пара паттернов попала в словарь второй раз её не записываю; и два массива счетчика старшего таймфрейма и младшего - они считают как часто участвовал паттерн в формировании пар, даже если его не записывали в словарь.
Формирование вектора обучения происходит по словарю, вес отдельного паттерна = счетчик_патерна / максимум_счетчика. Т.е. паттерн который чаще всего участвует в формировании пар равен 1, а все остальные меньше 1. Вот такая табличка получается после обучения НС:
Структура НС: 64 нейрона на входе, 4 внутренних, 1 выход. Т.е. один входной нейрон описывает один паттерн. Сетка обучается за 40-50 минут, ошибка НС не превышает 0,00001.
Таким образом я имею модель которая может предсказывать значимость пар паттернов, даже если раньше её не было в словаре.
С флэтом и ложными пиками борюсь давно, но на уровне расчета ZigZaga. Я немного переделал код стандартного Zigzag, а именно реализовал на его базе процентный ZZ. Пока более или менее потребный код выглядит так:
Про массив интересное решение. А есть ли различия по статистике между парами/периодами, какая устойчивость вообще изменяемости частоты появления паттерна, дающего положительный результат предсказания?
Про зиг-заг, у меня так же есть решение на процентах, но я ещё использую более глубокую историю для расчета эталонного отрезка зиг-зага, по которому сравниваю изменение других в процентах.
На счет анализа индикаторов с помощью паттернов - это очень интересно... думаю на индикаторах меньше шума, но надо выбрать так индикаторы, чтобы одни подавляли "низкие шумы", а другие "высокие шумы", тогда получиться мультифильтр.
Вы с такой моделью на результаты надеетесь? У вас внутренний слой выступает промежуточным компрессором, а не классификатором.
Про массив интересное решение. А есть ли различия по статистике между парами/периодами, какая устойчивость вообще изменяемости частоты появления паттерна, дающего положительный результат предсказания?
Про зиг-заг, у меня так же есть решение на процентах, но я ещё использую более глубокую историю для расчета эталонного отрезка зиг-зага, по которому сравниваю изменение других в процентах.
Как всем известно паттерны А. Меррилла не дают точного ответа будет ли паттерн далее развиваться (сохранять тренд) или перейдет в другой паттерн (отскок цены). Поэтому я решил искать ответ при использовании двух временных периодов часового и минутного. Статистику повторяемости пар собираю, и пока универсального словаря обучения не имею. Однако точно уверен что связь эта должна быть... иначе бы не существовало гармоничных моделей: бабочек, летучая мышь и т.п.
Моя детка пока еще тупая-притупая, но уже кое что умеет.. 8 индикаторов на входе, 1 выход, 15 нейронов в с крытом слое. 2000 входной вектор, 10000 эпох обучения.
В общем-то это уже 3-й или 4-й, у всех результаты получаются примерно одинаковые. Я так полагаю, надо больше нейронов и входной вектор, но ждать долго пока обучится.
Примерно представляю себе закономерность, которую она должна уловить, и индикаторы специально подобрал с разных тф, и на выходы вроде бы осмысленная инфа подается.