// Osma // // osma // // Oscillator Moving Average // // // // Inputs: 5 // Outputs: 1 // Constants: 3 #include "ts.h" typedef struct { fp_t fast_k; fp_t slow_k; fp_t signal_k; } ts_osma_params_t; ts_parameter_t const ts_osma_p = { .n_inputs = 5, .n_outputs = 1, .n_constants = 3, .params_size = sizeof(ts_osma_params_t) }; uint_t ts_osma_offset( ts_constant_t const *c ) { ( void )c; return ( c ? (uint_t)((ts_osma_params_t *)c)->slow_k : 0 ); } int ts_osma( 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_osma_p ); if ( !c ) return -1; fp_t fast_k = ((ts_osma_params_t *)c)->fast_k; fp_t slow_k = ((ts_osma_params_t *)c)->slow_k; fp_t signal_k = ((ts_osma_params_t *)c)->signal_k; if (fast_k == 0 || slow_k == 0 || signal_k == 0) return -1; if (n == 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); if (n <= slow_offset + 1) 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 macd_line = fast_ema - slow_ema; fp_t signal_ema = macd_line; 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 ); macd_line = fast_ema - slow_ema; signal_ema = signal_ema + signal_a * ( macd_line - signal_ema ); y[0][i] = macd_line - signal_ema; } return 0; }