// Mfi // // mfi // // Money Flow Index // // 100 - 100/(1 + MF_ratio), volume-weighted RSI // // Inputs: 5 // Outputs: 1 // Constants: 1 #include #include "ts.h" typedef struct { uint_t k; } ts_mfi_params_t; ts_parameter_t const ts_mfi_p = { .n_inputs = 5, .n_outputs = 1, .n_constants = 1, .params_size = sizeof(ts_mfi_params_t) }; uint_t ts_mfi_offset( ts_constant_t const *c ) { ( void )c; return ( c ? ((ts_mfi_params_t *)c)->k : 0 ); } int ts_mfi( 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_mfi_p ); if ( !c ) return -1; uint_t k = ((ts_mfi_params_t *)c)->k; if (k == 0 || n <= k) return -1; fp_t *tp = calloc( n, sizeof( fp_t ) ); if ( !tp ) return -1; for( uint_t i = 0; i < n; ++i ) { tp[i] = ( ts_h( x, i ) + ts_l( x, i ) + ts_c( x, i ) ) / 3.0; } fp_t pos_sum = 0; fp_t neg_sum = 0; for (uint_t i = 0; i < k; ++i) y[0][i] = 0; for( uint_t i = 1; i <= k; ++i ) { fp_t raw_mf = tp[i] * ts_v( x, i ); if( tp[i] > tp[i - 1] ) pos_sum += raw_mf; else neg_sum += raw_mf; } y[0][k] = ( neg_sum == 0 ) ? 100.0 : 100.0 - 100.0 / ( 1.0 + pos_sum / neg_sum ); for( uint_t i = k + 1; i < n; ++i ) { fp_t cur_raw_mf = tp[i] * ts_v( x, i ); if( tp[i] > tp[i - 1] ) pos_sum += cur_raw_mf; else neg_sum += cur_raw_mf; fp_t old_raw_mf = tp[i - k] * ts_v( x, i - k ); if( tp[i - k] > tp[i - k - 1] ) pos_sum -= old_raw_mf; else neg_sum -= old_raw_mf; y[0][i] = ( neg_sum == 0 ) ? 100.0 : 100.0 - 100.0 / ( 1.0 + pos_sum / neg_sum ); } free( tp ); return 0; }