What I am looking to do is:

for a given time-series $P_t$ (which will be constructed from different timeseries itself):

$P_t$ = $\beta_1$$I_t^1$+$\beta_2$$I_t^2$+$\beta_3$$I_t^3$ $\qquad$ ($I_t^i$ are $i$ number of time-series)

I want to

$min$$\sum_t^T|$$P_t$-$\bar{P}$| where $\bar{P}$ = 1 (centered around 1)

esentially choosing the $\beta$s such that |$P_t$-$\bar{P}$| is minimized over [ t,T ].

  • $\begingroup$ Could you show us what you have tried so far and where the exact problem is? $\endgroup$
    – vonjd
    Commented May 31, 2018 at 16:58
  • $\begingroup$ Are you sure you want to minimise the differences? Or rather the absolute differences? $\endgroup$ Commented Jun 1, 2018 at 11:48
  • $\begingroup$ :+1: thanks Enrico! that is exactly what I meant $\endgroup$
    – MaxyD
    Commented Jun 1, 2018 at 14:35
  • 1
    $\begingroup$ Never answer an "or-question" with "yes" ;-) $\endgroup$
    – vonjd
    Commented Jun 7, 2018 at 9:06
  • $\begingroup$ Vonjd, I am sorry you couldn’t gather from context that I indeed meant to minimize the absolute differences (also changed it in the initial question) $\endgroup$
    – MaxyD
    Commented Jun 10, 2018 at 9:24

2 Answers 2


A simple, though somewhat inflexible, way would be to regress $\bar{P}$ on the $I$ series only (no constant). This will minimise squared differences instead of absolute ones, though.

R example; I start with creating random data:

nobs <- 250  ## length of series
ns <- 3      ## number of I series

P <- c(1, cumprod(1 + rnorm(nobs, sd = 0.01)))
M <- sum(range(P))/2  ## midpoint of range
I <- array(rnorm((nobs)*ns, sd = 0.01),
           dim = c(nobs, ns))
I <- apply(I, 2, function(x) cumprod(1+x))
I <- rbind(1, I)

plot(P, ylim = range(P, I), type = "l",
     col = "darkgreen", lwd = 2)
abline(h = M)
for (i in 1:ns)
    lines(I[,i], col = grey(0.7))

## regression
res1 <- lm(rep(M, nrow(I)) ~ -1 + I)
lines(I %*% coef(res1),
      col = "blue", lwd = 2,
      type = "l")

An alternative way would be to use a generic solver. Here is an example with Differential Evolution, as implemented in the R package NMOF, which I maintain.

## Differential Evolution
diff_mean <- function(b, M, I)
    sum(abs(M - I %*% b))

res2 <- DEopt(diff_mean,
              list(min = rep(-1, ns),
                   max = rep(1, ns)),
              M = M, I = I)

lines(I %*% res2$xbest, 
      col = "red", lwd = 2)

The advantage of such a solver is that it is much more flexible: you may use another function to measure the similarity of the series, or add constraints.

  • $\begingroup$ Didn't know the package, thank you for pointing it out. $\endgroup$
    – vonjd
    Commented Jun 7, 2018 at 9:05
  • $\begingroup$ I just changed the question slightly... It should be enough to make $\bar{P}$ a constant. However, I am unsure how to apply DEopt for a dataframe (of multiple vectors) in order to extract my betas. $\endgroup$
    – MaxyD
    Commented Jun 11, 2018 at 15:32
  • $\begingroup$ It is unfortunate that you changed your question, as now my code example does not match it any more. But anyway: what do you mean by multiple vectors? In the example, I is already a matrix; simply overwrite M with your constant series. $\endgroup$ Commented Jun 12, 2018 at 9:43
  • $\begingroup$ I did get the DEopt working now. However I am getting more than one solution for xbest across multiple runs even though I do think there should be one definitive solution. I already did change the min&max values. $\endgroup$
    – MaxyD
    Commented Jun 14, 2018 at 11:33
  • $\begingroup$ DE is a stochastic method, so its solutions are, in a sense, random. However, with more iterations, this randomness should decrease and eventually disappear. So, try with an increased number of steps (nG in DEopt). See also the discussion in section 3 of ssrn.com/abstract=1140655 $\endgroup$ Commented Jun 15, 2018 at 9:49

I is a t x i matrix. Each vector in I is weighted by a beta each such that diff_mean is minimized. I will center the process around 1 (M=1) and square the differences to "punish" higher deviations (and prevent netting of errors) from M:

diff_mean <- function(b, M, df)
res <- DEopt(diff_mean,
             list(nG = 100000,
                  min = rep(-100, ns),
                  max = rep(100, ns)),
             M = M, df = df)




Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.