// Supertrend // // supertrend // // SuperTrend Indicator // // // // Inputs: 4 // Outputs: 2 // Constants: 2 #include #include "ts.h" typedef struct { uint_t k; fp_t mult; } ts_supertrend_params_t; ts_parameter_t const ts_supertrend_p = { .n_inputs = 4, .n_outputs = 2, .n_constants = 2, .params_size = sizeof(ts_supertrend_params_t) }; uint_t ts_supertrend_offset( ts_constant_t const *c ) { ( void )c; return ( c ? ((ts_supertrend_params_t *)c)->k : 0 ); } int ts_supertrend( 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_supertrend_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); uint_t k = ((ts_supertrend_params_t *)c)->k; fp_t mult = ((ts_supertrend_params_t *)c)->mult; if (k == 0 || n <= k) return -1; fp_t tr = ts_h( x, 1 ) - ts_l( x, 1 ); fp_t tr2 = fabs( ts_h( x, 1 ) - ts_c( x, 0 ) ); fp_t tr3 = fabs( ts_l( x, 1 ) - ts_c( x, 0 ) ); if( tr2 > tr ) tr = tr2; if( tr3 > tr ) tr = tr3; fp_t atr = tr; for( uint_t i = 2; i <= k; ++i ) { tr = ts_h( x, i ) - ts_l( x, i ); tr2 = fabs( ts_h( x, i ) - ts_c( x, i - 1 ) ); tr3 = fabs( ts_l( x, i ) - ts_c( x, i - 1 ) ); if( tr2 > tr ) tr = tr2; if( tr3 > tr ) tr = tr3; atr = atr + (tr - atr) / k; } fp_t median = ( ts_h( x, k ) + ts_l( x, k ) ) / 2.0; fp_t raw_upper = median + mult * atr; fp_t raw_lower = median - mult * atr; fp_t final_upper = raw_upper; fp_t final_lower = raw_lower; int_t trend = 1; if( ts_c( x, k ) > raw_lower ) { trend = 1; } else { trend = -1; } y[0][k] = trend == 1 ? final_lower : final_upper; y[1][k] = trend; for( uint_t i = k + 1; i < n; ++i ) { tr = ts_h( x, i ) - ts_l( x, i ); tr2 = fabs( ts_h( x, i ) - ts_c( x, i - 1 ) ); tr3 = fabs( ts_l( x, i ) - ts_c( x, i - 1 ) ); if( tr2 > tr ) tr = tr2; if( tr3 > tr ) tr = tr3; atr = atr + (tr - atr) / k; median = ( ts_h( x, i ) + ts_l( x, i ) ) / 2.0; raw_upper = median + mult * atr; raw_lower = median - mult * atr; if( raw_upper < final_upper || ts_c( x, i - 1 ) > final_upper ) final_upper = raw_upper; if( raw_lower > final_lower || ts_c( x, i - 1 ) < final_lower ) final_lower = raw_lower; int_t new_trend = trend; if( trend == 1 ) { if( ts_c( x, i ) < final_lower ) new_trend = -1; } else { if( ts_c( x, i ) > final_upper ) new_trend = 1; } trend = new_trend; y[0][i] = trend == 1 ? final_lower : final_upper; y[1][i] = trend; } return 0; }