Вобщем все так. Показатель Херста считается для каждого канала, главное, чтобы количество баров его составляющих превышало некоторую величину, например 30 - т\ф не важен поскольку расчет идет от дневных каналов например за 3-5-7 дней (все зависит от точности, которую хотите получить - однодневная подборка может быть неустойчивой) - внутридневных баров будет достаточно ;). И только потом делается заключение о пригодности данного канала к прогнозированию и построению проекций разворотных зон. Один и тот же разворотный уровень по Мюррею у разных каналов будет в разных доверительных интервалах - ведь Вам нужно как-то это отсечь не так ли ? А критерием качества есть потенциальная энергия - смотрите о квадратичных формах - ничего необычного.
А не собираюсь я делиться ГОТОВЫМ РЕШЕНИЕМ, а методика - пожалуйста, без проблем.
А не собираюсь я делиться ГОТОВЫМ РЕШЕНИЕМ, а методика - пожалуйста, без проблем.
В общем понятно. Всё как в диссертации. Есть всё, кроме той самой несложной схемки, без которой ничего не заработает;o)! А схемку знает только тот, кто её придумал, и всё остальное без неё является просто бумагой, которой и так много вокруг. Хотя заметьте, я только констатирую факт, без какого-либо иного смысла. Каждый всё равно должен ездить на собственном велосипеде. Это ведь FOREX!:o)
А вот ещё один вопросик. Это всё у Вас реализовано на чём? На МТ4? То есть в МТ4 есть индикатор Мюррея, который Вы привели. Это понятно. А вот расчёт каналов и Хёрста Вы делаете на чём? Тоже в МТ4? Вы как-то делали упоминание о размере кода порядка 0,5М. Это Вы что имели в виду? Вес текста расчётной программы на mql4? Если да, то честно говоря мне сложно представить такой объём. Поскольку по моим скромным подсчётом текст такой программы должен иметь примерно что-то в районе 10000 строк. Простая стратегия по белому шуму, которой пользуюсь я, занимает всего 1000 строк и это при том, что я просто запускаю параллельно 6 нитей торговли, которые используют информацию из разных таймфреймов, и куски такого кода проще (удобнее для возможной дальнейшей модернизации) оставить в том виде, который имется сейчас, чем используя массивы превратить например в 400-500 строк (хотя в перспективе и такие планы имеются тоже). То есть запуск одной нити по одному таймфрейму как раз и будет занимать 400-500 строк. Я использую полнофункционального советника, за которым не нужно следить. Конечно же от его дальнейшего совершенствования я не отказываюсь, но пока что всё что можно было соптимизировать я уже соптимизировал в нём на тестере. Но в Ваших методах есть определённый интерес и я постараюсь что-то применить, если конечно же получится.
PS: А то что я использую не одну нить торговли с большим лотом, а несколько параллельных нитей по разным таймфреймам с маленькими лотами объясняется исключительно тем, что при такой торговле возникает что-то типа эффекта фильтрации максимальной просадки. То есть если у вас есть несколько случайных процессов (динамика баланса по одной нити), то при сложении балансов на одном счёте максимальная просадка будет равняться не сумме просадок по каждой нити, а сумме просадок по каждой нити, разделённой на корень квадратный из числа нитей! Таким образом я стараюсь уменьшить общую максимальную просадку. То есть если у вас есть 6 нитей, каждая из которых имеет просадку допустим в 50USD на истории в 1,5 года, то по логике суммарная просадка 6 нитей должна составить 300USD, но на практике эту сумму нужно РАЗДЕЛИТЬ на корень из 6 = 2,45. Ну примерно так в тестере и показывается. По тестеру получается, что нужно делить примерно на 2,2. Что я думаю хорошо согласуется с моей идеей об уменьшении максимальной просадки.
Вобщем "схемку" Вы и свою сможете придумать, не скажу, что это будет просто, но только тогда можно будет понять как это работает и как (и почему именно так и никак не иначе) трактуются сигналы. По поводу кода : писал на МКЛ4 - он весьма похож на С\С++ на котором я программирую давненько, хоть и работает медленно - перекомпилю все под С++. По поводу размеров проги - действительно немаленький : 0.5M это размер откомпилированной программы, то есть размер .ех4 файла. С количеством строк Вы немного ошиблись - около 6000 всего то - в основном все в функциях, циклах и многомерных массивах, так что если просто развернуть - даже не представляю :) .....
А то мы не по делу чужую ветку зафлудили :). Удачи.
Позволю себе не согласится с Вами. Эта ветка только тогда и стала интересной, когда Вы решили поделиться своим опытом и идеями.
Как физику мне понятно все про поле, потенциальность и т.п. С оптимизацией тоже все ясно - это проблема нетривиальная и интересная. Что же касается мат.статистики, то здесь я смог понять о чем речь только в общих чертах, увы. А тема интересная. Особенно в части априорной оценки значимости уровней и возможности неслучайного прогнозирования.
Мой подход (до сих пор) концентрировался вокруг определения периодов трендового рынка. Я не использовал показатель Херста ни в том виде, который приведен в статье выше, ни в другом. Тем не менее, я тоже пытаюсь опираться на меру фрактальности рынка, имеющую мой собственный алгоритм вычисления. Идея о том, что периоды контртрендовости можно использовать не хуже, чем трендовые, оказалась для меня совершенно неожиданной. Иногда трудно увидеть даже то, что лежит под носом. :-)
Так что я с удовольствием продолжил бы диалог, если не на этом форуме, то через Ваш email, приведенный в индикаторе уровней Мюррей, или на пауке в личке.
В любом случае хочу сказать: Ваша работа произвела на меня впечатление ! Впервые увидел работу не "образного мышления" любителя (к которым отношу и себя), математику в руках математика. Особенно мне понравилось вот это:
...с января 2006 мне удалось получить способы решения, которые на любом датафиде дают одинаковые уровни и границы зон разворотов, то есть на любом ДЦ, несмотря на некоторые различия в котировках и при этом алгоритмы сглаживания я не использую - они все запаздывают.
Сходящиеся результаты на различных потоках данных и без использования сглаживания - это значит, что Ваша методика достала природу процесса !
Так что я с удовольствием продолжил бы диалог, если не на этом форуме, то через Ваш email, приведенный в индикаторе уровней Мюррей, или на пауке в личке.
Да без проблем .
Сходящиеся результаты на различных потоках данных и без использования сглаживания - это значит, что Ваша методика достала природу процесса !
Я высказался бы несколько скромнее - это значит, что работают методы матстатистики - их только нужно правильно применять, и что все-таки многие методы ТА имеют обоснование. ( то есть на рынке присутствуют участки преддетерминированного движения). В том числе и качественные методы типа Эллиотта или Ганна, хотя, как я уже писал - мне Эллиотт не сильно нравится из-за отсутствия количественных оценок.
В любом случае - удачи и попутных трендов.
ЗЫ На пауке есть пару неплохих книжек по мат.статистике - ищите МакКормика "Энциклопедию торговых стратегий" и Булашева "Статистику для трейдеров" - весьма полезны в прикладном смысле - показана логика применения методов.
С интересом прочитал Ваше обсуждение, и с тем большим интересом, что применяемые методы мне в силу профессиональных занятий весьма и весьма близки. Позвольте внести свою небольшую лепту.
алгоритмы сглаживания я не использую - они все запаздывают
Попробуйте DCT-преобразование с диффракционным ядром - сглаживает очень хорошо, совсем не запаздывает. ИМХО, работает лучше традиционных ЛЦФ. Ниже приведены куски кода на С++. Способ употребления, думаю, понятен из комментариев.
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Прямое дискретное косинус-преобразование (DCT) x[] --> y[] |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
/*
Входные глобальные переменные:
double x[] // входной массив
Входные локальные переменные:
int n_bars // полное число баров для DCT-преобразования
Выходные локальные переменные: нет
Выходные глобальные переменные:
double y[] // массив гармоник
*/
void DCT(int n_bars, double x [], double y [])
{
int k; // счетчик строк матрицы коэффициентов
int n; // счетчик столбцов матрицы коэффициентов
double sum; // накопитель
double PIN2 = PI / (n_bars * 2.0);
double wgt_zero = 1.0 / sqrt(n_bars); // вес при 0-м коэффициенте
double wgt_nzero = sqrt(2.0) * wgt_zero; // вес при всех остальных
//----
// dct-преобразование
for (k = 0; k < n_bars; k++)
{ // цикл по k
sum = 0.0; // обнуляем накопитель
for (n = 0; n < n_bars; n++)
{ sum += x[n] * cos(PIN2 * (2.0 * n + 1.0) * k); } // цикл по n
if (k != 0)
{ y[k] = wgt_nzero * sum; }
else
{ y[k] = wgt_zero * sum; }
} // цикл по k
//----
return;
}
//
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Обратное дискретное косинус-преобразование (IDCT) y[] --> x[] |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
/*
Входные глобальные переменные:
double y[] // массив гармоник
Входные локальные переменные:
int n_bars // полное число баров для DCT-преобразования
Выходные локальные переменные: нет
Выходные глобальные переменные:
double x[] // выходной массив
*/
void IDCT(int n_bars, double x [], double y [])
{
int k; // счетчик строк матрицы коэффициентов
int n; // счетчик столбцов матрицы коэффициентов
double sum; // накопитель
double PIN2 = PI / (n_bars * 2.0);
double wgt_zero = 1.0 / sqrt(n_bars); // вес при 0-м коэффициенте
double wgt_nzero = sqrt(2.0) * wgt_zero; // вес при всех остальных
//----
// idct-преобразование
for (n = 0; n < n_bars; n++)
{ // цикл по n
sum = 0.0; // обнуляем накопитель
for (k = 0; k < n_bars; k++)
{ // цикл по k
if (k != 0)
{ sum += wgt_nzero * y[k] * cos(PIN2 * (2.0 * n + 1.0) * k); }
else
{ sum += wgt_zero * y[k] * cos(PIN2 * (2.0 * n + 1.0) * k); }
} // цикл по k
x[n] = sum;
} // цикл по n
//----
return;
}
//
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Вычисление левой части уравнения y[] --> y[] (диффракционное ядро) |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
/*
Входные глобальные переменные:
double y[] // массив гармоник
Входные локальные переменные:
int n_bars // полное число баров для расчета
double eye // размер "окна"
double alfa // параметр регуляризации
Выходные локальные переменные: нет
Выходные глобальные переменные:
double y[] // массив значений левой части уравнения
*/
void GetDiffrLeftSide(int n_bars, double eye, double alfa, double y [])
{
double kern; //
double omega; //
double domega; //
double omega2; // 1 + omega^2
double delta = 2.0 * PI / (n_bars - 1);
int i;
//----
for (i = 0; i < n_bars; i++)
{
omega = i * delta;
domega = omega * eye;
omega2 = 1.0 + omega * omega; // 1. + omega^2
kern = (sin(domega) + EPS) / (domega + EPS); // sin(arg)/arg
y[i] = (kern * y[i]) / (kern * kern + alfa * omega2);
}
//----
return;
}
//
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Линейное сглаживание массива x[] по 5 точкам; результат - y[] |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
/*
Входные глобальные переменные:
double x[] // входной массив - аргумент;
Входные локальные переменные:
int n_beg // номер начального бара
int n_end // номер конечного бара
Выходные локальные переменные: нет
Выходные глобальные переменные:
double y[] // выходной массив - ответ;
*/
void GetSmooth5(int n_beg, int n_end, double x [], double y [])
{
int i;
//----
y[n_beg] = (3.0 * x[n_beg] + 2.0 * x[n_beg+1] +
x[n_beg+2] - x[n_beg+4]) / 5.0;
y[n_beg+1] = (4.0 * x[n_beg] + 3.0 * x[n_beg+1] +
2.0 * x[n_beg+2] + x[n_beg+3]) / 10.0;
for (i = n_beg + 2; i < n_end - 2; i++)
{ y[i] = (x[i-2] + x[i-1] + x[i] + x[i+1] + x[i+2]) / 5.0; }
y[n_end-2] = (x[n_end-4] + 2.0 * x[n_end-3] +
3.0 * x[n_end-2] + 4.0 * x[n_end-1]) / 10.0;
y[n_end-1] = (3.0 * x[n_end-1] + 2.0 * x[n_end-2] +
x[n_end-3] - x[n_end-5]) / 5.0;
//----
return;
}
//
А это - способ применения:
//
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Сглаживание методом DCT-преобразования (без запаздывания) |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
/*
Входные глобальные переменные:
double x[] // несглаженный массив значений аргумента (цена);
Входные локальные переменные:
int n_bars // полное число баров для преобразования
double eye // размер "окна"
double alfa // параметр регуляризации
Выходные локальные переменные:
int nn_tot // число сглаженных баров
Выходные глобальные переменные:
double x[] // ответ - сглаженный массив значений аргумента;
*/
MT4_EXPFUNC int __stdcall GetDiffrDCTS (int nn_tot, double eye, double alfa,
double x [])
{
int err_code = 0; // код ошибки
int i; // счетчик
//
// ########################### Error Definitions ###########################
// *** Ошибка: если превышено максимальное число баров, выход ***
if (nn_tot > NN_MAX)
{
err_code = -1;
return(err_code);
}
// *** Ошибка: для преобразования задано слишком мало баров, выход ***
if (nn_tot < NN_MIN)
{
err_code = -2;
return(err_code);
}
// *** Ошибка: параметр alfa = 0 при eye <> 0, выход ***
if ((alfa == 0.0) && (eye != 0.0))
{
err_code = -3;
return(err_code);
}
// *** Ошибка: параметр eye_size < 0, выход ***
if (eye < 0.0)
{
err_code = -4;
return(err_code);
}
// *** Ошибка: параметр eye_alfa < 0, выход ***
if (alfa < 0.0)
{
err_code = -5;
return(err_code);
}
// #########################################################################
//
//----
//
DCT (nn_tot, x, y); // x[] --> y[]
GetDiffrLeftSide (nn_tot, eye, alfa, y); // y[] --> y[]
IDCT (nn_tot, x, y); // y[] --> x[]
GetSmooth5 (0, nn_tot, x, y); // x[] --> y[]
for (i = 0; i < nn_tot; i++) { x[i] = y[i]; } // y[] --> x[]
//
//----
err_code = nn_tot;
return(err_code);
}
//
Попробуйте, например, параметры Eye = 2.5, Alfa = 0.5. Важно помнить, что комбинация (Eye !=0, Alfa == 0) недопустима. Для избежания неопределенности типа 0/0 используется EPS. Я беру EPS = 1.0Е-09. Сглаженный массив надо нормировать на диапазон изменения цены за nn_tot баров:
//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Нормировка результов вычислений на заданный диапазон значений |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
/*
Входные глобальные переменные:
double x[] // неномированный массив значений аргумента;
Входные локальные переменные:
int n_beg // номер начального бара
int n_end // номер конечного бара
double v_max // максимальное значение диапазона для нормировки;
double v_min // минимальное значение диапазона для нормировки;
Выходные локальные переменные: нет
Выходные глобальные переменные:
double x[] // ответ - нормированный массив значений аргумента;
*/
MT4_EXPFUNC int __stdcall NormRange(int n_beg, int n_end,
double v_max, double v_min, double x [])
{
int err_code = 0; // возвращаемый код ошибки
double x_max; // максимальное значение в нормируемом массиве
double x_min; // минимальное значение в нормируемом массиве
double x_curr; // текущее ненормированное значение
double x_norm; // текущее нормированное значение
double coef_1; // 1-й нормировочный коэффициент
double coef_2; // 2-й нормировочный коэффициент
double diff_x; // разность x_max - x_min
int n_bars; // n_end - n_beg
int i; // счетчик
//
n_bars = n_end - n_beg;
// ########################### Error Definitions ###########################
// *** Ошибка: если перепутаны местами начальный и конечный бары, выход ***
if (n_bars < 0)
{
err_code = -6;
return(err_code);
}
// *** Ошибка: если превышено максимальное число баров, выход ***
if ((n_bars > 0) && (n_bars > NN_MAX))
{
err_code = -1;
return(err_code);
}
// *** Ошибка: для преобразования задано слишком мало баров, выход ***
if ((n_bars > 0) && (n_bars < NN_MIN))
{
err_code = -2;
return(err_code);
}
// #########################################################################
//
//----
// находим максимумы и минимумы в массиве результата
x_min = 999999999.0;
x_max = -999999999.0;
for (i = n_beg; i < n_end; i++)
{
x_curr = x[i];
if (x_curr >= x_max) { x_max = x_curr; }
if (x_curr <= x_min) { x_min = x_curr; }
}
diff_x = x_max - x_min;
//
// ########################### Error Definitions ###########################
// *** Ошибка: diff_x = 0 ***
if (diff_x == 0.0)
{
err_code = -7;
return(err_code);
}
// #########################################################################
//
// находим коэффициенты пересчета
coef_1 = (v_min * x_max - v_max * x_min) / diff_x;
coef_2 = (v_max - v_min) / diff_x;
// нормируем результат на заданный диапазон
for (i = n_beg; i < n_end; i++)
{
x_curr = x[i];
x_norm = coef_1 + x_curr * coef_2;
x[i] = x_norm;
}
//----
return(err_code);
}
//
Переменные v_max и v_min должны быть получены раньше, при формировании массива цен для обработки.
Vladislav, Понимаю Ваше желание обойтись без громких фраз и отношение к методам матстатистики. Однако, у меня другое мнение.
Рынок - нестационарный, хаотический процесс. А матстатистика имеет дело в основном со стационарными процессами. Переход к пределу в ней - один из главных методов доказательства утверждений. А какое предельное состояние у рынка ? Броуновское движение - явление в замкнутой системе, а рынок существенно открытая система. С другой стороны, рынок - самоорганизующийся процесс, следовательно есть и законы этой самоорганизации.
С моей точки зрения, Ваш успех обусловлен не применением методов матстатистики, а ОГРАНИЧЕНИЕМ на методы матстатистики со стороны конструктивной части Вашей стратегии. Эти ограничения и помогли ухватить что-то важное, не дав методу (т.е. инструменту) растворить это в подробностях применения.
Спасибо за книжки, обязательно посмотрю. Ваш ник на пауке тот же ?
alexjou Означают ли эти три исходника, что вы используете их в связке с МТ4 (похоже на это). И как бы это пощупать, если нет среды Си для компиляции?
Можно попробовать в МТ. Первоначально они были запрограммированы в MQL для отладки, а потом уже с минимальными изменениями перекочевали в С. А самый древний вариант был на ассемблере.
А не собираюсь я делиться ГОТОВЫМ РЕШЕНИЕМ, а методика - пожалуйста, без проблем.
Удачи и попутных трендов.
А не собираюсь я делиться ГОТОВЫМ РЕШЕНИЕМ, а методика - пожалуйста, без проблем.
В общем понятно. Всё как в диссертации. Есть всё, кроме той самой несложной схемки, без которой ничего не заработает;o)! А схемку знает только тот, кто её придумал, и всё остальное без неё является просто бумагой, которой и так много вокруг. Хотя заметьте, я только констатирую факт, без какого-либо иного смысла. Каждый всё равно должен ездить на собственном велосипеде. Это ведь FOREX!:o)
А вот ещё один вопросик. Это всё у Вас реализовано на чём? На МТ4?
То есть в МТ4 есть индикатор Мюррея, который Вы привели. Это понятно.
А вот расчёт каналов и Хёрста Вы делаете на чём? Тоже в МТ4? Вы как-то делали упоминание о размере кода порядка 0,5М. Это Вы что имели в виду? Вес текста расчётной программы на mql4? Если да, то честно говоря мне сложно представить такой объём. Поскольку по моим скромным подсчётом текст такой программы должен иметь примерно что-то в районе 10000 строк. Простая стратегия по белому шуму, которой пользуюсь я, занимает всего 1000 строк и это при том, что я просто запускаю параллельно 6 нитей торговли, которые используют информацию из разных таймфреймов, и куски такого кода проще (удобнее для возможной дальнейшей модернизации) оставить в том виде, который имется сейчас, чем используя массивы превратить например в 400-500 строк (хотя в перспективе и такие планы имеются тоже). То есть запуск одной нити по одному таймфрейму как раз и будет занимать 400-500 строк. Я использую полнофункционального советника, за которым не нужно следить. Конечно же от его дальнейшего совершенствования я не отказываюсь, но пока что всё что можно было соптимизировать я уже соптимизировал в нём на тестере. Но в Ваших методах есть определённый интерес и я постараюсь что-то применить, если конечно же получится.
PS: А то что я использую не одну нить торговли с большим лотом, а несколько параллельных нитей по разным таймфреймам с маленькими лотами объясняется исключительно тем, что при такой торговле возникает что-то типа эффекта фильтрации максимальной просадки. То есть если у вас есть несколько случайных процессов (динамика баланса по одной нити), то при сложении балансов на одном счёте максимальная просадка будет равняться не сумме просадок по каждой нити, а сумме просадок по каждой нити, разделённой на корень квадратный из числа нитей! Таким образом я стараюсь уменьшить общую максимальную просадку. То есть если у вас есть 6 нитей, каждая из которых имеет просадку допустим в 50USD на истории в 1,5 года, то по логике суммарная просадка 6 нитей должна составить 300USD, но на практике эту сумму нужно РАЗДЕЛИТЬ на корень из 6 = 2,45. Ну примерно так в тестере и показывается. По тестеру получается, что нужно делить примерно на 2,2. Что я думаю хорошо согласуется с моей идеей об уменьшении максимальной просадки.
Удачи и попутных трендов.
Позволю себе не согласится с Вами. Эта ветка только тогда и стала интересной, когда Вы решили поделиться своим опытом и идеями.
Как физику мне понятно все про поле, потенциальность и т.п. С оптимизацией тоже все ясно - это проблема нетривиальная и интересная. Что же касается мат.статистики, то здесь я смог понять о чем речь только в общих чертах, увы. А тема интересная. Особенно в части априорной оценки значимости уровней и возможности неслучайного прогнозирования.
Мой подход (до сих пор) концентрировался вокруг определения периодов трендового рынка. Я не использовал показатель Херста ни в том виде, который приведен в статье выше, ни в другом. Тем не менее, я тоже пытаюсь опираться на меру фрактальности рынка, имеющую мой собственный алгоритм вычисления. Идея о том, что периоды контртрендовости можно использовать не хуже, чем трендовые, оказалась для меня совершенно неожиданной. Иногда трудно увидеть даже то, что лежит под носом. :-)
Так что я с удовольствием продолжил бы диалог, если не на этом форуме, то через Ваш email, приведенный в индикаторе уровней Мюррей, или на пауке в личке.
В любом случае хочу сказать: Ваша работа произвела на меня впечатление ! Впервые увидел работу не "образного мышления" любителя (к которым отношу и себя), математику в руках математика.
Особенно мне понравилось вот это:
Сходящиеся результаты на различных потоках данных и без использования сглаживания - это значит, что Ваша методика достала природу процесса !
Да без проблем .
Сходящиеся результаты на различных потоках данных и без использования сглаживания - это значит, что Ваша методика достала природу процесса !
Я высказался бы несколько скромнее - это значит, что работают методы матстатистики - их только нужно правильно применять, и что все-таки многие методы ТА имеют обоснование. ( то есть на рынке присутствуют участки преддетерминированного движения). В том числе и качественные методы типа Эллиотта или Ганна, хотя, как я уже писал - мне Эллиотт не сильно нравится из-за отсутствия количественных оценок.
В любом случае - удачи и попутных трендов.
ЗЫ На пауке есть пару неплохих книжек по мат.статистике - ищите МакКормика "Энциклопедию торговых стратегий" и Булашева "Статистику для трейдеров" - весьма полезны в прикладном смысле - показана логика применения методов.
Попробуйте DCT-преобразование с диффракционным ядром - сглаживает очень хорошо, совсем не запаздывает. ИМХО, работает лучше традиционных ЛЦФ. Ниже приведены куски кода на С++. Способ употребления, думаю, понятен из комментариев.
//*************************************************************************// ///////////////////////////////////////////////////////////////////////////// //+-----------------------------------------------------------------------+// //| Прямое дискретное косинус-преобразование (DCT) x[] --> y[] |// //+-----------------------------------------------------------------------+// ///////////////////////////////////////////////////////////////////////////// /* Входные глобальные переменные: double x[] // входной массив Входные локальные переменные: int n_bars // полное число баров для DCT-преобразования Выходные локальные переменные: нет Выходные глобальные переменные: double y[] // массив гармоник */ void DCT(int n_bars, double x [], double y []) { int k; // счетчик строк матрицы коэффициентов int n; // счетчик столбцов матрицы коэффициентов double sum; // накопитель double PIN2 = PI / (n_bars * 2.0); double wgt_zero = 1.0 / sqrt(n_bars); // вес при 0-м коэффициенте double wgt_nzero = sqrt(2.0) * wgt_zero; // вес при всех остальных //---- // dct-преобразование for (k = 0; k < n_bars; k++) { // цикл по k sum = 0.0; // обнуляем накопитель for (n = 0; n < n_bars; n++) { sum += x[n] * cos(PIN2 * (2.0 * n + 1.0) * k); } // цикл по n if (k != 0) { y[k] = wgt_nzero * sum; } else { y[k] = wgt_zero * sum; } } // цикл по k //---- return; } // //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// //+-----------------------------------------------------------------------+// //| Обратное дискретное косинус-преобразование (IDCT) y[] --> x[] |// //+-----------------------------------------------------------------------+// ///////////////////////////////////////////////////////////////////////////// /* Входные глобальные переменные: double y[] // массив гармоник Входные локальные переменные: int n_bars // полное число баров для DCT-преобразования Выходные локальные переменные: нет Выходные глобальные переменные: double x[] // выходной массив */ void IDCT(int n_bars, double x [], double y []) { int k; // счетчик строк матрицы коэффициентов int n; // счетчик столбцов матрицы коэффициентов double sum; // накопитель double PIN2 = PI / (n_bars * 2.0); double wgt_zero = 1.0 / sqrt(n_bars); // вес при 0-м коэффициенте double wgt_nzero = sqrt(2.0) * wgt_zero; // вес при всех остальных //---- // idct-преобразование for (n = 0; n < n_bars; n++) { // цикл по n sum = 0.0; // обнуляем накопитель for (k = 0; k < n_bars; k++) { // цикл по k if (k != 0) { sum += wgt_nzero * y[k] * cos(PIN2 * (2.0 * n + 1.0) * k); } else { sum += wgt_zero * y[k] * cos(PIN2 * (2.0 * n + 1.0) * k); } } // цикл по k x[n] = sum; } // цикл по n //---- return; } // //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// //+-----------------------------------------------------------------------+// //| Вычисление левой части уравнения y[] --> y[] (диффракционное ядро) |// //+-----------------------------------------------------------------------+// ///////////////////////////////////////////////////////////////////////////// /* Входные глобальные переменные: double y[] // массив гармоник Входные локальные переменные: int n_bars // полное число баров для расчета double eye // размер "окна" double alfa // параметр регуляризации Выходные локальные переменные: нет Выходные глобальные переменные: double y[] // массив значений левой части уравнения */ void GetDiffrLeftSide(int n_bars, double eye, double alfa, double y []) { double kern; // double omega; // double domega; // double omega2; // 1 + omega^2 double delta = 2.0 * PI / (n_bars - 1); int i; //---- for (i = 0; i < n_bars; i++) { omega = i * delta; domega = omega * eye; omega2 = 1.0 + omega * omega; // 1. + omega^2 kern = (sin(domega) + EPS) / (domega + EPS); // sin(arg)/arg y[i] = (kern * y[i]) / (kern * kern + alfa * omega2); } //---- return; } // //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// //+-----------------------------------------------------------------------+// //| Линейное сглаживание массива x[] по 5 точкам; результат - y[] |// //+-----------------------------------------------------------------------+// ///////////////////////////////////////////////////////////////////////////// /* Входные глобальные переменные: double x[] // входной массив - аргумент; Входные локальные переменные: int n_beg // номер начального бара int n_end // номер конечного бара Выходные локальные переменные: нет Выходные глобальные переменные: double y[] // выходной массив - ответ; */ void GetSmooth5(int n_beg, int n_end, double x [], double y []) { int i; //---- y[n_beg] = (3.0 * x[n_beg] + 2.0 * x[n_beg+1] + x[n_beg+2] - x[n_beg+4]) / 5.0; y[n_beg+1] = (4.0 * x[n_beg] + 3.0 * x[n_beg+1] + 2.0 * x[n_beg+2] + x[n_beg+3]) / 10.0; for (i = n_beg + 2; i < n_end - 2; i++) { y[i] = (x[i-2] + x[i-1] + x[i] + x[i+1] + x[i+2]) / 5.0; } y[n_end-2] = (x[n_end-4] + 2.0 * x[n_end-3] + 3.0 * x[n_end-2] + 4.0 * x[n_end-1]) / 10.0; y[n_end-1] = (3.0 * x[n_end-1] + 2.0 * x[n_end-2] + x[n_end-3] - x[n_end-5]) / 5.0; //---- return; } //А это - способ применения:
// //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// //+-----------------------------------------------------------------------+// //| Сглаживание методом DCT-преобразования (без запаздывания) |// //+-----------------------------------------------------------------------+// ///////////////////////////////////////////////////////////////////////////// /* Входные глобальные переменные: double x[] // несглаженный массив значений аргумента (цена); Входные локальные переменные: int n_bars // полное число баров для преобразования double eye // размер "окна" double alfa // параметр регуляризации Выходные локальные переменные: int nn_tot // число сглаженных баров Выходные глобальные переменные: double x[] // ответ - сглаженный массив значений аргумента; */ MT4_EXPFUNC int __stdcall GetDiffrDCTS (int nn_tot, double eye, double alfa, double x []) { int err_code = 0; // код ошибки int i; // счетчик // // ########################### Error Definitions ########################### // *** Ошибка: если превышено максимальное число баров, выход *** if (nn_tot > NN_MAX) { err_code = -1; return(err_code); } // *** Ошибка: для преобразования задано слишком мало баров, выход *** if (nn_tot < NN_MIN) { err_code = -2; return(err_code); } // *** Ошибка: параметр alfa = 0 при eye <> 0, выход *** if ((alfa == 0.0) && (eye != 0.0)) { err_code = -3; return(err_code); } // *** Ошибка: параметр eye_size < 0, выход *** if (eye < 0.0) { err_code = -4; return(err_code); } // *** Ошибка: параметр eye_alfa < 0, выход *** if (alfa < 0.0) { err_code = -5; return(err_code); } // ######################################################################### // //---- // DCT (nn_tot, x, y); // x[] --> y[] GetDiffrLeftSide (nn_tot, eye, alfa, y); // y[] --> y[] IDCT (nn_tot, x, y); // y[] --> x[] GetSmooth5 (0, nn_tot, x, y); // x[] --> y[] for (i = 0; i < nn_tot; i++) { x[i] = y[i]; } // y[] --> x[] // //---- err_code = nn_tot; return(err_code); } //Попробуйте, например, параметры Eye = 2.5, Alfa = 0.5. Важно помнить, что комбинация (Eye !=0, Alfa == 0) недопустима. Для избежания неопределенности типа 0/0 используется EPS. Я беру EPS = 1.0Е-09.
Сглаженный массив надо нормировать на диапазон изменения цены за nn_tot баров:
// ///////////////////////////////////////////////////////////////////////////// //+-----------------------------------------------------------------------+// //| Нормировка результов вычислений на заданный диапазон значений |// //+-----------------------------------------------------------------------+// ///////////////////////////////////////////////////////////////////////////// /* Входные глобальные переменные: double x[] // неномированный массив значений аргумента; Входные локальные переменные: int n_beg // номер начального бара int n_end // номер конечного бара double v_max // максимальное значение диапазона для нормировки; double v_min // минимальное значение диапазона для нормировки; Выходные локальные переменные: нет Выходные глобальные переменные: double x[] // ответ - нормированный массив значений аргумента; */ MT4_EXPFUNC int __stdcall NormRange(int n_beg, int n_end, double v_max, double v_min, double x []) { int err_code = 0; // возвращаемый код ошибки double x_max; // максимальное значение в нормируемом массиве double x_min; // минимальное значение в нормируемом массиве double x_curr; // текущее ненормированное значение double x_norm; // текущее нормированное значение double coef_1; // 1-й нормировочный коэффициент double coef_2; // 2-й нормировочный коэффициент double diff_x; // разность x_max - x_min int n_bars; // n_end - n_beg int i; // счетчик // n_bars = n_end - n_beg; // ########################### Error Definitions ########################### // *** Ошибка: если перепутаны местами начальный и конечный бары, выход *** if (n_bars < 0) { err_code = -6; return(err_code); } // *** Ошибка: если превышено максимальное число баров, выход *** if ((n_bars > 0) && (n_bars > NN_MAX)) { err_code = -1; return(err_code); } // *** Ошибка: для преобразования задано слишком мало баров, выход *** if ((n_bars > 0) && (n_bars < NN_MIN)) { err_code = -2; return(err_code); } // ######################################################################### // //---- // находим максимумы и минимумы в массиве результата x_min = 999999999.0; x_max = -999999999.0; for (i = n_beg; i < n_end; i++) { x_curr = x[i]; if (x_curr >= x_max) { x_max = x_curr; } if (x_curr <= x_min) { x_min = x_curr; } } diff_x = x_max - x_min; // // ########################### Error Definitions ########################### // *** Ошибка: diff_x = 0 *** if (diff_x == 0.0) { err_code = -7; return(err_code); } // ######################################################################### // // находим коэффициенты пересчета coef_1 = (v_min * x_max - v_max * x_min) / diff_x; coef_2 = (v_max - v_min) / diff_x; // нормируем результат на заданный диапазон for (i = n_beg; i < n_end; i++) { x_curr = x[i]; x_norm = coef_1 + x_curr * coef_2; x[i] = x_norm; } //---- return(err_code); } //Переменные v_max и v_min должны быть получены раньше, при формировании массива цен для обработки.
Понимаю Ваше желание обойтись без громких фраз и отношение к методам матстатистики.
Однако, у меня другое мнение.
Рынок - нестационарный, хаотический процесс. А матстатистика имеет дело в основном со стационарными процессами. Переход к пределу в ней - один из главных методов доказательства утверждений. А какое предельное состояние у рынка ? Броуновское движение - явление в замкнутой системе, а рынок существенно открытая система. С другой стороны, рынок - самоорганизующийся процесс, следовательно есть и законы этой самоорганизации.
С моей точки зрения, Ваш успех обусловлен не применением методов матстатистики,
а ОГРАНИЧЕНИЕМ на методы матстатистики со стороны конструктивной части Вашей стратегии.
Эти ограничения и помогли ухватить что-то важное, не дав методу (т.е. инструменту) растворить это в подробностях применения.
Спасибо за книжки, обязательно посмотрю.
Ваш ник на пауке тот же ?
Ваш ник на пауке тот же ?
На пауке - VG .
Удачи и попутных трндов.
Означают ли эти три исходника, что вы используете их в связке с МТ4 (похоже на это). И как бы это пощупать, если нет среды Си для компиляции?
Означают ли эти три исходника, что вы используете их в связке с МТ4 (похоже на это). И как бы это пощупать, если нет среды Си для компиляции?
Можно попробовать в МТ. Первоначально они были запрограммированы в MQL для отладки, а потом уже с минимальными изменениями перекочевали в С. А самый древний вариант был на ассемблере.