joshuaulrich / TTR

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

ROC discrete/continuous produces wrong answers for negative values #60

Open AndreMikulec opened 6 years ago

AndreMikulec commented 6 years ago

ROC discrete is producing wrong answers for negative values.

ROC discrete is producing the relative return instead of the absolute return.

> ROC(xts((1:3), zoo::as.Date(0:2)), type = "discrete")
           [,1]
1970-01-01   NA
1970-01-02  1.0
1970-01-03  0.5

> ROC(xts(-(1:3), zoo::as.Date(0:2)), type = "discrete")
           [,1]
1970-01-01   NA
1970-01-02  1.0 # *** should be negative ***
1970-01-03  0.5 # *** should be negative ***

> Y <- xts((1:3), zoo::as.Date(0:2))
> (Y - lag(Y)) / abs(lag(Y))
           [,1]
1970-01-01   NA
1970-01-02  1.0
1970-01-03  0.5

> Y <- xts(-(1:3), zoo::as.Date(0:2))
> (Y - lag(Y)) / abs(lag(Y))
           [,1]
1970-01-01   NA
1970-01-02 -1.0 # *** should be this value ***
1970-01-03 -0.5 # *** should be this value ***

ROC continuous is producing wrong answers for negative values.

"continuous" while using negative values also does not work.

> ROC(xts(-(1:3), zoo::as.Date(0:2)))
           [,1]
1970-01-01  NaN
1970-01-02  NaN
1970-01-03  NaN
Warning message:
In log(x) : NaNs produced

I do not know how to fix it.

This person has some ideas here. I do not understand. I can not generate any working math. I use this to test(validate)

exp(cumsum(na.fill(ROC(-(1:3)),0)))

Log transformations: How to handle negative data values? 166 By Rick Wicklin on The DO Loop April 27, 2011 https://blogs.sas.com/content/iml/2011/04/27/log-transformations-how-to-handle-negative-data-values.html

A log transformation of positive and negative values 10 By Rick Wicklin on The DO Loop July 14, 2014 https://blogs.sas.com/content/iml/2014/07/14/log-transformation-of-pos-neg.html

> sessionInfo()
R version 3.4.3 (2017-11-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 16299)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

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

other attached packages:
[1] xts_0.10-1 zoo_1.8-1  TTR_0.23-3

loaded via a namespace (and not attached):
 [1] httr_1.3.1       compiler_3.4.3   R6_2.2.2         tools_3.4.3
 [5] withr_2.1.1.9000 curl_3.1         memoise_1.1.0    grid_3.4.3
 [9] git2r_0.21.0     digest_0.6.15    devtools_1.13.5  lattice_0.20-35
Eluvias commented 5 years ago

This is because TTR is applied on financial price series; no negative prices. So , ROC works fine in this context.

But there is a corner case : for example in commodity future markets when you want to back adjust the price series with the roll yield, then on some contracts you might end up with negative price series.

braverock commented 5 years ago

@Eluvias , just to clarify... 'adjusted' prices aren't prices anymore. They are a derived series or indicator that corrects the true observed price for some other information (e.g. dividends). 'roll yield' is the cash that may be generated by selling one commodities contract and buying a different contract, so 'continuous' futures series are also 'not real'. You can't trade a continuous contract, and any construction of such a contract is making up fake 'prices' based on a set of rather tenuous assumptions.

There are real financial instruments that do trade with negative prices. Exchange listed commodity or other futures spreads are a good case in point. Short term interest rate yield contracts in Europe as I write this are another example.

In the presence of negative prices, or of leverage, the calculation of returns is more complicated, and ROC will not be the appropriate solution for calculating such returns.

cgiachalis commented 5 years ago

@braverock - Not sure what is your point here.

just to clarify... 'adjusted' prices aren't prices anymore

It will be the total return price series on which we're interested to apply the rate of change; we do not want to trade off this series, but to evaluate the performance or carry out some other analysis. The case of commodity futures is a perfect example as you might get negative values if you after the total return series.

There are real financial instruments that do trade with negative prices. Exchange listed commodity or other futures spreads are a good case in point. Short term interest rate yield contracts in Europe as I write this are another example.

Those are irrelevant examples. To your own words "...they are derived prices" for which the rate of change is not applicable. Nevetherless, from trading perspective we can treat them as prices.

In the presence ... or of leverage, the calculation of returns is more complicated...

Agreed, but for the record it shouldn't be any problem applying ROC on a fund's prices (or NAV) series when it uses derivatives or buying stocks on margin. On the other hand, if your goal is to compare the betas between a heavy levered fund and a fully funded one, perhaps you might want to adjust the levered returns.