Перейти до основного вмісту

Quantum Portfolio Optimizer: Qiskit Function від Global Data Quantum

Дивись довідник API

примітка

Qiskit Functions — це експериментальна функція, доступна лише користувачам тарифних планів IBM Quantum® Premium Plan, Flex Plan та On-Prem (через IBM Quantum Platform API). Вони перебувають у стані попереднього релізу та можуть змінюватися.

Огляд

Quantum Portfolio Optimizer — це Qiskit Function, яка вирішує задачу динамічної оптимізації портфеля, стандартну задачу у фінансах, що спрямована на перебалансування періодичних інвестицій між набором активів з метою максимізації прибутку та мінімізації ризиків. Використовуючи передові методи квантової оптимізації, ця функція спрощує процес так, щоб користувачі без будь-яких знань у сфері квантових обчислень могли скористатися її перевагами у пошуку оптимальних інвестиційних траєкторій. Ідеально підходить для портфельних менеджерів, дослідників у кількісних фінансах та індивідуальних інвесторів — цей інструмент дає змогу проводити бектестування торгових стратегій при оптимізації портфеля.

Опис функції

Функція Quantum Portfolio Optimizer використовує алгоритм Варіаційного Квантового Власного Розкладача (VQE) для розв'язання задачі Квадратичної Незв'язаної Бінарної Оптимізації (QUBO), вирішуючи задачі динамічної оптимізації портфеля. Користувачам потрібно лише надати дані про ціни активів і задати інвестиційні обмеження, після чого функція запускає процес квантової оптимізації, який повертає набір оптимізованих інвестиційних траєкторій.

Процес складається з чотирьох основних етапів. Спочатку вхідні дані відображаються у квантово-сумісну задачу: будується QUBO для задачі динамічної оптимізації портфеля та перетворюється на квантовий оператор (Ізінговий гамільтоніан). Далі вхідна задача і алгоритм VQE адаптуються для роботи на квантовому залізі. Після цього алгоритм VQE запускається на квантовому залізі, і нарешті результати постобробляються для отримання оптимальних інвестиційних траєкторій. Система також включає шумозахисну постобробку на основі (SQD) для максимізації якості вихідних даних.

Ця Qiskit Function базується на опублікованій статті компанії Global Data Quantum. Візуалізація робочого процесу функції

Початок роботи

Пройди автентифікацію за допомогою свого API-ключа та вибери Qiskit Function таким чином. (Цей фрагмент передбачає, що ти вже зберіг свій обліковий запис у локальному середовищі.)

# Added by doQumentation — required packages for this notebook
!pip install -q pandas qiskit-ibm-catalog
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# Access function
dpo_solver = catalog.load("global-data-quantum/quantum-portfolio-optimizer")

Приклад: динамічна оптимізація портфеля з сімома активами

Цей приклад демонструє, як виконати функцію динамічної оптимізації портфеля (DPO) та налаштувати її параметри для оптимальної продуктивності. Він включає детальні кроки з тонкого налаштування параметрів для досягнення бажаних результатів.

Цей випадок включає сім активів, чотири часові кроки та чотири qubits роздільної здатності, що разом потребує 112 qubits.

1. Зчитай активи, що входять до портфеля

Якщо всі активи портфеля зберігаються в папці за певним шляхом, ти можеш завантажити їх у pandas.DataFrame та перетворити на об'єкт у форматі dict за допомогою такої функції.

import os
import glob
import pandas as pd

def read_and_join_csv(file_pattern):
"""
Reads multiple CSV files matching the file pattern and combines them into a single DataFrame.

Parameters:
file_pattern (str): The pattern to match CSV files.

Returns:
pd.DataFrame: Combined DataFrame with data from all CSV files.
"""
# Find all files matching the pattern
csv_files = glob.glob(file_pattern)
# Get the base file names without the .csv extension
file_names = [os.path.basename(f).replace(".csv", "") for f in csv_files]
# Read each CSV file into a DataFrame and set the first column as the index
df_list = [pd.read_csv(f).set_index("Unnamed: 0") for f in csv_files]

# Rename columns in each DataFrame to the base file names
for df, name in zip(df_list, file_names):
df.columns = [name]

# Combine all DataFrames into one by merging them side by side
combined_df = pd.concat(df_list, axis=1)
return combined_df

file_pattern = "route/to/folder/with/assets/data/*.csv"
assets = read_and_join_csv(file_pattern).to_dict()

Для цього прикладу ми використали активи 8801.T, CLF, GBPJPY, ITX.MC, META, TMBMKDE-10Y та XS2239553048. Наступний графік ілюструє дані, використані в цьому прикладі, показуючи динаміку денних цін закриття активів з 1 січня по 1 вересня 2023 року.

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

2. Визнач задачу

Визнач специфікації задачі, налаштувавши параметри в словнику qubo_settings.

qubo_settings = {
"nt": 4,
"nq": 4,
"dt": 30,
"max_investment": 25,
"risk_aversion": 1000.0,
"transaction_fee": 0.01,
"restriction_coeff": 1.0,
}

3. Визнач налаштування оптимізатора та ансатцу (Необов'язково)

За бажанням визнач конкретні вимоги до процесу оптимізації, включаючи вибір оптимізатора та його параметрів, а також специфікацію примітиву та його конфігурацій.

Для Tailored Ansatz обраний розмір популяції базується на попередніх експериментах, які показали, що це значення забезпечує стабільну та ефективну оптимізацію.

У випадку Real Amplitudes Ansatz можна дотримуватися лінійного зв'язку між population_size та кількістю qubits у схемі. Як наближене правило, рекомендується використовувати мінімум population_size ~ 0.8 * n_qubits для ансатцу real_amplitudes.

Очікується, що Optimized Real Amplitudes матиме кращу продуктивність оптимізації, ніж ансатц Real Amplitudes. Однак кількість змінних для оптимізації в цьому ансатці зростає значно швидше, ніж у випадку Real Amplitudes (дивись статтю). Тому для великих задач Optimized Real Amplitudes потребує більше виконань схем. Optimized Real Amplitudes, мабуть, буде корисним для задач до 100 qubits, але рекомендується бути уважним при встановленні параметрів population_size. Як приклад такого масштабування population_size: для задачі з 84 qubits Optimize Real Amplitudes потребує 120 population_size, тоді як для задачі з 56 qubits достатньо population_size 40.

optimizer_settings = {
"de_optimizer_settings": {
"num_generations": 20,
"population_size": 90,
"recombination": 0.4,
"max_parallel_jobs": 5,
"max_batchsize": 4,
"mutation_range": [0.0, 0.25],
},
"optimizer": "differential_evolution",
"primitive_settings": {
"estimator_shots": 25_000,
"estimator_precision": None,
"sampler_shots": 100_000,
},
}

Також можна вибрати конкретний ансатц. Нижче використовується ансатц 'Tailored'.

ansatz_settings = {
"ansatz": "tailored",
"multiple_passmanager": False,
}

4. Запусти задачу

dpo_job = dpo_solver.run(
assets=assets,
qubo_settings=qubo_settings,
optimizer_settings=optimizer_settings,
ansatz_settings=ansatz_settings,
backend_name="<backend name>",
previous_session_id=[],
apply_postprocess=True,
)

5. Отримай результати

Функція повертає словник з інвестиційними траєкторіями, впорядкованими від найменшого до найбільшого за значенням цільової функції (дивись розділ Вихідні дані у довіднику API). Цей набір результатів дозволяє визначити траєкторію з найнижчою вартістю та відповідні інвестиційні оцінки. Крім того, він забезпечує аналіз різних траєкторій, полегшуючи вибір тих, що найкраще відповідають конкретним потребам або цілям. Така гнучкість дозволяє адаптувати вибір до різноманітних уподобань або сценаріїв. Почни з відображення результуючої стратегії, яка досягла найнижчої цільової вартості, знайденої в процесі.

# Get the results of the job
dpo_result = dpo_job.result()

# Show the solution strategy
dpo_result["result"]
{'time_step_0': {'8801.T': 0.11764705882352941,
'ITX.MC': 0.20588235294117646,
'META': 0.38235294117647056,
'GBPJPY=X': 0.058823529411764705,
'TMBMKDE-10Y': 0.0,
'CLF': 0.058823529411764705,
'XS2239553048': 0.17647058823529413},
'time_step_1': {'8801.T': 0.11428571428571428,
'ITX.MC': 0.14285714285714285,
'META': 0.2,
'GBPJPY=X': 0.02857142857142857,
'TMBMKDE-10Y': 0.42857142857142855,
'CLF': 0.0,
'XS2239553048': 0.08571428571428572},
'time_step_2': {'8801.T': 0.0,
'ITX.MC': 0.09375,
'META': 0.3125,
'GBPJPY=X': 0.34375,
'TMBMKDE-10Y': 0.0,
'CLF': 0.0,
'XS2239553048': 0.25},
'time_step_3': {'8801.T': 0.3939393939393939,
'ITX.MC': 0.09090909090909091,
'META': 0.12121212121212122,
'GBPJPY=X': 0.18181818181818182,
'TMBMKDE-10Y': 0.0,
'CLF': 0.0,
'XS2239553048': 0.21212121212121213}}

Далі, використовуючи метадані, ти можеш отримати доступ до результатів усіх відібраних стратегій. Завдяки цьому можна додатково проаналізувати альтернативні траєкторії, повернуті оптимізатором. Для цього зчитай словник, збережений у dpo_result['metadata']['all_samples_metrics'], який містить не лише додаткову інформацію про оптимальну стратегію, а й деталі інших стратегій-кандидатів, оцінених під час оптимізації.

Наступний приклад показує, як зчитати цю інформацію за допомогою pandas для вилучення ключових метрик, пов'язаних з оптимальною стратегією. До них належать відхилення від обмеження, коефіцієнт Шарпа та відповідна інвестиційна прибутковість.

# Convert metadata to a DataFrame
df = pd.DataFrame(dpo_result["metadata"]["all_samples_metrics"])

# Find the minimum objective cost
min_cost = df["objective_costs"].min()
print(f"Minimum Objective Cost Found: {min_cost:.2f}")

# Extract the row with the lowest cost
best_row = df[df["objective_costs"] == min_cost].iloc[0]

# Display the results associated with the best solution
print("Best Solution:")
print(f" - Restriction Deviation: {best_row['rest_breaches']}%")
print(f" - Sharpe Ratio: {best_row['sharpe_ratios']:.2f}")
print(f" - Return: {best_row['returns']}")
Minimum Objective Cost Found: -3.78
Best Solution:
- Restriction Deviation: 40.0
- Sharpe Ratio: 24.82
- Return: 0.46

6. Аналіз продуктивності

Нарешті, проаналізуй продуктивність свого застосунку оптимізації. Зокрема, порівняй свої результати, отримані в попередньому прикладі, з випадковою базовою лінією, щоб оцінити ефективність підходу. Якщо квантовий алгоритм стабільно і переконливо дає результати з нижчими значеннями вартості, це вказує на ефективний процес оптимізації.

На рисунку представлені розподіли ймовірностей значень цільових функцій. Для побудови цих розподілів візьми список значень цільових функцій із результату функції та підрахуй кількість входжень кожного значення вартості (значення округлені до другого десяткового знаку). Потім оновлюй стовпець кількостей відповідно, об'єднуючи кількості ідентичних округлених значень. Зверни увагу, що для кращого візуального порівняння кількості входжень нормалізовані так, щоб кожен розподіл відображався в діапазоні від 0 до 1. Візуалізація рішення оптимізації Як показано на рисунку (суцільна синя лінія), розподіл вартості для нашого підходу Варіаційного Квантового Власного Розкладача (постобробленого з SQD) різко сконцентрований на нижчих значеннях цільової функції, що свідчить про хорошу продуктивність оптимізації. На противагу цьому, шумова базова лінія має ширший розподіл, зосереджений навколо вищих значень вартості. Сіра штрихова вертикальна лінія представляє середнє значення випадкового розподілу, додатково підкреслюючи стабільність функції у поверненні оптимізованих інвестиційних стратегій. Для додаткового порівняння чорна штрихова лінія на рисунку відповідає рішенню, отриманому за допомогою оптимізатора Gurobi (безкоштовна версія). Всі ці результати детальніше розглядаються в бенчмарках нижче для прикладу "Mixed Assets", оціненого з ансатцем "Tailored".

Бенчмарки

Ця функція тестувалася за різних конфігурацій qubits роздільної здатності, схем ансатцу та груп активів із різних секторів: суміш різних активів (Набір 1), нафтові деривативи (Набір 2) та IBEX35 (Набір 3). Докладніші відомості наведені в таблиці нижче.

НабірДатаАктиви
Набір 101/01/20238801.T, CL=F, GBPJPY=X, ITX.MC, META, TMBMKDE-10Y, XS2239553048
Набір 201/06/2023CL=F, BZ=F, HO=F, NG=F, XOM, RB=F, 2222.SR
Набір 301/11/2022ACS.MC, ITX.MC, FER.MC, ELE.MC, SCYR.MC, AENA.MC, AMS.MC

Для оцінювання якості рішень використовувалися дві ключові метрики.

  1. Цільова вартість, яка вимірює ефективність оптимізації, порівнюючи значення цільової функції з кожного експерименту з результатами Gurobi (безкоштовна версія).
  2. Коефіцієнт Шарпа, який відображає скориговану на ризик прибутковість кожного портфеля, надаючи уявлення про фінансову ефективність рішень.

Разом ці метрики є бенчмарком як обчислювальних, так і фінансових аспектів квантово-згенерованих портфелів.

ПрикладQubitsАнсатцГлибинаВикористання Runtime (с)Загальне використання (с)Цільова вартістьШарпЦільова вартість GurobiШарп Gurobi
Mixed Assets (Набір 1, 4 часові кроки, 4-бітний)112Tailored831273513095-3.7824.82-4.2524.71
Mixed Assets (Набір 1, 4 часові кроки, 4 часові кроки, 4-бітний)112Real Amplitudes3591173911903-3.3923.64-4.2524.71
Oil Derivatives (Набір 2, 4 часові кроки, 3-бітний)84Optimized Real Amplitudes7861806350-3.7319.13-4.1921.71
IBEX35 (Набір 3, 4 часові кроки, 2-бітний)56Optimized Real Amplitudes9633143523-3.6714.48-4.1116.44

Результати показують, що квантовий оптимізатор із задачно-специфічними ансатцами ефективно визначає ефективні інвестиційні стратегії для різних типів портфелів. Нижче детально описані розмір популяції та кількість поколінь, вказані в словнику optimizer_options. Усі інші параметри були встановлені на значення за замовчуванням.

Прикладpopulation_sizenum_generations
Mixed Assets Portfolio9020
Mixed Assets Portfolio9220
Oil Derivatives Portfolio12020
IBEX35 Portfolio4020

Кількість поколінь була встановлена на 20, оскільки це значення виявилося достатнім для досягнення збіжності. Крім того, значення внутрішніх параметрів оптимізатора за замовчуванням залишилися незмінними, оскільки вони стабільно забезпечували хорошу продуктивність і загалом рекомендуються відповідною літературою та настановами з реалізації.

Отримати підтримку

Якщо тобі потрібна допомога, надішли електронного листа на qpo.support@globaldataquantum.com. У повідомленні вкажи ідентифікатор завдання функції.

Наступні кроки

Рекомендації