Я пытаюсь установить выполнение ограниченной минимизации в форме
x' C x
, где значения x должны быть в диапазоне от 0 до 1 и также должны равняться 1.
Для моя матрица C, у меня есть следующее:
Обратите внимание, что это ковариационная матрица. Моя проблема в том, что когда я использую алгоритм градиентного спуска, чтобы минимизировать эту форму, он помещает весь вес в MBS15Y, даже несмотря на то, что дисперсия не самая низкая в группе (0,99 против 0,36 для LA13). Алгоритм должен поместить 100% веса в LA13. Пожалуйста, посмотрите мой код ниже.
def get_portfolio_volatility(port_weights,Sigma):
#calculate x'Cx
product_1 = tf.transpose(port_weights)
product_2 = tf.matmul(product_1,Sigma)
portfolio_variance = tf.matmul(product_2,port_weights)
return portfolio_variance
def ensure_constraints_op(port_weights):
#all values positive, with sum = 1
weights_sum = tf.reduce_sum(port_weights)
wgts = port_weights.assign(tf.divide(tf.abs(port_weights), tf.abs(weights_sum) ))
return wgts
def generate_efficient_frontier(Sigma, u, risk_tol, learning_rate = 0.0005, steps = 3000):
port_weights = tf.Variable(tf.random_normal((len(u.columns), 1), dtype=tf.float64,seed=42)) #weights
portfolio_volatility = get_portfolio_volatility(port_weights,Sigma)
obj = portfolio_volatility
constraints_op = ensure_constraints_op(port_weights)
# Training using Gradient Descent to minimize cost
optimize_op = tf.train.GradientDescentOptimizer(learning_rate, use_locking=True).minimize(obj)
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
for i in range(steps):
sess.run(optimize_op)
sess.run(constraints_op)
sess.run(constraints_op)
#return optimal portfolio
return sess.run(port_weights),sess.run(portfolio_volatility)
Единственная проблема, о которой я могу подумать, это то, что я неправильно вычисляю x'Cx, или что способ ограничения оптимизации неверен.