*Nb. I have changed the calculation of the bands to use absolute price differences rather than log differences - I find that this change leads to better behaved bands.*

I have not done any testing of this oscillator as an indicator but I think it might have some value as a filter for a trend following system, or as a way of switching between trend following and mean reversion types of systems. The fact that the oscillator values lie in the range 0 to 1 also makes it suitable as an input to a neural net.

The Octave .oct code

```
DEFUN_DLD ( brownian_oscillator, args, nargout,
"-*- texinfo -*-\n\
@deftypefn {Function File} {} brownian_oscillator (@var{price,period})\n\
This function takes price and period vector inputs and outputs a value\n\
normalised by the max look back period for the number of look back periods\n\
from 1 to max look back period inclusive for which the price is between\n\
Brownian bands.\n\
@end deftypefn" )
{
octave_value_list retval_list ;
int nargin = args.length () ;
// check the input arguments
if ( nargin != 2 )
{
error ( "Invalid arguments. Type help to see usage." ) ;
return retval_list ;
}
if ( args(0).length () < 50 ) // check length of price vector input
{
error ( "Invalid arguments. Type help to see usage." ) ;
return retval_list ;
}
if ( args(1).length () != args(0).length () ) // lookback period length argument
{
error ( "Invalid arguments. Type help to see usage." ) ;
return retval_list ;
}
if ( error_state )
{
error ( "Invalid arguments. Type help to see usage." ) ;
return retval_list ;
}
// end of input checking
ColumnVector price = args(0).column_vector_value () ;
ColumnVector period = args(1).column_vector_value () ;
ColumnVector abs_price_diff = args(0).column_vector_value () ;
ColumnVector osc = args(0).column_vector_value () ; osc(0) = 0.0 ;
double sum ;
double osc_sum ;
double up_bb ;
double low_bb ;
int jj ;
for ( octave_idx_type ii (1) ; ii < 50 ; ii++ ) // initialising loop
{
abs_price_diff(ii) = fabs( price(ii) - price(ii-1) ) ;
osc(ii) = 0.0 ;
}
for ( octave_idx_type ii (50) ; ii < args(0).length () ; ii++ ) // main loop
{
// initialise calculation values
sum = 0.0 ;
osc_sum = 0.0 ;
up_bb = 0.0 ;
low_bb = 0.0 ;
for ( jj = 1 ; jj < period(ii) + 1 ; jj++ ) // nested jj loop
{
abs_price_diff(ii) = fabs( price(ii) - price(ii-1) ) ;
sum += abs_price_diff(ii-jj+1) ;
up_bb = price(ii-jj) + (sum/double(jj)) * sqrt(double(jj)) ;
low_bb = price(ii-jj) - (sum/double(jj)) * sqrt(double(jj)) ;
if ( price(ii) <= up_bb && price(ii) >= low_bb )
{
osc_sum += 1.0 ;
}
} // end of nested jj loop
osc(ii) = osc_sum / period(ii) ;
} // end of main loop
retval_list(0) = osc ;
return retval_list ;
} // end of function
```

## No comments:

Post a Comment