import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from pygrnd.qc.probabilisticNetworks import *
from pygrnd.qc.parallelQAE import constructGroverOperator, circuitStandardQAE, bit2prob, maxString
from pygrnd.qc.lowDepthQAEgradientDescent import *
from pygrnd.qc.helper import counts2probs
from qiskit.visualization import plot_histogram
from qiskit import transpile
from qiskit.circuit.library.standard_gates import ZGate

jos_palette = ['#4c32ff', '#b332ff', '#61FBF8', '#1E164F', '#c71ab1ff']
sns.set_palette(jos_palette)

matplotlib.rcParams.update({'font.size': 16})
				
			
In [2]:
import matplotlib.pyplot as plt import numpy as np import seaborn as sns from pygrnd.qc.probabilisticNetworks import * from pygrnd.qc.parallelQAE import constructGroverOperator, circuitStandardQAE, bit2prob, maxString from pygrnd.qc.lowDepthQAEgradientDescent import * from pygrnd.qc.helper import counts2probs from qiskit.visualization import plot_histogram from qiskit import transpile from qiskit.circuit.library.standard_gates import ZGate jos_palette = ['#4c32ff', '#b332ff', '#61FBF8', '#1E164F', '#c71ab1ff'] sns.set_palette(jos_palette) matplotlib.rcParams.update({'font.size': 16})

Financial network simulation on quantum computers (model only)

Here we present a quantum risk model that can be used to model time evolution of probabilistic networks. This can be used to model counterparty risks of financial institutions, companies and their clients. It allows for arbitrary network topologies including cycles, as each time step depends only on the states of the previous time steps. Each node NN represents an institutions with a certain probabilitiy of default pp. Also the nodes are connected with a transition probability tt. Furthermore, each node comes with a recovery probability rr that allows a node to recover after a failure with a certain probability. For example a bank has a probability of default of 2%, a correlation to another bank and a recovery probability of 30% in the next time step.

This is only a very small example but the space of possible solutions is already 26=642^6 = 64 and the space of possible solutions grows with number of nodes N ×\times time steps TT.

For 100 banks and 365 time steps this would already imply a possible state space of 2100×3652^{100\times365}. This would require a lot of classical Monte Carlo simulations to evaulate tail events.

Small example of a financial network with 2 banks

Definition of network topology and probabilities

In this example we have 2 banks: bank1, bank2

They have probabilities of default: p1, p2

Recovery probabilities after default: r1, r2

Transition orobabilities: t1, t2

In [3]:
nodes=['bank1','bank2'] ## nodes of the network p1=0.02 ## probability of default for bank 1 p2=0.05 ## probability of default for bank 2 probFail={'bank1':p1,'bank2':p2} r1=0.3 ## recover probability for bank 1 r2=0.8 ## recover probability for bank 2 probRecovery={'bank1':r1,'bank2':r2} t1=0.002 ## transition probability between bank 1 and bank 2 edges={('bank1','bank2'):t1} ## correlation and probabilities of transition between banks ## this function returns the quantum circuit for the network model timesteps=3 qc,qr,cr=createCircuit(timesteps, nodes, probFail, probRecovery, edges) qc.draw(output='mpl')
Out[3]:
Image in a Jupyter notebook
In [4]:
## evaluation of scenarios resultQuantum=evaluateQuantum(timesteps, nodes, probFail, probRecovery, edges) #print("quantum evaluation:",resultQuantum) print("The results are the probabilities for each scenario in the last time step:") print("probability of bank1 and bank2 healthy: ",resultQuantum[0]) print("probability of bank2 being defaulted: ",resultQuantum[1]) print("probability of bank1 being defaulted: ",resultQuantum[2]) print("probability of bank1 and bank2 being defaulted: ",resultQuantum[3])
Out[4]:
The results are the probabilities for each scenario in the last time step: probability of bank1 and bank2 healthy: 0.9010181984838997 probability of bank2 being defaulted: 0.05613380151610001 probability of bank1 being defaulted: 0.04029126532909998 probability of bank1 and bank2 being defaulted: 0.0025567346709000007

Here are the plots of the probabilities

In [6]:
N = 100000 # number of shots # Measure the last two qubits at the end and simulate the circuit with 1000 shots. qc.measure(qr[len(qr)-len(nodes):],cr) backend_qiskit = Aer.get_backend(name='qasm_simulator') job = execute(qc, backend_qiskit,shots=N) c = job.result().get_counts() probs={x:c[x]/sum(c.values()) for x in c} fig,axs=plt.subplots(1) plot_histogram([probs],legend=['100000 shots'],color=jos_palette[:2],ax=axs) axs.set(xlabel='result',ylabel='probability') #print(axs) #axs.text(24,0.55,r'default',fontsize=10)
Out[6]:
[Text(0.5, 0, 'result'), Text(0, 0.5, 'probability')]
Image in a Jupyter notebook

Results:

00 --> both banks healty: 90.1%

01 --> bank 1 defaulted, bank 2 healthy: 4.1%

10 --> bank 1 healthy, bank 2 defaulted: 5.6%

11 --> bank 1 defaulted, bank 2 defaulted: 0.2%

Remark

Evaluating the probabilities by just measuring the model is classical Monte Carlo simulation on a quantum computer. To benefit from quantum speedups we have to use QAE. This will be the topic of a further blog.