// Choppiness Index // // choppiness_index - CHOP // // 100 * log(SUM(H-L) / Range) / log(k), measures trend vs chop // // Inputs: 3 (HLC) // Outputs: 1 (CHOP) // Constants: 0 #include #include "ts.h" typedef struct { uint_t k; } ts_choppiness_index_params_t; ts_parameter_t const ts_choppiness_index_p = { .n_inputs = 3, .n_outputs = 1, .n_constants = 1, .params_size = sizeof(ts_choppiness_index_params_t) }; uint_t ts_choppiness_index_offset( ts_constant_t const *c ) { ( void )c; return ( c ? 2 * ((ts_choppiness_index_params_t const *)c)->k : 0 ); } int ts_choppiness_index( 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_choppiness_index_p ); if ( !c ) return -1; uint_t k = ((ts_choppiness_index_params_t const *)c)->k; uint_t range_period = 2 * k; if (k == 0 || n < range_period) return -1; for ( uint_t i = range_period; i < n; ++i ) { fp_t sum_range = 0; for ( uint_t j = i - k + 1; j <= i; ++j ) { sum_range += fabs( ts_h( x, j ) - ts_l( x, j ) ); } fp_t hh = ts_h( x, i - range_period + 1 ); fp_t ll = ts_l( x, i - range_period + 1 ); for ( uint_t j = i - range_period + 1; 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 ); } fp_t range = hh - ll; if ( range == 0 || sum_range == 0 || k <= 1 ) { y[0][i] = 0; } else { y[0][i] = 100.0 * log( sum_range / range ) / log( ( fp_t )k ); } } return 0; }