// Williams R // // williams_r // // Williams %R // // // // Inputs: 4 // Outputs: 1 // Constants: 1 #include "ts.h" typedef struct { uint_t k; } ts_williams_r_params_t; ts_parameter_t const ts_williams_r_p = { .n_inputs = 4, .n_outputs = 1, .n_constants = 1, .params_size = sizeof(ts_williams_r_params_t) }; uint_t ts_williams_r_offset( ts_constant_t const *c ) { ( void )c; return ( c ? ((ts_williams_r_params_t *)c)->k > 0 ? ((ts_williams_r_params_t *)c)->k - 1 : 0 : 0 ); } int ts_williams_r( fp_t * const *y, uint_t y_n, fp_t const * const *x, uint_t x_n, uint_t n, ts_constant_t const *c ) { TS_PROLOGUE( ts_williams_r_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); uint_t k = ((ts_williams_r_params_t *)c)->k; if (k == 0 || n < k) return -1; // Initial window max/min fp_t hh = ts_h( x, 0 ); fp_t ll = ts_l( x, 0 ); for( uint_t j = 1; j < k; ++j ) { if( ts_h( x, j ) > hh ) hh = ts_h( x, j ); if( ts_l( x, j ) < ll ) ll = ts_l( x, j ); } { if( hh == ll ) y[0][k - 1] = 0; else y[0][k - 1] = (hh - ts_c( x, k - 1 )) / (hh - ll) * (-100.0); } for( uint_t i = k; i < n; ++i ) { fp_t new_h = ts_h( x, i ); fp_t new_l = ts_l( x, i ); fp_t old_h = ts_h( x, i - k ); fp_t old_l = ts_l( x, i - k ); if ( new_h > hh ) hh = new_h; if ( new_l < ll ) ll = new_l; if ( old_h == hh || old_l == ll ) { hh = ts_h( x, i - k + 1 ); ll = ts_l( x, i - k + 1 ); for( uint_t j = i - k + 2; j <= i; ++j ) { if( ts_h( x, j ) > hh ) hh = ts_h( x, j ); if( ts_l( x, j ) < ll ) ll = ts_l( x, j ); } } if( hh == ll ) y[0][i] = 0; else y[0][i] = (hh - ts_c( x, i )) / (hh - ll) * (-100.0); } return 0; }