// Absolute Price Oscillator // // apo - APO // // Difference between fast and slow EMA: APO = EMA(fast) - EMA(slow) // // Inputs: 1 // Outputs: 1 (Oscillator) // Constants: 2 (fast period, slow period) #include "ts.h" typedef struct { fp_t fast_k; fp_t slow_k; } ts_apo_params_t; ts_parameter_t const ts_apo_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = 2, .params_size = sizeof(ts_apo_params_t) }; uint_t ts_apo_offset( ts_constant_t const *c ) { ( void )c; return ( c ? (uint_t)((ts_apo_params_t *)c)->slow_k - 1 : 0 ); } int ts_apo( 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_apo_p ); if ( !c ) return -1; if (n == 0) return -1; fp_t fast_k = ((ts_apo_params_t *)c)->fast_k; fp_t slow_k = ((ts_apo_params_t *)c)->slow_k; if (fast_k == 0 || slow_k == 0) return -1; fp_t fast_a = 1.0 / fast_k; fp_t slow_a = 1.0 / slow_k; uint_t slow_offset = (uint_t)(slow_k - 1); if (slow_offset >= n) return -1; fp_t fast_ema = x[0][0]; fp_t slow_ema = x[0][0]; for( uint_t i = 1; i <= slow_offset; ++i ) { fast_ema = fast_ema + fast_a * ( x[0][i] - fast_ema ); slow_ema = slow_ema + slow_a * ( x[0][i] - slow_ema ); } y[0][slow_offset] = fast_ema - slow_ema; for( uint_t i = slow_offset + 1; i < n; ++i ) { fast_ema = fast_ema + fast_a * ( x[0][i] - fast_ema ); slow_ema = slow_ema + slow_a * ( x[0][i] - slow_ema ); y[0][i] = fast_ema - slow_ema; } return 0; }