通过求解受等式约束的不等式系统在 R 中设置套利策略

Setting up an arbitrage strategy in R by solving system of inequalities subject to an equality constraint

我正在尝试构建一个套利投资组合 x 使得 Sx = 0 和 Ax>=0,其中 A 是 t=1 时的收益矩阵,S 是 t=0 时的价格。我无法手动完成,所以我尝试使用 limSolvelpSolve 包中包含的函数 R 没有成功,因为我不断得到零向量(我需要非平凡的解决方案)。我也不确定如何自己编写代码。任何有关如何进行的帮助或提示将不胜感激。谢谢!

    A = data.frame(
              cbind(
                 c(2,1,0),
                 c(1,1,1),
             c(0,1,2),
             c(3,2,1),
             c(1,1,0)
              )
             ) %>% as.matrix()
f.con = A
    
    S = data.frame(
              cbind(
             c(1,1,1,2,1/3)
              )
             ) %>% as.matrix()

f.obj = c(t(S))

# Set unequality signs
f.dir <- c(">",
           ">",
           ">")

# Set right hand side coefficients
f.rhs <- c(0,
           0,
           0)

# Final value 
lp("min", f.obj, f.con, f.dir, f.rhs)$solution

# Variables final values
lp("max", f.obj, f.con, f.dir, f.rhs)$solution

我们首先解释为什么问题中的代码得到了它所做的结果。

请注意,存在 x >= 0 的隐式约束。

关于引用等式约束的主题,问题中显示的代码中没有等式约束。

关于最小值,在lp参数中>表示>=所以很明显x=0是可行的。鉴于 objective 向量的所有分量都是正的,它导致最小值为 0。来自 ?lp

const.dir: Vector of character strings giving the direction of the constraint: each value should be one of "<," "<=," "=," "==," ">," or ">=". (In each pair the two values are identical.)

关于最大值,解没有上限约束,objective向量的分量都是正的,所以没有有限解。线性程序是否成功应始终在显示解决方案之前显示,如果不成功则不应显示解决方案,因为它没有任何意义。

关于代码,cbind 已经生成了一个矩阵,因此将其转换为数据帧然后再转换回矩阵是没有意义的。 objective 也可以表示为一个普通向量,约束的右侧可以写成一个标量,它将被回收到适当的长度。我们可以将问题中的代码等效地写为:

library(lpSolve)

A <- cbind(2:0, 1, 0:2, 3:1, c(1, 1, 0))
S <- c(1, 1, 1, 2, 1/3)

res1 <- lp("min", S, A, ">=", 0)   
res1
## Success: the objective function is 0 
res1$solution
## [1] 0 0 0 0 0

res2 <- lp("max", S, A, ">=", 0)
res2
## Error: status 3 

CVXR

使用 CVXR 更容易制定此公式,如下所示。

找到满足 Ax >= 0 和 Sx == 0 的向量 x。(A 和 S 来自上面。)我们添加约束 -1 <= x <= 1 以保持解决方案在边界并使用任意 objective sum(x) 因为我们只是在寻找任何可行的解决方案。

library(CVXR)

x <- Variable(5)
objective <- Maximize(sum(x))  # arbitrary objective
constraints <- list(A %*% x >= 0, sum(S*x) == 0, x >= -1, x <= 1)
problem <- Problem(objective, constraints)
soln <- solve(problem)

给予:

> soln$status
[1] "optimal"

> soln$value
[1] 1.66666

> soln$getValue(x)
           [,1]
[1,]  0.8788689
[2,]  0.4790521
[3,]  0.3087133
[4,] -0.9999857
[5,]  1.0000113

lp再次求解

为此,使用 lpSolve 更改变量

x = 2*y-1

或等同于

y = (x+1)/2

转换

Ax >= 0
Sx == 0
-1 <= x <= 1

2Ay >= A1
2Sy >= S'1
0 <= y <= 1

所以我们写:

f.con <- rbind(2*A, 2*S, diag(5))
f.dir <- c(rep(">=",3),  "=", rep("<=", 5))
f.rhs <- c(rowSums(A), sum(S), rep(1, 5))

res3 <- lp("max", rep(1, 5), f.con, f.dir, f.rhs)
res3
## Success: the objective function is 3.333333 
2*res3$solution-1
## [1]  1.000000e+00 -4.966028e-13  6.666667e-01 -1.000000e+00  1.000000e+00