// Stochastic Momentum Index // // stochastic_momentum_index // // Stochastic Momentum Index // // // // Inputs: 4 // Outputs: 2 // Constants: 3 #include #include #include "ts.h" typedef struct { uint_t k1; uint_t k2; uint_t signal_period; } ts_stochastic_momentum_index_params_t; ts_parameter_t const ts_stochastic_momentum_index_p = { .n_inputs = 4, .n_outputs = 2, .n_constants = 3, .params_size = sizeof(ts_stochastic_momentum_index_params_t) }; uint_t ts_stochastic_momentum_index_offset( ts_constant_t const *c ) { ( void )c; return ( c ? ((ts_stochastic_momentum_index_params_t *)c)->k1 + ((ts_stochastic_momentum_index_params_t *)c)->k2 : 0 ); } int ts_stochastic_momentum_index( 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_stochastic_momentum_index_p ); if ( !c ) return -1; uint_t k1 = ((ts_stochastic_momentum_index_params_t *)c)->k1; uint_t k2 = ((ts_stochastic_momentum_index_params_t *)c)->k2; uint_t signal_period = ((ts_stochastic_momentum_index_params_t *)c)->signal_period; if (k1 == 0 || k2 == 0) return -1; fp_t *midpoint = calloc(n, sizeof(fp_t)); fp_t *deviation = calloc(n, sizeof(fp_t)); if (!midpoint || !deviation) { free(midpoint); free(deviation); return -1; } for( uint_t i = 0; i < n; ++i ) { midpoint[i] = (ts_h(x, i) + ts_l(x, i)) / 2.0; deviation[i] = ts_c(x, i) - midpoint[i]; } fp_t *sma_dev = calloc(n, sizeof(fp_t)); fp_t *sma_high = calloc(n, sizeof(fp_t)); if (!sma_dev || !sma_high) { free(midpoint); free(deviation); free(sma_dev); free(sma_high); return -1; } uint_t start = k1 - 1; for( uint_t i = start; i < n; ++i ) { fp_t sum_dev = 0; fp_t sum_high = 0; for( uint_t j = 0; j < k1; ++j ) { sum_dev += deviation[i - j]; fp_t abs_dev = fabs(deviation[i - j]); if( abs_dev > sum_high ) sum_high = abs_dev; } sma_dev[i] = sum_dev / k1; sma_high[i] = sum_high; } uint_t start2 = start + k2 - 1; fp_t *smi = calloc(n, sizeof(fp_t)); if (!smi) { free(midpoint); free(deviation); free(sma_dev); free(sma_high); free(smi); return -1; } for( uint_t i = start2; i < n; ++i ) { fp_t sum_sma_dev = 0; fp_t sum_sma_high = 0; for( uint_t j = 0; j < k2; ++j ) { sum_sma_dev += sma_dev[i - j]; sum_sma_high += sma_high[i - j]; } sum_sma_dev /= k2; sum_sma_high /= k2; if( sum_sma_high == 0 ) smi[i] = 0; else smi[i] = (sum_sma_dev / sum_sma_high) * 100; } fp_t sig_a = 2.0 / (signal_period + 1); fp_t signal_ema = 0; uint_t signal_init = 0; for (uint_t j = 0; j < n && j < start2; ++j) { y[0][j] = 0; y[1][j] = 0; } for( uint_t i = start2; i < n; ++i ) { y[0][i] = smi[i]; if( !signal_init ) { signal_ema = smi[i]; signal_init = 1; } else { signal_ema = signal_ema + sig_a * (smi[i] - signal_ema); } y[1][i] = signal_ema; } free(midpoint); free(deviation); free(sma_dev); free(sma_high); free(smi); return 0; }