Sari la conținutul principal

Quantum Portfolio Optimizer: O Funcție Qiskit de la Global Data Quantum

notă

Funcțiile Qiskit sunt o funcționalitate experimentală disponibilă doar utilizatorilor planurilor IBM Quantum® Premium, Flex și On-Prem (prin API-ul IBM Quantum Platform). Acestea se află în stadiu de previzualizare și pot suferi modificări.

Prezentare generală

Quantum Portfolio Optimizer este o Funcție Qiskit care abordează problema optimizării dinamice a portofoliului, o problemă standard în finanțe ce urmărește reechilibrarea periodică a investițiilor într-un set de active, pentru a maximiza randamentele și a minimiza riscurile. Prin aplicarea tehnicilor de vârf din optimizarea cuantică, această funcție simplifică procesul astfel încât utilizatorii, fără expertiză în calculul cuantic, să poată beneficia de avantajele sale în identificarea traiectoriilor optime de investiție. Ideală pentru managerii de portofoliu, cercetătorii în finanțe cantitative și investitorii individuali, acest instrument permite back-testarea strategiilor de tranzacționare în optimizarea portofoliului.

Descrierea funcției

Funcția Quantum Portfolio Optimizer folosește algoritmul Variational Quantum Eigensolver (VQE) pentru a rezolva o problemă de Optimizare Binară Neconstrasă Pătratică (QUBO), abordând probleme de optimizare dinamică a portofoliului. Utilizatorii trebuie doar să furnizeze datele privind prețurile activelor și să definească constrângerea de investiție, după care funcția rulează procesul de optimizare cuantică ce returnează un set de traiectorii de investiție optimizate.

Procesul constă în patru etape principale. Mai întâi, datele de intrare sunt mapate într-o problemă compatibilă cu calculul cuantic, construindu-se qubo-ul problemei de optimizare dinamică a portofoliului și transformându-l într-un operator cuantic (Hamiltonianul Ising). Apoi, problema de intrare și algoritmul VQE sunt adaptate pentru a fi rulate pe hardware cuantic. Algoritmul VQE este apoi rulat pe hardware cuantic, iar în final, rezultatele sunt post-procesate pentru a furniza traiectoriile optime de investiție. Sistemul include, de asemenea, o post-procesare conștientă de zgomot (bazată pe SQD) pentru a maximiza calitatea rezultatelor.

Această Funcție Qiskit se bazează pe manuscrisul publicat de Global Data Quantum. Vizualizarea fluxului de lucru al funcției

Date de intrare

Argumentele de intrare ale funcției sunt descrise în tabelul următor. Datele despre active și alte specificații ale problemei trebuie furnizate; în plus, setările VQE pot fi incluse pentru a personaliza procesul de optimizare.

NumeTipDescriereObligatoriuImplicitExemplu
assetsjsonDicționar cu prețurile activelorDa--
qubo_settingsjsonSetările QUBODa-Vezi exemplele din tabelul de mai jos
ansatz_settingsjsonSetările ansatz-uluiNuNoneVezi exemplele din tabelul de mai jos.
optimizer_settingsjsonSetările Optimizer-uluiNuNoneVezi exemplele din tabelul de mai jos.
backendstrNumele backend-ului QPUNu-"ibm_torino"
previous_session_idlist of strLista ID-urilor de Session pentru a prelua date din rulări anterioare(*)NuListă goală["session_id_1", "session_id_2"]
apply_postprocessboolAplică post-procesarea SQD conștientă de zgomotNuTrueTrue
tagslist of stringsListă de etichete pentru identificarea experimentuluiNuListă goală["optimization", "quantum_computing"]

*Pentru a relua o execuție sau pentru a recupera job-uri procesate în una sau mai multe sesiuni anterioare, lista ID-urilor de Session trebuie pasată în parametrul previous_session_id. Acest lucru este deosebit de util în cazurile în care o sarcină de optimizare nu a putut fi finalizată din cauza unei erori în proces, iar execuția trebuie continuată. Pentru a realiza acest lucru, trebuie să furnizezi aceleași argumente utilizate în execuția inițială, împreună cu lista previous_session_id descrisă mai sus.

Avertisment

Încărcarea datelor pentru sesiunile anterioare (pentru reluarea unei optimizări) poate dura până la o oră.

assets

Datele trebuie structurate ca un obiect JSON ce stochează informații despre prețurile de închidere ale activelor financiare la date specifice. Formatul este următorul:

  • Cheie primară (string): Numele sau simbolul ticker al activului financiar (de exemplu, "8801.T").
  • Cheie secundară (string): Data în formatul YYYY-MM-DD.
  • Valoare (number): Prețul de închidere al activului la data specificată. Prețurile pot fi introduse fie normalizate, fie nenormalizate.

Rețineți că toate dicționarele trebuie să aibă aceeași cheie secundară (date). Dacă un anumit activ nu are o dată pe care celelalte o au, datele trebuie completate pentru a asigura consistența. De exemplu, acest lucru se poate face folosind ultimul preț de închidere înregistrat al acelui activ.

Exemplu

{
"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,
...
},
...
}
Notă

Datele despre active trebuie să conțină cel puțin prețurile de închidere la (nt+1) * dt (vezi secțiunea de intrare qubo_settings) marcaje temporale (de exemplu, zile).

qubo_settings

Tabelul următor descrie cheile dicționarului qubo_settings. Construiește dicționarul specificând numărul de pași de timp nt, numărul de Qubit-uri de rezoluție nq și max_investment - sau modifică alte valori implicite.

NumeTipDescriereObligatoriuImplicitExemplu
ntintNumărul de pași de timpDa-4
nqintNumărul de Qubit-uri de rezoluțieDa-4
max_investmentfloatNumărul maxim de unități de monedă investite pe toate activeleDa-10
dt*intFereastra de timp luată în considerare la fiecare pas de timp. Unitatea corespunde intervalelor de timp dintre cheile din datele activuluiNu30-
risk_aversionfloatCoeficientul de aversiune față de riscNu1000-
transaction_feefloatCoeficientul taxei de tranzacțieNu0.01-
restriction_coefffloatMultiplicatorul Lagrange utilizat pentru a impune constrângerea problemei în formularea QUBONu1-

ansatz_settings

Pentru a modifica opțiunile implicite, creează un dicționar pentru parametrul ansatz_settings cu cheile următoare. În mod implicit, ansatz-ul este setat la "real_amplitudes", iar ambele opțiuni suplimentare (vezi tabelul următor) sunt setate la False.

NumeTipDescriereObligatoriuImplicit
ansatz*stransatz-ul de utilizatNu"real_amplitudes"
multiple_passmanager**boolActivează subrutina multiple passmanager (indisponibilă pentru ansatz-ul Tailored)NuFalse
dd_enableboolAdaugă decuplare dinamicăNuFalse

* ansatz-uri disponibile

  • real_amplitudes
  • cyclic
  • optimized_real_amplitudes
  • tailored (Doar pentru backend-ul ibm_torino, 7 active, 4 pași de timp și 4 Qubit-uri de rezoluție)

** Dacă multiple_passmanager este setat la False, funcția folosește managerul de pasare implicit Qiskit cu optimization_level=3. Dacă este setat la True, subrutina multiple_passmanager compară trei manageri de pasare: managerul de pasare implicit Qiskit anterior, un manager de pasare care mapează Qubit-urile pe lanțul de vecini apropiați ai QPU și serviciile Transpiler AI. Apoi, este selectat managerul de pasare cu eroarea cumulată estimată mai mică.

optimizer_settings

Acest parametru este un dicționar cu câteva opțiuni reglabile ale procesului de optimizare.

NumeTipDescriereObligatoriuImplicit
primitive_optionsjsonSetările primitiveiNu-
optimizerstrOptimizer-ul clasic selectatNu"differential_evolution"
optimizer_optionsjsonConfigurarea Optimizer-uluiNu-
Notă

În prezent, singura opțiune de Optimizer disponibilă este "differential_evolution".

Sub cheile primitive_options și optimizer_options se setează dicționare cu următorii parametri:

primitive_options

NumeTipDescriereObligatoriuImplicitExemplu
sampler_shotsintNumărul de shot-uri ale Sampler-ului.Nu100000-
estimator_shotsintNumărul de shot-uri ale Estimator-ului.Nu25000-
estimator_precisionfloatPrecizia dorită a valorii așteptate. Dacă este specificată, precizia va fi utilizată în locul estimator_shots.NuNone0.015625 · (1 / sqrt(4096))
max_timeint or strDurata maximă de timp în care o Session de runtime poate rămâne deschisă înainte de a fi închisă forțat. Poate fi specificată în secunde (int) sau ca șir de caractere, precum "2h 30m 40s". Trebuie să fie mai mică decât maximul impus de sistem.NuNone"1h 15m"

optimizer_options

NumeTipDescriereObligatoriuImplicit
num_generationsintNumărul de generațiiNu20
population_sizeintMărimea populațieiNu20
mutation_rangelistFactorul maxim și minim de mutațieNu[0, 0.25]
recombinationfloatFactorul de recombinareNu0.4
max_parallel_jobsintNumărul maxim de job-uri QPU executate în paralelNu3
max_batchsizeintDimensiunea maximă a lotuluiNu200
Notă
  • Numărul de generații evaluate de evoluția diferențială este num_generations + 1, deoarece populația inițială este inclusă.

  • Numărul total de Circuit-uri este calculat ca (num_generations + 1) * population_size.

  • Utilizarea unei populații mai mari și a mai multor generații îmbunătățește în general calitatea rezultatelor optimizării. Cu toate acestea, nu se recomandă depășirea unui population_size de 120 și a unui număr de generații mai mare de 20 (de exemplu, 120 * 21 = 2520 Circuit-uri totale), deoarece aceasta ar genera un număr excesiv de Circuit-uri, care poate fi costisitor din punct de vedere computațional și consumator de timp.

  • Funcția îți permite să reiei optimizări anterioare și este întotdeauna posibil să crești numărul de generații (furnizând aceleași date de intrare, cu excepția previous_session_id și a unui num_generations mărit).

Notă

Asigură-te că respecți limitele job-urilor Qiskit Runtime.

  • Sampler: sampler_shots <= 10_000_000.
  • Estimator: max_batchsize * estimator_shots * observable_size <= 10_000_000 (pentru această funcție, toți termenii observabilului comutează, deci observable_size=1).

Vezi ghidul Limitele job-urilor pentru mai multe informații.

Rezultate

Funcția returnează două dicționare: dicționarul "result", care conține cele mai bune rezultate ale optimizării, inclusiv soluția optimă și costul obiectiv minim asociat; și "metadata", cu date din toate rezultatele obținute în timpul procesului de optimizare, împreună cu metricile respective.

Primul dicționar se concentrează pe soluția cu cele mai bune performanțe, în timp ce al doilea oferă informații detaliate despre toate soluțiile, inclusiv costurile obiective și alte metrici relevante.

Output dictionaries:

NumeTipDescriereExemplu
resultdict[str, dict[str, float]]Conține strategia de investiții în timp, fiecare marcaj temporal mapând ponderi de investiție specifice activelor (fiecare pondere reprezintă suma investită normalizată prin suma totală a investiției).{'time_1': {'asset_1': 0.2, 'asset_2': 0.3, ...\}, ...\}
metadatadict[str, Any]Date generate în timpul analizei, inclusiv soluții, costuri și metrici.Vezi exemplele de mai jos

Descrierea dicționarului metadata

NumeTipDescriereExemplu
session_idstrIdentificator unic pentru sesiunea IBM Quantum."d0h30qjvpqf00084fgw0"
all_samples_metricsdictDicționar care conține diverse metrici pentru fiecare eșantion postprocesat, cum ar fi costuri sau constrângeri.Vezi descrierea de mai jos
sampler_countsdict[str, int]Dicționar în care cheile sunt reprezentări sub formă de șir de biți ale soluțiilor eșantionate, iar valorile sunt numărul lor de apariții.{"101010": 3, "111000": 1\}
asset_orderlist[str]Listă cu ordinea de investiție corespunzătoare a activelor la fiecare pas de timp în cadrul strategiilor de investiții.["Asset_0", "Asset_1", "Asset_3"]
QUBOlist[list[float]]Matricea qubo a problemei.[[-6.96e-01, 5.81e-01, -1.26e-02, 0.00e+00], ...]
resource_summarydict[str, dict[str, float]]Rezumat al timpilor de utilizare CPU și QPU (în secunde) în diferite etape ale procesului.{'RUNNING: EXECUTING_QPU': {'CPU_TIME': 412.84, 'QPU_TIME': 87.22\}, ...\}

Descrierea dicționarului all_samples_metrics

NumeTipDescriereExemplu
investment_trajectorieslist[list]Strategii de investiții derivate din stările cuantice decodate.[[1, 2, 2], [1, 2, 1]]

| counts | list[int] | Numărul de ori în care fiecare traiectorie de investiție a fost eșantionată. Indexul corespunde cu investment_trajectories. | [5, 3] | | objective_costs | list[float] | Valoarea funcției obiectiv pentru fiecare traiectorie de investiție, ordonată de la cea mai mică la cea mai mare. | [0.98, 1.25] | | sharpe_ratios | list[float] | Performanța ajustată la risc (raportul Sharpe) pentru fiecare traiectorie de investiție. Aliniate după index. | [1.1, 0.7] | | returns | list[float] | Randamentul așteptat pentru fiecare traiectorie de investiție. Aliniat după index. | [0.15, 0.10] | | rest_breaches | list[float] | Abaterea maximă a constrângerii în cadrul fiecărei traiectorii de investiție. Aliniată după index. | [0.0, 0.25] | | transaction_costs | list[float] | Costul estimat al tranzacției asociat fiecărei traiectorii de investiție. Aliniat după index. | [0.01, 0.02] |

Începe

Autentifică-te folosind cheia ta API și selectează Qiskit Function-ul după cum urmează. (Acest fragment presupune că ți-ai salvat deja contul în mediul tău local.)

from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

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

Exemplu: Optimizarea dinamică a portofoliului cu șapte active

Acest exemplu demonstrează cum să execuți funcția de optimizare dinamică a portofoliului (DPO) și cum să îi ajustezi setările pentru performanță optimă. Include pași detaliați pentru reglarea fină a parametrilor în vederea obținerii rezultatelor dorite.

Acest caz implică șapte active, patru pași de timp și patru Qubit de rezoluție, rezultând un total de 112 qubiți necesari.

1. Citește activele incluse în portofoliu.

Dacă toate activele din portofoliu sunt stocate într-un folder la o cale specifică, le poți încărca într-un pandas.DataFrame și le poți converti în obiect de tip dict folosind funcția de mai jos.

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()

Pentru acest exemplu, am utilizat activele 8801.T, CLF, GBPJPY, ITX.MC, META, TMBMKDE-10Y și XS2239553048. Figura de mai jos ilustrează datele utilizate în acest exemplu, prezentând evoluția zilnică a prețului de închidere al activelor în perioada 1 ianuarie – 1 septembrie 2023.

În acest exemplu, pentru a asigura uniformitatea datelor, am completat zilele fără tranzacționare cu prețul de închidere din ziua disponibilă anterioară. Aplicăm acest pas deoarece activele selectate provin din piețe diferite cu zile de tranzacționare variate, fiind esențial să standardizăm setul de date pentru consistență. Visualization of the historical data of the assets

2. Definește problema.

Definește specificațiile problemei configurând parametrii din dicționarul 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. Definește setările Optimizer-ului și ale ansatz-ului. (Opțional)

Opțional, poți defini cerințe specifice pentru procesul de optimizare, inclusiv alegerea Optimizer-ului și a parametrilor acestuia, precum și specificarea primitivei și a configurațiilor sale.

Pentru Tailored Ansatz, dimensiunea populației aleasă s-a bazat pe experimente anterioare care au arătat că această valoare produce o optimizare stabilă și eficientă.

În cazul Real Amplitudes Ansatz, poți urma o relație liniară între population_size și numărul de qubiți din Circuit. Ca regulă aproximativă orientativă, se recomandă utilizarea unui population_size minim ~ 0.8 * n_qubits pentru ansatz-ul real_amplitudes.

Se preconizează că Optimized Real Amplitudes va avea o performanță de optimizare mai bună decât ansatz-ul Real Amplitudes. Totuși, numărul de variabile de optimizat în acest ansatz crește mult mai rapid decât în cazul Real Amplitudes (a se vedea manuscrisul). Prin urmare, pentru probleme de mari dimensiuni, Optimized Real Amplitudes necesită mai multe execuții de Circuit. Optimized Real Amplitudes este probabil util pentru probleme care necesită până la 100 de qubiți, însă se recomandă precauție la setarea parametrilor population_size. Ca exemplu al acestei scalări a population_size, tabelul anterior arată că pentru o problemă cu 84 de qubiți, Optimized Real Amplitudes necesită un population_size de 120, în timp ce pentru o problemă cu 56 de qubiți, un population_size de 40 este suficient.

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

De asemenea, este posibil să alegi un ansatz specific. Exemplul de mai jos folosește ansatz-ul 'Tailored'.

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

4. Run the problem.

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. Retrieve results.

Așa cum s-a menționat în secțiunea Output, funcția returnează un dicționar cu traiectoriile de investiții ordonate de la cea mai mică la cea mai mare valoare a funcției obiectiv. Acest set de rezultate permite identificarea traiectoriei cu cel mai mic cost și a evaluărilor corespunzătoare ale investițiilor. În plus, oferă posibilitatea de a analiza diferite traiectorii, facilitând selectarea celor care se aliniază cel mai bine cu nevoile sau obiectivele specifice. Această flexibilitate asigură că alegerile pot fi adaptate pentru a corespunde unei varietăți de preferințe sau scenarii. Începe prin a prezenta strategia rezultată care a obținut cel mai mic cost obiectiv găsit în timpul procesului.

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

Ulterior, folosind metadatele, poți accesa rezultatele tuturor strategiilor eșantionate. Astfel, poți analiza în continuare traiectoriile alternative returnate de Optimizer. Pentru a face acest lucru, citește dicționarul stocat în dpo_result['metadata']['all_samples_metrics'], care conține nu doar informații suplimentare despre strategia optimă, ci și detalii despre celelalte strategii candidate evaluate în timpul optimizării.

Următorul exemplu arată cum să citești aceste informații folosind pandas pentru a extrage valorile cheie asociate strategiei optime. Acestea includ Deviația de Restricție, Raportul Sharpe și rentabilitatea corespunzătoare a investiției.

# 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. Analiza performanței

În final, analizează performanța aplicației tale de optimizare. Mai concret, compară rezultatele tale, obținute în exemplul anterior, cu o linie de bază aleatorie pentru a evalua eficacitatea abordării noastre. Dacă algoritmul cuantic produce în mod demonstrabil și consistent rezultate cu valori de cost mai mici, acest lucru indică un proces de optimizare eficient.

Figura prezintă distribuțiile de probabilitate ale costurilor obiectiv. Pentru a genera aceste distribuții, ia lista costurilor obiectiv din rezultatul funcției și numără aparițiile fiecărei valori de cost (valori rotunjite la a doua zecimală). Apoi, actualizează coloana de numărare în mod corespunzător, combinând numărătorile valorilor rotunjite identice. Rețineți că, pentru o mai bună comparație vizuală, numărătorile de apariții au fost normalizate astfel încât fiecare distribuție să fie afișată între 0 și 1. Vizualizarea soluției optimizării Așa cum se arată în figură (linia albastră continuă), distribuția costurilor pentru abordarea noastră bazată pe Variational Quantum Eigensolver (post-procesată cu SQD) este puternic concentrată la valori de cost obiectiv mai mici, indicând o bună performanță de optimizare. În contrast, linia de bază cu zgomot prezintă o distribuție mai largă, centrată în jurul unor valori de cost mai mari. Linia verticală gri punctată reprezintă valoarea medie a distribuției aleatoare, evidențiind și mai mult consistența funcției în returnarea strategiilor de investiții optimizate. Ca o comparație suplimentară, linia neagră punctată din figură corespunde soluției obținute cu optimizatorul Gurobi (versiunea gratuită). Toate aceste rezultate sunt explorate mai detaliat în benchmark-urile de mai jos pentru exemplul „Active Mixte" evaluat cu ansatz-ul „Tailored".

Benchmark-uri

Această funcție a fost testată în diferite configurații de qubiți de rezoluție, circuite ansatz și grupări de active din diverse sectoare: un mix de active diferite (Setul 1), derivative petroliere (Setul 2) și IBEX35 (Setul 3). Vezi mai multe detalii în tabelul următor.

SetDatăActive
Setul 101/01/20238801.T, CL=F, GBPJPY=X, ITX.MC, META, TMBMKDE-10Y, XS2239553048
Setul 201/06/2023CL=F, BZ=F, HO=F, NG=F, XOM, RB=F, 2222.SR
Setul 301/11/2022ACS.MC, ITX.MC, FER.MC, ELE.MC, SCYR.MC, AENA.MC, AMS.MC

Au fost utilizate două metrici cheie pentru a evalua calitatea soluției.

  1. Costul obiectiv, care măsoară eficiența optimizării comparând valoarea funcției de cost din fiecare experiment cu rezultatele din Gurobi (versiunea gratuită).
  2. Indicele Sharpe, care surprinde randamentul ajustat la risc al fiecărui portofoliu, oferind o perspectivă asupra performanței financiare a soluțiilor.

Împreună, aceste metrici servesc drept benchmark atât pentru aspectele computaționale, cât și pentru cele financiare ale portofoliilor generate cuantic.

ExempluQubițiAnsatzAdâncimeUtilizare Runtime (s)Utilizare totală (s)Cost obiectivSharpeCost obiectiv GurobiSharpe Gurobi
Active Mixte (Setul 1, 4 pași de timp, 4 biți)112Tailored831273513095-3.7824.82-4.2524.71
Active Mixte (Setul 1, 4 pași de timp, 4 pași de timp, 4 biți)112Real Amplitudes3591173911903-3.3923.64-4.2524.71
Derivative Petroliere (Setul 2, 4 pași de timp, 3 biți)84Optimized Real Amplitudes7861806350-3.7319.13-4.1921.71
IBEX35 (Setul 3, 4 pași de timp, 2 biți)56Optimized Real Amplitudes9633143523-3.6714.48-4.1116.44

Rezultatele arată că Optimizer-ul cuantic, cu ansatz-uri specifice problemei, identifică eficient strategii de investiții eficiente pentru diverse tipuri de portofolii. Mai jos detaliem atât dimensiunea populației, cât și numărul de generații specificate în dicționarul optimizer_options. Toți ceilalți parametri au fost setați la valorile lor implicite.

Exemplupopulation_sizenum_generations
Portofoliu Active Mixte9020
Portofoliu Active Mixte9220
Portofoliu Derivative Petroliere12020
Portofoliu IBEX354020

Numărul de generații a fost setat la 20, deoarece s-a constatat că această valoare este suficientă pentru a atinge convergența. În plus, valorile implicite pentru parametrii interni ai optimizatorului au rămas neschimbate, deoarece acestea au furnizat în mod constant performanțe bune și sunt în general recomandate de literatura de specialitate și ghidurile de implementare.

Obține suport

Dacă ai nevoie de ajutor, poți trimite un e-mail la qpo.support@globaldataquantum.com. În mesajul tău, furnizează ID-ul jobului funcției.

Pașii următori

Recomandări