通过求解受等式约束的不等式系统在 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 时的价格。我无法手动完成,所以我尝试使用 limSolve 和 lpSolve 包中包含的函数 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
我正在尝试构建一个套利投资组合 x 使得 Sx = 0 和 Ax>=0,其中 A 是 t=1 时的收益矩阵,S 是 t=0 时的价格。我无法手动完成,所以我尝试使用 limSolve 和 lpSolve 包中包含的函数 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