在R中优化具有2个输出的自定义功能

时间:2014-03-06 21:42:38

标签: r optimization

我对R很新,但我已经在Excel中编写复杂的宏很长一段时间了。最近,那些宏已经花了很长时间才能运行所以我试图转换为R.下面的函数接收5个权重作为输入并返回两个值作为输出。我试图找到输入,以便对于其中一个输出的每个值,其他输出最大化。当我输入optim(par=c(.5,.5,.5,.5,.5), dataGetter, gr=NULL)时,它给我一个错误,我认为这是两个输出的结果。有没有办法指定其中一个输出的值(保持不变)并使用optim()来最大化另一个输出?

dataGetter <- function( hedgeWeights ) {
    spotData        <- read.csv("RtestSpots.csv")
    fwdData         <- read.csv("RtestFWDs.csv")
    notionals       <- c(341538461.54, 46153846.15, 32307692.31, 
                         27692307.69, 13846153.85)
    currentFWDs     <- (fwdData[nrow(fwdData),] -
                        spotData[nrow(spotData), 2:6]) / 
                        spotData[nrow(spotData), 2:6]
    #hedgeWeights   <- c(.4, .4, .4, .4, .4)
    unhedgedWeights <- 1 - hedgeWeights

    returns <- getReturn(spotData[c("Date","EURUSD")],18, "EURUSD")
    returns <- cbind(returns, getReturn(spotData[c("Date","USDJPY")], 
                     18, "USDJPY"))
    returns <- cbind(returns, getReturn(spotData[c("Date","USDCAD")], 
                     18, "USDCAD"))
    returns <- cbind(returns, getReturn(spotData[1:(nrow(spotData)-8), 
                     c("Date","USDMXN")],10, "USDMXN")                )
    returns <- cbind(returns, getReturn(spotData[1:(nrow(spotData)-8), 
                                       c("Date","AUDUSD")], 10, "AUDUSD"))
    cost    <- hedgeWeights * currentFWDs*notionals
    returnAmounts <- t(notionals*t(returns)*unhedgedWeights)
    returnAmounts <- cbind(returnAmounts, rowSums(returnAmounts))
    colnames(returnAmounts)[6] <- c("Total")
    returnAmounts <- cbind(returnAmounts, abs(returnAmounts[,c("Total")]))
    colnames(returnAmounts)[7] <- c("Absolute")
    EURpercentile <- quantile(returnAmounts[,c("EURUSD")], c(.05, .95))
    JPYpercentile <- quantile(returnAmounts[,c("USDJPY")], c(.05, .95))
    CADpercentile <- quantile(returnAmounts[,c("USDCAD")], c(.05, .95))
    MXNpercentile <- quantile(returnAmounts[,c("USDMXN")], c(.05, .95))
    AUDpercentile <- quantile(returnAmounts[,c("AUDUSD")], c(.05, .95))
    TOTpercentile <- quantile(returnAmounts[,c("Total")], c(.05, .95))
    ABSpercentile <- quantile(returnAmounts[,c("Absolute")], c(.05, .95))
    #print(returnAmounts)
    #print(list(colMeans(returnAmounts), EURUSD=EURpercentile, 
    #      USDJPY=JPYpercentile,         USDCAD=CADpercentile, 
    #      USDMXN=MXNpercentile,         AUDUSD=AUDpercentile, 
    #      Total=TOTpercentile, Absolute=ABSpercentile))
    return(list(Risk=TOTpercentile, Cost=sum(cost)))
}

这是第二个功能:

getReturn <- function(data, months, CCY) {
    #Assumes 'data' is a two-column data frame with date in the first 
    #  column, price in the second

    num.rows <- nrow(data)
    #num.cols <- ncol(data)

    output.range <- 1:(num.rows-(months+1))

    buy.price  <- data[output.range,2]
    sell.price <- data[output.range+months,2]

    returns         <- data.frame((sell.price - buy.price)/buy.price)
    #returns        <- cbind(data[output.range,],returns)
    #names(returns) <- c("Date","Price","Return")
    names(returns)  <- c(CCY)

    return(returns)
}

1 个答案:

答案 0 :(得分:1)

你提出的问题如下: 你有两个功能,fg, 并且你想找到参数p 最大化f(p)主题 条件g(p)=q(适用于q)的各种值。

这是一个受限制的优化问题: 您可以查看Rsolnpalabama个包。 或者,您可以将约束转换为惩罚, 最大化f(p) - A*(g(p)-q)^2以增加A的值 使用optim或任何其他非约束优化程序。

然而,既然你显然在计算一个有效的边界, 对于f(p) - A * g(p)的各种值,您可以简单地最大化AA的每个值都会在有效边界上给出一个观点。 这通常更容易,更快,更准确。