量子ポートフォリオオプティマイザー: Global Data QuantumによるQiskit Function
APIリファレンスを参照してください。
Qiskit Functionsは、IBM Quantum® Premiumプラン、Flexプラン、およびOn-Prem(IBM Quantum Platform API経由)プランのユーザーのみが利用できる実験的な機能です。プレビューリリースの状態であり、変更される場合があります。
概要
量子ポートフォリオオプティマイザーは、動的ポートフォリオ最適化問題に取り組むQiskit Functionです。これは、リターンを最大化しリスクを最小化するために、一連の資産にわたる定期的な投資のリバランスを目的とする、金融における標準的な問題です。最先端の量子最適化技術を活用することで、この関数はプロセスを簡素化し、量子コンピューティングの専門知識がないユーザーでも、最適な投資トラジェクトリーを見つけるうえでその利点を活用できるようにします。ポートフォリオマネージャー、定量的金融の研究者、および個人投資家に最適で、このツールはポートフォリオ最適化における取引戦略のバックテストを可能にします。
関数の説明
量子ポートフォリオオプティマイザー関数は、変分量子固有値ソルバー(VQE)アルゴリズムを使用して二次制約なし二値最適化(QUBO)問題を解き、動的ポートフォリオ最適化問題に対処します。ユーザーは資産価格データを提供し、投資制約を定義するだけで、関数が量子最適化プロセスを実行し、最適化された投資トラジェクトリーのセットを返します。
このプロセスは4つの主要なステージで構成されています。まず、入力データを量子互換の問題にマッピングし、動的ポートフォリオ最適化問題の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")
例:7資産を用いた動的ポートフォリオ最適化
この例では、動的ポートフォリオ最適化(DPO)関数を実行し、最適なパフォーマンスを得るためにその設定を調整する方法を示します。最適な結果を得るためにパラメーターをファインチューニングするための詳細な手順が含まれています。
このケースでは、7資産、4タイムステップ、4分解量子ビットを使用しており、合計112量子ビットが必要となります。
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の資産を使用しています。以下の図は、この例で使用したデータを示しており、2023年1月1日から9月1日までの資産の日次終値の推移を示しています。
この例では、日付全体で均一性を確保するために、非取引日には直前の利用可能な日付の終値を補完しています。選択した資産が取引日の異なる複数の市場に属しているため、データセットの一貫性を標準化するためにこのステップを適用しています。
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と回路内の量子ビット数の間の線形関係に従うことができます。経験則として、real_amplitudesアンザッツには最低population_size ~ 0.8 * n_qubitsを使用することが推奨されます。
Optimized Real AmplitudesはReal Amplitudesアンザッツよりも優れた最適化性能を発揮することが期待されます。ただし、このアンザッツで最適化する変数の数はReal Amplitudesの場合よりもはるかに速く増加します(論文を参照)。したがって、大規模な問題では、Optimized Real Amplitudesはより多くの回路実行が必要です。Optimized Real Amplitudesは最大100量子ビットを必要とする問題に有効である可能性が高いですが、population_sizeパラメーターを設定する際には注意が必要です。このpopulation_sizeのスケールアップの例として、前の表では84量子ビットの問題でOptimize Real Amplitudesが120のpopulation_sizeを必要とするのに対し、56量子ビットの問題では40のpopulation_sizeで十分であることを示しています。
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. パフォーマンス分析
最後に、最適化アプリケーションのパフォーマンスを分析します。具体的には、前の例で得られた結果をランダムベースラインと比較して、このアプローチの有効性を評価します。量子アルゴリズムが一貫してより低いコスト値の結果を出す場合、それは効果的な最適化プロセスを示しています。
この図は目的コストの確率分布を示しています。これらの分布を生成するには、関数の結果から目的コストのリストを取得し、各コスト値の出現回数をカウントします(値は小数点以下2桁に丸められます)。その後、同一の丸められた値のカウントを結合することでカウント列を更新します。なお、視覚的な比較のために、出現カウントは各分布が0から1の間で表示されるように正規化されています。
図に示されているように(青い実線)、変分量子固有値ソルバー(SQDによるポストプロセッシング)アプローチのコスト分布は、より低い目的コスト値に鋭く集中しており、良好な最適化パフォーマンスを示しています。対照的に、ノイジーなベースラインはより広い分布を示し、より高いコスト値を中心としています。灰色の破線の垂直線はランダム分布の平均値を表しており、最適化された投資戦略を返す関数の一貫性をさらに強調しています。追加の比較として、図中の黒い破線はGurobiオプティマイザー(無料版)で得られた解に対応しています。これらの結果はすべて、「Tailored」アンザッツで評価された「Mixed Assets」の例についての以下のベンチマークでさらに検討されています。
ベンチマーク
この関数は、分解量子ビット、アンザッツ回路、およびさまざまなセクターからの資産グループの異なる設定でテストされました:さまざまな資産の混合(セット1)、石油デリバティブ(セット2)、およびIBEX35(セット3)。詳細は以下の表を参照してください。
| セット | 日付 | 資産 |
|---|---|---|
| セット1 | 01/01/2023 | 8801.T, CL=F, GBPJPY=X, ITX.MC, META, TMBMKDE-10Y, XS2239553048 |
| セット2 | 01/06/2023 | CL=F, BZ=F, HO=F, NG=F, XOM, RB=F, 2222.SR |
| セット3 | 01/11/2022 | ACS.MC, ITX.MC, FER.MC, ELE.MC, SCYR.MC, AENA.MC, AMS.MC |
解の品質を評価するために2つの主要なメトリクスが使用されました。
- 目的コスト。各実験のコスト関数値をGurobi(無料版)の結果と比較することで最適化効率を測定します。
- シャープ比。各ポートフォリオのリスク調整後リターンを捉え、解の金融パフォーマンスへの洞察を提供します。
これらのメトリクスを組み合わせることで、量子生成ポートフォリオの計算面と金融面の両方をベンチマークします。
| 例 | 量子ビット | アンザッツ | 深度 | ランタイム使用量(秒) | 総使用量(秒) | 目的コスト | シャープ | Gurobi目的コスト | GurobiシャープF |
|---|---|---|---|---|---|---|---|---|---|
| Mixed Assets(セット1、4タイムステップ、4ビット) | 112 | Tailored | 83 | 12735 | 13095 | -3.78 | 24.82 | -4.25 | 24.71 |
| Mixed Assets(セット1、4タイムステップ、4タイムステップ、4ビット) | 112 | Real Amplitudes | 359 | 11739 | 11903 | -3.39 | 23.64 | -4.25 | 24.71 |
| Oil Derivatives(セット2、4タイムステップ、3ビット) | 84 | Optimized Real Amplitudes | 78 | 6180 | 6350 | -3.73 | 19.13 | -4.19 | 21.71 |
| IBEX35(セット3、4タイムステップ、2ビット) | 56 | Optimized Real Amplitudes | 96 | 3314 | 3523 | -3.67 | 14.48 | -4.11 | 16.44 |
結果は、問題固有のアンザッツを使用した量子オプティマイザーが、さまざまなポートフォリオタイプにわたって効率的な投資戦略を効果的に識別することを示しています。
以下に、optimizer_options辞書で指定された集団サイズと世代数の両方を詳述します。その他のすべてのパラメーターはデフォルト値に設定されています。
| 例 | population_size | num_generations |
|---|---|---|
| Mixed Assets Portfolio | 90 | 20 |
| Mixed Assets Portfolio | 92 | 20 |
| Oil Derivatives Portfolio | 120 | 20 |
| IBEX35 Portfolio | 40 | 20 |
世代数は20に設定されました。この値で収束に達するのに十分であることが確認されたためです。また、オプティマイザーの内部パラメーターのデフォルト値は変更されていません。これらは一貫して良好なパフォーマンスを提供し、一般的に文献および実装ガイドラインで推奨されているためです。
サポートを受ける
ヘルプが必要な場合は、qpo.support@globaldataquantum.comにメールを送信してください。メッセージには関数のジョブIDを記載してください。
次のステップ
- 関連する研究論文を読む。
-
- このQiskit FunctionのAPIリファレンスを参照する。
- このフォームを記入して関数へのアクセスを申請する。
- 動的ポートフォリオ最適化チュートリアルを試す。