// Parabolic Sar // // parabolic_sar // // Parabolic SAR // // // // Inputs: 4 // Outputs: 2 // Constants: 2 #include #include "ts.h" typedef struct { fp_t step; fp_t max_af; } ts_parabolic_sar_params_t; ts_parameter_t const ts_parabolic_sar_p = { .n_inputs = 4, .n_outputs = 2, .n_constants = 2, .params_size = sizeof(ts_parabolic_sar_params_t) }; uint_t ts_parabolic_sar_offset( ts_constant_t const *c ) { ( void )c; return ( 0 ); } int ts_parabolic_sar( 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_parabolic_sar_p ); if ( !c ) return -1; fp_t step = ((ts_parabolic_sar_params_t *)c)->step; fp_t max_af = ((ts_parabolic_sar_params_t *)c)->max_af; if (step <= 0 || max_af <= 0) return -1; if (isnan(step) || isnan(max_af)) return -1; if (step > max_af) return -1; if (n == 0) return -1; int_t trend = 1; fp_t sar = ts_l( x, 0 ); fp_t ep = ts_h( x, 0 ); fp_t af = step; for ( uint_t i = 0; i < n; ++i ) { y[0][i] = sar; y[1][i] = (fp_t)(trend > 0); if (i == 0) continue; if (trend > 0) { sar = sar + af * (ep - sar); if (ts_l( x, i ) < sar) { trend = -1; sar = ep; ep = ts_l( x, i ); af = step; } else { if (ts_h( x, i ) > ep) { ep = ts_h( x, i ); af = af + step; if (af > max_af) af = max_af; } } } else { sar = sar + af * (ep - sar); if (ts_h( x, i ) > sar) { trend = 1; sar = ep; ep = ts_h( x, i ); af = step; } else { if (ts_l( x, i ) < ep) { ep = ts_l( x, i ); af = af + step; if (af > max_af) af = max_af; } } } } return 0; }