Использование метода Монте-Карло для оптимизации портфеля, но должно удовлетворять ограничениям

#python #optimization #montecarlo #quantitative-finance #portfolio

#python #оптимизация #монтекарло #количественный-финансы #Портфолио

Вопрос:

У меня проблема с поиском весов портфеля и их оптимизацией при соблюдении ограничений. Мне нужна некоторая помощь в разработке кода, который позволил бы мне моделировать несколько массивов весов при соблюдении ряда ограничений, объяснение см. В Примере ниже:

Проблема — имитировать различные веса при удовлетворении ограничениям:

Инструменты = [‘Фиксированный доход’, ‘Собственный капитал 1’, ‘Собственный капитал 2’, ‘Мультиактивы’, ‘Денежные средства’]

Ограничения:

  1. каждый вес от 0,1 до 0,4
  2. денежные средства = 0,05
  3. Собственный капитал 1 меньше 0,3

На данный момент у меня есть код:

 import numpy as np:

instruments = ['Fixed Income', 'Equity 1', 'Equity 2', 'Multi-Asset', 'Cash']

weights = np.random.uniform(0.1, 0.4, len(instruments)) # random number generation
weights = weights / weights.sum() # normalise weights
# I have done test runs, and normalised weights always fit the constraints

if weights[-1] > 0.03:
   excess = weights[-1] - 0.03
   # distribute excess weights equally
   weights[:-1] = weights[:-1]   excess / (len(weights) - 1)

  

и я застрял, я также понял, что когда я распределяю избыточные веса, я фактически нарушил свое ограничение.

Есть ли способ это сделать? и я должен сделать это с помощью метода Монте-Карло

Спасибо всем за вашу помощь.

Комментарии:

1. что именно представляет собой Монте-Карло в приведенной выше настройке? Я не вижу повторений / симуляций

Ответ №1:

Вот одно из решений:

 import numpy as np
N = 1000000
instruments = ['Fixed Income', 'Equity 1', 'Equity 2', 'Multi-Asset', 'Cash']

# each row is set of weights in order of instruments above
weights = np.zeros(shape=(N, len(instruments)))

weights[:, -1] = 0.05
weights[:, 1] = np.random.uniform(0, 0.3, N)

cols = (0, 2, 3)

# fill columns with random numbers
for col in cols[0:-1]:
    w_remaining = 1 - np.sum(weights, axis=1)
    weights[:, col] = np.random.uniform(0.1, 0.4, N)

# the last column is constrained for normalization
weights[:, cols[-1]] = 1 - np.sum(weights, axis=1)

# select only rows that meet condition:
cond1 = np.all(0.1 <= weights[:, cols], axis=1)
cond2 = np.all(weights[:, cols] <= 0.4, axis=1)
valid_rows = cond1*cond2

weights = weights[valid_rows, :]

# verify sum of weights == 1:
np.testing.assert_allclose(np.sum(weights, axis=1), 1)
  

Это решение является производительным, но отбрасывает сгенерированные примеры, которые не удовлетворяют ограничениям.

Комментарии:

1. Я не считаю, что это вполне математически обоснованно. Сначала вы выбираете вес для столбца [1], а затем распределяете остальные. Это близко, потому что сумма ожидаемых значений близка к общему весу, но не совсем.

2. @AirSquid Я не знаю, что вы считаете необоснованным. Не существует уникального метода для удовлетворения предоставленных ограничений; это один из способов сделать это. Я включил тест утверждения нормализации для всех моделируемых весов

3. ОК. Достаточно справедливо. Это интересная проблема, и после небольшого исследования я не могу найти слишком много дыр или найти альтернативный подход. Пока мы понимаем, что в конце дня распределения для отдельных весов не будут равномерными [и, вероятно, не могут быть выполнены в этом случае] из-за взаимосвязанности проблемы

4. @anon01, спасибо за ваше решение, я нашел его очень полезным, мне просто интересно, сможете ли вы также помочь мне в более сложной задаче, что, если у меня есть дополнительные ограничения, при которых собственный капитал должен быть <0,5, т. Е. Сумма собственного капитала 1 и собственного капитала 2 должна быть <0.5?

5. @DazzW не стесняйтесь создавать новый вопрос и отправлять мне комментарий

Ответ №2:

В моем PoV использование моделирования montecarlo для оптимизации портфеля очень неэффективно из-за того, что проблема очень сложна при увеличении количества активов, даже если вы используете последовательность sobol.

С другой стороны, большинство задач оптимизации портфеля являются задачами квадратичного или линейного программирования, поэтому вы можете использовать cvxpy для их решения, но для моделирования каждой проблемы требуется время. Наконец, вы можете попробовать Riskfolio-Lib библиотеку, основанную на cvxpy, которая упрощает реализацию моделей оптимизации портфеля, даже имеет формат для реализации ограничений классов активов, которые вы пытаетесь реализовать.

Вы можете проверить первый пример по этой ссылке: https://riskfolio-lib.readthedocs.io/en/latest/examples.html