ข้ามไปยังเนื้อหาหลัก

Quantum Portfolio Optimizer: A Qiskit Function by Global Data Quantum

หมายเหตุ

Qiskit Functions เป็นฟีเจอร์ทดลองที่ให้บริการเฉพาะสำหรับผู้ใช้ IBM Quantum® Premium Plan, Flex Plan และ On-Prem (via IBM Quantum Platform API) Plan เท่านั้น ขณะนี้อยู่ในสถานะ preview release และอาจมีการเปลี่ยนแปลง

ภาพรวม

Quantum Portfolio Optimizer คือ Qiskit Function ที่ออกแบบมาเพื่อแก้ปัญหา dynamic portfolio optimization ซึ่งเป็นปัญหาพื้นฐานในด้านการเงินที่มุ่งปรับสัดส่วนการลงทุนเป็นระยะ ๆ ในสินทรัพย์หลายประเภท เพื่อเพิ่มผลตอบแทนและลดความเสี่ยง ด้วยการใช้เทคนิค quantum optimization ล้ำสมัย ฟังก์ชันนี้ทำให้กระบวนการง่ายขึ้น ผู้ใช้ที่ไม่มีความเชี่ยวชาญด้าน quantum computing ก็สามารถได้รับประโยชน์จากมันในการหา investment trajectory ที่ดีที่สุด เหมาะสำหรับผู้จัดการพอร์ตโฟลิโอ นักวิจัยด้าน quantitative finance และนักลงทุนทั่วไป เครื่องมือนี้รองรับการ back-testing กลยุทธ์การซื้อขายในการ optimize พอร์ตโฟลิโอ

คำอธิบายฟังก์ชัน

Quantum Portfolio Optimizer ใช้อัลกอริทึม Variational Quantum Eigensolver (VQE) เพื่อแก้ปัญหา Quadratic Unconstrained Binary Optimization (QUBO) สำหรับ dynamic portfolio optimization ผู้ใช้เพียงแค่ระบุข้อมูลราคาสินทรัพย์และกำหนดเงื่อนไขการลงทุน จากนั้นฟังก์ชันจะรันกระบวนการ quantum optimization และคืนค่าชุด investment trajectory ที่ optimize แล้ว

กระบวนการประกอบด้วยสี่ขั้นตอนหลัก ขั้นแรก ข้อมูล input จะถูก map ไปยังปัญหาที่ compatible กับ quantum โดยสร้าง QUBO ของ dynamic portfolio optimization และแปลงเป็น quantum operator (Ising Hamiltonian) ต่อมา ปัญหา input และอัลกอริทึม VQE จะถูกปรับแต่งเพื่อรันบน quantum hardware จากนั้นรัน VQE บน quantum hardware และสุดท้ายผลลัพธ์จะถูก post-process เพื่อให้ได้ investment trajectory ที่ดีที่สุด ระบบยังมี noise-aware (SQD-based) post-processing เพื่อเพิ่มคุณภาพของ output ด้วย

Qiskit Function นี้อ้างอิงจาก published manuscript ของ Global Data Quantum

Visualization of the workflow of the function

Input

อาร์กิวเมนต์ input ของฟังก์ชันมีรายละเอียดในตารางต่อไปนี้ ต้องระบุข้อมูลสินทรัพย์และรายละเอียดของปัญหา นอกจากนี้ยังสามารถกำหนด VQE settings เพื่อปรับแต่งกระบวนการ optimize ได้

ชื่อประเภทคำอธิบายจำเป็นค่าเริ่มต้นตัวอย่าง
assetsjsonDictionary ที่เก็บราคาสินทรัพย์ใช่--
qubo_settingsjsonการตั้งค่าของ QUBOใช่-ดูตัวอย่างในตารางด้านล่าง
ansatz_settingsjsonการตั้งค่าของ ansatzไม่Noneดูตัวอย่างในตารางด้านล่าง
optimizer_settingsjsonการตั้งค่าของ optimizerไม่Noneดูตัวอย่างในตารางด้านล่าง
backendstrชื่อ QPU Backendไม่-"ibm_torino"
previous_session_idlist of strรายการ Session ID สำหรับดึงข้อมูลจากการรันก่อนหน้า(*)ไม่Empty list["session_id_1", "session_id_2"]
apply_postprocessboolใช้ noise-aware SQD post-processingไม่TrueTrue
tagslist of stringsรายการ tag สำหรับระบุ experimentไม่Empty list["optimization", "quantum_computing"]

หากต้องการรันต่อจากเดิมหรือดึง job ที่ประมวลผลใน Session ก่อนหน้า ให้ส่งรายการ Session ID ผ่านพารามิเตอร์ previous_session_id ซึ่งมีประโยชน์มากในกรณีที่ optimization task ล้มเหลวกลางคัน และต้องรันต่อจนเสร็จ ในการทำเช่นนั้น ต้องระบุอาร์กิวเมนต์เดิมที่ใช้ในการรันครั้งแรก พร้อมกับรายการ previous_session_id ตามที่อธิบาย

คำเตือน

การโหลดข้อมูลจาก Session ก่อนหน้า (เพื่อรันต่อ) อาจใช้เวลาสูงสุดหนึ่งชั่วโมง

assets

ข้อมูลต้องมีโครงสร้างเป็น JSON object ที่เก็บข้อมูลราคาปิดของสินทรัพย์ทางการเงินในวันที่ระบุ รูปแบบมีดังนี้

  • Primary key (string): ชื่อหรือสัญลักษณ์ ticker ของสินทรัพย์ทางการเงิน (เช่น "8801.T")
  • Secondary key (string): วันที่ในรูปแบบ YYYY-MM-DD
  • Value (number): ราคาปิดของสินทรัพย์ในวันที่ระบุ สามารถป้อนราคาแบบ normalized หรือไม่ normalized ก็ได้

โปรดทราบว่า dictionary ทั้งหมดต้องมี secondary key (วันที่) เหมือนกัน หากสินทรัพย์บางตัวไม่มีวันที่ที่สินทรัพย์อื่นมี ต้องเติมข้อมูลให้ครบเพื่อความสม่ำเสมอ เช่น สามารถใช้ราคาปิดล่าสุดที่บันทึกไว้ของสินทรัพย์นั้น

ตัวอย่าง

{
"8801.T": {
"2023-01-01": 2374.0,
"2023-01-02": 2374.0,
"2023-01-03": 2374.0,
"2023-01-04": 2356.5,
...
},
"AAPL": {
"2023-01-01": 145.2,
"2023-01-02": 146.5,
"2023-01-03": 147.3,
"2023-01-04": 148.1,
...
},
...
}
# Added by doQumentation — required packages for this notebook
!pip install -q pandas qiskit-ibm-catalog
{
"asset_name": {
"date": closing_value,
...
},
...
}
หมายเหตุ

ข้อมูลสินทรัพย์ต้องมีราคาปิดอย่างน้อย (nt+1) * dt timestamps (เช่น วัน) (ดูส่วน qubo_settings)

qubo_settings

ตารางต่อไปนี้อธิบาย key ของ dictionary qubo_settings สร้าง dictionary โดยระบุจำนวน time steps nt, จำนวน resolution Qubit nq, และ max_investment หรือจะเปลี่ยนค่า default อื่น ๆ ก็ได้

ชื่อประเภทคำอธิบายจำเป็นค่าเริ่มต้นตัวอย่าง
ntintจำนวน time stepsใช่-4
nqintจำนวน resolution Qubitใช่-4
max_investmentfloatจำนวนสูงสุดของหน่วยเงินที่ลงทุนรวมทุกสินทรัพย์ใช่-10
dt*intช่วงเวลาที่พิจารณาในแต่ละ time step หน่วยตรงกับช่วงเวลาระหว่าง key ในข้อมูลสินทรัพย์ไม่30-
risk_aversionfloatค่าสัมประสิทธิ์ความเกลียดความเสี่ยงไม่1000-
transaction_feefloatค่าสัมประสิทธิ์ค่าธรรมเนียมการซื้อขายไม่0.01-
restriction_coefffloatLagrange multiplier ที่ใช้บังคับเงื่อนไขของปัญหาใน QUBO formulationไม่1-

ansatz_settings

หากต้องการแก้ไข default options ให้สร้าง dictionary สำหรับพารามิเตอร์ ansatz_settings โดยมี key ดังต่อไปนี้ ค่าเริ่มต้นของ ansatz คือ "real_amplitudes" และทั้ง extra options (ดูตารางต่อไปนี้) ถูกตั้งเป็น False

ชื่อประเภทคำอธิบายจำเป็นค่าเริ่มต้น
ansatz*strAnsatz ที่จะใช้ไม่"real_amplitudes"
multiple_passmanager**boolเปิดใช้งาน multiple passmanager subroutine (ไม่รองรับสำหรับ Tailored ansatz)ไม่False
dd_enableboolเพิ่ม dynamical decouplingไม่False

* Ansatz ที่รองรับ

  • real_amplitudes
  • cyclic
  • optimized_real_amplitudes
  • tailored (เฉพาะ ibm_torino Backend, 7 สินทรัพย์, 4 time steps และ 4 resolution Qubit)

** ถ้า multiple_passmanager ถูกตั้งเป็น False ฟังก์ชันจะใช้ default Qiskit pass manager ที่มี optimization_level=3 ถ้าตั้งเป็น True subroutine multiple_passmanager จะเปรียบเทียบ pass manager สามตัว ได้แก่ default Qiskit pass manager เดิม, pass manager ที่ map Qubit ไปยัง QPU first neighbors chain และ AI transpiler services จากนั้นจะเลือก pass manager ที่มีค่า cumulative error ต่ำที่สุดโดยประมาณ

optimizer_settings

พารามิเตอร์นี้คือ dictionary ที่มี options ที่ปรับแต่งได้สำหรับกระบวนการ optimize

ชื่อประเภทคำอธิบายจำเป็นค่าเริ่มต้น
primitive_optionsjsonการตั้งค่าของ primitiveไม่-
optimizerstrclassical optimizer ที่เลือกไม่"differential_evolution"
optimizer_optionsjsonการกำหนดค่าของ optimizerไม่-
หมายเหตุ

ปัจจุบัน optimizer option ที่รองรับมีเพียง "differential_evolution" เท่านั้น

ภายใต้ key primitive_options และ optimizer_options เราตั้งค่า dictionary ที่มีพารามิเตอร์ดังต่อไปนี้

primitive_options

ชื่อประเภทคำอธิบายจำเป็นค่าเริ่มต้นตัวอย่าง
sampler_shotsintจำนวน shots ของ Samplerไม่100000-
estimator_shotsintจำนวน shots ของ Estimatorไม่25000-
estimator_precisionfloatความแม่นยำที่ต้องการของค่าคาดหวัง ถ้าระบุ จะใช้ precision แทน estimator_shotsไม่None0.015625 · (1 / sqrt(4096))
max_timeint or strเวลาสูงสุดที่ runtime session จะเปิดอยู่ได้ก่อนถูกปิดโดยบังคับ สามารถกำหนดเป็นวินาที (int) หรือ string เช่น "2h 30m 40s" ต้องน้อยกว่าค่าสูงสุดที่ระบบกำหนดไม่None"1h 15m"

optimizer_options

ชื่อประเภทคำอธิบายจำเป็นค่าเริ่มต้น
num_generationsintจำนวน generationไม่20
population_sizeintขนาดของ populationไม่20
mutation_rangelistค่า mutation factor สูงสุดและต่ำสุดไม่[0, 0.25]
recombinationfloatค่า recombination factorไม่0.4
max_parallel_jobsintจำนวนสูงสุดของ QPU job ที่รันแบบ parallelไม่3
max_batchsizeintขนาด batch สูงสุดไม่200
หมายเหตุ
  • จำนวน generation ที่ประเมินโดย differential evolution คือ num_generations + 1 เนื่องจาก population เริ่มต้นถูกรวมด้วย

  • จำนวน Circuit ทั้งหมดคำนวณเป็น (num_generations + 1) * population_size

  • การใช้ population size และจำนวน generation ที่มากขึ้นโดยทั่วไปจะปรับปรุงคุณภาพของผล optimization แต่ไม่แนะนำให้เกิน population size 120 และจำนวน generation มากกว่า 20 (เช่น 120 * 21 = 2520 Circuit ทั้งหมด) เพราะจะสร้าง Circuit จำนวนมากเกินไป ซึ่งอาจใช้ทรัพยากรการคำนวณและเวลามาก

  • ฟังก์ชันรองรับการรัน optimization ต่อจากครั้งก่อน และสามารถเพิ่มจำนวน generation ได้เสมอ (โดยใช้ input เดิมยกเว้น previous_session_id และเพิ่มค่า num_generations)

หมายเหตุ

ตรวจสอบให้แน่ใจว่าเป็นไปตามข้อจำกัด Qiskit Runtime job

  • Sampler: sampler_shots <= 10_000_000
  • Estimator: max_batchsize * estimator_shots * observable_size <= 10_000_000 (สำหรับฟังก์ชันนี้ ทุก term ของ observable commute กัน ดังนั้น observable_size=1)

ดูคำแนะนำ Job limits สำหรับข้อมูลเพิ่มเติม

Output

ฟังก์ชันคืนค่า dictionary สองตัว ได้แก่ dictionary "result" ที่มีผลลัพธ์ optimization ที่ดีที่สุด รวมถึง optimal solution และ minimum objective cost ที่เกี่ยวข้อง และ "metadata" ที่มีข้อมูลจากผลลัพธ์ทั้งหมดที่ได้ในระหว่างกระบวนการ optimize พร้อมกับ metric ที่เกี่ยวข้อง

Dictionary แรกมุ่งเน้นที่ solution ที่ทำงานได้ดีที่สุด ขณะที่ dictionary ที่สองให้ข้อมูลรายละเอียดเกี่ยวกับ solution ทั้งหมด รวมถึง objective cost และ metric อื่น ๆ ที่เกี่ยวข้อง

Output dictionaries

ชื่อประเภทคำอธิบายตัวอย่าง
resultdict[str, dict[str, float]]มีกลยุทธ์การลงทุนตามช่วงเวลา โดยแต่ละ timestamp จะ map ไปยังน้ำหนักการลงทุนเฉพาะสินทรัพย์ (น้ำหนักแต่ละตัวคือจำนวนเงินลงทุนที่ normalize ด้วยจำนวนเงินลงทุนรวม){'time_1': {'asset_1': 0.2, 'asset_2': 0.3, ...\}, ...\}
metadatadict[str, Any]ข้อมูลที่สร้างระหว่างการวิเคราะห์ รวมถึงผลลัพธ์ ต้นทุน และ metricsดูตัวอย่างด้านล่าง

คำอธิบาย dictionary metadata

ชื่อประเภทคำอธิบายตัวอย่าง
session_idstrตัวระบุเฉพาะสำหรับ IBM Quantum Session"d0h30qjvpqf00084fgw0"
all_samples_metricsdictDictionary ที่มี metrics ต่าง ๆ สำหรับแต่ละ sample ที่ผ่าน postprocess เช่น ต้นทุนหรือ constraintsดูคำอธิบายด้านล่าง
sampler_countsdict[str, int]Dictionary ที่ key เป็น bitstring ของผลลัพธ์ที่สุ่มได้และ value เป็นจำนวนครั้งที่พบ{"101010": 3, "111000": 1\}
asset_orderlist[str]List ที่แสดงลำดับการลงทุนของสินทรัพย์ในแต่ละ time step ภายในกลยุทธ์การลงทุน["Asset_0", "Asset_1", "Asset_3"]
QUBOlist[list[float]]QUBO matrix ของปัญหา[[-6.96e-01, 5.81e-01, -1.26e-02, 0.00e+00], ...]
resource_summarydict[str, dict[str, float]]สรุปเวลาการใช้งาน CPU และ QPU (หน่วยวินาที) ในแต่ละขั้นตอนของกระบวนการ{'RUNNING: EXECUTING_QPU': {'CPU_TIME': 412.84, 'QPU_TIME': 87.22\}, ...\}

คำอธิบาย dictionary all_samples_metrics

ชื่อประเภทคำอธิบายตัวอย่าง
investment_trajectorieslist[list]กลยุทธ์การลงทุนที่ได้จากการ decode quantum states[[1, 2, 2], [1, 2, 1]]

| counts | list[int] | จำนวนครั้งที่แต่ละ investment trajectory ถูกสุ่ม index ตรงกับ investment_trajectories | [5, 3] | | objective_costs | list[float] | ค่าของ objective function สำหรับแต่ละ investment trajectory เรียงจากต่ำสุดไปสูงสุด | [0.98, 1.25] | | sharpe_ratios | list[float] | ประสิทธิภาพที่ปรับตามความเสี่ยง (Sharpe ratio) สำหรับแต่ละ investment trajectory จัดเรียงตาม index | [1.1, 0.7] | | returns | list[float] | ผลตอบแทนที่คาดหวังสำหรับแต่ละ investment trajectory จัดเรียงตาม index | [0.15, 0.10] | | rest_breaches | list[float] | การเบี่ยงเบนสูงสุดของ constraint ภายในแต่ละ investment trajectory จัดเรียงตาม index | [0.0, 0.25] | | transaction_costs | list[float] | ต้นทุนธุรกรรมโดยประมาณของแต่ละ investment trajectory จัดเรียงตาม index | [0.01, 0.02] |

เริ่มต้นใช้งาน

ยืนยันตัวตนด้วย API key และเลือก Qiskit Function ดังนี้ (โค้ดนี้สมมติว่าคุณบันทึก account ไว้ในเครื่องแล้ว)

from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

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

ตัวอย่าง: Dynamic portfolio optimization กับเจ็ดสินทรัพย์

ตัวอย่างนี้แสดงวิธีรัน dynamic portfolio optimization (DPO) function และปรับแต่งการตั้งค่าเพื่อประสิทธิภาพสูงสุด โดยมีขั้นตอนละเอียดสำหรับการ fine-tune พารามิเตอร์เพื่อให้ได้ผลลัพธ์ที่ต้องการ

กรณีนี้ใช้เจ็ดสินทรัพย์ สี่ time steps และสี่ resolution qubits ทำให้ต้องการ Qubit รวมทั้งหมด 112 ตัว

1. อ่านสินทรัพย์ที่รวมอยู่ใน portfolio

ถ้าสินทรัพย์ทั้งหมดใน portfolio ถูกเก็บไว้ในโฟลเดอร์ที่ path หนึ่ง สามารถโหลดลง pandas.DataFrame และแปลงเป็น object รูปแบบ 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

ในตัวอย่างนี้ เพื่อให้ข้อมูลสอดคล้องกันในทุกวัน เราได้เติมวันที่ไม่ใช่วันซื้อขายด้วยราคาปิดจากวันที่มีข้อมูลก่อนหน้า ทำขั้นตอนนี้เพราะสินทรัพย์ที่เลือกมาจากตลาดต่างกันที่มีวันซื้อขายต่างกัน จึงจำเป็นต้องทำให้ชุดข้อมูลมีมาตรฐานเดียวกัน

Visualization of the historical data of the assets

2. กำหนดปัญหา

กำหนด specification ของปัญหาโดยตั้งค่าพารามิเตอร์ใน dictionary 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. กำหนดการตั้งค่า optimizer และ ansatz (ไม่บังคับ)

ตั้งค่าเฉพาะสำหรับกระบวนการ optimization ได้ตามต้องการ รวมถึงการเลือก optimizer และพารามิเตอร์ของมัน รวมถึงการระบุ primitive และการตั้งค่าต่าง ๆ

สำหรับ Tailored Ansatz ขนาด population size ที่เลือกมาจากการทดลองก่อนหน้าที่แสดงว่าค่านี้ให้ผล optimization ที่เสถียรและมีประสิทธิภาพ

สำหรับ Real Amplitudes Ansatz สามารถใช้ความสัมพันธ์เชิงเส้นระหว่าง population_size กับจำนวน Qubit ใน Circuit ได้ ตามกฎคร่าว ๆ แนะนำให้ใช้ population_size ~ 0.8 * n_qubits ขั้นต่ำ สำหรับ ansatz real_amplitudes

คาดว่า Optimized Real Amplitudes จะมีประสิทธิภาพ optimization ดีกว่า Real Amplitudes ansatz อย่างไรก็ตาม จำนวนตัวแปรที่ต้อง optimize ใน ansatz นี้เพิ่มขึ้นเร็วกว่า Real Amplitudes มาก (ดูงานวิจัย) ดังนั้นสำหรับปัญหาขนาดใหญ่ Optimized Real Amplitudes ต้องการการรัน Circuit มากขึ้น Optimized Real Amplitudes น่าจะเหมาะกับปัญหาที่ต้องการ Qubit ไม่เกิน 100 ตัว แต่ควรระวังในการตั้งค่าพารามิเตอร์ population_size เพื่อเป็นตัวอย่างของการ scale-up ใน population_size ตารางก่อนหน้าแสดงว่าสำหรับปัญหา 84 Qubit Optimized Real Amplitudes ต้องการ population_size 120 ขณะที่ปัญหา 56 Qubit ใช้ 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,
},
}

นอกจากนี้ยังสามารถเลือก ansatz เฉพาะได้ ตัวอย่างต่อไปนี้ใช้ ansatz '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. ดึงผลลัพธ์

ตามที่กล่าวไว้ในส่วน Output ฟังก์ชันส่งคืน dictionary ที่มี investment trajectories เรียงจากต่ำสุดไปสูงสุดตามค่า objective function ผลลัพธ์ชุดนี้ช่วยระบุ trajectory ที่มีต้นทุนต่ำสุดและการประเมินการลงทุนที่สอดคล้องกัน นอกจากนี้ยังเปิดโอกาสให้วิเคราะห์ trajectories ทางเลือกต่าง ๆ ทำให้เลือกได้ว่าแบบไหนตรงกับความต้องการหรือเป้าหมายของตัวเองมากที่สุด ความยืดหยุ่นนี้ทำให้ปรับแต่งการเลือกให้เหมาะกับสถานการณ์ที่หลากหลาย

เริ่มต้นด้วยการแสดงกลยุทธ์ผลลัพธ์ที่ได้ objective cost ต่ำสุดที่พบในระหว่างกระบวนการ

# 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}}

หลังจากนั้น ใช้ metadata เพื่อเข้าถึงผลลัพธ์ของกลยุทธ์ทั้งหมดที่ถูกสุ่ม จึงวิเคราะห์ trajectories ทางเลือกที่ optimizer ส่งคืนได้ต่อไป โดยอ่าน dictionary ที่เก็บไว้ใน dpo_result['metadata']['all_samples_metrics'] ซึ่งมีทั้งข้อมูลเพิ่มเติมเกี่ยวกับกลยุทธ์ที่ดีที่สุด และรายละเอียดของกลยุทธ์ผู้สมัครอื่น ๆ ที่ถูกประเมินระหว่าง optimization

ตัวอย่างต่อไปนี้แสดงวิธีอ่านข้อมูลนี้โดยใช้ pandas เพื่อดึง key metrics ที่เกี่ยวข้องกับกลยุทธ์ที่ดีที่สุด ได้แก่ Restriction Deviation, Sharpe Ratio และผลตอบแทนการลงทุนที่สอดคล้องกัน

# 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. การวิเคราะห์ประสิทธิภาพ

สุดท้าย วิเคราะห์ประสิทธิภาพของแอปพลิเคชัน optimization ของคุณ โดยเฉพาะเปรียบเทียบผลลัพธ์ที่ได้จากตัวอย่างก่อนหน้ากับ random baseline เพื่อประเมินประสิทธิผลของแนวทางที่ใช้ ถ้า quantum algorithm แสดงให้เห็นอย่างชัดเจนและสม่ำเสมอว่าได้ค่าต้นทุนต่ำกว่า แสดงว่ากระบวนการ optimization มีประสิทธิภาพ

รูปแสดง probability distributions ของ objective costs เพื่อสร้าง distributions เหล่านี้ ให้นำ list ของ objective costs จากผลลัพธ์ฟังก์ชันและนับการปรากฏของแต่ละค่า (ค่าถูก round ไป 2 ทศนิยม) จากนั้นอัปเดต count column ตามนั้นโดย join counts ของค่า round ที่เหมือนกัน ทั้งนี้ เพื่อการเปรียบเทียบที่มองเห็นได้ชัดขึ้น occurrence counts ถูก normalize ให้แต่ละ distribution แสดงระหว่าง 0 ถึง 1

Visualization of the solution of the optimization

ดังที่เห็นในรูป (เส้นสีน้ำเงิน) cost distribution ของแนวทาง Variational Quantum Eigensolver (ผ่าน postprocess ด้วย SQD) กระจุกตัวอย่างชัดเจนที่ค่า objective cost ต่ำ บ่งชี้ประสิทธิภาพ optimization ที่ดี ในทางตรงกันข้าม noisy baseline มี distribution กว้างกว่า โดยศูนย์กลางอยู่ที่ค่าต้นทุนสูงกว่า เส้นประแนวตั้งสีเทาแสดงค่าเฉลี่ยของ random distribution เน้นย้ำถึงความสม่ำเสมอของฟังก์ชันในการส่งคืนกลยุทธ์การลงทุนที่ผ่าน optimization แล้ว สำหรับการเปรียบเทียบเพิ่มเติม เส้นประสีดำในรูปแสดงผลลัพธ์ที่ได้จาก Gurobi optimizer (เวอร์ชันฟรี) ผลลัพธ์ทั้งหมดนี้ถูกสำรวจเพิ่มเติมใน benchmarks ด้านล่างสำหรับตัวอย่าง "Mixed Assets" ที่ประเมินด้วย ansatz "Tailored"

Benchmarks

ฟังก์ชันนี้ถูกทดสอบภายใต้การตั้งค่าต่าง ๆ ของ resolution qubits, ansatz circuits และกลุ่มสินทรัพย์จากหลายภาคส่วน ได้แก่ สินทรัพย์ผสม (Set 1) อนุพันธ์น้ำมัน (Set 2) และ IBEX35 (Set 3) ดูรายละเอียดเพิ่มเติมในตารางต่อไปนี้

Setวันที่สินทรัพย์
Set 101/01/20238801.T, CL=F, GBPJPY=X, ITX.MC, META, TMBMKDE-10Y, XS2239553048
Set 201/06/2023CL=F, BZ=F, HO=F, NG=F, XOM, RB=F, 2222.SR
Set 301/11/2022ACS.MC, ITX.MC, FER.MC, ELE.MC, SCYR.MC, AENA.MC, AMS.MC

ใช้ metrics หลักสองตัวในการประเมินคุณภาพของผลลัพธ์

  1. Objective cost ที่วัดประสิทธิภาพ optimization โดยเปรียบเทียบค่า cost function จากแต่ละการทดลองกับผลลัพธ์จาก Gurobi (เวอร์ชันฟรี)
  2. Sharpe ratio ที่ capture ผลตอบแทนที่ปรับตามความเสี่ยงของแต่ละ portfolio ให้ข้อมูลเชิงลึกเกี่ยวกับประสิทธิภาพทางการเงินของผลลัพธ์

metrics เหล่านี้ร่วมกัน benchmark ทั้งด้านการคำนวณและด้านการเงินของ portfolio ที่สร้างโดย quantum

ตัวอย่างQubitAnsatzDepthRuntime Usage (s)Total usage (s)Objective costSharpeGurobi objective costGurobi Sharpe
Mixed Assets (Set 1, 4 time steps, 4-bit)112Tailored831273513095-3.7824.82-4.2524.71
Mixed Assets (Set 1,4 time steps, 4 time steps, 4-bit)112Real Amplitudes3591173911903-3.3923.64-4.2524.71
Oil Derivatives (Set 2, 4 time steps, 3-bit)84Optimized Real Amplitudes7861806350-3.7319.13-4.1921.71
IBEX35 (Set 3, 4 time steps, 2-bit)56Optimized Real Amplitudes9633143523-3.6714.48-4.1116.44

ผลลัพธ์แสดงว่า quantum optimizer ที่ใช้ ansatz เฉพาะปัญหาสามารถระบุกลยุทธ์การลงทุนที่มีประสิทธิภาพได้ในหลากหลายประเภท portfolio

ด้านล่างนี้ระบุรายละเอียดทั้ง population size และจำนวน generations ที่กำหนดใน dictionary optimizer_options พารามิเตอร์อื่น ๆ ทั้งหมดถูกตั้งเป็นค่า default

ตัวอย่างpopulation_sizenum_generations
Mixed Assets Portfolio9020
Mixed Assets Portfolio9220
Oil Derivatives Portfolio12020
IBEX35 Portfolio4020

จำนวน generations ถูกกำหนดเป็น 20 เนื่องจากพบว่าค่านี้เพียงพอสำหรับการ converge นอกจากนี้ ค่า default ของพารามิเตอร์ภายในของ optimizer ถูกปล่อยไว้ไม่เปลี่ยนแปลง เพราะให้ประสิทธิภาพที่ดีอย่างสม่ำเสมอและแนะนำโดยทั่วไปในเอกสารและแนวทางการ implementation

รับการสนับสนุน

ถ้าต้องการความช่วยเหลือ ส่งอีเมลไปที่ qpo.support@globaldataquantum.com พร้อมระบุ function job ID ในข้อความ

ขั้นตอนถัดไป

Recommendations
Source: IBM Quantum docs — updated 27 มี.ค. 2569
English version on doQumentation — updated 7 พ.ค. 2569
This translation based on the English version of 11 มี.ค. 2569