Two ways:
Model the returns using an Ornstein-Uhlenbeck process
You can control the variance of the residual noise in the process to your desired level of correlation. Conceptually you inject gaussian noise into the synthetic OU process to satisfy your requirement.
For example, let's say you have time-series A which is what you are modelling. Time-series B is your synthetic series. You model time-series A via the OU process. Now you have to parametrize the OU process. For example, you can choose how much variance to allow for in time-series B.
We know that the correlation is simply the covariance(a,b)/[ stdev(a) * stdev(b) ]. Therefore, we can solve for this equation in terms of variance(b) so you can plug in your IC and crank out the appropriate level of variance for time-series 'b' in the OU process.
The OU process will give you more flexibility but it is not as straightforward to setup.
Use the Fundamental Law of Active Management
BARRA performs a Monte Carlo for simulating alpha signals to a specific level of Information Coefficient using this technique. Simulating alpha signals with a specific correlation is the same idea as generating a time-series that correlates to a price. The difference is that you would have to convert your original price-series into a return series, apply the procedure to generate a correlated alpha signal, and then integrate the alpha series so it is in the form of price levels instead of returns.
You can find more about the approach here.
Update:
I have added some simple code to demonstrate injecting orthogonal gaussian noise so the resulting series has a specific level of correlation:
# rho = desired correlation
# signals = a matrix where columns are asset returns and rows are periods
# covlist = a list of covariance matrixs corresponding to a given row (i.e. period)
# See example below for illustration
simpleNormalNoise <- function( signals , covlist , rho ) # one noisy signal per each mu and covariance matrix
{
noise = sapply( 1:ncol( signals ) , function(x) { normals = rnorm( nrow( covlist[[x]])) ; return( normals * sqrt(diag( covlist[[x]] ))) } )
signals = sapply( 1:ncol( signals ) , function(x) { return( rho*signals[,x] + sqrt( 1-rho*rho ) * noise[,x] ) } )
return( signals )
}
# Example:
sd1 = 1 # asset1
sd2 = 1 # asset2
cor = 0.8
cov = cor * sd1 * sd2
sample = matrix( c( sd1^2 , cov , cov , sd2^2 ) , 2 , 2 )
covs = lapply( 1:1000000 , function(x) { return( sample ) } )
fakemus = sapply( 1:1000000 , function(x) { return( rnorm( 2 ) ) } )
signals = simpleNormalNoise( fakemus, covs, .10 )
sd(t(signals)) #should be ~1
cor(t(signals)) #shoudl be ~0
cor(fakemus[1,],signals[1,]) #~.1
cor(fakemus[2,],signals[2,]) #~.1
mean(signals[1,]) #~ .05*.1
mean(signals[2,]) #~ .08*.1