diff options
| author | Ethan Werner <mail@ethanwerner.com> | 2026-08-09 15:02:21 +0400 |
|---|---|---|
| committer | Ethan Werner <mail@ethanwerner.com> | 2026-08-09 15:02:21 +0400 |
| commit | 3d92926a902017e7cf1f5738e99ff62da596ce12 (patch) | |
| tree | 2b55422c26a48759d56fa91f06df24449e9dfa88 /lib | |
| parent | 07e18043145f3d91c8ea7ec3ad41b3c905585277 (diff) | |
refactormain
Diffstat (limited to 'lib')
185 files changed, 672 insertions, 584 deletions
diff --git a/lib/acceleration_bands.c b/lib/acceleration_bands.c index 776b990..19c174a 100644 --- a/lib/acceleration_bands.c +++ b/lib/acceleration_bands.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_acceleration_bands_p = { .n_inputs = 4, .n_outputs = 3, uint_t ts_acceleration_bands_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_acceleration_bands_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_acceleration_bands_params_t const *)c)->k - 1 : 0 ); } int ts_acceleration_bands( @@ -33,9 +33,11 @@ int ts_acceleration_bands( { TS_PROLOGUE( ts_acceleration_bands_p ); if ( !c ) return -1; - uint_t k = ((ts_acceleration_bands_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_acceleration_bands_params_t const *)c)->k; if (k == 0 || n < k) return -1; + if (n > SIZE_MAX / sizeof( fp_t )) return -1; fp_t *hh_r = malloc( n * sizeof( fp_t ) ); fp_t *ll_r = malloc( n * sizeof( fp_t ) ); fp_t *tp = malloc( n * sizeof( fp_t ) ); @@ -27,7 +27,6 @@ int ts_ad( { TS_PROLOGUE( ts_ad_p ); (void)c; - if( n == 0 ) return -1; fp_t hl0 = ts_h( x, 0 ) - ts_l( x, 0 ); y[0][0] = hl0 != 0 diff --git a/lib/ad_oscillator.c b/lib/ad_oscillator.c index 5021140..66ca3cf 100644 --- a/lib/ad_oscillator.c +++ b/lib/ad_oscillator.c @@ -31,10 +31,9 @@ int ts_ad_oscillator( { TS_PROLOGUE( ts_ad_oscillator_p ); if ( !c ) return -1; - if( n == 0 ) return -1; - fp_t fast = ((ts_ad_oscillator_params_t *)c)->fast; - fp_t slow = ((ts_ad_oscillator_params_t *)c)->slow; + fp_t fast = ((ts_ad_oscillator_params_t const *)c)->fast; + fp_t slow = ((ts_ad_oscillator_params_t const *)c)->slow; if (fast == 0 || slow == 0) return -1; fp_t a_fast = 1.0 / fast; fp_t a_slow = 1.0 / slow; @@ -24,7 +24,7 @@ ts_parameter_t const ts_adx_p = { .n_inputs = 4, .n_outputs = 4, .n_constants = uint_t ts_adx_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_adx_params_t *)c)->k + 1 : 0 ); + return ( c ? ((ts_adx_params_t const *)c)->k + 1 : 0 ); } int ts_adx( @@ -36,7 +36,7 @@ int ts_adx( TS_PROLOGUE( ts_adx_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_adx_params_t *)c)->k; + uint_t k = ((ts_adx_params_t const *)c)->k; if (k == 0) return -1; fp_t ema_plus = 0, ema_minus = 0, ema_tr = 0; diff --git a/lib/alligator.c b/lib/alligator.c index 81450b0..a74602c 100644 --- a/lib/alligator.c +++ b/lib/alligator.c @@ -28,7 +28,6 @@ int ts_alligator( { TS_PROLOGUE( ts_alligator_p ); (void)c; - if( n == 0 ) return -1; /* Jaw: SMA(13) shifted 8 positions */ /* Teeth: SMA(8) shifted 5 positions */ /* Lips: SMA(5) shifted 3 positions */ diff --git a/lib/annualized_historical_volatility.c b/lib/annualized_historical_volatility.c index c0c88cf..27ed0f0 100644 --- a/lib/annualized_historical_volatility.c +++ b/lib/annualized_historical_volatility.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_annualized_historical_volatility_p = { .n_inputs = 1, .n uint_t ts_annualized_historical_volatility_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_annualized_historical_volatility_params_t *)c)->k : 0 ); + return ( c ? ((ts_annualized_historical_volatility_params_t const *)c)->k : 0 ); } int ts_annualized_historical_volatility( @@ -31,9 +31,13 @@ int ts_annualized_historical_volatility( { TS_PROLOGUE( ts_annualized_historical_volatility_p ); if ( !c ) return -1; - uint_t k = ((ts_annualized_historical_volatility_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_annualized_historical_volatility_params_t const *)c)->k; if (k == 0 || n <= k) return -1; + for ( uint_t i = 0; i < k; ++i ) + y[0][i] = NAN; + /* Compute log returns, then stddev, then annualize */ for (uint_t i = k; i < n; ++i) { @@ -20,7 +20,7 @@ ts_parameter_t const ts_apo_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_apo_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? (uint_t)((ts_apo_params_t *)c)->slow_k - 1 : 0 ); + return ( c ? (uint_t)((ts_apo_params_t const *)c)->slow_k - 1 : 0 ); } int ts_apo( @@ -31,10 +31,9 @@ int ts_apo( { TS_PROLOGUE( ts_apo_p ); if ( !c ) return -1; - if (n == 0) return -1; - fp_t fast_k = ((ts_apo_params_t *)c)->fast_k; - fp_t slow_k = ((ts_apo_params_t *)c)->slow_k; + fp_t fast_k = ((ts_apo_params_t const *)c)->fast_k; + fp_t slow_k = ((ts_apo_params_t const *)c)->slow_k; if (fast_k == 0 || slow_k == 0) return -1; fp_t fast_a = 1.0 / fast_k; diff --git a/lib/aroon.c b/lib/aroon.c index 539e97b..1bf824b 100644 --- a/lib/aroon.c +++ b/lib/aroon.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_aroon_p = { .n_inputs = 4, .n_outputs = 2, .n_constants uint_t ts_aroon_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_aroon_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_aroon_params_t const *)c)->k - 1 : 0 ); } int ts_aroon( @@ -32,7 +32,7 @@ int ts_aroon( { TS_PROLOGUE( ts_aroon_p ); if ( !c ) return -1; - uint_t k = ((ts_aroon_params_t *)c)->k; + uint_t k = ((ts_aroon_params_t const *)c)->k; if (k == 0 || n < k) return -1; for ( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/aroon_oscillator.c b/lib/aroon_oscillator.c index db9fe9d..2152655 100644 --- a/lib/aroon_oscillator.c +++ b/lib/aroon_oscillator.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_aroon_oscillator_p = { .n_inputs = 4, .n_outputs = 1, .n uint_t ts_aroon_oscillator_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_aroon_oscillator_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_aroon_oscillator_params_t const *)c)->k - 1 : 0 ); } int ts_aroon_oscillator( @@ -32,7 +32,7 @@ int ts_aroon_oscillator( { TS_PROLOGUE( ts_aroon_oscillator_p ); if ( !c ) return -1; - uint_t k = ((ts_aroon_oscillator_params_t *)c)->k; + uint_t k = ((ts_aroon_oscillator_params_t const *)c)->k; if (k == 0 || n < k) return -1; for ( uint_t i = k - 1; i < n; ++i ) @@ -28,7 +28,6 @@ int ts_asi( { TS_PROLOGUE( ts_asi_p ); (void)c; - if( n == 0 ) return -1; y[0][0] = 0; @@ -26,7 +26,7 @@ ts_parameter_t const ts_atr_p = { .n_inputs = 4, .n_outputs = 1, .n_constants = uint_t ts_atr_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_atr_params_t *)c)->k : 0 ); + return ( c ? ((ts_atr_params_t const *)c)->k : 0 ); } int ts_atr( @@ -38,7 +38,7 @@ int ts_atr( TS_PROLOGUE( ts_atr_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_atr_params_t *)c)->k; + uint_t k = ((ts_atr_params_t const *)c)->k; if (k == 0) return -1; if (n < 2) return -1; diff --git a/lib/atr_bands.c b/lib/atr_bands.c index 73b7d44..1aa7464 100644 --- a/lib/atr_bands.c +++ b/lib/atr_bands.c @@ -25,7 +25,7 @@ ts_parameter_t const ts_atr_bands_p = { .n_inputs = 4, .n_outputs = 3, .n_consta uint_t ts_atr_bands_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_atr_bands_params_t *)c)->k : 0 ); + return ( c ? ((ts_atr_bands_params_t const *)c)->k : 0 ); } int ts_atr_bands( @@ -36,11 +36,20 @@ int ts_atr_bands( { TS_PROLOGUE( ts_atr_bands_p ); if ( !c ) return -1; - uint_t k = ((ts_atr_bands_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_atr_bands_params_t const *)c)->k; if (k == 0 || n < k) return -1; if (n < 2) return -1; - fp_t mult = ((ts_atr_bands_params_t *)c)->mult; + fp_t mult = ((ts_atr_bands_params_t const *)c)->mult; + if (mult < 0 || isnan(mult) || isinf(mult)) return -1; + + for ( uint_t i = 0; i < k - 1; ++i ) + { + y[0][i] = NAN; + y[1][i] = NAN; + y[2][i] = NAN; + } fp_t tr_sum = 0; fp_t atr = 0; diff --git a/lib/atr_trailing_stops.c b/lib/atr_trailing_stops.c index 2c7cd73..46628a2 100644 --- a/lib/atr_trailing_stops.c +++ b/lib/atr_trailing_stops.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_atr_trailing_stops_p = { .n_inputs = 4, .n_outputs = 2, uint_t ts_atr_trailing_stops_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_atr_trailing_stops_params_t *)c)->k : 0 ); + return ( c ? ((ts_atr_trailing_stops_params_t const *)c)->k : 0 ); } int ts_atr_trailing_stops( @@ -35,11 +35,19 @@ int ts_atr_trailing_stops( { TS_PROLOGUE( ts_atr_trailing_stops_p ); if ( !c ) return -1; - uint_t k = ((ts_atr_trailing_stops_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_atr_trailing_stops_params_t const *)c)->k; if (k == 0) return -1; if (n < k + 1) return -1; - fp_t mult = ((ts_atr_trailing_stops_params_t *)c)->mult; + fp_t mult = ((ts_atr_trailing_stops_params_t const *)c)->mult; + if (mult < 0 || isnan(mult) || isinf(mult)) return -1; + + for ( uint_t i = 0; i < k; ++i ) + { + y[0][i] = NAN; + y[1][i] = NAN; + } fp_t tr_sum = 0; fp_t atr = 0; diff --git a/lib/average.c b/lib/average.c index 391de93..ece89ca 100644 --- a/lib/average.c +++ b/lib/average.c @@ -33,7 +33,7 @@ ts_parameter_t const ts_average_p = { .n_inputs = 1, .n_outputs = 1, .n_constant uint_t ts_average_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_average_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_average_params_t const *)c)->k - 1 : 0 ); } int ts_average( @@ -45,7 +45,7 @@ int ts_average( TS_PROLOGUE( ts_average_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_average_params_t *)c)->k; + uint_t k = ((ts_average_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; diff --git a/lib/average_exponential.c b/lib/average_exponential.c index bae9d5f..1875bc3 100644 --- a/lib/average_exponential.c +++ b/lib/average_exponential.c @@ -40,7 +40,7 @@ int ts_average_exponential( TS_PROLOGUE( ts_average_exponential_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - fp_t k = ((ts_average_exponential_params_t *)c)->k; + fp_t k = ((ts_average_exponential_params_t const *)c)->k; if (k <= 0 || isnan(k)) return -1; fp_t a = 1.0 / k; diff --git a/lib/average_exponential_double.c b/lib/average_exponential_double.c index eeb890f..5c3dcb4 100644 --- a/lib/average_exponential_double.c +++ b/lib/average_exponential_double.c @@ -35,8 +35,8 @@ int ts_average_exponential_double( TS_PROLOGUE( ts_average_exponential_double_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - fp_t a = ((ts_average_exponential_double_params_t *)c)->a; - if (a == 0 || n == 0) return -1; + fp_t a = ((ts_average_exponential_double_params_t const *)c)->a; + if (a == 0) return -1; fp_t ema1 = x[0][0]; fp_t ema2 = x[0][0]; diff --git a/lib/average_exponential_triple.c b/lib/average_exponential_triple.c index 467d87f..793d048 100644 --- a/lib/average_exponential_triple.c +++ b/lib/average_exponential_triple.c @@ -33,8 +33,8 @@ int ts_average_exponential_triple( TS_PROLOGUE( ts_average_exponential_triple_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - fp_t a = ((ts_average_exponential_triple_params_t *)c)->a; - if (a == 0 || n == 0) return -1; + fp_t a = ((ts_average_exponential_triple_params_t const *)c)->a; + if (a == 0) return -1; fp_t ema1 = x[0][0]; fp_t ema2 = x[0][0]; diff --git a/lib/average_triangle.c b/lib/average_triangle.c index 9ac952d..fd1c037 100644 --- a/lib/average_triangle.c +++ b/lib/average_triangle.c @@ -29,7 +29,7 @@ ts_parameter_t const ts_average_triangle_p = { .n_inputs = 1, .n_outputs = 1, .n uint_t ts_average_triangle_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? 2 * ( ((ts_average_triangle_params_t *)c)->k - 1 ) : 0 ); + return ( c ? 2 * ( ((ts_average_triangle_params_t const *)c)->k - 1 ) : 0 ); } int ts_average_triangle( @@ -40,7 +40,7 @@ int ts_average_triangle( { TS_PROLOGUE( ts_average_triangle_p ); if ( !c ) return -1; - uint_t k = ((ts_average_triangle_params_t *)c)->k; + uint_t k = ((ts_average_triangle_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t rk2 = _ts_reciprocal( _ts_square( k ) ); diff --git a/lib/average_weighted.c b/lib/average_weighted.c index eb99a17..632de8b 100644 --- a/lib/average_weighted.c +++ b/lib/average_weighted.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_average_weighted_p = { .n_inputs = 1, .n_outputs = 1, .n uint_t ts_average_weighted_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_average_weighted_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_average_weighted_params_t const *)c)->k - 1 : 0 ); } int ts_average_weighted( @@ -35,7 +35,7 @@ int ts_average_weighted( { TS_PROLOGUE( ts_average_weighted_p ); if ( !c ) return -1; - uint_t k = ((ts_average_weighted_params_t *)c)->k; + uint_t k = ((ts_average_weighted_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; diff --git a/lib/average_weighted_series.c b/lib/average_weighted_series.c index d7e2ccb..d388651 100644 --- a/lib/average_weighted_series.c +++ b/lib/average_weighted_series.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_average_weighted_series_p = { .n_inputs = 2, .n_outputs uint_t ts_average_weighted_series_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_average_weighted_series_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_average_weighted_series_params_t const *)c)->k - 1 : 0 ); } int ts_average_weighted_series( @@ -34,7 +34,7 @@ int ts_average_weighted_series( { TS_PROLOGUE( ts_average_weighted_series_p ); if ( !c ) return -1; - uint_t k = ((ts_average_weighted_series_params_t *)c)->k; + uint_t k = ((ts_average_weighted_series_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; diff --git a/lib/band_width.c b/lib/band_width.c index 822d835..4a4d6cb 100644 --- a/lib/band_width.c +++ b/lib/band_width.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_band_width_p = { .n_inputs = 1, .n_outputs = 1, .n_const uint_t ts_band_width_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_band_width_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_band_width_params_t const *)c)->k > 0 ? ((ts_band_width_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_band_width( @@ -32,9 +32,11 @@ int ts_band_width( { TS_PROLOGUE( ts_band_width_p ); if ( !c ) return -1; - uint_t k = ((ts_band_width_params_t *)c)->k; - fp_t std_mult = ((ts_band_width_params_t *)c)->std_mult; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_band_width_params_t const *)c)->k; + fp_t std_mult = ((ts_band_width_params_t const *)c)->std_mult; if (k == 0 || n < k) return -1; + if (std_mult < 0 || isnan(std_mult) || isinf(std_mult)) return -1; for (uint_t i = k - 1; i < n; ++i) { diff --git a/lib/beta_pdf.c b/lib/beta_pdf.c index a23ed68..1366665 100644 --- a/lib/beta_pdf.c +++ b/lib/beta_pdf.c @@ -32,8 +32,8 @@ int ts_beta_pdf( { TS_PROLOGUE( ts_beta_pdf_p ); if ( !c ) return -1; - fp_t alpha = ((ts_beta_pdf_params_t *)c)->alpha; - fp_t beta = ((ts_beta_pdf_params_t *)c)->beta; + fp_t alpha = ((ts_beta_pdf_params_t const *)c)->alpha; + fp_t beta = ((ts_beta_pdf_params_t const *)c)->beta; if (isnan(alpha) || isnan(beta) || alpha <= 0 || beta <= 0) { for( uint_t i = 0; i < n; ++i ) y[0][i] = 0; diff --git a/lib/binomial_pdf.c b/lib/binomial_pdf.c index 8b3a442..f10663f 100644 --- a/lib/binomial_pdf.c +++ b/lib/binomial_pdf.c @@ -32,8 +32,8 @@ int ts_binomial_pdf( { TS_PROLOGUE( ts_binomial_pdf_p ); if ( !c ) return -1; - uint_t n_trials = ((ts_binomial_pdf_params_t *)c)->n_trials; - fp_t p = ((ts_binomial_pdf_params_t *)c)->p; + uint_t n_trials = ((ts_binomial_pdf_params_t const *)c)->n_trials; + fp_t p = ((ts_binomial_pdf_params_t const *)c)->p; if (p < 0.0 || p > 1.0 || isnan(p) || isinf(p)) return -1; for( uint_t i = 0; i < n; ++i ) { diff --git a/lib/bollinger_bands.c b/lib/bollinger_bands.c index 55da054..56ce8f9 100644 --- a/lib/bollinger_bands.c +++ b/lib/bollinger_bands.c @@ -25,7 +25,7 @@ ts_parameter_t const ts_bollinger_bands_p = { .n_inputs = 1, .n_outputs = 3, .n_ uint_t ts_bollinger_bands_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_bollinger_bands_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_bollinger_bands_params_t const *)c)->k > 0 ? ((ts_bollinger_bands_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_bollinger_bands( @@ -37,10 +37,17 @@ int ts_bollinger_bands( TS_PROLOGUE( ts_bollinger_bands_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_bollinger_bands_params_t *)c)->k; + uint_t k = ((ts_bollinger_bands_params_t const *)c)->k; if (k == 0 || n < k) return -1; - fp_t std_mult = ((ts_bollinger_bands_params_t *)c)->std_mult; - if (std_mult < 0 || isnan(std_mult)) return -1; + fp_t std_mult = ((ts_bollinger_bands_params_t const *)c)->std_mult; + if (std_mult < 0 || isnan(std_mult) || isinf(std_mult)) return -1; + + for( uint_t i = 0; i < k - 1; ++i ) + { + y[0][i] = NAN; + y[1][i] = NAN; + y[2][i] = NAN; + } // Two-pass initial window for numerical stability { @@ -56,8 +63,8 @@ int ts_bollinger_bands( } variance /= (fp_t)k; fp_t stddev = sqrt( variance ); - y[1][k - 1] = mean + std_mult * stddev; - y[0][k - 1] = mean; + y[0][k - 1] = mean + std_mult * stddev; + y[1][k - 1] = mean; y[2][k - 1] = mean - std_mult * stddev; } @@ -79,8 +86,8 @@ int ts_bollinger_bands( } variance *= rk; fp_t stddev = sqrt( variance ); - y[1][i] = mean + std_mult * stddev; - y[0][i] = mean; + y[0][i] = mean + std_mult * stddev; + y[1][i] = mean; y[2][i] = mean - std_mult * stddev; } return 0; diff --git a/lib/bollinger_lower.c b/lib/bollinger_lower.c index 05a0883..3eac1f0 100644 --- a/lib/bollinger_lower.c +++ b/lib/bollinger_lower.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_bollinger_lower_p = { .n_inputs = 1, .n_outputs = 1, .n_ uint_t ts_bollinger_lower_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_bollinger_lower_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_bollinger_lower_params_t const *)c)->k - 1 : 0 ); } int ts_bollinger_lower( @@ -34,9 +34,9 @@ int ts_bollinger_lower( { TS_PROLOGUE( ts_bollinger_lower_p ); if ( !c ) return -1; - uint_t k = ((ts_bollinger_lower_params_t *)c)->k; + uint_t k = ((ts_bollinger_lower_params_t const *)c)->k; if (k == 0 || n < k) return -1; - fp_t std_mult = ((ts_bollinger_lower_params_t *)c)->std_mult; + fp_t std_mult = ((ts_bollinger_lower_params_t const *)c)->std_mult; if (isnan(std_mult) || isinf(std_mult)) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/bollinger_pctb.c b/lib/bollinger_pctb.c index a3425cd..6387f16 100644 --- a/lib/bollinger_pctb.c +++ b/lib/bollinger_pctb.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_bollinger_pctb_p = { .n_inputs = 1, .n_outputs = 1, .n_c uint_t ts_bollinger_pctb_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_bollinger_pctb_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_bollinger_pctb_params_t const *)c)->k > 0 ? ((ts_bollinger_pctb_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_bollinger_pctb( @@ -34,10 +34,11 @@ int ts_bollinger_pctb( { TS_PROLOGUE( ts_bollinger_pctb_p ); if ( !c ) return -1; - uint_t k = ((ts_bollinger_pctb_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_bollinger_pctb_params_t const *)c)->k; if (k == 0 || n < k) return -1; - fp_t std_mult = ((ts_bollinger_pctb_params_t *)c)->std_mult; - if (isnan(std_mult) || isinf(std_mult)) return -1; + fp_t std_mult = ((ts_bollinger_pctb_params_t const *)c)->std_mult; + if (std_mult < 0 || isnan(std_mult) || isinf(std_mult)) return -1; for( uint_t i = k - 1; i < n; ++i ) { diff --git a/lib/bollinger_upper.c b/lib/bollinger_upper.c index 9294cfb..51ced24 100644 --- a/lib/bollinger_upper.c +++ b/lib/bollinger_upper.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_bollinger_upper_p = { .n_inputs = 1, .n_outputs = 1, .n_ uint_t ts_bollinger_upper_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_bollinger_upper_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_bollinger_upper_params_t const *)c)->k > 0 ? ((ts_bollinger_upper_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_bollinger_upper( @@ -34,10 +34,11 @@ int ts_bollinger_upper( { TS_PROLOGUE( ts_bollinger_upper_p ); if ( !c ) return -1; - uint_t k = ((ts_bollinger_upper_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_bollinger_upper_params_t const *)c)->k; if (k == 0 || n < k) return -1; - fp_t std_mult = ((ts_bollinger_upper_params_t *)c)->std_mult; - if (isnan(std_mult) || isinf(std_mult)) return -1; + fp_t std_mult = ((ts_bollinger_upper_params_t const *)c)->std_mult; + if (std_mult < 0 || isnan(std_mult) || isinf(std_mult)) return -1; for( uint_t i = k - 1; i < n; ++i ) { diff --git a/lib/bollinger_width.c b/lib/bollinger_width.c index d9bca25..00891ce 100644 --- a/lib/bollinger_width.c +++ b/lib/bollinger_width.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_bollinger_width_p = { .n_inputs = 1, .n_outputs = 1, .n_ uint_t ts_bollinger_width_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_bollinger_width_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_bollinger_width_params_t const *)c)->k > 0 ? ((ts_bollinger_width_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_bollinger_width( @@ -34,10 +34,11 @@ int ts_bollinger_width( { TS_PROLOGUE( ts_bollinger_width_p ); if ( !c ) return -1; - uint_t k = ((ts_bollinger_width_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_bollinger_width_params_t const *)c)->k; if (k == 0 || n < k) return -1; - fp_t std_mult = ((ts_bollinger_width_params_t *)c)->std_mult; - if (isnan(std_mult) || isinf(std_mult)) return -1; + fp_t std_mult = ((ts_bollinger_width_params_t const *)c)->std_mult; + if (std_mult < 0 || isnan(std_mult) || isinf(std_mult)) return -1; for( uint_t i = k - 1; i < n; ++i ) { @@ -20,7 +20,7 @@ ts_parameter_t const ts_cci_p = { .n_inputs = 4, .n_outputs = 1, .n_constants = uint_t ts_cci_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_cci_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_cci_params_t const *)c)->k - 1 : 0 ); } int ts_cci( @@ -32,7 +32,7 @@ int ts_cci( TS_PROLOGUE( ts_cci_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_cci_params_t *)c)->k; + uint_t k = ((ts_cci_params_t const *)c)->k; if (k == 0 || n < k) return -1; // Compute initial typical prices diff --git a/lib/center_of_gravity.c b/lib/center_of_gravity.c index 3186c44..ae78bdc 100644 --- a/lib/center_of_gravity.c +++ b/lib/center_of_gravity.c @@ -19,7 +19,7 @@ ts_parameter_t const ts_center_of_gravity_p = { .n_inputs = 1, .n_outputs = 1, . uint_t ts_center_of_gravity_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_center_of_gravity_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_center_of_gravity_params_t const *)c)->k - 1 : 0 ); } int ts_center_of_gravity( @@ -30,7 +30,7 @@ int ts_center_of_gravity( { TS_PROLOGUE( ts_center_of_gravity_p ); if ( !c ) return -1; - uint_t k = ((ts_center_of_gravity_params_t *)c)->k; + uint_t k = ((ts_center_of_gravity_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/chande_forecast_oscillator.c b/lib/chande_forecast_oscillator.c index 6e65bbe..c3b2c8c 100644 --- a/lib/chande_forecast_oscillator.c +++ b/lib/chande_forecast_oscillator.c @@ -19,7 +19,7 @@ ts_parameter_t const ts_chande_forecast_oscillator_p = { .n_inputs = 1, .n_outpu uint_t ts_chande_forecast_oscillator_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_chande_forecast_oscillator_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_chande_forecast_oscillator_params_t const *)c)->k - 1 : 0 ); } int ts_chande_forecast_oscillator( @@ -30,7 +30,7 @@ int ts_chande_forecast_oscillator( { TS_PROLOGUE( ts_chande_forecast_oscillator_p ); if ( !c ) return -1; - uint_t k = ((ts_chande_forecast_oscillator_params_t *)c)->k; + uint_t k = ((ts_chande_forecast_oscillator_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/change.c b/lib/change.c index 84815a5..8e4c1b2 100644 --- a/lib/change.c +++ b/lib/change.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_change_p = { .n_inputs = 1, .n_outputs = 1, .n_constants uint_t ts_change_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_change_params_t *)c)->k : 0 ); + return ( c ? ((ts_change_params_t const *)c)->k : 0 ); } int ts_change( @@ -31,7 +31,7 @@ int ts_change( { TS_PROLOGUE( ts_change_p ); if ( !c ) return -1; - uint_t k = ((ts_change_params_t *)c)->k; + uint_t k = ((ts_change_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k; i < n; ++i ) diff --git a/lib/channel.c b/lib/channel.c index a2d8bd9..9fbd0e3 100644 --- a/lib/channel.c +++ b/lib/channel.c @@ -19,7 +19,7 @@ ts_parameter_t const ts_channel_p = { .n_inputs = 4, .n_outputs = 2, .n_constant uint_t ts_channel_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_channel_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_channel_params_t const *)c)->k - 1 : 0 ); } int ts_channel( @@ -30,7 +30,7 @@ int ts_channel( { TS_PROLOGUE( ts_channel_p ); if ( !c ) return -1; - uint_t k = ((ts_channel_params_t *)c)->k; + uint_t k = ((ts_channel_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = k - 1; diff --git a/lib/chebyshev_t.c b/lib/chebyshev_t.c index a0230b8..5428fa4 100644 --- a/lib/chebyshev_t.c +++ b/lib/chebyshev_t.c @@ -28,32 +28,32 @@ int ts_chebyshev_t( { TS_PROLOGUE( ts_chebyshev_t_p ); (void)c; - for( uint_t i = 0; i < n; ++i ) - { - fp_t xv = x[0][i]; - uint_t n_val = (uint_t)x[1][i]; - if (x[1][i] < 0 || x[1][i] > 10000) { y[0][i] = 0; continue; } - if( n_val == 0 ) - { - y[0][i] = 1.0; - } - else if( n_val == 1 ) - { - y[0][i] = xv; - } - else - { - fp_t t0 = 1.0; - fp_t t1 = xv; - for( uint_t k = 2; k <= n_val; ++k ) - { - fp_t t2 = 2.0 * xv * t1 - t0; - t0 = t1; - t1 = t2; - } - y[0][i] = t1; - } - } + for( uint_t i = 0; i < n; ++i ) + { + fp_t xv = x[0][i]; + uint_t n_val = (uint_t)x[1][i]; + if (x[1][i] < 0 || x[1][i] > 10000) { y[0][i] = 0; continue; } + if( n_val == 0 ) + { + y[0][i] = 1.0; + } + else if( n_val == 1 ) + { + y[0][i] = xv; + } + else + { + fp_t t0 = 1.0; + fp_t t1 = xv; + for( uint_t k = 2; k <= n_val; ++k ) + { + fp_t t2 = 2.0 * xv * t1 - t0; + t0 = t1; + t1 = t2; + } + y[0][i] = t1; + } + } return 0; } diff --git a/lib/chi_squared_pdf.c b/lib/chi_squared_pdf.c index 7f2ba09..7a3c7df 100644 --- a/lib/chi_squared_pdf.c +++ b/lib/chi_squared_pdf.c @@ -31,7 +31,7 @@ int ts_chi_squared_pdf( { TS_PROLOGUE( ts_chi_squared_pdf_p ); if ( !c ) return -1; - fp_t k = ((ts_chi_squared_pdf_params_t *)c)->k; + fp_t k = ((ts_chi_squared_pdf_params_t const *)c)->k; if ( k <= 0 ) { for( uint_t i = 0; i < n; ++i ) y[0][i] = 0; diff --git a/lib/choppiness_index.c b/lib/choppiness_index.c index 55ecb46..332e8b3 100644 --- a/lib/choppiness_index.c +++ b/lib/choppiness_index.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_choppiness_index_p = { .n_inputs = 3, .n_outputs = 1, .n uint_t ts_choppiness_index_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? 2 * ((ts_choppiness_index_params_t *)c)->k : 0 ); + return ( c ? 2 * ((ts_choppiness_index_params_t const *)c)->k : 0 ); } int ts_choppiness_index( @@ -31,7 +31,7 @@ int ts_choppiness_index( { TS_PROLOGUE( ts_choppiness_index_p ); if ( !c ) return -1; - uint_t k = ((ts_choppiness_index_params_t *)c)->k; + uint_t k = ((ts_choppiness_index_params_t const *)c)->k; uint_t range_period = 2 * k; if (k == 0 || n < range_period) return -1; diff --git a/lib/close_to_high.c b/lib/close_to_high.c index dc7cf7b..a4c15f4 100644 --- a/lib/close_to_high.c +++ b/lib/close_to_high.c @@ -8,7 +8,6 @@ // Outputs: 1 (ratio) // Constants: 0 -#include <math.h> #include "ts.h" diff --git a/lib/close_to_open_ratio.c b/lib/close_to_open_ratio.c index d857dd2..466b5e1 100644 --- a/lib/close_to_open_ratio.c +++ b/lib/close_to_open_ratio.c @@ -8,7 +8,6 @@ // Outputs: 1 (ratio) // Constants: 0 -#include <math.h> #include "ts.h" @@ -20,7 +20,7 @@ ts_parameter_t const ts_cmf_p = { .n_inputs = 5, .n_outputs = 1, .n_constants = uint_t ts_cmf_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_cmf_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_cmf_params_t const *)c)->k - 1 : 0 ); } int ts_cmf( @@ -31,7 +31,7 @@ int ts_cmf( { TS_PROLOGUE( ts_cmf_p ); if ( !c ) return -1; - uint_t k = ((ts_cmf_params_t *)c)->k; + uint_t k = ((ts_cmf_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_mf = 0; @@ -20,7 +20,7 @@ ts_parameter_t const ts_cmo_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_cmo_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_cmo_params_t *)c)->k : 0 ); + return ( c ? ((ts_cmo_params_t const *)c)->k : 0 ); } int ts_cmo( @@ -31,7 +31,7 @@ int ts_cmo( { TS_PROLOGUE( ts_cmo_p ); if ( !c ) return -1; - uint_t k = ((ts_cmo_params_t *)c)->k; + uint_t k = ((ts_cmo_params_t const *)c)->k; if (k == 0 || n <= k) return -1; for (uint_t j = 0; j < k; ++j) y[0][j] = 0; diff --git a/lib/coppock_curve.c b/lib/coppock_curve.c index dfa1ad2..e192bd1 100644 --- a/lib/coppock_curve.c +++ b/lib/coppock_curve.c @@ -33,9 +33,9 @@ int ts_coppock_curve( uint_t roc_short = 11; uint_t wma_period = 10; - if (n == 0 || n < roc_long) return -1; + if (n < roc_long) return -1; - fp_t *combined = calloc( n, sizeof( fp_t ) ); + fp_t *combined = calloc( n, sizeof( fp_t ) ); if ( !combined ) return -1; for ( uint_t i = roc_long; i < n; ++i ) @@ -50,7 +50,7 @@ int ts_coppock_curve( combined[i - roc_long] = roc14 + roc11; } - for (uint_t j = 0; j < n && j < roc_long; ++j) y[0][j] = 0; + for ( uint_t j = 0; j < n && j < roc_long; ++j ) y[0][j] = 0; for ( uint_t i = roc_long; i < n; ++i ) { diff --git a/lib/correlation_coefficient.c b/lib/correlation_coefficient.c index d20d1ea..a806daf 100644 --- a/lib/correlation_coefficient.c +++ b/lib/correlation_coefficient.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_correlation_coefficient_p = { .n_inputs = 2, .n_outputs uint_t ts_correlation_coefficient_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_correlation_coefficient_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_correlation_coefficient_params_t const *)c)->k - 1 : 0 ); } int ts_correlation_coefficient( @@ -31,7 +31,7 @@ int ts_correlation_coefficient( { TS_PROLOGUE( ts_correlation_coefficient_p ); if ( !c ) return -1; - uint_t k = ((ts_correlation_coefficient_params_t *)c)->k; + uint_t k = ((ts_correlation_coefficient_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0, sum_y2 = 0; @@ -4,7 +4,7 @@ // // EMA_fast(H-L) - EMA_slow(H-L), volatility measure // -// Inputs: 5 (OHLCV) +// Inputs: 4 (OHLC) // Outputs: 1 (CV) // Constants: 2 (fast, slow periods) @@ -21,7 +21,7 @@ ts_parameter_t const ts_cv_p = { .n_inputs = 4, .n_outputs = 1, .n_constants = 2 uint_t ts_cv_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? (uint_t)((ts_cv_params_t *)c)->slow : 0 ); + return ( c ? (uint_t)((ts_cv_params_t const *)c)->slow : 0 ); } int ts_cv( @@ -32,9 +32,9 @@ int ts_cv( { TS_PROLOGUE( ts_cv_p ); if ( !c ) return -1; - fp_t fast = ((ts_cv_params_t *)c)->fast; - fp_t slow = ((ts_cv_params_t *)c)->slow; - if (fast == 0 || slow == 0 || n == 0) return -1; + fp_t fast = ((ts_cv_params_t const *)c)->fast; + fp_t slow = ((ts_cv_params_t const *)c)->slow; + if (fast == 0 || slow == 0) return -1; fp_t a_fast = 1.0 / fast; fp_t a_slow = 1.0 / slow; diff --git a/lib/darvas_box.c b/lib/darvas_box.c index 573ed1e..a3bb5c1 100644 --- a/lib/darvas_box.c +++ b/lib/darvas_box.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_darvas_box_p = { .n_inputs = 4, .n_outputs = 2, .n_const uint_t ts_darvas_box_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_darvas_box_params_t *)c)->k > 0 ? ((ts_darvas_box_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_darvas_box_params_t const *)c)->k > 0 ? ((ts_darvas_box_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_darvas_box( @@ -32,7 +32,7 @@ int ts_darvas_box( { TS_PROLOGUE( ts_darvas_box_p ); if ( !c ) return -1; - uint_t k = ((ts_darvas_box_params_t *)c)->k; + uint_t k = ((ts_darvas_box_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/decay_exponential.c b/lib/decay_exponential.c index 97afe36..506d225 100644 --- a/lib/decay_exponential.c +++ b/lib/decay_exponential.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_decay_exponential_p = { .n_inputs = 1, .n_outputs = 1, . uint_t ts_decay_exponential_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_decay_exponential_params_t *)c)->k : 0 ); + return ( c ? ((ts_decay_exponential_params_t const *)c)->k : 0 ); } int ts_decay_exponential( @@ -34,8 +34,9 @@ int ts_decay_exponential( { TS_PROLOGUE( ts_decay_exponential_p ); if ( !c ) return -1; - uint_t k = ((ts_decay_exponential_params_t *)c)->k; - if (k == 0 || n <= k) return -1; + uint_t k = ((ts_decay_exponential_params_t const *)c)->k; + if (k == 0) return -1; + if (n <= k) return -1; fp_t a = ( fp_t ) 1.0 - _ts_reciprocal( k ); diff --git a/lib/decay_linear.c b/lib/decay_linear.c index 8519d13..9d92b49 100644 --- a/lib/decay_linear.c +++ b/lib/decay_linear.c @@ -25,7 +25,7 @@ ts_parameter_t const ts_decay_linear_p = { .n_inputs = 1, .n_outputs = 1, .n_con uint_t ts_decay_linear_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_decay_linear_params_t *)c)->k : 0 ); + return ( c ? ((ts_decay_linear_params_t const *)c)->k : 0 ); } int ts_decay_linear( @@ -36,47 +36,47 @@ int ts_decay_linear( { TS_PROLOGUE( ts_decay_linear_p ); if ( !c ) return -1; - uint_t k = ((ts_decay_linear_params_t *)c)->k; + uint_t k = ((ts_decay_linear_params_t const *)c)->k; if (k == 0 || n < k) return -1; - for (uint_t zi = 0; zi < k; ++zi) y[0][zi] = 0; + for (uint_t zi = 0; zi < k; ++zi) y[0][zi] = 0; - uint_t xi = 1; + uint_t xi = 1; - fp_t prev = x[0][0]; - fp_t r = prev / k; + fp_t prev = x[0][0]; + fp_t r = prev / (fp_t)k; for( ; xi < k; xi++ ) { - prev -= r; + prev -= r; - if( x[0][xi] > prev ) - { - prev = x[0][xi]; - r = x[0][xi] / k; - } - else - { - prev = fmax( prev, 0 ); - } + if( x[0][xi] > prev ) + { + prev = x[0][xi]; + r = x[0][xi] / (fp_t)k; + } + else + { + prev = fmax( prev, 0 ); + } } for( uint_t yi = k; xi < n; xi++, yi++ ) { - fp_t curr = prev - r; + fp_t curr = prev - r; - if( x[0][xi] > curr ) - { - curr = x[0][xi]; - r = x[0][xi] / k; - } - else - { - curr = fmax( curr, 0 ); - } + if( x[0][xi] > curr ) + { + curr = x[0][xi]; + r = x[0][xi] / (fp_t)k; + } + else + { + curr = fmax( curr, 0 ); + } - y[0][yi] = curr; - prev = curr; + y[0][yi] = curr; + prev = curr; } return 0; } diff --git a/lib/delta.c b/lib/delta.c index 02ccb66..2ee037a 100644 --- a/lib/delta.c +++ b/lib/delta.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_delta_p = { .n_inputs = 1, .n_outputs = 1, .n_constants uint_t ts_delta_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_delta_params_t *)c)->k : 0 ); + return ( c ? ((ts_delta_params_t const *)c)->k : 0 ); } int ts_delta( @@ -35,7 +35,7 @@ int ts_delta( { TS_PROLOGUE( ts_delta_p ); if ( !c ) return -1; - uint_t k = ((ts_delta_params_t *)c)->k; + uint_t k = ((ts_delta_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = k; diff --git a/lib/deviation_average.c b/lib/deviation_average.c index 5ac7109..552d226 100644 --- a/lib/deviation_average.c +++ b/lib/deviation_average.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_deviation_average_p = { .n_inputs = 1, .n_outputs = 1, . uint_t ts_deviation_average_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_deviation_average_params_t *)c)->k > 0 ? ((ts_deviation_average_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_deviation_average_params_t const *)c)->k > 0 ? ((ts_deviation_average_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_deviation_average( @@ -32,7 +32,7 @@ int ts_deviation_average( { TS_PROLOGUE( ts_deviation_average_p ); if ( !c ) return -1; - uint_t k = ((ts_deviation_average_params_t *)c)->k; + uint_t k = ((ts_deviation_average_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; diff --git a/lib/deviation_standard.c b/lib/deviation_standard.c index a2a0a76..f843224 100644 --- a/lib/deviation_standard.c +++ b/lib/deviation_standard.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_deviation_standard_p = { .n_inputs = 1, .n_outputs = 1, uint_t ts_deviation_standard_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_deviation_standard_params_t *)c)->k > 0 ? ((ts_deviation_standard_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_deviation_standard_params_t const *)c)->k > 0 ? ((ts_deviation_standard_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_deviation_standard( @@ -32,7 +32,7 @@ int ts_deviation_standard( TS_PROLOGUE( ts_deviation_standard_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_deviation_standard_params_t *)c)->k; + uint_t k = ((ts_deviation_standard_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; diff --git a/lib/deviation_standard_average_exponential.c b/lib/deviation_standard_average_exponential.c index 8c484f5..a27cc6a 100644 --- a/lib/deviation_standard_average_exponential.c +++ b/lib/deviation_standard_average_exponential.c @@ -32,9 +32,8 @@ int ts_deviation_standard_average_exponential( { TS_PROLOGUE( ts_deviation_standard_average_exponential_p ); if ( !c ) return -1; - if (n == 0) return -1; - fp_t a = ((ts_deviation_standard_average_exponential_params_t *)c)->a; + fp_t a = ((ts_deviation_standard_average_exponential_params_t const *)c)->a; if (a == 0) return -1; y[0][0] = x[0][0]; diff --git a/lib/deviation_vector.c b/lib/deviation_vector.c index 4f10037..02d9f72 100644 --- a/lib/deviation_vector.c +++ b/lib/deviation_vector.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_deviation_vector_p = { .n_inputs = 1, .n_outputs = 1, .n uint_t ts_deviation_vector_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_deviation_vector_params_t *)c)->k > 0 ? ((ts_deviation_vector_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_deviation_vector_params_t const *)c)->k > 0 ? ((ts_deviation_vector_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_deviation_vector( @@ -31,7 +31,7 @@ int ts_deviation_vector( { TS_PROLOGUE( ts_deviation_vector_p ); if ( !c ) return -1; - uint_t k = ((ts_deviation_vector_params_t *)c)->k; + uint_t k = ((ts_deviation_vector_params_t const *)c)->k; if (k == 0 || n < k) return -1; for (uint_t i = 0; i < n; ++i) diff --git a/lib/di_minus.c b/lib/di_minus.c index 95b0559..7fe0115 100644 --- a/lib/di_minus.c +++ b/lib/di_minus.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_di_minus_p = { .n_inputs = 4, .n_outputs = 1, .n_constan uint_t ts_di_minus_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_di_minus_params_t *)c)->k : 0 ); + return ( c ? ((ts_di_minus_params_t const *)c)->k : 0 ); } int ts_di_minus( @@ -32,7 +32,7 @@ int ts_di_minus( { TS_PROLOGUE( ts_di_minus_p ); if ( !c ) return -1; - uint_t k = ((ts_di_minus_params_t *)c)->k; + uint_t k = ((ts_di_minus_params_t const *)c)->k; if (k == 0 || n < 2) return -1; fp_t *ema_minus = calloc( n, sizeof( fp_t ) ); fp_t *ema_plus = calloc( n, sizeof( fp_t ) ); diff --git a/lib/di_plus.c b/lib/di_plus.c index fb3c076..2939fc5 100644 --- a/lib/di_plus.c +++ b/lib/di_plus.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_di_plus_p = { .n_inputs = 4, .n_outputs = 1, .n_constant uint_t ts_di_plus_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_di_plus_params_t *)c)->k : 0 ); + return ( c ? ((ts_di_plus_params_t const *)c)->k : 0 ); } int ts_di_plus( @@ -32,7 +32,7 @@ int ts_di_plus( { TS_PROLOGUE( ts_di_plus_p ); if ( !c ) return -1; - uint_t k = ((ts_di_plus_params_t *)c)->k; + uint_t k = ((ts_di_plus_params_t const *)c)->k; if (k == 0 || n < 2) return -1; fp_t *ema_plus = calloc( n, sizeof( fp_t ) ); fp_t *ema_minus = calloc( n, sizeof( fp_t ) ); diff --git a/lib/disparity_index.c b/lib/disparity_index.c index ebf5e0d..2909033 100644 --- a/lib/disparity_index.c +++ b/lib/disparity_index.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_disparity_index_p = { .n_inputs = 1, .n_outputs = 1, .n_ uint_t ts_disparity_index_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_disparity_index_params_t *)c)->k > 0 ? ((ts_disparity_index_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_disparity_index_params_t const *)c)->k > 0 ? ((ts_disparity_index_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_disparity_index( @@ -31,7 +31,7 @@ int ts_disparity_index( { TS_PROLOGUE( ts_disparity_index_p ); if ( !c ) return -1; - uint_t k = ((ts_disparity_index_params_t *)c)->k; + uint_t k = ((ts_disparity_index_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum = 0; diff --git a/lib/donchian_channel.c b/lib/donchian_channel.c index 760c396..93ae589 100644 --- a/lib/donchian_channel.c +++ b/lib/donchian_channel.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_donchian_channel_p = { .n_inputs = 4, .n_outputs = 3, .n uint_t ts_donchian_channel_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_donchian_channel_params_t *)c)->k > 0 ? ((ts_donchian_channel_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_donchian_channel_params_t const *)c)->k > 0 ? ((ts_donchian_channel_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_donchian_channel( @@ -33,7 +33,7 @@ int ts_donchian_channel( { TS_PROLOGUE( ts_donchian_channel_p ); if ( !c ) return -1; - uint_t k = ((ts_donchian_channel_params_t *)c)->k; + uint_t k = ((ts_donchian_channel_params_t const *)c)->k; if (k == 0 || n < k) return -1; for ( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/donchian_width.c b/lib/donchian_width.c index c69936f..f6eb42c 100644 --- a/lib/donchian_width.c +++ b/lib/donchian_width.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_donchian_width_p = { .n_inputs = 4, .n_outputs = 1, .n_c uint_t ts_donchian_width_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_donchian_width_params_t *)c)->k > 0 ? ((ts_donchian_width_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_donchian_width_params_t const *)c)->k > 0 ? ((ts_donchian_width_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_donchian_width( @@ -31,7 +31,7 @@ int ts_donchian_width( { TS_PROLOGUE( ts_donchian_width_p ); if ( !c ) return -1; - uint_t k = ((ts_donchian_width_params_t *)c)->k; + uint_t k = ((ts_donchian_width_params_t const *)c)->k; if (k == 0 || n < k) return -1; for ( uint_t i = k - 1; i < n; ++i ) @@ -21,7 +21,7 @@ ts_parameter_t const ts_dpo_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_dpo_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_dpo_params_t *)c)->k / 2 + 1 : 0 ); + return ( c ? ((ts_dpo_params_t const *)c)->k / 2 + 1 : 0 ); } int ts_dpo( @@ -32,7 +32,7 @@ int ts_dpo( { TS_PROLOGUE( ts_dpo_p ); if ( !c ) return -1; - uint_t k = ((ts_dpo_params_t *)c)->k; + uint_t k = ((ts_dpo_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t sma_period = k; @@ -21,7 +21,7 @@ ts_parameter_t const ts_dx_p = { .n_inputs = 4, .n_outputs = 1, .n_constants = 1 uint_t ts_dx_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_dx_params_t *)c)->k : 0 ); + return ( c ? ((ts_dx_params_t const *)c)->k : 0 ); } int ts_dx( @@ -32,7 +32,7 @@ int ts_dx( { TS_PROLOGUE( ts_dx_p ); if ( !c ) return -1; - uint_t k = ((ts_dx_params_t *)c)->k; + uint_t k = ((ts_dx_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t *plus_dm_arr = calloc( n, sizeof( fp_t ) ); diff --git a/lib/ease_of_movement.c b/lib/ease_of_movement.c index d16f32c..f6f1f46 100644 --- a/lib/ease_of_movement.c +++ b/lib/ease_of_movement.c @@ -31,7 +31,7 @@ int ts_ease_of_movement( { TS_PROLOGUE( ts_ease_of_movement_p ); if ( !c ) return -1; - uint_t k = ((ts_ease_of_movement_params_t *)c)->k; + uint_t k = ((ts_ease_of_movement_params_t const *)c)->k; if (k == 0 || n <= k) return -1; fp_t *eom = calloc( n, sizeof( fp_t ) ); diff --git a/lib/elder_force_index.c b/lib/elder_force_index.c index 23cce66..c2b367c 100644 --- a/lib/elder_force_index.c +++ b/lib/elder_force_index.c @@ -31,7 +31,7 @@ int ts_elder_force_index( { TS_PROLOGUE( ts_elder_force_index_p ); if ( !c ) return -1; - uint_t k = ((ts_elder_force_index_params_t *)c)->k; + uint_t k = ((ts_elder_force_index_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t a = 1.0 / k; diff --git a/lib/elder_impulse.c b/lib/elder_impulse.c index d629e7c..b86514d 100644 --- a/lib/elder_impulse.c +++ b/lib/elder_impulse.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_elder_impulse_p = { .n_inputs = 1, .n_outputs = 2, .n_co uint_t ts_elder_impulse_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? 2 * ((ts_elder_impulse_params_t *)c)->k - 1 : 0 ); + return ( c ? 2 * ((ts_elder_impulse_params_t const *)c)->k - 1 : 0 ); } int ts_elder_impulse( @@ -31,7 +31,7 @@ int ts_elder_impulse( { TS_PROLOGUE( ts_elder_impulse_p ); if ( !c ) return -1; - uint_t k = ((ts_elder_impulse_params_t *)c)->k; + uint_t k = ((ts_elder_impulse_params_t const *)c)->k; if (k == 0 || n < 2 * k - 1) return -1; fp_t *sma = malloc( n * sizeof( fp_t ) ); diff --git a/lib/elder_ray.c b/lib/elder_ray.c index a0f330f..730810b 100644 --- a/lib/elder_ray.c +++ b/lib/elder_ray.c @@ -33,7 +33,7 @@ int ts_elder_ray( { TS_PROLOGUE( ts_elder_ray_p ); if ( !c ) return -1; - fp_t k = ((ts_elder_ray_params_t *)c)->k; + fp_t k = ((ts_elder_ray_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t a = 1.0 / k; fp_t *ema = calloc( n, sizeof( fp_t ) ); diff --git a/lib/ema_variable.c b/lib/ema_variable.c index c20fee2..38f505e 100644 --- a/lib/ema_variable.c +++ b/lib/ema_variable.c @@ -31,9 +31,8 @@ int ts_ema_variable( { TS_PROLOGUE( ts_ema_variable_p ); if ( !c ) return -1; - fp_t k = ((ts_ema_variable_params_t *)c)->k; + fp_t k = ((ts_ema_variable_params_t const *)c)->k; if (k <= 0) return -1; - if (n == 0) return -1; fp_t alpha = 2.0 / (k + 1.0); y[0][0] = x[0][0]; diff --git a/lib/envelope.c b/lib/envelope.c index 1ddda0c..0813ee5 100644 --- a/lib/envelope.c +++ b/lib/envelope.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_envelope_p = { .n_inputs = 1, .n_outputs = 2, .n_constan uint_t ts_envelope_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_envelope_params_t *)c)->k > 0 ? ((ts_envelope_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_envelope_params_t const *)c)->k > 0 ? ((ts_envelope_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_envelope( @@ -32,8 +32,8 @@ int ts_envelope( { TS_PROLOGUE( ts_envelope_p ); if ( !c ) return -1; - uint_t k = ((ts_envelope_params_t *)c)->k; - fp_t pct = ((ts_envelope_params_t *)c)->pct; + uint_t k = ((ts_envelope_params_t const *)c)->k; + fp_t pct = ((ts_envelope_params_t const *)c)->pct; if (k == 0 || n < k) return -1; fp_t sum = 0; diff --git a/lib/exponential.c b/lib/exponential.c index b3a6205..a4e19c9 100644 --- a/lib/exponential.c +++ b/lib/exponential.c @@ -36,7 +36,7 @@ int ts_exponential( { TS_PROLOGUE( ts_exponential_p ); if ( !c ) return -1; - fp_t b = ((ts_exponential_params_t *)c)->b; + fp_t b = ((ts_exponential_params_t const *)c)->b; if (b <= 0) return -1; for( uint_t i = 0; i < n; ++i ) diff --git a/lib/factorial.c b/lib/factorial.c index 8e64fa3..7e82ffb 100644 --- a/lib/factorial.c +++ b/lib/factorial.c @@ -8,6 +8,7 @@ // Outputs: 1 (n!) // Constants: 0 +#include <math.h> #include "ts.h" @@ -31,7 +32,7 @@ int ts_factorial( (void)c; for( uint_t i = 0; i < n; ++i ) { - if (x[0][i] < 0) { y[0][i] = NAN; continue; } + if (isnan(x[0][i]) || isinf(x[0][i]) || x[0][i] < 0) { y[0][i] = NAN; continue; } fp_t result = 1.0; uint_t k = (uint_t)x[0][i]; if (k > 170) k = 170; diff --git a/lib/fill_indicator.c b/lib/fill_indicator.c index 9cb9cbc..448c32d 100644 --- a/lib/fill_indicator.c +++ b/lib/fill_indicator.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_fill_indicator_p = { .n_inputs = 4, .n_outputs = 1, .n_c uint_t ts_fill_indicator_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_fill_indicator_params_t *)c)->k > 0 ? ((ts_fill_indicator_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_fill_indicator_params_t const *)c)->k > 0 ? ((ts_fill_indicator_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_fill_indicator( @@ -31,7 +31,7 @@ int ts_fill_indicator( { TS_PROLOGUE( ts_fill_indicator_p ); if ( !c ) return -1; - uint_t k = ((ts_fill_indicator_params_t *)c)->k; + uint_t k = ((ts_fill_indicator_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; diff --git a/lib/fisher_transform.c b/lib/fisher_transform.c index 2b416ba..1bf8c51 100644 --- a/lib/fisher_transform.c +++ b/lib/fisher_transform.c @@ -20,7 +20,7 @@ ts_parameter_t const ts_fisher_transform_p = { .n_inputs = 4, .n_outputs = 2, .n uint_t ts_fisher_transform_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_fisher_transform_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_fisher_transform_params_t const *)c)->k - 1 : 0 ); } int ts_fisher_transform( @@ -31,7 +31,7 @@ int ts_fisher_transform( { TS_PROLOGUE( ts_fisher_transform_p ); if ( !c ) return -1; - uint_t k = ((ts_fisher_transform_params_t *)c)->k; + uint_t k = ((ts_fisher_transform_params_t const *)c)->k; if (k == 0 || n < k) return -1; for (uint_t i = k - 1; i < n; ++i) diff --git a/lib/fractal_chaos_bands.c b/lib/fractal_chaos_bands.c index 57bbf00..1cbef90 100644 --- a/lib/fractal_chaos_bands.c +++ b/lib/fractal_chaos_bands.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_fractal_chaos_bands_p = { .n_inputs = 4, .n_outputs = 2, uint_t ts_fractal_chaos_bands_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_fractal_chaos_bands_params_t *)c)->k / 2 : 0 ); + return ( c ? ((ts_fractal_chaos_bands_params_t const *)c)->k / 2 : 0 ); } int ts_fractal_chaos_bands( @@ -33,7 +33,8 @@ int ts_fractal_chaos_bands( { TS_PROLOGUE( ts_fractal_chaos_bands_p ); if ( !c ) return -1; - uint_t k = ((ts_fractal_chaos_bands_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_fractal_chaos_bands_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t alpha = 2.0 / (k + 1.0); @@ -69,6 +70,13 @@ int ts_fractal_chaos_bands( y[0][i] = ema_upper; y[1][i] = ema_lower; } + + for ( uint_t i = n - half_k; i < n; ++i ) + { + y[0][i] = 0; + y[1][i] = 0; + } + return 0; } diff --git a/lib/fractal_chaos_oscillator.c b/lib/fractal_chaos_oscillator.c index 5c845d3..835bb05 100644 --- a/lib/fractal_chaos_oscillator.c +++ b/lib/fractal_chaos_oscillator.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_fractal_chaos_oscillator_p = { .n_inputs = 4, .n_outputs uint_t ts_fractal_chaos_oscillator_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_fractal_chaos_oscillator_params_t *)c)->k / 2 : 0 ); + return ( c ? ((ts_fractal_chaos_oscillator_params_t const *)c)->k / 2 : 0 ); } int ts_fractal_chaos_oscillator( @@ -33,7 +33,7 @@ int ts_fractal_chaos_oscillator( { TS_PROLOGUE( ts_fractal_chaos_oscillator_p ); if ( !c ) return -1; - uint_t k = ((ts_fractal_chaos_oscillator_params_t *)c)->k; + uint_t k = ((ts_fractal_chaos_oscillator_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t alpha = 2.0 / (k + 1.0); diff --git a/lib/gamma_pdf.c b/lib/gamma_pdf.c index 977f8b7..7a8370c 100644 --- a/lib/gamma_pdf.c +++ b/lib/gamma_pdf.c @@ -34,7 +34,7 @@ int ts_gamma_pdf( { TS_PROLOGUE( ts_gamma_pdf_p ); if ( !c ) return -1; - fp_t shape = ((ts_gamma_pdf_params_t *)c)->shape; + fp_t shape = ((ts_gamma_pdf_params_t const *)c)->shape; if (shape <= 0.0) return -1; for( uint_t i = 0; i < n; ++i ) @@ -31,18 +31,25 @@ int ts_gcd( { TS_PROLOGUE( ts_gcd_p ); (void)c; - for( uint_t i = 0; i < n; ++i ) - { - long a = (long)fabs(x[0][i]); - long b = (long)fabs(x[1][i]); - while( b ) - { - long t = b; - b = a % b; - a = t; - } - y[0][i] = (fp_t)a; - } + for( uint_t i = 0; i < n; ++i ) + { + fp_t ax = fabs(x[0][i]); + fp_t bx = fabs(x[1][i]); + if (ax > 9223372036854775807.0 || bx > 9223372036854775807.0) + { + y[0][i] = 0; + continue; + } + long a = (long)ax; + long b = (long)bx; + while( b ) + { + long t = b; + b = a % b; + a = t; + } + y[0][i] = (fp_t)fabs((fp_t)a); + } return 0; } diff --git a/lib/gopalakrishnan_range_index.c b/lib/gopalakrishnan_range_index.c index 80da0b4..17e3d66 100644 --- a/lib/gopalakrishnan_range_index.c +++ b/lib/gopalakrishnan_range_index.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_gopalakrishnan_range_index_p = { .n_inputs = 4, .n_outpu uint_t ts_gopalakrishnan_range_index_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_gopalakrishnan_range_index_params_t *)c)->k : 0 ); + return ( c ? ((ts_gopalakrishnan_range_index_params_t const *)c)->k : 0 ); } int ts_gopalakrishnan_range_index( @@ -34,7 +34,7 @@ int ts_gopalakrishnan_range_index( { TS_PROLOGUE( ts_gopalakrishnan_range_index_p ); if ( !c ) return -1; - uint_t k = ((ts_gopalakrishnan_range_index_params_t *)c)->k; + uint_t k = ((ts_gopalakrishnan_range_index_params_t const *)c)->k; if (k == 0 || n <= k) return -1; fp_t sum_abs = 0; diff --git a/lib/harmonic.c b/lib/harmonic.c index 2c69ee8..c9920c9 100644 --- a/lib/harmonic.c +++ b/lib/harmonic.c @@ -1,10 +1,10 @@ -// Harmonic +// Harmonic Number // // harmonic // -// Harmonic mean +// Harmonic number H(n) = Σ(1/k) for k=1..n // -// H = n / Σ(1/x_i) +// H(n) = 1 + 1/2 + 1/3 + ... + 1/n // // Inputs: 1 // Outputs: 1 diff --git a/lib/high_low_bands.c b/lib/high_low_bands.c index 544796f..cc05feb 100644 --- a/lib/high_low_bands.c +++ b/lib/high_low_bands.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_high_low_bands_p = { .n_inputs = 4, .n_outputs = 2, .n_c uint_t ts_high_low_bands_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? 2 * ((ts_high_low_bands_params_t *)c)->k - 2 : 0 ); + return ( c ? 2 * ((ts_high_low_bands_params_t const *)c)->k - 2 : 0 ); } int ts_high_low_bands( @@ -34,7 +34,7 @@ int ts_high_low_bands( { TS_PROLOGUE( ts_high_low_bands_p ); if ( !c ) return -1; - uint_t k = ((ts_high_low_bands_params_t *)c)->k; + uint_t k = ((ts_high_low_bands_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = 2 * k - 2; i < n; ++i ) diff --git a/lib/highest_high.c b/lib/highest_high.c index d3ac753..22bd845 100644 --- a/lib/highest_high.c +++ b/lib/highest_high.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_highest_high_p = { .n_inputs = 4, .n_outputs = 1, .n_con uint_t ts_highest_high_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_highest_high_params_t *)c)->k > 0 ? ((ts_highest_high_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_highest_high_params_t const *)c)->k > 0 ? ((ts_highest_high_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_highest_high( @@ -34,7 +34,7 @@ int ts_highest_high( { TS_PROLOGUE( ts_highest_high_p ); if ( !c ) return -1; - uint_t k = ((ts_highest_high_params_t *)c)->k; + uint_t k = ((ts_highest_high_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t max_val = ts_h( x, 0 ); diff --git a/lib/historical_volatility.c b/lib/historical_volatility.c index cde0d91..5848d1c 100644 --- a/lib/historical_volatility.c +++ b/lib/historical_volatility.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_historical_volatility_p = { .n_inputs = 1, .n_outputs = uint_t ts_historical_volatility_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_historical_volatility_params_t *)c)->k > 0 ? ((ts_historical_volatility_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_historical_volatility_params_t const *)c)->k > 0 ? ((ts_historical_volatility_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_historical_volatility( @@ -34,7 +34,7 @@ int ts_historical_volatility( { TS_PROLOGUE( ts_historical_volatility_p ); if ( !c ) return -1; - uint_t k = ((ts_historical_volatility_params_t *)c)->k; + uint_t k = ((ts_historical_volatility_params_t const *)c)->k; if (k == 0 || n < k + 1) return -1; for ( uint_t d = k - 1; d < n - 1; ++d ) diff --git a/lib/hull_ma.c b/lib/hull_ma.c index e412a6f..1870397 100644 --- a/lib/hull_ma.c +++ b/lib/hull_ma.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_hull_ma_p = { .n_inputs = 1, .n_outputs = 1, .n_constant uint_t ts_hull_ma_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_hull_ma_params_t *)c)->k + (uint_t)sqrt((fp_t)((ts_hull_ma_params_t *)c)->k) - 2 : 0 ); + return ( c ? ((ts_hull_ma_params_t const *)c)->k + (uint_t)sqrt((fp_t)((ts_hull_ma_params_t const *)c)->k) - 2 : 0 ); } int ts_hull_ma( @@ -36,7 +36,7 @@ int ts_hull_ma( TS_PROLOGUE( ts_hull_ma_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_hull_ma_params_t *)c)->k; + uint_t k = ((ts_hull_ma_params_t const *)c)->k; if (k < 2) return -1; uint_t half_k = k / 2; diff --git a/lib/hurst_exponent.c b/lib/hurst_exponent.c index aa58036..3eea141 100644 --- a/lib/hurst_exponent.c +++ b/lib/hurst_exponent.c @@ -34,7 +34,7 @@ int ts_hurst_exponent( { TS_PROLOGUE( ts_hurst_exponent_p ); if ( !c ) return -1; - uint_t k = ((ts_hurst_exponent_params_t *)c)->k; + uint_t k = ((ts_hurst_exponent_params_t const *)c)->k; if (k == 0 || k > n) return -1; for ( uint_t i = 0; i < n; ++i ) diff --git a/lib/ichimoku.c b/lib/ichimoku.c index 76f85e6..da63626 100644 --- a/lib/ichimoku.c +++ b/lib/ichimoku.c @@ -42,7 +42,7 @@ int ts_ichimoku( if ( c ) { - ts_ichimoku_params_t *p = (ts_ichimoku_params_t *)c; + ts_ichimoku_params_t const *p = (ts_ichimoku_params_t const *)c; if ( p->tenkan > 0 ) tenkan = p->tenkan; if ( p->kijun > 0 ) kijun = p->kijun; if ( p->senkou > 0 ) senkou = p->senkou; diff --git a/lib/kalman_filter.c b/lib/kalman_filter.c index f7adf6f..a5ac5bf 100644 --- a/lib/kalman_filter.c +++ b/lib/kalman_filter.c @@ -36,12 +36,11 @@ int ts_kalman_filter( TS_PROLOGUE( ts_kalman_filter_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - fp_t Q = ((ts_kalman_filter_params_t *)c)->Q; - fp_t R = ((ts_kalman_filter_params_t *)c)->R; + fp_t Q = ((ts_kalman_filter_params_t const *)c)->Q; + fp_t R = ((ts_kalman_filter_params_t const *)c)->R; if (Q < 0 || R < 0) return -1; if (isnan(Q) || isnan(R)) return -1; - if (n == 0) return -1; fp_t x_est = x[0][0]; /* NOTE: P=1.0 is a reasonable default for normalized data. * For price data in the range of 100-3000, consider initializing diff --git a/lib/kaufman_adaptive_ma.c b/lib/kaufman_adaptive_ma.c index f56c6a1..8822344 100644 --- a/lib/kaufman_adaptive_ma.c +++ b/lib/kaufman_adaptive_ma.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_kaufman_adaptive_ma_p = { .n_inputs = 1, .n_outputs = 1, uint_t ts_kaufman_adaptive_ma_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_kaufman_adaptive_ma_params_t *)c)->k : 0 ); + return ( c ? ((ts_kaufman_adaptive_ma_params_t const *)c)->k : 0 ); } int ts_kaufman_adaptive_ma( @@ -34,7 +34,7 @@ int ts_kaufman_adaptive_ma( { TS_PROLOGUE( ts_kaufman_adaptive_ma_p ); if ( !c ) return -1; - uint_t k = ((ts_kaufman_adaptive_ma_params_t *)c)->k; + uint_t k = ((ts_kaufman_adaptive_ma_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t ama = x[0][0]; diff --git a/lib/keltner_channel.c b/lib/keltner_channel.c index 259be03..c4bf3f6 100644 --- a/lib/keltner_channel.c +++ b/lib/keltner_channel.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_keltner_channel_p = { .n_inputs = 4, .n_outputs = 3, .n_ uint_t ts_keltner_channel_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_keltner_channel_params_t *)c)->k : 0 ); + return ( c ? ((ts_keltner_channel_params_t const *)c)->k : 0 ); } int ts_keltner_channel( @@ -34,7 +34,7 @@ int ts_keltner_channel( { TS_PROLOGUE( ts_keltner_channel_p ); if ( !c ) return -1; - uint_t k = ((ts_keltner_channel_params_t *)c)->k; + uint_t k = ((ts_keltner_channel_params_t const *)c)->k; if (k == 0 || n <= k) return -1; fp_t a = 2.0 / ((fp_t)k + 1.0); @@ -24,7 +24,7 @@ ts_parameter_t const ts_kvo_p = { .n_inputs = 5, .n_outputs = 2, .n_constants = uint_t ts_kvo_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_kvo_params_t *)c)->k1 > 10 ? ((ts_kvo_params_t *)c)->k1 : 10 : 0 ); + return ( c ? ((ts_kvo_params_t const *)c)->k1 > 10 ? ((ts_kvo_params_t const *)c)->k1 : 10 : 0 ); } int ts_kvo( @@ -35,8 +35,8 @@ int ts_kvo( { TS_PROLOGUE( ts_kvo_p ); if ( !c ) return -1; - uint_t k1 = ((ts_kvo_params_t *)c)->k1; - fp_t f0_raw = ((ts_kvo_params_t *)c)->f0; + uint_t k1 = ((ts_kvo_params_t const *)c)->k1; + fp_t f0_raw = ((ts_kvo_params_t const *)c)->f0; if (isnan(f0_raw) || isinf(f0_raw) || f0_raw < 0) return -1; uint_t k10 = (uint_t)f0_raw; if (k1 == 0) return -1; @@ -24,7 +24,7 @@ ts_parameter_t const ts_lag_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_lag_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_lag_params_t *)c)->k : 0 ); + return ( c ? ((ts_lag_params_t const *)c)->k : 0 ); } int ts_lag( @@ -35,10 +35,10 @@ int ts_lag( { TS_PROLOGUE( ts_lag_p ); if ( !c ) return -1; - uint_t k = ((ts_lag_params_t *)c)->k; + uint_t k = ((ts_lag_params_t const *)c)->k; if (k == 0) return -1; - fp_t insert = ((ts_lag_params_t *)c)->insert; + fp_t insert = ((ts_lag_params_t const *)c)->insert; if (n <= k) return -1; @@ -31,30 +31,34 @@ int ts_lcm( { TS_PROLOGUE( ts_lcm_p ); (void)c; - for( uint_t i = 0; i < n; ++i ) - { - fp_t ax = fabs(x[0][i]); - fp_t bx = fabs(x[1][i]); - if (ax > 1e15 || bx > 1e15) { y[0][i] = 0.0; continue; } - long a = (long)ax; - long b = (long)bx; - if( !a || !b ) - { - y[0][i] = 0.0; - } - else - { - long ta = a; - long tb = b; - while( tb ) - { - long t = tb; - tb = ta % tb; - ta = t; - } - y[0][i] = (fp_t)(a / ta) * (fp_t)b; - } - } + for( uint_t i = 0; i < n; ++i ) + { + fp_t ax = fabs(x[0][i]); + fp_t bx = fabs(x[1][i]); + if (ax > 9223372036854775807.0 || bx > 9223372036854775807.0) + { + y[0][i] = 0.0; + continue; + } + long a = (long)ax; + long b = (long)bx; + if( !a || !b ) + { + y[0][i] = 0.0; + } + else + { + long ta = a; + long tb = b; + while( tb ) + { + long t = tb; + tb = ta % tb; + ta = t; + } + y[0][i] = (fp_t)(a / ta) * (fp_t)b; + } + } return 0; } diff --git a/lib/linear_regression.c b/lib/linear_regression.c index 5d595bc..842df1f 100644 --- a/lib/linear_regression.c +++ b/lib/linear_regression.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_linear_regression_p = { .n_inputs = 1, .n_outputs = 1, . uint_t ts_linear_regression_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_linear_regression_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_linear_regression_params_t const *)c)->k - 1 : 0 ); } int ts_linear_regression( @@ -35,7 +35,7 @@ int ts_linear_regression( TS_PROLOGUE( ts_linear_regression_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_linear_regression_params_t *)c)->k; + uint_t k = ((ts_linear_regression_params_t const *)c)->k; if (k == 0 || n < k) return -1; // Precompute constant x sums (x values are always 0..k-1) diff --git a/lib/linear_regression_angle.c b/lib/linear_regression_angle.c index 22928bc..0f60024 100644 --- a/lib/linear_regression_angle.c +++ b/lib/linear_regression_angle.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_linear_regression_angle_p = { .n_inputs = 1, .n_outputs uint_t ts_linear_regression_angle_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_linear_regression_angle_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_linear_regression_angle_params_t const *)c)->k - 1 : 0 ); } int ts_linear_regression_angle( @@ -34,7 +34,7 @@ int ts_linear_regression_angle( { TS_PROLOGUE( ts_linear_regression_angle_p ); if ( !c ) return -1; - uint_t k = ((ts_linear_regression_angle_params_t *)c)->k; + uint_t k = ((ts_linear_regression_angle_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_x = 0, sum_x2 = 0; diff --git a/lib/linear_regression_forecast.c b/lib/linear_regression_forecast.c index 02a78a8..73f974c 100644 --- a/lib/linear_regression_forecast.c +++ b/lib/linear_regression_forecast.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_linear_regression_forecast_p = { .n_inputs = 1, .n_outpu uint_t ts_linear_regression_forecast_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_linear_regression_forecast_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_linear_regression_forecast_params_t const *)c)->k - 1 : 0 ); } int ts_linear_regression_forecast( @@ -34,7 +34,7 @@ int ts_linear_regression_forecast( { TS_PROLOGUE( ts_linear_regression_forecast_p ); if ( !c ) return -1; - uint_t k = ((ts_linear_regression_forecast_params_t *)c)->k; + uint_t k = ((ts_linear_regression_forecast_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_x = 0, sum_x2 = 0; diff --git a/lib/linear_regression_intercept.c b/lib/linear_regression_intercept.c index 2b26478..adb153c 100644 --- a/lib/linear_regression_intercept.c +++ b/lib/linear_regression_intercept.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_linear_regression_intercept_p = { .n_inputs = 1, .n_outp uint_t ts_linear_regression_intercept_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_linear_regression_intercept_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_linear_regression_intercept_params_t const *)c)->k - 1 : 0 ); } int ts_linear_regression_intercept( @@ -33,7 +33,7 @@ int ts_linear_regression_intercept( { TS_PROLOGUE( ts_linear_regression_intercept_p ); if ( !c ) return -1; - uint_t k = ((ts_linear_regression_intercept_params_t *)c)->k; + uint_t k = ((ts_linear_regression_intercept_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_x = 0, sum_x2 = 0; diff --git a/lib/linear_regression_r2.c b/lib/linear_regression_r2.c index 5cec662..c15ee67 100644 --- a/lib/linear_regression_r2.c +++ b/lib/linear_regression_r2.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_linear_regression_r2_p = { .n_inputs = 1, .n_outputs = 1 uint_t ts_linear_regression_r2_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_linear_regression_r2_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_linear_regression_r2_params_t const *)c)->k - 1 : 0 ); } int ts_linear_regression_r2( @@ -34,7 +34,7 @@ int ts_linear_regression_r2( { TS_PROLOGUE( ts_linear_regression_r2_p ); if ( !c ) return -1; - uint_t k = ((ts_linear_regression_r2_params_t *)c)->k; + uint_t k = ((ts_linear_regression_r2_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_x = 0, sum_x2 = 0; diff --git a/lib/linear_regression_slope.c b/lib/linear_regression_slope.c index d20ca8e..5bdc01f 100644 --- a/lib/linear_regression_slope.c +++ b/lib/linear_regression_slope.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_linear_regression_slope_p = { .n_inputs = 1, .n_outputs uint_t ts_linear_regression_slope_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_linear_regression_slope_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_linear_regression_slope_params_t const *)c)->k - 1 : 0 ); } int ts_linear_regression_slope( @@ -33,7 +33,7 @@ int ts_linear_regression_slope( { TS_PROLOGUE( ts_linear_regression_slope_p ); if ( !c ) return -1; - uint_t k = ((ts_linear_regression_slope_params_t *)c)->k; + uint_t k = ((ts_linear_regression_slope_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_x = 0, sum_x2 = 0; diff --git a/lib/linear_weighted_ma.c b/lib/linear_weighted_ma.c index 70f660e..e11bf54 100644 --- a/lib/linear_weighted_ma.c +++ b/lib/linear_weighted_ma.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_linear_weighted_ma_p = { .n_inputs = 1, .n_outputs = 1, uint_t ts_linear_weighted_ma_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_linear_weighted_ma_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_linear_weighted_ma_params_t const *)c)->k - 1 : 0 ); } int ts_linear_weighted_ma( @@ -33,7 +33,7 @@ int ts_linear_weighted_ma( { TS_PROLOGUE( ts_linear_weighted_ma_p ); if ( !c ) return -1; - uint_t k = ((ts_linear_weighted_ma_params_t *)c)->k; + uint_t k = ((ts_linear_weighted_ma_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t w_sum = 0; diff --git a/lib/logarithm.c b/lib/logarithm.c index 7451976..9ca98a6 100755 --- a/lib/logarithm.c +++ b/lib/logarithm.c @@ -36,8 +36,8 @@ int ts_logarithm( { TS_PROLOGUE( ts_logarithm_p ); if ( !c ) return -1; - fp_t b = ((ts_logarithm_params_t *)c)->b; - if (b == 0 || b == 1.0) return -1; + fp_t b = ((ts_logarithm_params_t const *)c)->b; + if (b <= 0 || b == 1.0 || isnan(b) || isinf(b)) return -1; b = _ts_reciprocal( log( b ) ); diff --git a/lib/lowest_low.c b/lib/lowest_low.c index d8ac284..687cdeb 100644 --- a/lib/lowest_low.c +++ b/lib/lowest_low.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_lowest_low_p = { .n_inputs = 4, .n_outputs = 1, .n_const uint_t ts_lowest_low_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_lowest_low_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_lowest_low_params_t const *)c)->k - 1 : 0 ); } int ts_lowest_low( @@ -33,7 +33,7 @@ int ts_lowest_low( { TS_PROLOGUE( ts_lowest_low_p ); if ( !c ) return -1; - uint_t k = ((ts_lowest_low_params_t *)c)->k; + uint_t k = ((ts_lowest_low_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t min_val = ts_l( x, 0 ); @@ -25,7 +25,7 @@ ts_parameter_t const ts_macd_p = { .n_inputs = 1, .n_outputs = 3, .n_constants = uint_t ts_macd_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? (uint_t)(((ts_macd_params_t *)c)->slow_k + ((ts_macd_params_t *)c)->signal_k - 2) : 0 ); + return ( c ? (uint_t)(((ts_macd_params_t const *)c)->slow_k + ((ts_macd_params_t const *)c)->signal_k - 2) : 0 ); } int ts_macd( @@ -37,13 +37,13 @@ int ts_macd( TS_PROLOGUE( ts_macd_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - fp_t fast_k = ((ts_macd_params_t *)c)->fast_k; - fp_t slow_k = ((ts_macd_params_t *)c)->slow_k; - fp_t signal_k = ((ts_macd_params_t *)c)->signal_k; + fp_t fast_k = ((ts_macd_params_t const *)c)->fast_k; + fp_t slow_k = ((ts_macd_params_t const *)c)->slow_k; + fp_t signal_k = ((ts_macd_params_t const *)c)->signal_k; if (fast_k < 1 || slow_k < 1 || signal_k < 1) return -1; if (isnan(fast_k) || isnan(slow_k) || isnan(signal_k)) return -1; - if (n == 0) return -1; + if (isinf(fast_k) || isinf(slow_k) || isinf(signal_k)) return -1; fp_t fast_a = 2.0 / (fast_k + 1.0); fp_t slow_a = 2.0 / (slow_k + 1.0); @@ -52,9 +52,17 @@ int ts_macd( fp_t fast_ema = x[0][0]; fp_t slow_ema = x[0][0]; + if (slow_k > (fp_t)UINT64_MAX || signal_k > (fp_t)UINT64_MAX) return -1; uint_t total_offset = (uint_t)(slow_k + signal_k - 2); if (n <= total_offset) return -1; + // Initialize warm-up period to NAN + for (uint_t i = 0; i < total_offset; i++) { + y[0][i] = NAN; + y[1][i] = NAN; + y[2][i] = NAN; + } + // Compute EMAs up to total_offset for( uint_t i = 1; i <= total_offset; ++i ) { diff --git a/lib/maximum.c b/lib/maximum.c index f4d124a..0f1539b 100755 --- a/lib/maximum.c +++ b/lib/maximum.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_maximum_p = { .n_inputs = 1, .n_outputs = 1, .n_constant uint_t ts_maximum_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_maximum_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_maximum_params_t const *)c)->k - 1 : 0 ); } int ts_maximum( @@ -32,7 +32,7 @@ int ts_maximum( { TS_PROLOGUE( ts_maximum_p ); if ( !c ) return -1; - uint_t k = ((ts_maximum_params_t *)c)->k; + uint_t k = ((ts_maximum_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = k - 1; diff --git a/lib/mesa_sine_wave.c b/lib/mesa_sine_wave.c index 8ed5fa6..91fbcd2 100644 --- a/lib/mesa_sine_wave.c +++ b/lib/mesa_sine_wave.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_mesa_sine_wave_p = { .n_inputs = 1, .n_outputs = 2, .n_c uint_t ts_mesa_sine_wave_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_mesa_sine_wave_params_t *)c)->k : 0 ); + return ( c ? ((ts_mesa_sine_wave_params_t const *)c)->k : 0 ); } int ts_mesa_sine_wave( @@ -35,64 +35,64 @@ int ts_mesa_sine_wave( { TS_PROLOGUE( ts_mesa_sine_wave_p ); if ( !c ) return -1; - uint_t k = ((ts_mesa_sine_wave_params_t *)c)->k; + uint_t k = ((ts_mesa_sine_wave_params_t const *)c)->k; if (k < 2 || n < k) return -1; - fp_t *sma = calloc(n, sizeof(fp_t)); - if (!sma) return -1; + fp_t *sma = calloc( n, sizeof( fp_t ) ); + if ( !sma ) return -1; - for (uint_t i = 0; i < n; ++i) + for ( uint_t i = 0; i < n; ++i ) { - if (i < k - 1) + if ( i < k - 1 ) { fp_t sum = 0; - for (uint_t j = 0; j <= i; ++j) + for ( uint_t j = 0; j <= i; ++j ) sum += x[0][j]; - sma[i] = sum / (i + 1); + sma[i] = sum / (fp_t)( i + 1 ); } else { fp_t sum = 0; - for (uint_t j = i - k + 1; j <= i; ++j) + for ( uint_t j = i - k + 1; j <= i; ++j ) sum += x[0][j]; - sma[i] = sum / k; + sma[i] = sum / (fp_t)k; } } fp_t ema_roc = 0; uint_t ema_period = 5; - fp_t ema_a = 2.0 / (ema_period + 1); + fp_t ema_a = 2.0 / ( (fp_t)ema_period + 1 ); fp_t phase = 0; int_t first = 1; - for (uint_t j = 0; j < n && j < k; ++j) { y[0][j] = 0; y[1][j] = 0; } - for (uint_t i = k; i < n; ++i) + for ( uint_t j = 0; j < n && j < k; ++j ) { y[0][j] = 0; y[1][j] = 0; } + for ( uint_t i = k; i < n; ++i ) { fp_t roc = sma[i] - sma[i - 2]; - if (first) + if ( first ) { ema_roc = roc; first = 0; } else { - ema_roc = ema_roc + ema_a * (roc - ema_roc); + ema_roc = ema_roc + ema_a * ( roc - ema_roc ); } fp_t smoothed = ema_roc; - if (smoothed > 1.0) smoothed = 1.0; - if (smoothed < 0.01) smoothed = 0.01; + if ( smoothed > 1.0 ) smoothed = 1.0; + if ( smoothed < 0.01 ) smoothed = 0.01; fp_t wperiod = 2 * PI / smoothed; - if (wperiod < 5) wperiod = 5; - if (wperiod > 12) wperiod = 12; + if ( wperiod < 5 ) wperiod = 5; + if ( wperiod > 12 ) wperiod = 12; - if (smoothed >= 1.0) + if ( smoothed >= 1.0 ) { phase = 0; } - else if (smoothed <= 0.01) + else if ( smoothed <= 0.01 ) { phase = 2 * PI; } @@ -100,13 +100,13 @@ int ts_mesa_sine_wave( { phase += 2 * PI / wperiod; } - while (phase > 2 * PI) phase -= 2 * PI; + while ( phase > 2 * PI ) phase -= 2 * PI; - y[0][i] = cos(phase); - y[1][i] = cos(phase + PI / 2); + y[0][i] = cos( phase ); + y[1][i] = cos( phase + PI / 2 ); } - free(sma); + free( sma ); return 0; } @@ -23,7 +23,7 @@ ts_parameter_t const ts_mfi_p = { .n_inputs = 5, .n_outputs = 1, .n_constants = uint_t ts_mfi_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_mfi_params_t *)c)->k : 0 ); + return ( c ? ((ts_mfi_params_t const *)c)->k : 0 ); } int ts_mfi( @@ -34,7 +34,7 @@ int ts_mfi( { TS_PROLOGUE( ts_mfi_p ); if ( !c ) return -1; - uint_t k = ((ts_mfi_params_t *)c)->k; + uint_t k = ((ts_mfi_params_t const *)c)->k; if (k == 0 || n <= k) return -1; fp_t *tp = calloc( n, sizeof( fp_t ) ); diff --git a/lib/midpoint.c b/lib/midpoint.c index c28cdff..da24eba 100644 --- a/lib/midpoint.c +++ b/lib/midpoint.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_midpoint_p = { .n_inputs = 1, .n_outputs = 1, .n_constan uint_t ts_midpoint_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_midpoint_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_midpoint_params_t const *)c)->k - 1 : 0 ); } int ts_midpoint( @@ -33,7 +33,7 @@ int ts_midpoint( { TS_PROLOGUE( ts_midpoint_p ); if ( !c ) return -1; - uint_t k = ((ts_midpoint_params_t *)c)->k; + uint_t k = ((ts_midpoint_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/midprice.c b/lib/midprice.c index d26a58e..8c8dfe0 100644 --- a/lib/midprice.c +++ b/lib/midprice.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_midprice_p = { .n_inputs = 1, .n_outputs = 1, .n_constan uint_t ts_midprice_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_midprice_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_midprice_params_t const *)c)->k - 1 : 0 ); } int ts_midprice( @@ -33,7 +33,7 @@ int ts_midprice( { TS_PROLOGUE( ts_midprice_p ); if ( !c ) return -1; - uint_t k = ((ts_midprice_params_t *)c)->k; + uint_t k = ((ts_midprice_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/minimum.c b/lib/minimum.c index d2ba15f..5a2814c 100755 --- a/lib/minimum.c +++ b/lib/minimum.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_minimum_p = { .n_inputs = 1, .n_outputs = 1, .n_constant uint_t ts_minimum_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_minimum_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_minimum_params_t const *)c)->k - 1 : 0 ); } int ts_minimum( @@ -32,7 +32,7 @@ int ts_minimum( { TS_PROLOGUE( ts_minimum_p ); if ( !c ) return -1; - uint_t k = ((ts_minimum_params_t *)c)->k; + uint_t k = ((ts_minimum_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = k - 1; diff --git a/lib/minmax.c b/lib/minmax.c index 4bee598..8763266 100644 --- a/lib/minmax.c +++ b/lib/minmax.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_minmax_p = { .n_inputs = 1, .n_outputs = 2, .n_constants uint_t ts_minmax_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_minmax_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_minmax_params_t const *)c)->k - 1 : 0 ); } int ts_minmax( @@ -33,7 +33,7 @@ int ts_minmax( { TS_PROLOGUE( ts_minmax_p ); if ( !c ) return -1; - uint_t k = ((ts_minmax_params_t *)c)->k; + uint_t k = ((ts_minmax_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/missing_bar_count.c b/lib/missing_bar_count.c index e6f548e..d001a5f 100644 --- a/lib/missing_bar_count.c +++ b/lib/missing_bar_count.c @@ -34,8 +34,7 @@ int ts_missing_bar_count( { TS_PROLOGUE( ts_missing_bar_count_p ); if ( !c ) return -1; - if (n == 0) return -1; - fp_t threshold = ((ts_missing_bar_count_params_t *)c)->threshold; + fp_t threshold = ((ts_missing_bar_count_params_t const *)c)->threshold; y[0][0] = 0; diff --git a/lib/momentum.c b/lib/momentum.c index f0d89fd..8e1dcf4 100644 --- a/lib/momentum.c +++ b/lib/momentum.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_momentum_p = { .n_inputs = 1, .n_outputs = 1, .n_constan uint_t ts_momentum_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_momentum_params_t *)c)->k : 0 ); + return ( c ? ((ts_momentum_params_t const *)c)->k : 0 ); } int ts_momentum( @@ -34,7 +34,7 @@ int ts_momentum( TS_PROLOGUE( ts_momentum_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_momentum_params_t *)c)->k; + uint_t k = ((ts_momentum_params_t const *)c)->k; for( uint_t i = k; i < n; ++i ) { diff --git a/lib/moving_linear_regression.c b/lib/moving_linear_regression.c index ceb34d5..66b750c 100644 --- a/lib/moving_linear_regression.c +++ b/lib/moving_linear_regression.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_moving_linear_regression_p = { .n_inputs = 1, .n_outputs uint_t ts_moving_linear_regression_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_moving_linear_regression_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_moving_linear_regression_params_t const *)c)->k - 1 : 0 ); } int ts_moving_linear_regression( @@ -33,7 +33,7 @@ int ts_moving_linear_regression( { TS_PROLOGUE( ts_moving_linear_regression_p ); if ( !c ) return -1; - uint_t k = ((ts_moving_linear_regression_params_t *)c)->k; + uint_t k = ((ts_moving_linear_regression_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_x = 0, sum_x2 = 0; diff --git a/lib/moving_linear_regression_r2.c b/lib/moving_linear_regression_r2.c index 3015a25..71eb081 100644 --- a/lib/moving_linear_regression_r2.c +++ b/lib/moving_linear_regression_r2.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_moving_linear_regression_r2_p = { .n_inputs = 1, .n_outp uint_t ts_moving_linear_regression_r2_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_moving_linear_regression_r2_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_moving_linear_regression_r2_params_t const *)c)->k - 1 : 0 ); } int ts_moving_linear_regression_r2( @@ -34,7 +34,7 @@ int ts_moving_linear_regression_r2( { TS_PROLOGUE( ts_moving_linear_regression_r2_p ); if ( !c ) return -1; - uint_t k = ((ts_moving_linear_regression_r2_params_t *)c)->k; + uint_t k = ((ts_moving_linear_regression_r2_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum_x = 0, sum_x2 = 0; @@ -25,7 +25,7 @@ ts_parameter_t const ts_natr_p = { .n_inputs = 4, .n_outputs = 1, .n_constants = uint_t ts_natr_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_natr_params_t *)c)->k : 0 ); + return ( c ? ((ts_natr_params_t const *)c)->k : 0 ); } int ts_natr( @@ -36,10 +36,14 @@ int ts_natr( { TS_PROLOGUE( ts_natr_p ); if ( !c ) return -1; - uint_t k = ((ts_natr_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_natr_params_t const *)c)->k; if (k == 0) return -1; if (n < k + 1) return -1; + for( uint_t i = 0; i < k; ++i ) + y[0][i] = NAN; + for( uint_t i = k; i < n; ++i ) { fp_t tr_sum = 0; @@ -30,7 +30,6 @@ int ts_nvi( { TS_PROLOGUE( ts_nvi_p ); (void)c; - if (n == 0) return -1; fp_t nvi = 1000; @@ -31,7 +31,6 @@ int ts_obv( TS_PROLOGUE( ts_obv_p ); (void)c; TS_CHECK_INPUT(x, x_n, n); - if (n == 0) return -1; fp_t obv = 0; y[0][0] = 0; diff --git a/lib/on_balance_volume_rate.c b/lib/on_balance_volume_rate.c index 7183c23..242f00a 100644 --- a/lib/on_balance_volume_rate.c +++ b/lib/on_balance_volume_rate.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_on_balance_volume_rate_p = { .n_inputs = 5, .n_outputs = uint_t ts_on_balance_volume_rate_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? (uint_t)((ts_on_balance_volume_rate_params_t *)c)->f0 + 1 : 0 ); + return ( c ? (uint_t)((ts_on_balance_volume_rate_params_t const *)c)->f0 + 1 : 0 ); } int ts_on_balance_volume_rate( @@ -34,7 +34,7 @@ int ts_on_balance_volume_rate( { TS_PROLOGUE( ts_on_balance_volume_rate_p ); if ( !c ) return -1; - uint_t k = (uint_t)((ts_on_balance_volume_rate_params_t *)c)->f0; + uint_t k = (uint_t)((ts_on_balance_volume_rate_params_t const *)c)->f0; if (k == 0 || k >= n) return -1; fp_t obv = 0; diff --git a/lib/oscillator_cross.c b/lib/oscillator_cross.c index 0c6c5f8..1510738 100644 --- a/lib/oscillator_cross.c +++ b/lib/oscillator_cross.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_oscillator_cross_p = { .n_inputs = 1, .n_outputs = 1, .n uint_t ts_oscillator_cross_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? (uint_t)((ts_oscillator_cross_params_t *)c)->slow : 0 ); + return ( c ? (uint_t)((ts_oscillator_cross_params_t const *)c)->slow : 0 ); } int ts_oscillator_cross( @@ -34,10 +34,9 @@ int ts_oscillator_cross( { TS_PROLOGUE( ts_oscillator_cross_p ); if ( !c ) return -1; - fp_t const fast = ((ts_oscillator_cross_params_t *)c)->fast; - fp_t const slow = ((ts_oscillator_cross_params_t *)c)->slow; + fp_t const fast = ((ts_oscillator_cross_params_t const *)c)->fast; + fp_t const slow = ((ts_oscillator_cross_params_t const *)c)->slow; if (fast == 0 || slow == 0) return -1; - if (n == 0) return -1; fp_t const fast_a = 1.0 / fast; fp_t const slow_a = 1.0 / slow; fp_t fast_e = x[0][0]; @@ -24,7 +24,7 @@ ts_parameter_t const ts_osma_p = { .n_inputs = 5, .n_outputs = 1, .n_constants = uint_t ts_osma_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? (uint_t)((ts_osma_params_t *)c)->slow_k : 0 ); + return ( c ? (uint_t)((ts_osma_params_t const *)c)->slow_k : 0 ); } int ts_osma( @@ -35,12 +35,11 @@ int ts_osma( { TS_PROLOGUE( ts_osma_p ); if ( !c ) return -1; - fp_t fast_k = ((ts_osma_params_t *)c)->fast_k; - fp_t slow_k = ((ts_osma_params_t *)c)->slow_k; - fp_t signal_k = ((ts_osma_params_t *)c)->signal_k; + fp_t fast_k = ((ts_osma_params_t const *)c)->fast_k; + fp_t slow_k = ((ts_osma_params_t const *)c)->slow_k; + fp_t signal_k = ((ts_osma_params_t const *)c)->signal_k; if (fast_k == 0 || slow_k == 0 || signal_k == 0) return -1; - if (n == 0) return -1; fp_t fast_a = 1.0 / fast_k; fp_t slow_a = 1.0 / slow_k; diff --git a/lib/parabolic_sar.c b/lib/parabolic_sar.c index ff84834..cd699aa 100644 --- a/lib/parabolic_sar.c +++ b/lib/parabolic_sar.c @@ -35,12 +35,11 @@ int ts_parabolic_sar( { 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; + fp_t step = ((ts_parabolic_sar_params_t const *)c)->step; + fp_t max_af = ((ts_parabolic_sar_params_t const *)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 ); diff --git a/lib/performance_ratio.c b/lib/performance_ratio.c index ffd0ece..a429b8b 100644 --- a/lib/performance_ratio.c +++ b/lib/performance_ratio.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_performance_ratio_p = { .n_inputs = 1, .n_outputs = 1, . uint_t ts_performance_ratio_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_performance_ratio_params_t *)c)->k : 0 ); + return ( c ? ((ts_performance_ratio_params_t const *)c)->k : 0 ); } int ts_performance_ratio( @@ -34,8 +34,8 @@ int ts_performance_ratio( { TS_PROLOGUE( ts_performance_ratio_p ); if ( !c ) return -1; - uint_t k = ((ts_performance_ratio_params_t *)c)->k; - if (k <= 1 || n == 0) return -1; + uint_t k = ((ts_performance_ratio_params_t const *)c)->k; + if (k <= 1) return -1; fp_t factor = (fp_t)k / (k - 1); diff --git a/lib/poisson_pdf.c b/lib/poisson_pdf.c index e1e2d59..60a62ac 100644 --- a/lib/poisson_pdf.c +++ b/lib/poisson_pdf.c @@ -34,7 +34,7 @@ int ts_poisson_pdf( { TS_PROLOGUE( ts_poisson_pdf_p ); if ( !c ) return -1; - fp_t lambda = ((ts_poisson_pdf_params_t *)c)->lambda; + fp_t lambda = ((ts_poisson_pdf_params_t const *)c)->lambda; if (lambda < 0.0 || isnan(lambda) || isinf(lambda)) return -1; for( uint_t i = 0; i < n; ++i ) { diff --git a/lib/polynomial.c b/lib/polynomial.c index 2914fe6..82d8fba 100644 --- a/lib/polynomial.c +++ b/lib/polynomial.c @@ -33,7 +33,7 @@ int ts_polynomial( { fp_t base = x[0][i]; fp_t exponent = x[1][i]; - if( base < 0.0 && exponent != (fp_t)(long)exponent ) { y[0][i] = 0; continue; } + if( base < 0.0 && exponent != (fp_t)(long)exponent ) { y[0][i] = NAN; continue; } y[0][i] = pow(base, exponent); } return 0; diff --git a/lib/power.c b/lib/power.c index 41bb644..1d9c8cd 100755 --- a/lib/power.c +++ b/lib/power.c @@ -36,7 +36,7 @@ int ts_power( { TS_PROLOGUE( ts_power_p ); if ( !c ) return -1; - fp_t r = ((ts_power_params_t *)c)->r; + fp_t r = ((ts_power_params_t const *)c)->r; for( uint_t i = 0; i < n; ++i ) { @@ -24,7 +24,7 @@ ts_parameter_t const ts_ppo_p = { .n_inputs = 5, .n_outputs = 2, .n_constants = uint_t ts_ppo_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? (uint_t)(((ts_ppo_params_t *)c)->slow_k + ((ts_ppo_params_t *)c)->signal_k - 2) : 0 ); + return ( c ? (uint_t)(((ts_ppo_params_t const *)c)->slow_k + ((ts_ppo_params_t const *)c)->signal_k - 2) : 0 ); } int ts_ppo( @@ -35,12 +35,11 @@ int ts_ppo( { TS_PROLOGUE( ts_ppo_p ); if ( !c ) return -1; - fp_t fast_k = ((ts_ppo_params_t *)c)->fast_k; - fp_t slow_k = ((ts_ppo_params_t *)c)->slow_k; - fp_t signal_k = ((ts_ppo_params_t *)c)->signal_k; + fp_t fast_k = ((ts_ppo_params_t const *)c)->fast_k; + fp_t slow_k = ((ts_ppo_params_t const *)c)->slow_k; + fp_t signal_k = ((ts_ppo_params_t const *)c)->signal_k; if (fast_k == 0 || slow_k == 0 || signal_k == 0) return -1; - if (n == 0) return -1; fp_t fast_a = 1.0 / fast_k; fp_t slow_a = 1.0 / slow_k; diff --git a/lib/pretty_good_oscillator.c b/lib/pretty_good_oscillator.c index 65a05c2..2dbc6f1 100644 --- a/lib/pretty_good_oscillator.c +++ b/lib/pretty_good_oscillator.c @@ -30,7 +30,7 @@ int ts_pretty_good_oscillator( { TS_PROLOGUE( ts_pretty_good_oscillator_p ); (void)c; - if (n == 0) return -1; + fp_t ema14 = x[0][0]; fp_t ema30 = x[0][0]; fp_t ema90 = x[0][0]; diff --git a/lib/price_channel.c b/lib/price_channel.c index 9aba070..4a3129c 100644 --- a/lib/price_channel.c +++ b/lib/price_channel.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_price_channel_p = { .n_inputs = 1, .n_outputs = 3, .n_co uint_t ts_price_channel_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_price_channel_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_price_channel_params_t const *)c)->k - 1 : 0 ); } int ts_price_channel( @@ -33,7 +33,7 @@ int ts_price_channel( { TS_PROLOGUE( ts_price_channel_p ); if ( !c ) return -1; - uint_t k = ((ts_price_channel_params_t *)c)->k; + uint_t k = ((ts_price_channel_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/price_momentum_oscillator.c b/lib/price_momentum_oscillator.c index b03f350..d92fccb 100644 --- a/lib/price_momentum_oscillator.c +++ b/lib/price_momentum_oscillator.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_price_momentum_oscillator_p = { .n_inputs = 1, .n_output uint_t ts_price_momentum_oscillator_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_price_momentum_oscillator_params_t *)c)->k : 0 ); + return ( c ? ((ts_price_momentum_oscillator_params_t const *)c)->k : 0 ); } int ts_price_momentum_oscillator( @@ -33,7 +33,7 @@ int ts_price_momentum_oscillator( { TS_PROLOGUE( ts_price_momentum_oscillator_p ); if ( !c ) return -1; - uint_t k = ((ts_price_momentum_oscillator_params_t *)c)->k; + uint_t k = ((ts_price_momentum_oscillator_params_t const *)c)->k; if (k == 0 || n < k) return -1; for (uint_t i = k; i < n; ++i) diff --git a/lib/price_rate_of_change.c b/lib/price_rate_of_change.c index 8f26548..4dc9834 100644 --- a/lib/price_rate_of_change.c +++ b/lib/price_rate_of_change.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_price_rate_of_change_p = { .n_inputs = 1, .n_outputs = 1 uint_t ts_price_rate_of_change_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_price_rate_of_change_params_t *)c)->k : 0 ); + return ( c ? ((ts_price_rate_of_change_params_t const *)c)->k : 0 ); } int ts_price_rate_of_change( @@ -33,7 +33,7 @@ int ts_price_rate_of_change( { TS_PROLOGUE( ts_price_rate_of_change_p ); if ( !c ) return -1; - uint_t k = ((ts_price_rate_of_change_params_t *)c)->k; + uint_t k = ((ts_price_rate_of_change_params_t const *)c)->k; if (k == 0 || n < k) return -1; for (uint_t i = k; i < n; ++i) diff --git a/lib/prime_number_bands.c b/lib/prime_number_bands.c index ac94e7b..bb01c2c 100644 --- a/lib/prime_number_bands.c +++ b/lib/prime_number_bands.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_prime_number_bands_p = { .n_inputs = 1, .n_outputs = 3, uint_t ts_prime_number_bands_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_prime_number_bands_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_prime_number_bands_params_t const *)c)->k - 1 : 0 ); } int ts_prime_number_bands( @@ -34,7 +34,7 @@ int ts_prime_number_bands( { TS_PROLOGUE( ts_prime_number_bands_p ); if ( !c ) return -1; - uint_t k = ((ts_prime_number_bands_params_t *)c)->k; + uint_t k = ((ts_prime_number_bands_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/prings_special_k.c b/lib/prings_special_k.c index 91a40ba..9191567 100644 --- a/lib/prings_special_k.c +++ b/lib/prings_special_k.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_prings_special_k_p = { .n_inputs = 4, .n_outputs = 2, .n uint_t ts_prings_special_k_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_prings_special_k_params_t *)c)->k1 > 0 && ((ts_prings_special_k_params_t *)c)->k2 > 0 ? ((ts_prings_special_k_params_t *)c)->k1 + ((ts_prings_special_k_params_t *)c)->k2 - 2 : 0 : 0 ); + return ( c ? ((ts_prings_special_k_params_t const *)c)->k1 > 0 && ((ts_prings_special_k_params_t const *)c)->k2 > 0 ? ((ts_prings_special_k_params_t const *)c)->k1 + ((ts_prings_special_k_params_t const *)c)->k2 - 2 : 0 : 0 ); } int ts_prings_special_k( @@ -34,8 +34,8 @@ int ts_prings_special_k( { TS_PROLOGUE( ts_prings_special_k_p ); if ( !c ) return -1; - uint_t k1 = ((ts_prings_special_k_params_t *)c)->k1; - uint_t k2 = ((ts_prings_special_k_params_t *)c)->k2; + uint_t k1 = ((ts_prings_special_k_params_t const *)c)->k1; + uint_t k2 = ((ts_prings_special_k_params_t const *)c)->k2; if (k1 == 0 || k2 == 0) return -1; fp_t ema = 0; diff --git a/lib/psychological_line.c b/lib/psychological_line.c index 35fd912..86ebcd3 100644 --- a/lib/psychological_line.c +++ b/lib/psychological_line.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_psychological_line_p = { .n_inputs = 4, .n_outputs = 1, uint_t ts_psychological_line_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_psychological_line_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_psychological_line_params_t const *)c)->k - 1 : 0 ); } int ts_psychological_line( @@ -33,7 +33,7 @@ int ts_psychological_line( { TS_PROLOGUE( ts_psychological_line_p ); if ( !c ) return -1; - uint_t k = ((ts_psychological_line_params_t *)c)->k; + uint_t k = ((ts_psychological_line_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t sum = 0; @@ -30,9 +30,8 @@ int ts_pvi( { TS_PROLOGUE( ts_pvi_p ); (void)c; - fp_t pvi = 1000; - if (n == 0) return -1; + fp_t pvi = 1000; y[0][0] = pvi; diff --git a/lib/qstick.c b/lib/qstick.c index d2f4361..dd7d7da 100644 --- a/lib/qstick.c +++ b/lib/qstick.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_qstick_p = { .n_inputs = 4, .n_outputs = 1, .n_constants uint_t ts_qstick_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_qstick_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_qstick_params_t const *)c)->k - 1 : 0 ); } int ts_qstick( @@ -33,7 +33,7 @@ int ts_qstick( { TS_PROLOGUE( ts_qstick_p ); if ( !c ) return -1; - uint_t k = ((ts_qstick_params_t *)c)->k; + uint_t k = ((ts_qstick_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/rainbow_oscillator.c b/lib/rainbow_oscillator.c index 1a56b55..463577f 100644 --- a/lib/rainbow_oscillator.c +++ b/lib/rainbow_oscillator.c @@ -58,7 +58,7 @@ int ts_rainbow_oscillator( max_ma = ma_values[p]; } - if( max_ma == min_ma ) + if( fabs(max_ma - min_ma) < TS_FILL_ZERO_THRESHOLD ) y[0][i] = 0; else y[0][i] = ( x[0][i] - min_ma ) / ( max_ma - min_ma ) * 100.0; diff --git a/lib/random_walk_index.c b/lib/random_walk_index.c index b4375e5..aa8e5f5 100644 --- a/lib/random_walk_index.c +++ b/lib/random_walk_index.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_random_walk_index_p = { .n_inputs = 1, .n_outputs = 1, . uint_t ts_random_walk_index_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_random_walk_index_params_t *)c)->k : 0 ); + return ( c ? ((ts_random_walk_index_params_t const *)c)->k : 0 ); } int ts_random_walk_index( @@ -34,7 +34,7 @@ int ts_random_walk_index( { TS_PROLOGUE( ts_random_walk_index_p ); if ( !c ) return -1; - uint_t k = ((ts_random_walk_index_params_t *)c)->k; + uint_t k = ((ts_random_walk_index_params_t const *)c)->k; if (k == 0 || n < k + 1) return -1; fp_t sum_abs = 0; @@ -22,7 +22,7 @@ ts_parameter_t const ts_rank_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_rank_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_rank_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_rank_params_t const *)c)->k - 1 : 0 ); } int ts_rank( @@ -33,7 +33,7 @@ int ts_rank( { TS_PROLOGUE( ts_rank_p ); if ( !c ) return -1; - uint_t k = ((ts_rank_params_t *)c)->k; + uint_t k = ((ts_rank_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/ratio.c b/lib/ratio.c index 8568476..813d46c 100755 --- a/lib/ratio.c +++ b/lib/ratio.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_ratio_p = { .n_inputs = 1, .n_outputs = 1, .n_constants uint_t ts_ratio_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_ratio_params_t *)c)->k : 0 ); + return ( c ? ((ts_ratio_params_t const *)c)->k : 0 ); } int ts_ratio( @@ -35,7 +35,7 @@ int ts_ratio( { TS_PROLOGUE( ts_ratio_p ); if ( !c ) return -1; - uint_t k = ((ts_ratio_params_t *)c)->k; + uint_t k = ((ts_ratio_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = k; @@ -25,7 +25,7 @@ ts_parameter_t const ts_ravi_p = { .n_inputs = 4, .n_outputs = 2, .n_constants = uint_t ts_ravi_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_ravi_params_t *)c)->k + (uint_t)((ts_ravi_params_t *)c)->k2 - 2 : 0 ); + return ( c ? ((ts_ravi_params_t const *)c)->k + (uint_t)((ts_ravi_params_t const *)c)->k2 - 2 : 0 ); } int ts_ravi( @@ -36,19 +36,19 @@ int ts_ravi( { TS_PROLOGUE( ts_ravi_p ); if ( !c ) return -1; - uint_t k = ((ts_ravi_params_t *)c)->k; - fp_t k2 = ((ts_ravi_params_t *)c)->k2; + uint_t k = ((ts_ravi_params_t const *)c)->k; + fp_t k2 = ((ts_ravi_params_t const *)c)->k2; - if( k == 0 || k2 == 0 ) return -1; + if( k == 0 || k2 <= 0 || isnan(k2) || isinf(k2) ) return -1; - fp_t *num_buf = calloc( n, sizeof( fp_t ) ); + fp_t *num_buf = calloc( n, sizeof( fp_t ) ); fp_t *den_buf = calloc( n, sizeof( fp_t ) ); if( !num_buf || !den_buf ) { free( num_buf ); free( den_buf ); return -1; } for( uint_t i = 0; i < n; ++i ) { - num_buf[i] = (x[3][i] - x[0][i]) + (x[3][i] - (i > 0 ? x[3][i - 1] : x[3][i])); - den_buf[i] = fabs(x[1][i] - x[2][i]) + fabs(x[3][i] - x[0][i]); + num_buf[i] = ( x[3][i] - x[0][i] ) + ( x[3][i] - ( i > 0 ? x[3][i - 1] : x[3][i] ) ); + den_buf[i] = fabs( x[1][i] - x[2][i] ) + fabs( x[3][i] - x[0][i] ); } fp_t num_sum = 0; @@ -65,14 +65,14 @@ int ts_ravi( fp_t sig_a = 1.0 / k2; uint_t offset = k + (uint_t)k2 - 2; - for (uint_t i = 0; i < offset; ++i) { y[0][i] = 0; y[1][i] = 0; } + for ( uint_t i = 0; i < offset; ++i ) { y[0][i] = 0; y[1][i] = 0; } for( uint_t i = k; i < n; ++i ) { num_sum = num_sum - num_buf[i - k] + num_buf[i]; den_sum = den_sum - den_buf[i - k] + den_buf[i]; rvi = ( den_sum != 0 ) ? num_sum / den_sum : 0; - sig = sig + sig_a * (rvi - sig); + sig = sig + sig_a * ( rvi - sig ); if( i >= offset ) { diff --git a/lib/regression_linear_least_squares.c b/lib/regression_linear_least_squares.c index 49123bb..5e37e38 100755 --- a/lib/regression_linear_least_squares.c +++ b/lib/regression_linear_least_squares.c @@ -34,7 +34,7 @@ ts_parameter_t const ts_regression_linear_least_squares_p = { .n_inputs = 2, .n_ uint_t ts_regression_linear_least_squares_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_regression_linear_least_squares_params_t *)c)->k : 0 ); + return ( c ? ((ts_regression_linear_least_squares_params_t const *)c)->k : 0 ); } int ts_regression_linear_least_squares( @@ -45,7 +45,7 @@ int ts_regression_linear_least_squares( { TS_PROLOGUE( ts_regression_linear_least_squares_p ); if ( !c ) return -1; - uint_t k = ((ts_regression_linear_least_squares_params_t *)c)->k; + uint_t k = ((ts_regression_linear_least_squares_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = k; diff --git a/lib/relative_volatility.c b/lib/relative_volatility.c index 9682a2d..77b6968 100644 --- a/lib/relative_volatility.c +++ b/lib/relative_volatility.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_relative_volatility_p = { .n_inputs = 1, .n_outputs = 1, uint_t ts_relative_volatility_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_relative_volatility_params_t *)c)->k - 1 : 0 ); + return ( c ? ((ts_relative_volatility_params_t const *)c)->k - 1 : 0 ); } int ts_relative_volatility( @@ -34,7 +34,7 @@ int ts_relative_volatility( { TS_PROLOGUE( ts_relative_volatility_p ); if ( !c ) return -1; - uint_t k = ((ts_relative_volatility_params_t *)c)->k; + uint_t k = ((ts_relative_volatility_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; @@ -22,7 +22,7 @@ ts_parameter_t const ts_roc_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_roc_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_roc_params_t *)c)->k : 0 ); + return ( c ? ((ts_roc_params_t const *)c)->k : 0 ); } int ts_roc( @@ -34,7 +34,7 @@ int ts_roc( TS_PROLOGUE( ts_roc_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_roc_params_t *)c)->k; + uint_t k = ((ts_roc_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k; i < n; ++i ) @@ -22,7 +22,7 @@ ts_parameter_t const ts_rocp_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_rocp_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_rocp_params_t *)c)->k : 0 ); + return ( c ? ((ts_rocp_params_t const *)c)->k : 0 ); } int ts_rocp( @@ -33,7 +33,7 @@ int ts_rocp( { TS_PROLOGUE( ts_rocp_p ); if ( !c ) return -1; - uint_t k = ((ts_rocp_params_t *)c)->k; + uint_t k = ((ts_rocp_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k; i < n; ++i ) @@ -22,7 +22,7 @@ ts_parameter_t const ts_rocr_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_rocr_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_rocr_params_t *)c)->k : 0 ); + return ( c ? ((ts_rocr_params_t const *)c)->k : 0 ); } int ts_rocr( @@ -33,7 +33,7 @@ int ts_rocr( { TS_PROLOGUE( ts_rocr_p ); if ( !c ) return -1; - uint_t k = ((ts_rocr_params_t *)c)->k; + uint_t k = ((ts_rocr_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k; i < n; ++i ) diff --git a/lib/rocr100.c b/lib/rocr100.c index b90413f..22b6dbf 100644 --- a/lib/rocr100.c +++ b/lib/rocr100.c @@ -21,7 +21,7 @@ ts_parameter_t const ts_rocr100_p = { .n_inputs = 1, .n_outputs = 1, .n_constant uint_t ts_rocr100_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_rocr100_params_t *)c)->k : 0 ); + return ( c ? ((ts_rocr100_params_t const *)c)->k : 0 ); } int ts_rocr100( @@ -32,7 +32,7 @@ int ts_rocr100( { TS_PROLOGUE( ts_rocr100_p ); if ( !c ) return -1; - uint_t k = ((ts_rocr100_params_t *)c)->k; + uint_t k = ((ts_rocr100_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k; i < n; ++i ) @@ -36,7 +36,7 @@ int ts_root( { TS_PROLOGUE( ts_root_p ); if ( !c ) return -1; - fp_t r = ((ts_root_params_t *)c)->r; + fp_t r = ((ts_root_params_t const *)c)->r; if (r == 0) return -1; for( uint_t i = 0; i < n; ++i ) @@ -25,7 +25,7 @@ ts_parameter_t const ts_rsi_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = uint_t ts_rsi_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_rsi_params_t *)c)->k : 0 ); + return ( c ? ((ts_rsi_params_t const *)c)->k : 0 ); } int ts_rsi( @@ -37,7 +37,7 @@ int ts_rsi( TS_PROLOGUE( ts_rsi_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_rsi_params_t *)c)->k; + uint_t k = ((ts_rsi_params_t const *)c)->k; if (k == 0 || n <= k) return -1; for (uint_t i = 0; i < k; ++i) y[0][i] = NAN; diff --git a/lib/schaff_trend_cycle.c b/lib/schaff_trend_cycle.c index f4584e6..0ff3e1c 100644 --- a/lib/schaff_trend_cycle.c +++ b/lib/schaff_trend_cycle.c @@ -35,9 +35,8 @@ int ts_schaff_trend_cycle( { TS_PROLOGUE( ts_schaff_trend_cycle_p ); if ( !c ) return -1; - uint_t period = ((ts_schaff_trend_cycle_params_t *)c)->period; + uint_t period = ((ts_schaff_trend_cycle_params_t const *)c)->period; if (period == 0) period = 3; - if (n == 0) return -1; if (period > n) { for (uint_t j = 0; j < n; ++j) { y[0][j] = 0; y[1][j] = 0; } return 0; } uint_t fast = 10; diff --git a/lib/shinohara_intensity_ratio.c b/lib/shinohara_intensity_ratio.c index fcdd364..5476892 100644 --- a/lib/shinohara_intensity_ratio.c +++ b/lib/shinohara_intensity_ratio.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_shinohara_intensity_ratio_p = { .n_inputs = 4, .n_output uint_t ts_shinohara_intensity_ratio_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_shinohara_intensity_ratio_params_t *)c)->k > 0 ? ((ts_shinohara_intensity_ratio_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_shinohara_intensity_ratio_params_t const *)c)->k > 0 ? ((ts_shinohara_intensity_ratio_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_shinohara_intensity_ratio( @@ -35,7 +35,7 @@ int ts_shinohara_intensity_ratio( { TS_PROLOGUE( ts_shinohara_intensity_ratio_p ); if ( !c ) return -1; - uint_t k = ((ts_shinohara_intensity_ratio_params_t *)c)->k; + uint_t k = ((ts_shinohara_intensity_ratio_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t *intensity = calloc( n, sizeof( fp_t ) ); diff --git a/lib/sigmoid.c b/lib/sigmoid.c index 05ea126..33fd58b 100644 --- a/lib/sigmoid.c +++ b/lib/sigmoid.c @@ -44,10 +44,11 @@ int ts_sigmoid( { TS_PROLOGUE( ts_sigmoid_p ); if ( !c ) return -1; - fp_t m = ((ts_sigmoid_params_t *)c)->m; - fp_t L = ((ts_sigmoid_params_t *)c)->L; - fp_t b = ((ts_sigmoid_params_t *)c)->b; + fp_t m = ((ts_sigmoid_params_t const *)c)->m; + fp_t L = ((ts_sigmoid_params_t const *)c)->L; + fp_t b = ((ts_sigmoid_params_t const *)c)->b; + if (L == 0 || isnan(L) || isinf(L) || isnan(m) || isinf(m)) return -1; m = -( 4.0 * m ) / L; b = b - ( 0.5 * L ); diff --git a/lib/slope.c b/lib/slope.c index ca4fd22..5005fff 100755 --- a/lib/slope.c +++ b/lib/slope.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_slope_p = { .n_inputs = 1, .n_outputs = 1, .n_constants uint_t ts_slope_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_slope_params_t *)c)->k : 0 ); + return ( c ? ((ts_slope_params_t const *)c)->k : 0 ); } int ts_slope( @@ -35,7 +35,7 @@ int ts_slope( { TS_PROLOGUE( ts_slope_p ); if ( !c ) return -1; - uint_t k = ((ts_slope_params_t *)c)->k; + uint_t k = ((ts_slope_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = k; diff --git a/lib/softplus.c b/lib/softplus.c index b61f96b..6853f66 100644 --- a/lib/softplus.c +++ b/lib/softplus.c @@ -34,7 +34,12 @@ int ts_softplus( for( uint_t i = 0; i < n; ++i ) { fp_t xi = x[0][i]; - y[0][i] = xi > 20 ? xi : log( 1 + exp( xi ) ); + if ( xi > 20 ) + y[0][i] = xi; + else if ( xi < -37 ) + y[0][i] = exp( xi ); + else + y[0][i] = log( 1 + exp( xi ) ); } return 0; } diff --git a/lib/standard_error.c b/lib/standard_error.c index 9b0ac3b..e090deb 100644 --- a/lib/standard_error.c +++ b/lib/standard_error.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_standard_error_p = { .n_inputs = 1, .n_outputs = 1, .n_c uint_t ts_standard_error_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_standard_error_params_t *)c)->k > 0 ? ((ts_standard_error_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_standard_error_params_t const *)c)->k > 0 ? ((ts_standard_error_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_standard_error( @@ -34,7 +34,7 @@ int ts_standard_error( { TS_PROLOGUE( ts_standard_error_p ); if ( !c ) return -1; - uint_t k = ((ts_standard_error_params_t *)c)->k; + uint_t k = ((ts_standard_error_params_t const *)c)->k; if (k < 2) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/starc_bands.c b/lib/starc_bands.c index 0c545f8..4975952 100644 --- a/lib/starc_bands.c +++ b/lib/starc_bands.c @@ -26,7 +26,7 @@ ts_parameter_t const ts_starc_bands_p = { .n_inputs = 4, .n_outputs = 3, .n_cons uint_t ts_starc_bands_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_starc_bands_params_t *)c)->k : 0 ); + return ( c ? ((ts_starc_bands_params_t const *)c)->k : 0 ); } int ts_starc_bands( @@ -37,11 +37,20 @@ int ts_starc_bands( { TS_PROLOGUE( ts_starc_bands_p ); if ( !c ) return -1; - uint_t k = ((ts_starc_bands_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_starc_bands_params_t const *)c)->k; if (k == 0) return -1; if (n < k + 1) return -1; - fp_t mult = ((ts_starc_bands_params_t *)c)->mult; + fp_t mult = ((ts_starc_bands_params_t const *)c)->mult; + if (mult < 0 || isnan(mult) || isinf(mult)) return -1; + + for( uint_t i = 0; i < k; ++i ) + { + y[0][i] = NAN; + y[1][i] = NAN; + y[2][i] = NAN; + } for( uint_t i = k; i < n; ++i ) { diff --git a/lib/starc_lower.c b/lib/starc_lower.c index 97ac02f..16c5084 100644 --- a/lib/starc_lower.c +++ b/lib/starc_lower.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_starc_lower_p = { .n_inputs = 4, .n_outputs = 1, .n_cons uint_t ts_starc_lower_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_starc_lower_params_t *)c)->k > 0 ? ((ts_starc_lower_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_starc_lower_params_t const *)c)->k > 0 ? ((ts_starc_lower_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_starc_lower( @@ -35,9 +35,11 @@ int ts_starc_lower( { TS_PROLOGUE( ts_starc_lower_p ); if ( !c ) return -1; - uint_t k = ((ts_starc_lower_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_starc_lower_params_t const *)c)->k; if( k == 0 ) return -1; - fp_t mult = ((ts_starc_lower_params_t *)c)->mult; + fp_t mult = ((ts_starc_lower_params_t const *)c)->mult; + if (mult < 0 || isnan(mult) || isinf(mult)) return -1; uint_t half_k = k / 2; if (n <= half_k) return -1; diff --git a/lib/starc_upper.c b/lib/starc_upper.c index bcccb95..ad80b07 100644 --- a/lib/starc_upper.c +++ b/lib/starc_upper.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_starc_upper_p = { .n_inputs = 4, .n_outputs = 1, .n_cons uint_t ts_starc_upper_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_starc_upper_params_t *)c)->k : 0 ); + return ( c ? ((ts_starc_upper_params_t const *)c)->k : 0 ); } int ts_starc_upper( @@ -35,8 +35,8 @@ int ts_starc_upper( { TS_PROLOGUE( ts_starc_upper_p ); if ( !c ) return -1; - uint_t k = ((ts_starc_upper_params_t *)c)->k; - fp_t mult = ((ts_starc_upper_params_t *)c)->mult; + uint_t k = ((ts_starc_upper_params_t const *)c)->k; + fp_t mult = ((ts_starc_upper_params_t const *)c)->mult; if ( k == 0 || k >= n ) return -1; for ( uint_t i = k; i < n; ++i ) diff --git a/lib/std_error.c b/lib/std_error.c index f55d34e..ebcab35 100644 --- a/lib/std_error.c +++ b/lib/std_error.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_std_error_p = { .n_inputs = 1, .n_outputs = 1, .n_consta uint_t ts_std_error_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_std_error_params_t *)c)->k > 0 ? ((ts_std_error_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_std_error_params_t const *)c)->k > 0 ? ((ts_std_error_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_std_error( @@ -34,7 +34,7 @@ int ts_std_error( { TS_PROLOGUE( ts_std_error_p ); if ( !c ) return -1; - uint_t k = ((ts_std_error_params_t *)c)->k; + uint_t k = ((ts_std_error_params_t const *)c)->k; if ( k == 0 ) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/stoch_rsi.c b/lib/stoch_rsi.c index 81992a6..97427be 100644 --- a/lib/stoch_rsi.c +++ b/lib/stoch_rsi.c @@ -25,7 +25,7 @@ ts_parameter_t const ts_stoch_rsi_p = { .n_inputs = 1, .n_outputs = 2, .n_consta uint_t ts_stoch_rsi_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_stoch_rsi_params_t *)c)->rsi_period + ((ts_stoch_rsi_params_t *)c)->stoch_period - 1 : 0 ); + return ( c ? ((ts_stoch_rsi_params_t const *)c)->rsi_period + ((ts_stoch_rsi_params_t const *)c)->stoch_period - 1 : 0 ); } int ts_stoch_rsi( @@ -36,8 +36,8 @@ int ts_stoch_rsi( { TS_PROLOGUE( ts_stoch_rsi_p ); if ( !c ) return -1; - uint_t rsi_period = ((ts_stoch_rsi_params_t *)c)->rsi_period; - uint_t stoch_period = ((ts_stoch_rsi_params_t *)c)->stoch_period; + uint_t rsi_period = ((ts_stoch_rsi_params_t const *)c)->rsi_period; + uint_t stoch_period = ((ts_stoch_rsi_params_t const *)c)->stoch_period; if (rsi_period == 0 || stoch_period == 0) return -1; fp_t *rsi_values = NULL; diff --git a/lib/stochastic_fast.c b/lib/stochastic_fast.c index eb203c8..d9340ad 100644 --- a/lib/stochastic_fast.c +++ b/lib/stochastic_fast.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_stochastic_fast_p = { .n_inputs = 4, .n_outputs = 2, .n_ uint_t ts_stochastic_fast_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_stochastic_fast_params_t *)c)->k > 0 ? 2 * ((ts_stochastic_fast_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_stochastic_fast_params_t const *)c)->k > 0 ? 2 * ((ts_stochastic_fast_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_stochastic_fast( @@ -34,7 +34,7 @@ int ts_stochastic_fast( TS_PROLOGUE( ts_stochastic_fast_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_stochastic_fast_params_t *)c)->k; + uint_t k = ((ts_stochastic_fast_params_t const *)c)->k; if (k == 0 || n < k) return -1; // Initial window max/min diff --git a/lib/stochastic_momentum_index.c b/lib/stochastic_momentum_index.c index 5491c30..35af230 100644 --- a/lib/stochastic_momentum_index.c +++ b/lib/stochastic_momentum_index.c @@ -26,7 +26,7 @@ ts_parameter_t const ts_stochastic_momentum_index_p = { .n_inputs = 4, .n_output 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 ); + return ( c ? ((ts_stochastic_momentum_index_params_t const *)c)->k1 + ((ts_stochastic_momentum_index_params_t const *)c)->k2 : 0 ); } int ts_stochastic_momentum_index( @@ -37,9 +37,9 @@ int ts_stochastic_momentum_index( { 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; + uint_t k1 = ((ts_stochastic_momentum_index_params_t const *)c)->k1; + uint_t k2 = ((ts_stochastic_momentum_index_params_t const *)c)->k2; + uint_t signal_period = ((ts_stochastic_momentum_index_params_t const *)c)->signal_period; if (k1 == 0 || k2 == 0) return -1; fp_t *midpoint = calloc(n, sizeof(fp_t)); diff --git a/lib/stochastic_slow.c b/lib/stochastic_slow.c index 0f84e1a..35f8b47 100644 --- a/lib/stochastic_slow.c +++ b/lib/stochastic_slow.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_stochastic_slow_p = { .n_inputs = 4, .n_outputs = 2, .n_ uint_t ts_stochastic_slow_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_stochastic_slow_params_t *)c)->k > 0 ? 3 * ((ts_stochastic_slow_params_t *)c)->k - 3 : 0 : 0 ); + return ( c ? ((ts_stochastic_slow_params_t const *)c)->k > 0 ? 3 * ((ts_stochastic_slow_params_t const *)c)->k - 3 : 0 : 0 ); } int ts_stochastic_slow( @@ -35,7 +35,7 @@ int ts_stochastic_slow( TS_PROLOGUE( ts_stochastic_slow_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_stochastic_slow_params_t *)c)->k; + uint_t k = ((ts_stochastic_slow_params_t const *)c)->k; if (k == 0) return -1; fp_t *fast_k = calloc( k, sizeof( fp_t ) ); diff --git a/lib/student_t_pdf.c b/lib/student_t_pdf.c index 67c9f1d..ad8f256 100644 --- a/lib/student_t_pdf.c +++ b/lib/student_t_pdf.c @@ -34,7 +34,7 @@ int ts_student_t_pdf( { TS_PROLOGUE( ts_student_t_pdf_p ); if ( !c ) return -1; - fp_t nu = ((ts_student_t_pdf_params_t *)c)->nu; + fp_t nu = ((ts_student_t_pdf_params_t const *)c)->nu; if ( nu <= 0 ) { for( uint_t i = 0; i < n; ++i ) y[0][i] = 0; diff --git a/lib/summation.c b/lib/summation.c index 6d0020b..01d6735 100755 --- a/lib/summation.c +++ b/lib/summation.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_summation_p = { .n_inputs = 1, .n_outputs = 1, .n_consta uint_t ts_summation_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_summation_params_t *)c)->k > 0 ? ((ts_summation_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_summation_params_t const *)c)->k > 0 ? ((ts_summation_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_summation( @@ -35,7 +35,7 @@ int ts_summation( { TS_PROLOGUE( ts_summation_p ); if ( !c ) return -1; - uint_t k = ((ts_summation_params_t *)c)->k; + uint_t k = ((ts_summation_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; diff --git a/lib/supertrend.c b/lib/supertrend.c index 4487e96..c062805 100644 --- a/lib/supertrend.c +++ b/lib/supertrend.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_supertrend_p = { .n_inputs = 4, .n_outputs = 2, .n_const uint_t ts_supertrend_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_supertrend_params_t *)c)->k : 0 ); + return ( c ? ((ts_supertrend_params_t const *)c)->k : 0 ); } int ts_supertrend( @@ -36,8 +36,8 @@ int ts_supertrend( 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; + uint_t k = ((ts_supertrend_params_t const *)c)->k; + fp_t mult = ((ts_supertrend_params_t const *)c)->mult; if (k == 0 || n <= k) return -1; fp_t tr = ts_h( x, 1 ) - ts_l( x, 1 ); diff --git a/lib/swish.c b/lib/swish.c index 7d09787..ae0105f 100644 --- a/lib/swish.c +++ b/lib/swish.c @@ -34,7 +34,12 @@ int ts_swish( for( uint_t i = 0; i < n; ++i ) { fp_t xi = x[0][i]; - y[0][i] = xi / ( 1 + exp( -xi ) ); + if ( xi > 20 ) + y[0][i] = xi; + else if ( xi < -20 ) + y[0][i] = xi * exp( xi ); + else + y[0][i] = xi / ( 1 + exp( -xi ) ); } return 0; } diff --git a/lib/synthetic_yield.c b/lib/synthetic_yield.c index c2c8d62..fecde51 100644 --- a/lib/synthetic_yield.c +++ b/lib/synthetic_yield.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_synthetic_yield_p = { .n_inputs = 1, .n_outputs = 1, .n_ uint_t ts_synthetic_yield_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_synthetic_yield_params_t *)c)->k : 0 ); + return ( c ? ((ts_synthetic_yield_params_t const *)c)->k : 0 ); } int ts_synthetic_yield( @@ -34,9 +34,10 @@ int ts_synthetic_yield( { TS_PROLOGUE( ts_synthetic_yield_p ); if ( !c ) return -1; - uint_t k = ((ts_synthetic_yield_params_t *)c)->k; + uint_t k = ((ts_synthetic_yield_params_t const *)c)->k; if (k == 0 || n < k) return -1; + for( uint_t i = 0; i < k; ++i ) y[0][i] = 0; for( uint_t i = k; i < n; ++i ) { if( x[0][i - k] == 0 ) { y[0][i] = 0; continue; } @@ -29,7 +29,6 @@ int ts_t3( { TS_PROLOGUE( ts_t3_p ); (void)c; - if (n == 0) return -1; uint_t k = 5; @@ -33,42 +33,55 @@ void ts_test_all( void ) } bool ts_test( - void ( *ts_function )( - fp_t * const *y, - fp_t const * const *x, - uint_t n, - ts_constant_t const *c + int ( *ts_function )( + 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 ), - uint_t ( *ts_offset )( - ts_constant_t const *c + uint_t ( *ts_offset )( + ts_constant_t const *c ), fp_t const * const *x, fp_t const * const *e, uint_t n, ts_constant_t const *c, ts_parameter_t const *m ) -{ +{ + if ( !ts_function || !ts_offset || !m || !e || !x ) return false; + uint_t offset = ts_offset( c ); - uint_t y_n = n - offset; + if ( offset >= n ) return false; + uint_t y_len = n - offset; bool result = true; - - fp_t *y[m->y]; - for( uint_t i = 0; i < m->y; i++ ) + fp_t *y[m->n_outputs]; + + for( uint_t i = 0; i < m->n_outputs; i++ ) { - fp_t *tmp = malloc( y_n * sizeof( fp_t ) ); + fp_t *tmp = calloc( y_len, sizeof( fp_t ) ); + if ( !tmp ) + { + for ( uint_t j = 0; j < i; j++ ) free( y[j] ); + return false; + } y[i] = tmp; } - ts_function( y, x, n, c ); + if ( ts_function( y, m->n_outputs, x, m->n_inputs, n, c ) != 0 ) + { + for ( uint_t i = 0; i < m->n_outputs; i++ ) free( y[i] ); + return false; + } - for( uint_t i = 0; i < m->y; ++i ) + for( uint_t i = 0; i < m->n_outputs; ++i ) { - for( uint_t j = 0; j < y_n; ++j ) + for( uint_t j = 0; j < y_len; ++j ) { - // _ts_assert_approximate( y[i][j], e[i][j], TS_TEST_EPSILON ); - result &= _ts_is_approximate( y[i][j], e[i][j], TS_TEST_EPSILON ); - } + result &= _ts_is_approximate( y[i][j], e[i][j], TS_TEST_EPSILON ); + } free( y[i] ); } diff --git a/lib/trade_volume_index.c b/lib/trade_volume_index.c index 2e1b50d..a123379 100644 --- a/lib/trade_volume_index.c +++ b/lib/trade_volume_index.c @@ -24,20 +24,20 @@ uint_t ts_trade_volume_index_offset( ts_constant_t const *c ) } int ts_trade_volume_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_trade_volume_index_p ); - (void)c; + 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_trade_volume_index_p ); + (void)c; if (n < 2) return -1; for( uint_t i = 0; i + 1 < n; ++i ) - { - fp_t roc = x[3][i] != 0 ? ( x[3][i + 1] - x[3][i] ) / x[3][i] : 0; - y[0][i] = ( i == 0 ? 0 : y[0][i - 1] ) + roc * x[4][i + 1]; - } - y[0][n - 1] = y[0][n - 2]; - return 0; + { + fp_t roc = x[3][i] != 0 ? ( x[3][i + 1] - x[3][i] ) / x[3][i] : 0; + y[0][i] = ( i == 0 ? 0 : y[0][i - 1] ) + roc * x[4][i + 1]; } + y[0][n - 1] = y[0][n - 2]; + return 0; +} diff --git a/lib/trend_intensity_index.c b/lib/trend_intensity_index.c index 451e440..2f8a628 100644 --- a/lib/trend_intensity_index.c +++ b/lib/trend_intensity_index.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_trend_intensity_index_p = { .n_inputs = 5, .n_outputs = uint_t ts_trend_intensity_index_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_trend_intensity_index_params_t *)c)->k > 0 ? ((ts_trend_intensity_index_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_trend_intensity_index_params_t const *)c)->k > 0 ? ((ts_trend_intensity_index_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_trend_intensity_index( @@ -33,7 +33,7 @@ int ts_trend_intensity_index( { TS_PROLOGUE( ts_trend_intensity_index_p ); if ( !c ) return -1; - uint_t k = ((ts_trend_intensity_index_params_t *)c)->k; + uint_t k = ((ts_trend_intensity_index_params_t const *)c)->k; if ( k == 0 || n < k ) return -1; fp_t signed_sum = 0; @@ -31,9 +31,8 @@ int ts_trix( { TS_PROLOGUE( ts_trix_p ); if ( !c ) return -1; - if (n == 0) return -1; - fp_t a = ((ts_trix_params_t *)c)->a; + fp_t a = ((ts_trix_params_t const *)c)->a; if (a == 0) return -1; fp_t ema1 = x[0][0]; @@ -7,18 +7,19 @@ fp_t * ts_fill( fp_t *x, uint_t n, fp_t x0, fp_t x1 ) { - fp_t step = ( x1 - x0 ) / ( n - 1 ); + if ( !x || n == 0 ) return x; - if( x0 == 0.0 && x1 == 0.0 ) + fp_t step = n > 1 ? ( x1 - x0 ) / ( fp_t )( n - 1 ) : 0.0; + + if( fabs( x0 ) < TS_FILL_ZERO_THRESHOLD && fabs( x1 ) < TS_FILL_ZERO_THRESHOLD ) { - memset(x, 0, sizeof( fp_t ) * n ); + memset( x, 0, sizeof( fp_t ) * n ); } - else { for( uint_t i = 0; i < n; i++ ) { - x[i] = x0 + ( i * step ); + x[i] = x0 + ( (fp_t)i * step ); } } @@ -26,42 +27,48 @@ fp_t * ts_fill( fp_t *x, uint_t n, fp_t x0, fp_t x1 ) } -void ts_print( fp_t *x, uint_t n ) +void ts_print( fp_t const *x, uint_t n, FILE *stream ) { - fputc('[', stdout); + if ( !x || n == 0 ) return; + + FILE *out = stream ? stream : stdout; - uint_t i; - for( i = 0; i < n - 1; i++ ) - { - fprintf(stdout, "%f,", x[i]); - } + fputc( '[', out ); + + for ( uint_t i = 0; i < n - 1; i++ ) + { + fprintf( out, "%f,", x[i] ); + } - fprintf(stdout, "%f]", x[i]); + fprintf( out, "%f]", x[n - 1] ); } -void ts_pretty_print( fp_t const * const *x, uint_t m, uint_t n ) +void ts_pretty_print( fp_t const * const *x, uint_t m, uint_t n, FILE *stream ) { - if( m > 1 ) - { - for( uint_t i = 0; i < n; i++ ) - { - uint_t j = 0; - for( ; j < m; j++ ) - { - fprintf( stdout, "%f ", x[i][j] ); - } + if ( !x || m == 0 || n == 0 ) return; - fputs( "\n", stdout ); - } - } - else - { - for( uint_t i = 0; i < n; i++ ) - { - fprintf( stdout, "%f\n", x[0][i] ); - } - } + FILE *out = stream ? stream : stdout; + + if( m > 1 ) + { + for( uint_t i = 0; i < n; i++ ) + { + for( uint_t j = 0; j < m; j++ ) + { + fprintf( out, "%f ", x[j][i] ); + } + + fputs( "\n", out ); + } + } + else + { + for( uint_t i = 0; i < n; i++ ) + { + fprintf( out, "%f\n", x[0][i] ); + } + } } @@ -91,29 +98,19 @@ fp_t _ts_triangle_number( fp_t x ) fp_t _ts_sum_to_covariance( fp_t sum_xy, fp_t sum_x, fp_t sum_y, uint_t k ) { + if ( k == 0 ) return 0.0; return ( sum_xy - ( sum_x * sum_y / k ) ) / k; } fp_t _ts_sum_to_variance( fp_t sum_x2, fp_t sum_x, uint_t k ) { - return _ts_sum_to_covariance( sum_x2, sum_x, sum_x, k ); + return fmax( 0.0, _ts_sum_to_covariance( sum_x2, sum_x, sum_x, k ) ); } uint_t _ts_circle_increment( uint_t i, uint_t k ) { + if ( k == 0 ) return i; return ( i + 1 ) % k; -} - - -// ts_constant_t * ts_constant_init( uint_t n, ... ) -// { -// va_list args; -// va_start( args, n ); - -// for( uint_t i = 0; i < n; i++ ) -// { - -// } -// }
\ No newline at end of file +}
\ No newline at end of file diff --git a/lib/ulcer_index.c b/lib/ulcer_index.c index ca70734..1063880 100644 --- a/lib/ulcer_index.c +++ b/lib/ulcer_index.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_ulcer_index_p = { .n_inputs = 1, .n_outputs = 1, .n_cons uint_t ts_ulcer_index_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_ulcer_index_params_t *)c)->k > 0 ? ((ts_ulcer_index_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_ulcer_index_params_t const *)c)->k > 0 ? ((ts_ulcer_index_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_ulcer_index( @@ -35,8 +35,8 @@ int ts_ulcer_index( { TS_PROLOGUE( ts_ulcer_index_p ); if ( !c ) return -1; - uint_t k = ((ts_ulcer_index_params_t *)c)->k; - if (k == 0 || n < k) return -1; + uint_t k = ((ts_ulcer_index_params_t const *)c)->k; + if (k == 0) return -1; /* Precompute cumulative highest-high for each index: O(n) */ fp_t *cum_hhv = calloc( n, sizeof( fp_t ) ); @@ -50,13 +50,13 @@ int ts_ulcer_index( } } - for( uint_t i = k - 1; i < n; ++i ) + for( uint_t i = k - 1; i < n; ++i ) { fp_t hhv = x[0][i - k + 1]; for( uint_t j = 1; j < k; ++j ) { fp_t v = x[0][i - k + 1 + j]; - if (v > hhv) hhv = v; + if ( v > hhv ) hhv = v; } fp_t d_sq_sum = 0; diff --git a/lib/valuation_lines.c b/lib/valuation_lines.c index b56a871..cba9b2e 100644 --- a/lib/valuation_lines.c +++ b/lib/valuation_lines.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_valuation_lines_p = { .n_inputs = 4, .n_outputs = 2, .n_ uint_t ts_valuation_lines_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_valuation_lines_params_t *)c)->k > 0 ? ((ts_valuation_lines_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_valuation_lines_params_t const *)c)->k > 0 ? ((ts_valuation_lines_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_valuation_lines( @@ -34,7 +34,7 @@ int ts_valuation_lines( { TS_PROLOGUE( ts_valuation_lines_p ); if ( !c ) return -1; - uint_t k = ((ts_valuation_lines_params_t *)c)->k; + uint_t k = ((ts_valuation_lines_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k - 1; i < n; ++i ) diff --git a/lib/variable_index_dynamic_average.c b/lib/variable_index_dynamic_average.c index 5f4ae4f..0e78d13 100644 --- a/lib/variable_index_dynamic_average.c +++ b/lib/variable_index_dynamic_average.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_variable_index_dynamic_average_p = { .n_inputs = 1, .n_o uint_t ts_variable_index_dynamic_average_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_variable_index_dynamic_average_params_t *)c)->period : 0 ); + return ( c ? ((ts_variable_index_dynamic_average_params_t const *)c)->period : 0 ); } int ts_variable_index_dynamic_average( @@ -34,7 +34,7 @@ int ts_variable_index_dynamic_average( { TS_PROLOGUE( ts_variable_index_dynamic_average_p ); if ( !c ) return -1; - uint_t period = ((ts_variable_index_dynamic_average_params_t *)c)->period; + uint_t period = ((ts_variable_index_dynamic_average_params_t const *)c)->period; if (period < 2 || n <= period) return -1; fp_t vidya = x[0][period]; diff --git a/lib/variance.c b/lib/variance.c index f307198..e288233 100755 --- a/lib/variance.c +++ b/lib/variance.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_variance_p = { .n_inputs = 1, .n_outputs = 1, .n_constan uint_t ts_variance_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_variance_params_t *)c)->k > 0 ? ((ts_variance_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_variance_params_t const *)c)->k > 0 ? ((ts_variance_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_variance( @@ -34,7 +34,7 @@ int ts_variance( TS_PROLOGUE( ts_variance_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_variance_params_t *)c)->k; + uint_t k = ((ts_variance_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t xi = 0; diff --git a/lib/variance_exponential.c b/lib/variance_exponential.c index 338a140..0700aee 100755 --- a/lib/variance_exponential.c +++ b/lib/variance_exponential.c @@ -30,9 +30,8 @@ int ts_variance_exponential( { TS_PROLOGUE( ts_variance_exponential_p ); if ( !c ) return -1; - if (n == 0) return -1; - fp_t a = ((ts_variance_exponential_params_t *)c)->a; + fp_t a = ((ts_variance_exponential_params_t const *)c)->a; if (a == 0) return -1; y[0][0] = 0; diff --git a/lib/vertical_horizontal_filter.c b/lib/vertical_horizontal_filter.c index f5c91cf..e032dbd 100644 --- a/lib/vertical_horizontal_filter.c +++ b/lib/vertical_horizontal_filter.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_vertical_horizontal_filter_p = { .n_inputs = 4, .n_outpu uint_t ts_vertical_horizontal_filter_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_vertical_horizontal_filter_params_t *)c)->k : 0 ); + return ( c ? ((ts_vertical_horizontal_filter_params_t const *)c)->k : 0 ); } int ts_vertical_horizontal_filter( @@ -34,7 +34,7 @@ int ts_vertical_horizontal_filter( { TS_PROLOGUE( ts_vertical_horizontal_filter_p ); if ( !c ) return -1; - uint_t k = ((ts_vertical_horizontal_filter_params_t *)c)->k; + uint_t k = ((ts_vertical_horizontal_filter_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t cum_den = 0; diff --git a/lib/volatility_stop.c b/lib/volatility_stop.c index bfb207b..6055144 100644 --- a/lib/volatility_stop.c +++ b/lib/volatility_stop.c @@ -24,7 +24,7 @@ ts_parameter_t const ts_volatility_stop_p = { .n_inputs = 4, .n_outputs = 2, .n_ uint_t ts_volatility_stop_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_volatility_stop_params_t *)c)->k : 0 ); + return ( c ? ((ts_volatility_stop_params_t const *)c)->k : 0 ); } int ts_volatility_stop( @@ -35,9 +35,17 @@ int ts_volatility_stop( { TS_PROLOGUE( ts_volatility_stop_p ); if ( !c ) return -1; - uint_t k = ((ts_volatility_stop_params_t *)c)->k; - fp_t mult = ((ts_volatility_stop_params_t *)c)->mult; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_volatility_stop_params_t const *)c)->k; + fp_t mult = ((ts_volatility_stop_params_t const *)c)->mult; if (k == 0 || n < k) return -1; + if (mult < 0 || isnan(mult) || isinf(mult)) return -1; + + for( uint_t i = 0; i < k; ++i ) + { + y[0][i] = NAN; + y[1][i] = NAN; + } for( uint_t i = k; i < n; ++i ) { diff --git a/lib/volatility_system.c b/lib/volatility_system.c index dbb74d1..b8e0c33 100644 --- a/lib/volatility_system.c +++ b/lib/volatility_system.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_volatility_system_p = { .n_inputs = 4, .n_outputs = 1, . uint_t ts_volatility_system_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? 2 * ((ts_volatility_system_params_t *)c)->k : 0 ); + return ( c ? 2 * ((ts_volatility_system_params_t const *)c)->k : 0 ); } int ts_volatility_system( @@ -34,12 +34,16 @@ int ts_volatility_system( { TS_PROLOGUE( ts_volatility_system_p ); if ( !c ) return -1; - uint_t k = ((ts_volatility_system_params_t *)c)->k; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_volatility_system_params_t const *)c)->k; if (k == 0 || n < k) return -1; uint_t range_period = 2 * k; if (n < range_period) return -1; + for ( uint_t i = 0; i < range_period; ++i ) + y[0][i] = NAN; + fp_t ema = (ts_c(x, range_period - 2) + ts_c(x, range_period - 1)) / 2.0; for( uint_t i = range_period; i < n; ++i ) diff --git a/lib/volume_moving_average.c b/lib/volume_moving_average.c index 93eb592..33f263c 100644 --- a/lib/volume_moving_average.c +++ b/lib/volume_moving_average.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_volume_moving_average_p = { .n_inputs = 5, .n_outputs = uint_t ts_volume_moving_average_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_volume_moving_average_params_t *)c)->k > 0 ? ((ts_volume_moving_average_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_volume_moving_average_params_t const *)c)->k > 0 ? ((ts_volume_moving_average_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_volume_moving_average( @@ -33,7 +33,7 @@ int ts_volume_moving_average( { TS_PROLOGUE( ts_volume_moving_average_p ); if ( !c ) return -1; - uint_t k = ((ts_volume_moving_average_params_t *)c)->k; + uint_t k = ((ts_volume_moving_average_params_t const *)c)->k; if (k == 0 || n < k) return -1; for (uint_t i = k - 1; i < n; ++i) diff --git a/lib/volume_oscillator.c b/lib/volume_oscillator.c index 6aa59f0..37d34c4 100644 --- a/lib/volume_oscillator.c +++ b/lib/volume_oscillator.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_volume_oscillator_p = { .n_inputs = 1, .n_outputs = 1, . uint_t ts_volume_oscillator_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_volume_oscillator_params_t *)c)->slow_k > 0 ? (uint_t)(((ts_volume_oscillator_params_t *)c)->slow_k - 1) : 0 : 0 ); + return ( c ? ((ts_volume_oscillator_params_t const *)c)->slow_k > 0 ? (uint_t)(((ts_volume_oscillator_params_t const *)c)->slow_k - 1) : 0 : 0 ); } int ts_volume_oscillator( @@ -34,10 +34,9 @@ int ts_volume_oscillator( { TS_PROLOGUE( ts_volume_oscillator_p ); if ( !c ) return -1; - fp_t fast_k = ((ts_volume_oscillator_params_t *)c)->fast_k; - fp_t slow_k = ((ts_volume_oscillator_params_t *)c)->slow_k; + fp_t fast_k = ((ts_volume_oscillator_params_t const *)c)->fast_k; + fp_t slow_k = ((ts_volume_oscillator_params_t const *)c)->slow_k; if (fast_k == 0 || slow_k == 0) return -1; - if (n == 0) return -1; fp_t fast_a = 2.0 / (fast_k + 1); fp_t slow_a = 2.0 / (slow_k + 1); diff --git a/lib/volume_rate_of_change.c b/lib/volume_rate_of_change.c index ae9c776..b9d09c8 100644 --- a/lib/volume_rate_of_change.c +++ b/lib/volume_rate_of_change.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_volume_rate_of_change_p = { .n_inputs = 5, .n_outputs = uint_t ts_volume_rate_of_change_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_volume_rate_of_change_params_t *)c)->k : 0 ); + return ( c ? ((ts_volume_rate_of_change_params_t const *)c)->k : 0 ); } int ts_volume_rate_of_change( @@ -34,7 +34,7 @@ int ts_volume_rate_of_change( { TS_PROLOGUE( ts_volume_rate_of_change_p ); if ( !c ) return -1; - uint_t k = ((ts_volume_rate_of_change_params_t *)c)->k; + uint_t k = ((ts_volume_rate_of_change_params_t const *)c)->k; if (k == 0 || n < k) return -1; for (uint_t i = k; i < n; ++i) diff --git a/lib/volume_weighted_moving_average.c b/lib/volume_weighted_moving_average.c index d6cd6bd..a7dc781 100644 --- a/lib/volume_weighted_moving_average.c +++ b/lib/volume_weighted_moving_average.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_volume_weighted_moving_average_p = { .n_inputs = 5, .n_o uint_t ts_volume_weighted_moving_average_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_volume_weighted_moving_average_params_t *)c)->k > 0 ? ((ts_volume_weighted_moving_average_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_volume_weighted_moving_average_params_t const *)c)->k > 0 ? ((ts_volume_weighted_moving_average_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_volume_weighted_moving_average( @@ -33,7 +33,7 @@ int ts_volume_weighted_moving_average( { TS_PROLOGUE( ts_volume_weighted_moving_average_p ); if ( !c ) return -1; - uint_t k = ((ts_volume_weighted_moving_average_params_t *)c)->k; + uint_t k = ((ts_volume_weighted_moving_average_params_t const *)c)->k; if (k == 0 || n < k) return -1; fp_t cv_sum = 0; diff --git a/lib/vortex_indicator.c b/lib/vortex_indicator.c index 39ecfbc..6e80974 100644 --- a/lib/vortex_indicator.c +++ b/lib/vortex_indicator.c @@ -23,7 +23,7 @@ ts_parameter_t const ts_vortex_indicator_p = { .n_inputs = 4, .n_outputs = 2, .n uint_t ts_vortex_indicator_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_vortex_indicator_params_t *)c)->k : 0 ); + return ( c ? ((ts_vortex_indicator_params_t const *)c)->k : 0 ); } int ts_vortex_indicator( @@ -34,7 +34,7 @@ int ts_vortex_indicator( { TS_PROLOGUE( ts_vortex_indicator_p ); if ( !c ) return -1; - uint_t k = ((ts_vortex_indicator_params_t *)c)->k; + uint_t k = ((ts_vortex_indicator_params_t const *)c)->k; if (k == 0 || n < k) return -1; for( uint_t i = k; i < n; ++i ) diff --git a/lib/vwap_period.c b/lib/vwap_period.c index b8af2bd..58873ed 100644 --- a/lib/vwap_period.c +++ b/lib/vwap_period.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_vwap_period_p = { .n_inputs = 5, .n_outputs = 1, .n_cons uint_t ts_vwap_period_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_vwap_period_params_t *)c)->k > 0 ? ((ts_vwap_period_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_vwap_period_params_t const *)c)->k > 0 ? ((ts_vwap_period_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_vwap_period( @@ -33,7 +33,7 @@ int ts_vwap_period( { TS_PROLOGUE( ts_vwap_period_p ); if ( !c ) return -1; - uint_t k = ((ts_vwap_period_params_t *)c)->k; + uint_t k = ((ts_vwap_period_params_t const *)c)->k; if (k == 0 || n < k) return -1; /* Periodic VWAP: reset cumulative sums every k bars */ diff --git a/lib/weibull_pdf.c b/lib/weibull_pdf.c index 894c94a..ddfd77d 100644 --- a/lib/weibull_pdf.c +++ b/lib/weibull_pdf.c @@ -34,7 +34,7 @@ int ts_weibull_pdf( { TS_PROLOGUE( ts_weibull_pdf_p ); if ( !c ) return -1; - fp_t k = ((ts_weibull_pdf_params_t *)c)->k; + fp_t k = ((ts_weibull_pdf_params_t const *)c)->k; if (k <= 0.0 || isnan(k) || isinf(k)) return -1; for( uint_t i = 0; i < n; ++i ) { diff --git a/lib/wilders_smoothing.c b/lib/wilders_smoothing.c index 7aca8ad..f6a48b2 100644 --- a/lib/wilders_smoothing.c +++ b/lib/wilders_smoothing.c @@ -33,9 +33,8 @@ int ts_wilders_smoothing( { TS_PROLOGUE( ts_wilders_smoothing_p ); if ( !c ) return -1; - if (n == 0) return -1; - fp_t k = ((ts_wilders_smoothing_params_t *)c)->k; + fp_t k = ((ts_wilders_smoothing_params_t const *)c)->k; if (k == 0) return -1; fp_t a = 1.0 / k; diff --git a/lib/williams_r.c b/lib/williams_r.c index f0fae3f..f755284 100644 --- a/lib/williams_r.c +++ b/lib/williams_r.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_williams_r_p = { .n_inputs = 4, .n_outputs = 1, .n_const uint_t ts_williams_r_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_williams_r_params_t *)c)->k > 0 ? ((ts_williams_r_params_t *)c)->k - 1 : 0 : 0 ); + return ( c ? ((ts_williams_r_params_t const *)c)->k > 0 ? ((ts_williams_r_params_t const *)c)->k - 1 : 0 : 0 ); } int ts_williams_r( @@ -34,7 +34,7 @@ int ts_williams_r( TS_PROLOGUE( ts_williams_r_p ); if ( !c ) return -1; TS_CHECK_INPUT(x, x_n, n); - uint_t k = ((ts_williams_r_params_t *)c)->k; + uint_t k = ((ts_williams_r_params_t const *)c)->k; if (k == 0 || n < k) return -1; // Initial window max/min diff --git a/lib/zero_lag_ema.c b/lib/zero_lag_ema.c index c78adbd..a2b27d9 100644 --- a/lib/zero_lag_ema.c +++ b/lib/zero_lag_ema.c @@ -22,7 +22,7 @@ ts_parameter_t const ts_zero_lag_ema_p = { .n_inputs = 1, .n_outputs = 1, .n_con uint_t ts_zero_lag_ema_offset( ts_constant_t const *c ) { ( void )c; - return ( c ? ((ts_zero_lag_ema_params_t *)c)->k : 0 ); + return ( c ? ((ts_zero_lag_ema_params_t const *)c)->k : 0 ); } int ts_zero_lag_ema( @@ -33,7 +33,7 @@ int ts_zero_lag_ema( { TS_PROLOGUE( ts_zero_lag_ema_p ); if ( !c ) return -1; - uint_t k = ((ts_zero_lag_ema_params_t *)c)->k; + uint_t k = ((ts_zero_lag_ema_params_t const *)c)->k; if (k == 0 || n < k) return -1; /* Zero-lag EMA: compute lag, then apply EMA to (2*x - x_lag) */ diff --git a/lib/zigzag.c b/lib/zigzag.c index 50549e2..db4a5f2 100644 --- a/lib/zigzag.c +++ b/lib/zigzag.c @@ -35,9 +35,8 @@ int ts_zigzag( { TS_PROLOGUE( ts_zigzag_p ); if ( !c ) return -1; - if (n == 0) return -1; - fp_t threshold = ((ts_zigzag_params_t *)c)->threshold; + fp_t threshold = ((ts_zigzag_params_t const *)c)->threshold; if (threshold <= 0 || isnan(threshold) || isinf(threshold)) return -1; y[0][0] = x[0][0]; |