// Candlestick Formations // // candlestick_formations - candle // // Detects doji, engulfing, shooting star, and hammer patterns // // Inputs: 4 (OHLC) // Outputs: 1 (formation flag) // Constants: 0 #include #include "ts.h" ts_parameter_t const ts_candlestick_formations_p = { .n_inputs = 4, .n_outputs = 1, .n_constants = 0, .params_size = 0 }; uint_t ts_candlestick_formations_offset( ts_constant_t const *c ) { ( void )c; return ( 1 ); } int ts_candlestick_formations( 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_candlestick_formations_p ); (void)c; if (n > 0) y[0][0] = 0; for( uint_t i = 1; i < n; ++i ) { fp_t const body = ts_c( x, i ) - ts_o( x, i ); fp_t const prev_body = ts_c( x, i - 1 ) - ts_o( x, i - 1 ); fp_t const range = ts_h( x, i ) - ts_l( x, i ); fp_t const body_abs = fabs( body ); fp_t const upper_wick = ts_h( x, i ) - fmax( ts_o( x, i ), ts_c( x, i ) ); fp_t const lower_wick = fmin( ts_o( x, i ), ts_c( x, i ) ) - ts_l( x, i ); y[0][i] = 0; if( range > 0 && body_abs / range < 0.1 ) y[0][i] = 1; // doji else if( prev_body > 0 && body < 0 && body_abs >= fabs( prev_body ) ) y[0][i] = 2; // bearish engulfing else if( prev_body < 0 && body > 0 && body_abs >= fabs( prev_body ) ) y[0][i] = 3; // bullish engulfing else if( upper_wick >= 2 * body_abs && body <= 0 ) y[0][i] = 4; // shooting star else if( lower_wick >= 2 * body_abs && body >= 0 ) y[0][i] = 5; // hammer } return 0; }