Interpreting Cumulative Returns from Signal-Weighted Price Changes
Summary
The document examines an R example that assigns long and short positions from buy and sell signals, carries the latest signal forward, multiplies it by discrete close-to-close returns, and exponentiates the cumulative sum. The replies explain why the resulting equity curve may look unexpectedly strong or fluctuate sharply: the price series is randomly generated, and a single simulation can be misleading. They suggest using a more suitable positive price model, examining many simulations, and plotting returns and drawdowns.
A key methodological issue is that exponentiating a cumulative sum is appropriate for accumulated log returns, whereas the example uses discrete simple returns. The replies also flag the unusually large volatility in the simulated prices as a source of dramatic movement. The discussion does not provide a corrected backtest or address practical details such as execution timing, transaction costs, or signal lookahead, so its suggestions are diagnostic rather than a complete strategy evaluation.
Key ideas
- Exponentiating cumulative returns is appropriate when the inputs are log returns, not simple discrete returns.
- A single run on randomly generated prices cannot establish that a strategy performs well.
- Price and volatility assumptions can strongly affect the shape of a simulated equity curve.
- Reviewing daily returns and drawdowns can help interpret performance over time.
Tags
Full text
# Calculating and interpreting cumulative returns is R
# Calculating and interpreting cumulative returns is R
I have buy and sell signals,and accordingly, I artificially generate a signal series,for which,I assign 1 to every buy and -1 to every sell:
```
library(xts)
require(TTR)
close_series=rnorm(20,100,10)
date=seq(as.Date("2000/1/1"), as.Date("2000/1/20"), "days")
close_xts=xts(close_series,date)
x.points.buy=c(1,5,9,17)
x.points.sell=c(3,6,12,20)
buy.points=index(close_xts[x.points.buy])
sell.points=index(close_xts[x.points.sell])
signal<- xts(rep(NA,length(close_xts)),index(close_xts))
signal[buy.points]<-1
signal[sell.points]<--1
signal<-na.locf(signal)
returns <- ROC(close_xts,type="discrete")*signal
returns[is.na(returns)]<- 0
eq <- exp(cumsum(returns))
```
This is giving me returns that seem to be too good to be true,I am not able to understand the fundamental methodology on the basis of which these cumulative returns show such huge figures.Can anyone please help me to understand this?
## Answer by htrahdis (score 1)
https://quant.stackexchange.com/a/9759
This is the equity line i got after i repeated your code. how is this good ? may be you have run with only one set of numbers. any ways here are a few things you can do to come closer to reality :
- take the close prices as lognormal distribution instead of a normal distribution.
- you are adding up the returns later on. this is only right if you have logarithmic differences instead of simple differences.
- run the same simulation with a lot of samples to get a distribution and then decide if it is good or bad.
- the fluctuations you will see in the equity line is because you have provided a huge value for the standard deviation.
## Answer by SMohan (score 0)
https://quant.stackexchange.com/a/14281
You can use the PerformanceAnalytics package , and get the following charts, Cumulative Returns, Daily Returns as well as Drawdown for understanding the time series.
Code: library("PerformanceAnalytics")
charts.PerformanceSummary( ROC(eq, n = 1, type = "discrete"), main = "Returns (PerformanceAnalytice::charts.PerformanceSummary)" )Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.