a trading strategy based on Elliott Wave Theory - page 10

 
Basically it's like this. Hurst ratio is calculated for each channel, the main thing is to make sure that the number of bars in it exceeds a certain value, for example 30 - Òôô is not important as we calculate from daily channels for 3-5-7 days (everything depends on accuracy you want to get - one-day collection may be unstable) - intraday bars will be enough). And only then we make conclusions about the suitability of this channel for forecasting and constructing projections of reversal zones. One and the same reversal level according to Murray in different channels will be in different confidence intervals - you need to cut it off somehow, don't you? And the quality criterion is potential energy - see about quadratic forms - nothing unusual.

And I'm not going to share the DONE SOLUTION, but the methodology - please, no problem.

Good luck and happy trends.
 
<br / translate="no"> And I'm not going to share the DIRECT solution, but the methodology - no problem.

In general it's clear. Everything is like in the thesis. There is everything, except that simple scheme, without which nothing will work ;o)! And the schematic is known only to those who invented it, and everything else without it is just paper, which is so much around. Mind you though, I'm only stating a fact, without any other meaning. Everyone has to ride their own bicycle anyway. It's FOREX after all!)

And here's another question. All of this is implemented on what? On MT4?
That is, MT4 has the Murray indicator that you mentioned. It is clear.
But what do you use to calculate channels and Hearst? Do you use MT4 as well? You once mentioned the code size of 0.5M. What do you mean by that? The weight of the text of a calculation program on mql4? If so, frankly speaking, I can hardly imagine such a volume. Because, according to my conservative estimate, the text of such a program should be about 10000 lines. A simple white noise strategy I use takes only 1000 lines, even though I simply launch 6 trading threads in parallel that use information from different timeframes and it is easier (more convenient for further modification) to leave pieces of such code as they are now than convert them into 400-500 lines using arrays (although such plans are also possible in future). That is, running one thread by one timeframe will take 400-500 lines. I am using a fully functional Expert Advisor which does not need to be monitored. Of course I don't refuse its further improvement but so far I have already optimized everything that could be optimized in it in the tester. But there is a certain interest in your methods and I will try to apply something, if I succeed, of course.

PS: And the fact that I use not one thread of trade with a large lot, but several parallel threads on different timeframes with small lots is explained solely by the fact that in this kind of trade appears something like a maximum drawdown filtration effect. That is, if you have several random processes (balance dynamics of one thread), then when summing up the balances in one account, the maximal drawdown will be equal to the sum of drawdowns of each thread divided by the square root of the number of threads, not the sum of drawdowns of each! Thus, I try to decrease the total maximal drawdown. That is, if you have 6 threads, each with drawdown of 50USD on 1,5 year history, logically the total drawdown of 6 threads should be 300USD, but in practice, this amount should be divided by the square root of 6 = 2,45. This is roughly what the tester shows. The tester shows that you should divide by about 2.2. Which I think agrees well with my idea of reducing the maximum drawdown.
 
In general, you can come up with your own "circuit", I can't say that it will be easy, but only then you will understand how it works and how (and why exactly and in no other way) signals are interpreted. About the code: I wrote it in MKL4 - it's very similar to C/C++, which I've been programming in for a long time, though it's slow - I'll recompile everything for C++. Regarding the size of the program, it's really not so big: 0.5M is the size of a compiled program, i.e. the size of an .ex4 file. You're a little wrong about the number of lines - about 6000 total - mostly all in functions, loops and multidimensional arrays, so if you just unroll it, I can't even imagine :) .....


Good luck and good trends.
 
Hi Vladislav !
I don't use smoothing algorithms - they all lag behind.) Good luck.


I beg to differ with you. This thread became interesting only when you decided to share your experiences and ideas.

As a physicist, I understand everything about the field, potentiality, etc. All is clear with optimisation too - it is a non-trivial and interesting problem. As for mathematical statistics I could only grasp what it's all about in general terms, alas. But the subject is interesting. Especially in part of a priori estimation of significance levels and possibility of non-random prediction.

My approach (so far) has concentrated around defining trend market periods. I haven't used the Hearst index in the form given in the article above, nor in any other way. However, I too try to rely on a measure of market fractality that has my own calculation algorithm. The idea that counter-trend periods can be used just as well as trend periods has come as a complete surprise to me. Sometimes it's hard to see even what lies underneath. :-)

So I would be happy to continue the dialogue, if not on this forum, then via your email given in the Murray levels indicator, or on the spider in the private message.

Anyway I would like to say: your work impressed me ! For the first time I saw the work not of "figurative thinking" of an amateur (of which I include myself), but of mathematics in the hands of a mathematician.
I especially liked this one:
...since January 2006 I managed to get solution methods that on any datafeed give the same levels and boundaries of reversal zones, that is on any DC, despite some differences in quotes and at the same time I don't use smoothing algorithms - they all lag.

Converging results on different data streams and without using smoothing means that your methodology has got to the nature of the process !
 
So I'd love to continue the dialogue, if not on this forum, then via your email given in the Murray levels indicator, or on the spider in private. <br/ translate="no">


No problem .


Converging results on different data streams and without using smoothing means your methodology has got to the nature of the process !


I would put it a bit more modestly - it means that matstatistics methods work - they just need to be applied correctly, and that still many TA methods have justification. (i.e. there are areas of pre-determined movement in the market). The qualitative methods such as Elliott or Gann, although, as I wrote - I do not like Elliott much due to lack of quantitative estimates.

Anyway, good luck and good trends.

Look for McCormick's "Encyclopedia of Trading Strategies" and Bulashev's "Statistics for Traders" - very useful in an applied sense - the logic of the methods is shown.
 
I read your discussion with interest, and with even more interest because the methods used are quite close to me by virtue of my professional occupation. Allow me to make a small contribution.
I don't use smoothing algorithms - they all lag

Try DCT-transformation with diffraction kernel - it smoothes very well, doesn't lag at all. IMHO, it works better than traditional LCF. Below are some pieces of C++ code. The way to use it, I think, is clear from comments.

//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Прямое дискретное косинус-преобразование (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;
} 
//



And this is the method of application:

//
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Сглаживание методом 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);
}
//



Try, for example, the parameters Eye = 2.5, Alfa = 0.5. It is important to remember that the combination (Eye !=0, Alfa == 0) is not allowed. The EPS is used to avoid uncertainty like 0/0. I take EPS = 1.0E-09.
The smoothed array must be normalized to the range of price change over nn_tot bars:

//
/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| Нормировка результов вычислений на заданный диапазон значений         |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
/*
   Входные глобальные переменные:
 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);
} 
//



The variables v_max and v_min should be obtained earlier, when forming the price array for processing.

 
Vladislav,
I understand your desire to dispense with big words and your attitude to the methods of matstatistics.
However, I have a different opinion.

The market is a non-stationary, chaotic process. And matstatistics deals mainly with stationary processes. Transition to the limit is one of the main methods of proving statements. And what is the limit state of the market? Brownian motion is a phenomenon in a closed system, while the market is a substantially open system. On the other hand, the market is a self-organizing process, hence there are laws of this self-organization.

From my point of view, your success is not due to the application of matstatistical methods,
but to the LIMITATIONS on the methods of matstatistics on the part of the constructive part of your strategy.
These limitations are what helped to capture something important, without letting the method (i.e. the tool) dissolve it into the details of application.

Thanks for the books, will definitely have a look.
Is your nickname on the spider the same ?
 
<br / translate="no"> Is your nickname on the spider the same ?


On the spider it's VG .

Good luck and good luck with the trnds.
 
alexjou
Do these three sources mean that you are using them in conjunction with MT4 (looks like it). And how would it feel if there is no C environment to compile?
 
alexjou
Do these three sources mean that you are using them in conjunction with MT4 (looks like it). And how would it feel if there is no C environment to compile?

You could try it in MT. Originally they were programmed in MQL for debugging, and then they were moved with minimal changes to C. And the oldest version was in assembler.
Reason: