// Ppo // // ppo // // Percentage Price Oscillator // // // // Inputs: 5 // Outputs: 2 // Constants: 3 #include "ts.h" typedef struct { fp_t fast_k; fp_t slow_k; fp_t signal_k; } ts_ppo_params_t; ts_parameter_t const ts_ppo_p = { .n_inputs = 5, .n_outputs = 2, .n_constants = 3, .params_size = sizeof(ts_ppo_params_t) }; uint_t ts_ppo_offset( ts_constant_t const *c ) { ( void )c; return ( c ? (uint_t)(((ts_ppo_params_t const *)c)->slow_k + ((ts_ppo_params_t const *)c)->signal_k - 2) : 0 ); } int ts_ppo( 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_ppo_p ); if ( !c ) return -1; fp_t fast_k = ((ts_ppo_params_t const *)c)->fast_k; fp_t slow_k = ((ts_ppo_params_t const *)c)->slow_k; fp_t signal_k = ((ts_ppo_params_t const *)c)->signal_k; if (fast_k == 0 || slow_k == 0 || signal_k == 0) return -1; fp_t fast_a = 1.0 / fast_k; fp_t slow_a = 1.0 / slow_k; fp_t signal_a = 1.0 / signal_k; fp_t fast_ema = x[0][0]; fp_t slow_ema = x[0][0]; uint_t slow_offset = (uint_t)(slow_k - 1); uint_t signal_offset = (uint_t)(signal_k - 1); uint_t total_offset = slow_offset + signal_offset; if (n <= total_offset) return -1; 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 ); } fp_t ppo_val = slow_ema != 0 ? (fast_ema - slow_ema) / slow_ema * 100.0 : 0; fp_t signal_ema = ppo_val; for( uint_t i = slow_offset + 1; i <= total_offset; ++i ) { fast_ema = fast_ema + fast_a * ( x[0][i] - fast_ema ); slow_ema = slow_ema + slow_a * ( x[0][i] - slow_ema ); ppo_val = slow_ema != 0 ? (fast_ema - slow_ema) / slow_ema * 100.0 : 0; signal_ema = signal_ema + signal_a * ( ppo_val - signal_ema ); } y[0][total_offset] = ppo_val; y[1][total_offset] = signal_ema; for( uint_t i = total_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 ); ppo_val = slow_ema != 0 ? (fast_ema - slow_ema) / slow_ema * 100.0 : 0; signal_ema = signal_ema + signal_a * ( ppo_val - signal_ema ); y[0][i] = ppo_val; y[1][i] = signal_ema; } return 0; }