joshuaulrich / TTR

Technical analysis and other functions to construct technical trading rules with R
GNU General Public License v2.0
325 stars 102 forks source link

malloc(): invalid size (unsorted) #126

Closed veda93589 closed 1 year ago

veda93589 commented 1 year ago

Description

When run with the nsig = 139, nfast=4 and nslow = 216 the TTR breaks the R session

joshuaulrich commented 1 year ago

Can you please provide a reproducible example that I can run, and the output from sessionInfo()? I can't begin to investigate or try to fix this if I can't reproduce the problem.

veda93589 commented 1 year ago

-Sorry. I found the exact reason for this, when ALMA moving average is getting used the leading NA values are causing the R session to crash it does not happen with other moving averages. You can use the data i have provided with the parameters nsig = 139, nfast=4 and nslow = 216 and maType= ALMA

input.csv

joshuaulrich commented 1 year ago

Please provide the output from sessionInfo().

I also need the function call that crashes the R session. I tried to guess, but couldn't replicate the crash.

library(xts)
x <- as.xts(read.csv.zoo("input.csv", tz = "UTC"))
macd <- TTR::MACD(x$askPrice, nFast = 4, nSlow = 216, nSig = 139, maType = TTR::ALMA)
smi  <- TTR::SMI( x$askPrice, nFast = 4, nSlow = 216, nSig = 139, maType = TTR::ALMA)
veda93589 commented 1 year ago

This is the function and data (input.csv) that causes it crash

library(xts)

x <- read.csv('input.csv')
macd <- TTR::MACD(x$Close, nFast = 4, nSlow = 216, nSig = 139, maType = 'ALMA')

sessionInfo() Ouput

R version 4.2.3 (2023-03-15)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 22.04.2 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0

locale:
 [1] LC_CTYPE=en_IN.UTF-8       LC_NUMERIC=C               LC_TIME=en_IN.UTF-8        LC_COLLATE=en_IN.UTF-8     LC_MONETARY=en_IN.UTF-8   
 [6] LC_MESSAGES=en_IN.UTF-8    LC_PAPER=en_IN.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_IN.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] lattice_0.21-8   zoo_1.8-11       fansi_1.0.4      utf8_1.2.3       dplyr_1.1.0      grid_4.2.3       R6_2.5.1        
 [8] lifecycle_1.0.3  magrittr_2.0.3   httr_1.4.5       pillar_1.8.1     rlang_1.1.0      cli_3.6.0        influxdbr_0.14.2
[15] rstudioapi_0.14  xts_0.13.0       vctrs_0.6.2      generics_0.1.3   tools_4.2.3      glue_1.6.2       purrr_1.0.1     
[22] compiler_4.2.3   pkgconfig_2.0.3  pbdZMQ_0.3-9     tidyselect_1.2.0 tibble_3.1.8    
veda93589 commented 1 year ago

Also is there any limits on what can be passed in as the parameters for the MACD indicator

joshuaulrich commented 1 year ago

Thanks for the reproducible example. I'm able to replicate the crash now. This is happening in the wma C function.

set.seed(21)
x <- c(rep(NA, 215), rnorm(78))
wts <- abs(rnorm(139))
wma <- TTR::WMA(x, 139, wts)

# may need to force garbage collection to crash
gc()

valgrind output:

==448820== Invalid write of size 8
==448820==    at 0x12762BD7: wma (moving_averages.c:247)
==448820==    by 0x495629D: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x495684C: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x4993254: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49ADCEF: Rf_eval (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49AFD85: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49B0BB4: Rf_applyClosure (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49ADE1B: Rf_eval (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49E3E49: Rf_ReplIteration (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49E41DF: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49E429F: run_Rmainloop (in /usr/lib/R/lib/libR.so)
==448820==    by 0x10909E: main (in /usr/lib/R/bin/exec/R)
==448820==  Address 0xac94158 is 0 bytes after a block of size 2,392 alloc'd
==448820==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==448820==    by 0x49F05A4: Rf_allocVector3 (in /usr/lib/R/lib/libR.so)
==448820==    by 0x12762B7E: wma (moving_averages.c:239)
==448820==    by 0x495629D: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x495684C: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x4993254: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49ADCEF: Rf_eval (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49AFD85: ??? (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49B0BB4: Rf_applyClosure (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49ADE1B: Rf_eval (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49E3E49: Rf_ReplIteration (in /usr/lib/R/lib/libR.so)
==448820==    by 0x49E41DF: ??? (in /usr/lib/R/lib/libR.so)
==448820== 
--448820-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--448820-- si_code=128;  Faulting address: 0x0;  sp: 0x1002da9e20

valgrind: the 'impossible' happened:
   Killed by fatal signal
joshuaulrich commented 1 year ago

The problem is that this call to WMA() should be an error. n = 139 and the length of wts is 139, but there are only 78 non-NA values in x.

Here's a tiny example to use for a unit test. It should throw an error.

x <- c(rep(NA, 10), 1)
TTR::WMA(x)
joshuaulrich commented 1 year ago

Also is there any limits on what can be passed in as the parameters for the MACD indicator

The only limit I can think of is that there are enough non-NA values to calculate the moving averages, including the MA specified by maType.