Skip to content
All library documents

Optimizing a Weighted Time Series to Stay Near a Target

Article Quant Q&A · Author: MaxyD

Summary

The document considers how to choose weights for several input time series so their weighted combination remains close to a target level over time. It presents two approaches. A no-intercept regression of the target on the input series chooses weights that minimize squared deviations, which is a convenient but less flexible substitute for the original objective of minimizing absolute deviations.

For direct optimization of total absolute deviation, the answer demonstrates using Differential Evolution with bounded weights. A second response proposes instead minimizing squared deviations with a generic optimizer, then normalizing the resulting weights. These alternatives reflect different objectives and constraints: squared error penalizes large misses more strongly, while absolute error treats deviations linearly. The examples are illustrative rather than evidence of out-of-sample performance. Choice of objective, bounds, normalization, and added constraints can materially change the solution, and the document does not address validation or stability across changing data.

Key ideas

  • A weighted combination of time series can be fitted to stay near a chosen target level.
  • No-intercept regression minimizes squared deviations and is a simple alternative to minimizing absolute deviations.
  • A generic optimizer can directly minimize total absolute deviation while allowing bounds or other constraints.
  • Squared and absolute error objectives penalize deviations differently and can produce different weights.
  • The code examples illustrate optimization choices but provide no evidence of out-of-sample robustness.

Tags

Full text
# R: optimize timeseries to minimize "integral"


# R: optimize timeseries to minimize "integral"












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 ].

## Answer by Enrico Schumann (score 3)

https://quant.stackexchange.com/a/40109

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
library("NMOF")
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.

## Answer by MaxyD (score 0)

https://quant.stackexchange.com/a/40415

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:

```
    #Optimization
library("NMOF")
ns=dim(df)[2]
M=1
diff_mean <- function(b, M, df)
  sum((10000*(M-(df%*%b)))^2)
res <- DEopt(diff_mean,
             list(nG = 100000,
                  min = rep(-100, ns),
                  max = rep(100, ns)),
             M = M, df = df)

output=res$xbest
solution=output/output[1]
```

Bingo!

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.