Stochastic indicator. A curious observation.

 

I think - Stochastic is quite a promising indicator for automatic trading.

But it turns out it is not that simple! I have made a very simple (about ten lines) Expert Advisor based on stochastic without any "excesses".

Entry - crossing of the main line over the signal line. Therefore, the algorithm is based on the signal line crossing:

int start()
  {
 
 
double StochK_0=iStochastic(NULL, 0, K_period,D_period,3,MODE_SMA,0,MODE_MAIN, 0);
double StochK_1=iStochastic(NULL, 0, K_period,D_period,3,MODE_SMA,0,MODE_MAIN, 1);
 
double StochD_0=iStochastic(NULL, 0, K_period,D_period,3,MODE_SMA,0,MODE_PLUSDI, 0);
 
 
//===== Ищем возможность войти в рынок ==================================================
 
int Orders=OrdersTotal ();     //получаем кол-во открытых ордеров
if (Orders==0)                 //если нет открытых ордеров
  {  
//---------проверяем условие на покупку----------------------------
  if   (  (StochK_1<StochD_0)  &&
          (StochK_0>StochD_0)  )
   {
  ticket= ... ...          
   }
 
//--------проверяем условие на продажу------------------------------
  if  (   (StochK_1>StochD_0)  &&
          (StochK_0<StochD_0)) 
   {       
  ticket=... ...       
   }

Then I optimized it by eye and ran it in the tester over a year and a half. And here I found out, or rather confirmed my old observation! Stochastic is not a symmetric indicator, as many people think. The dynamic range of the indicator, because of its structure, differently reflects the upward and downward price movements!

This is why in manual and autotrading we are sometimes initially at a disadvantage when opening SELL positions.

Symbol GBPUSD (Great Britain Pound vs US Dollar) Period 4 Hour (H4) (2006.01.01 - 2007.08.31)

Model All ticks (based on all smallest available periods with fractal interpolation of each tick)

Modeling quality 90.00% Initial deposit 10000.00

Net profit 3667.00

Total profit 9801.02

Total loss -6134.02 Profitability 1.60

Expected payoff 13.94 Absolute drawdown 202.02 Maximum drawdown 438.24 (3.25%) Relative drawdown 3.25% (438.24)

Total trades 263

Short positions (% win) 134 (51.49%)

Long positions (% win) 129 (67.44%)

Profitable trades (% of all) 156 (59.32%)

Loss trades (% of all) 107 (40.68%)

The most profitable trade is 130.00

Deal Deal loss -60.56

Average profitable trade 62.83

losing deal -57.33

At any layouts, variants and parameters it always turns out that long deals using the indicator on various pairs are more promising than short ones.

It always turns out that the number of profitable deals of long ones is up to 80

And of the short ones - at best 50/55%.

And this is true for the entries by the signal line, as well as by overbought/oversold levels, and even by iOnArray.

The conclusion is that when using Stochastic, parameters for buy and for sell should be set separately. I.e. apply two indicators.

 

Stochastic has a nasty property of changing its values retroactively, especially if the values are taken from higher timeframes.

If it were not for this problem - it would be hard to find a better indicator!

And it is hard to find a better indicator!

 
Aleksey24:

Stochastic has a nasty property of changing its values retroactively, especially if the values are taken from higher timeframes.

If it weren't for this problem, it would be hard to find a better indicator!


This is nonsense. Where have you seen such a stochastic?
 
leonid553:

The Stochastic is not at all a symmetric indicator. As many people think. The dynamic range of the indicator due to its structure differently depicts the upward and downward price movements!

That is another conclusion. Do you know the stochastic formula?
 

Not. 99/1.

Did you know that the full stochastic code is available at: 'Stochastic Oscillator, Stochastic'

Would you mind pointing your finger where in the code that is responsible for:

- " when opening a SELL position sometimes initially gets us at a disadvantage"?

- "Stochastic has a nasty property of changing its values retroactively"?

 

Here is a clear proof of the asymmetry of the stochastic.

The channel hanging from the indicator is constantly narrowing at the bottom and widening at the top. Or do we have to go boringly through the numbers here to figure out the formula?

 

If we take a superficial look at the Stochastic formula, we can already assume with great probability that unipolarity of the indicator is "to blame" for the asymmetry!

And I can't say anything about the change of "backward values", I have not faced with it.

 

What would a "mirror" formula do?

%K = 100*SUM (MAX (HIGH, Pk)-CLOSE), Sk) / SUM (MAX (HIGH, Pk) - MIN (LOW, Pk)), Sk)

 

It's hard to say right off the bat. You probably need to write the code for the mirror indicator. Compare their configuration on the chart.

For automated trading any difference in display will be significant. Enter to Buy using a normal indicator. Use a mirror indicator to enter Sell.

 

Well, the source code is available, it's easy to replace. But for perception it will be more natural by idea

%K = 100*(1-SUM (MAX (HIGH, Pk)-CLOSE), Sk) / SUM (MAX (HIGH, Pk) - MIN (LOW, Pk)), Sk))

 
leonid553:

If we take a superficial look at the Stochastic formula, we can already assume with great probability that unipolarity of the indicator is "to blame" for the asymmetry!

And I can't say anything about the change of "backward values", I have not faced with it.

Unipolarity of the indicator - can be corrected:
- In the standard indicator
iStochastic
High and Close formed by Bid - that's the whole point. This is a gross error!!! Especially for stochastics!!! And especially on small periods!!!
I'm not a programmer, don't judge severely, I improved the standard stochastic for myself. It works properly:
//+------------------------------------------------------------------+
//| $Stochastic. mq4 |
//| Vladimir |
//+------------------------------------------------------------------+
 
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 80
#property indicator_level2 50
#property indicator_level3 20
 
#property indicator_buffers 2
#property indicator_color1 LightSeaGreen
#property indicator_color2 Red
//---- input parameters
extern int KPeriod=6;
extern int DPeriod=2;
extern int Slowing=1;
//---- buffers
double MainBuffer[];
double SignalBuffer[];
double HighesBuffer[];
double LowesBuffer[];
//----
int draw_begin1=0;
int draw_begin2=0;
double CHigh,CClose;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- 2 additional buffers are used for counting.
IndicatorBuffers(4);
SetIndexBuffer(2, HighesBuffer);
SetIndexBuffer(3, LowesBuffer);
//---- indicator lines
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, MainBuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1, SignalBuffer);
//---- name for DataWindow and indicator subwindow label
short_name="Stochastic("+KPeriod+","+DPeriod+", "+Slowing+")";
IndicatorShortName(short_name);
SetIndexLabel(0,short_name);
SetIndexLabel(1,"Signal");
//----
draw_begin1=KPeriod+Slowing;
draw_begin2=draw_begin1+DPeriod;
SetIndexDrawBegin(0,draw_begin1);
SetIndexDrawBegin(1,draw_begin2);
//----
CHigh=MarketInfo(Symbol(),MODE_SPREAD)*MarketInfo(Symbol(),MODE_POINT);// Вычисляем спред
CClose=CHigh/2.0;// Спред пополам
//----
return(0);
}
//+------------------------------------------------------------------+
//| Stochastic oscillator |
//+------------------------------------------------------------------+
int start()
{
int i,k;
int counted_bars=IndicatorCounted();
double price;
//----
if(Bars<=draw_begin2) return(0);
//---- initial zero
if(counted_bars<1)
{
for(i=1;i<=draw_begin1;i++) MainBuffer[Bars-i]=0;
for(i=1;i<=draw_begin2;i++) SignalBuffer[Bars-i]=0;
}
//---- minimums counting
i=Bars-KPeriod;
if(counted_bars>KPeriod) i=Bars-counted_bars-1;
while(i>=0)
{
double min=1000000;
k=i+KPeriod-1;
while(k>=i)
{
price=Low[k];
if(min>price) min=price;
k--;
}
LowesBuffer[i]=min;
i--;
}
//---- maximums counting
i=Bars-KPeriod;
if(counted_bars>KPeriod) i=Bars-counted_bars-1;
while(i>=0)
{
double max=-1000000;
k=i+KPeriod-1;
while(k>=i)
{
price=High[k]+CHigh;
if(max<price) max=price;
k--;
}
HighesBuffer[i]=max;
i--;
}
//---- %K line
i=Bars-draw_begin1;
if(counted_bars>draw_begin1) i=Bars-counted_bars-1;
while(i>=0)
{
double sumlow=0.0;
double sumhigh=0.0;
for(k=(i+Slowing-1);k>=i;k--)
{
sumlow+=Close[k]+CClose-LowesBuffer[k];
sumhigh+=HighesBuffer[k]-LowesBuffer[k];
}
if(sumhigh==0.0) MainBuffer[i]=100.0;
else MainBuffer[i]=sumlow/sumhigh*100;
i--;
}
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
//---- signal line is simple movimg average
for(i=0; i<limit; i++)
SignalBuffer[i]=iMAOnArray(MainBuffer,Bars,DPeriod, 0, MODE_SMA, i);
//----
return(0);
}
//+------------------------------------------------------------------+
Reason: