$nCycles$ - number of simulation cycles
$nBuyers$ - number of the buyers
$nSellers$ - number of the sellers
$seed$ - the seed of the random numbers
$d_0$ - the lower bound for random uniform numbers, both for the buyers and the sellers in the warming up phase; in the running phase, the lower bound is $0$
$d_1$ - the upper bound for random uniform numbers for the buyers
$d_2$ - the upper bound for random uniform numbers for the sellers
initial buyer $i$ reservation price, different for each buyer: $p_{b,i}=\frac{1} {1 + u_i}$ with $u_i\sim\mathcal{U}(d_0,d_1)$
initial seller j reservation price, different for each seller: $p_{s,j}=1 + u_j$ with $u_j\sim\mathcal{U}(d_0,d_2)$
the running prices are changing following the correction coefficients:
$c_b=\frac{1} {1 + u_b}$ or $c_b=1 + u_b$ with $u_b\sim\mathcal{U}(0,d_1)$
$c_s=\frac{1} {1 + u_s}$ or $c_s=1 + u_s$ with $u_s\sim\mathcal{U}(0,d_2)$
$buyersSellersRatio$ - the ratio $\frac{nBuyers}{nSellers}$
$sellersBuyersRatio$ - the ratio $\frac{nSellers}{nBuyers}$
$usingRatios$ - a logic variable activating limitations to $d_1$ or $d_2$
$squeezeRate$ - always $< 1$, as further compression of $d_1$ or $d_2$
$usingSqueezeRate$ - a logic variable to further squeeze $d_1$ or $d_2$
$buyerThreshold$ - over this number of failures, a special price correction occurs, multiplying the buyer price by $c_b=1 + u_b$ with $u_b\sim\mathcal{U}(0,d_{1_{overT}})$
$sellerThreshold$ - over this number of failures, a special price correction occurs, multiplying the seller price by $c_s=\frac{1} {1 + u_s}$ with $u_s\sim\mathcal{U}(0,d_{2_{overT}})$
%pylab inline
import statistics as s
import numpy as np
import pylab as plt
from ipywidgets import Output
from IPython.display import clear_output
from IPython.display import display
import time
import math
Populating the interactive namespace from numpy and matplotlib
# warming up for corrupted version
# execute before the corrupted hayekian version
def warmingUp():
global nCycles, nBuyers, nSellers,\
buyersSellersRatio, sellersBuyersRatio,\
usingRatios, usingSqueezeRate, squeezeRate,\
d0, d1, d2, buyerPriceList, sellerPriceList,\
sellerThreshold, buyerThreshold,\
d1overT, d2overT, fig0
nCycles=10000
nBuyers= 100
nSellers=100
buyersSellersRatio=nBuyers/nSellers
sellersBuyersRatio=nSellers/nBuyers
usingRatios=True
squeezeRate=0.3 # always < 1
usingSqueezeRate=False
seed=111
np.random.seed(seed)
d0=0.1
d1=0.2
d2=0.2
d1overT=0.4
d2overT=0.4
sellerThreshold=50
buyerThreshold =5
buyerPriceList=[]
sellerPriceList=[]
for i in range(nBuyers):
buyerPriceList.append([1/(1+np.random.uniform(d0,d1)),0])
for j in range(nSellers):
sellerPriceList.append([1+np.random.uniform(d0,d2),0])
#zip is an iterator and * means iteratable
fig0=plt.figure(0)
plt.plot(list(zip(*sorted(buyerPriceList,reverse=True)))[0],"r");
plt.plot(list(zip(*sorted(sellerPriceList)))[0],"b");
xlabel("the agents");
ylabel("agents' reservation prices");
# corrupted simplified hayekian perspective
warmingUp()
out = Output()
display(out)
meanPrice_ts=[]
meanPriceStDev_ts=[]
meanPriceVar_ts=[]
if usingRatios and not usingSqueezeRate:
if buyersSellersRatio>1: d2*=sellersBuyersRatio
if sellersBuyersRatio>1: d1*=buyersSellersRatio
if usingRatios and usingSqueezeRate:
if buyersSellersRatio>1: d2*=sellersBuyersRatio*squeezeRate
if sellersBuyersRatio>1: d1*=buyersSellersRatio*squeezeRate
for t in range(1,nCycles+1):
dealPrices=[]
agNum=max(nBuyers,nSellers)
for n in range(agNum):
i = np.random.randint(0,nBuyers)
j = np.random.randint(0,nSellers)
if buyerPriceList[i][0]>=sellerPriceList[j][0]:
dealPrices.append(sellerPriceList[j][0])
buyerPriceList[i][0] *=1/(1+np.random.uniform(0,d1))
buyerPriceList[i][1] =0 # success
sellerPriceList[j][0]*=1+np.random.uniform(0,d2)
sellerPriceList[j][1] =0 # success
else:
buyerPriceList[i][0] *=1+np.random.uniform(0,d1)
buyerPriceList[i][1] +=1 # failure
sellerPriceList[j][0]*=1/(1+np.random.uniform(0,d2))
sellerPriceList[j][1]+=1 # failure
# corrections
if buyerPriceList[i][1] > buyerThreshold:
buyerPriceList[i][0] *=1+np.random.uniform(0,d1overT)
buyerPriceList[i][1] =0
if sellerPriceList[j][1] > sellerThreshold:
sellerPriceList[j][0]*=1/(1+np.random.uniform(0,d2overT))
sellerPriceList[j][1]=0
if len(dealPrices) > 2:
meanPrice_ts.append(s.mean(dealPrices))
meanPriceVar_ts.append(s.variance(dealPrices))
meanPriceStDev_ts.append(s.stdev(dealPrices))
else:
meanPrice_ts.append(np.nan)
meanPriceStDev_ts.append(np.nan)
if t % 1000==0:
with out:
clear_output()
with out:
print('time', t, 'and n. of exchanges in the last cycle', \
len(dealPrices))
print(\
'mean and var of exchange prices in the last cycle: %1.3e, %1.3e' %\
(meanPrice_ts[-1],meanPriceVar_ts[-1]))
fig1=plt.figure(1,figsize=(7,15),clear=True)
plt.subplot(311)
plt.plot(list(zip(*sorted(buyerPriceList, reverse=True)))[0],"r")
plt.plot(list(zip(*sorted(sellerPriceList)))[0],"b")
plt.title(\
"buyers' prices (red) and sellers' prices (blue)")
xlabel("the agents")
ylabel("agents' reservation prices")
plt.subplot(312)
plt.title("mean price of each cycle")
xlabel("t")
ylabel("mean price of each cycle")
plt.plot(meanPrice_ts,"g")
plt.subplot(313)
plt.title("price coef. of variation within each cycle")
coefOfVariation=[]
for m in range(len(meanPriceStDev_ts)):
coefOfVariation.append(meanPriceStDev_ts[m]/
meanPrice_ts[m])
plt.plot(coefOfVariation,".",markersize=0.1)
xlabel("t")
ylabel("price coef. of variation within each cycle")
#plt.show() #activate to see intermadiate plots
#time.sleep(1)
# hist crashes with NaN
meanPrice_ts_hist=[]
for k in range(len(meanPrice_ts)):
if not math.isnan(meanPrice_ts[k]):
meanPrice_ts_hist.append(meanPrice_ts[k])
meanPriceStDev_ts_hist=[]
for k in range(len(meanPriceStDev_ts)):
if not math.isnan(meanPriceStDev_ts[k]):
meanPriceStDev_ts_hist.append(meanPriceStDev_ts[k])
fig2=plt.figure(2,figsize=(7,9))
plt.subplot(211)
if meanPrice_ts_hist != []:
plt.title("mean price histogram")
plt.hist(meanPrice_ts_hist,100,color="g");
plt.subplot(212)
if meanPriceStDev_ts_hist != []:
plt.title("price standard deviation (within each cycle) histogram")
plt.hist(meanPriceStDev_ts_hist,100);
Output()
# the buyers in order of reservation price
# and their successful buy acctions
fig3=plt.figure(3,figsize=(7,9))
plt.title("the buyers in order of reservation price "+\
"and their unsuccessful buy actions since the "+\
"last successful one");
plt.bar(list(zip(*sorted(buyerPriceList)))[0],\
list(zip(*sorted(buyerPriceList)))[1],0.001)
xlabel("reservation prices");
ylabel("unsuccessful buy actions");