// Accumulation/Distribution Oscillator // // ad_oscillator - ADX // // Difference between fast and slow EMA of the A/D line // // Inputs: 5 (OHLCV) // Outputs: 1 (Oscillator) // Constants: 2 (fast period, slow period) #include "ts.h" typedef struct { fp_t fast; fp_t slow; } ts_ad_oscillator_params_t; ts_parameter_t const ts_ad_oscillator_p = { .n_inputs = 5, .n_outputs = 1, .n_constants = 2, .params_size = sizeof(ts_ad_oscillator_params_t) }; uint_t ts_ad_oscillator_offset( ts_constant_t const *c ) { ( void )c; return ( 0 ); } int ts_ad_oscillator( 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_ad_oscillator_p ); if ( !c ) return -1; if( n == 0 ) return -1; fp_t fast = ((ts_ad_oscillator_params_t *)c)->fast; fp_t slow = ((ts_ad_oscillator_params_t *)c)->slow; if (fast == 0 || slow == 0) return -1; fp_t a_fast = 1.0 / fast; fp_t a_slow = 1.0 / slow; fp_t hl = ts_h( x, 0 ) - ts_l( x, 0 ); fp_t mf = hl != 0 ? ( ( ts_c( x, 0 ) - ts_l( x, 0 ) ) - ( ts_h( x, 0 ) - ts_c( x, 0 ) ) ) / hl * ts_v( x, 0 ) : 0; fp_t ad = mf; fp_t ema_f = ad; fp_t ema_s = ad; y[0][0] = 0; for( uint_t i = 1; i < n; ++i ) { hl = ts_h( x, i ) - ts_l( x, i ); mf = hl != 0 ? ( ( ts_c( x, i ) - ts_l( x, i ) ) - ( ts_h( x, i ) - ts_c( x, i ) ) ) / hl * ts_v( x, i ) : 0; ad += mf; ema_f = ema_f + a_fast * ( ad - ema_f ); ema_s = ema_s + a_slow * ( ad - ema_s ); y[0][i] = ema_f - ema_s; } return 0; }