NB. based on Kenneth Steiglitz model circa 1996
NB. (c) 2014 Konstantin L. Metlov
NB. Simulation parameters
NB. ------- Production agents
rskillf =: 0.9 4 NB. min and max food skill of the producing agent
rskillg =: 0.9 4 NB. min and max gold skill of the producing agent
rreserve =: 20 40 NB. min and max reserve of the producing agent
np =: 100 NB. number of producing agents
b00 =: 4.0 NB. producer bid function at fp=0 and gp=0
b01 =: 8.0 NB. producer bid function at fp=0 and gp=1
b0inf =: 16.0 NB. producer bid function at fp=0 and gp=infinity
NB. 'np rr (min, max)' generates np random numbers
NB. in the range from min to max
rr =: ([: {. ]) + ([: ?. [ # 0:) * [: -~/ ]
NB. stats of each of the producing agents
ps =: (np rr rskillf) , (np rr rskillg) ,: np rr rreserve
specturn =: 200 NB. turn at which speculators come into play
NB. ------- DER speculators
nder =: 10 NB. number of der speculators
rmarginder =: 0.0 0.5 NB. min and max margin of der speculators
ders =: nder rr rmarginder NB. stats (margins) of der speculators
NB. ------- AVG speculators
navg =: 10 NB. number of der speculators
rmarginavg =: 0.0 0.5 NB. min and max margin of der speculators
beta =: 0.05 NB. forecast coefficient (memory of the agent)
avgs =: navg rr rmarginavg NB. stats (margins) of der speculators
NB. An agent verb is a dyad, called as "prices aprod state",
NB. which takes an array of past prices (with the most recent
NB. at the end) and the state of each agent (defined by the 2-d array
NB. of their food and gold inventories and computes a 2-d array,
NB. with first two rows being the new state (after production and
NB. consumption, for example) and the other two rows represent the
NB. market orders of the agents: food amount (positive for buy
NB. order and negatibe for sell) and the price per unit. Zero food
NB. amount indicates the absence of the order (in which case the
NB. price is irrelevant).
NB. production agent verb
gamma=: ^. (b0inf - b00) % b0inf - b01
aprod=: 4 : 0
p =. {: x NB. last price
t =. <:/ (p,1) * 2 {. ps NB. production type of each agent (0 - food,1-gold)
ns =. y + (|: t { (1 0 ,: 0 1)) * 2 {. ps NB. new state after production
NB. consumption
ns =. ns - 1 0
NB. utility function
fp =. (0 { ns) % 2 { ps
gp =. (1 { ns) % p * 2 { ps
uf =. (b0inf - (b0inf - b00) * ^ - gamma * gp) ^ 1 - fp
NB. bids to buy are limited by the gold reserve
cb =. (2 { ps) - 0 { ns NB. desired bid
mb =. (1 { ns) % (p*uf) NB. maximum amount the current gold can buy
buy =. cb > 0 NB. buy orders
cb =. ((cb <. mb)* buy) + cb * -. buy
NB. new state and bid
ns , cb ,: p*uf
)
NB. der agent verb
ader=: 4 : 0
p =. {: x NB. last price
d =. (_3 { x) + (_1 { x) - 2 * _2 { x NB. second derivative estimate
if. d > 0 do. NB. if price slope is increasing -- buy
np =. p * 1 + ders NB. price with margin
cb =. (1 { y) % np NB. maximum amount the current gold can buy
else. NB. if the price slope is decreasing -- sell
np =. p * 1 - ders NB. price with margin
cb =. - (0 { y) NB. sell all inventory
end.
y , cb ,: np
)
NB. avg agent verb
aavg=: 4 : 0
p =. {: x NB. last price
pf =. ([: +/ (1-beta) * ] * beta ^ [: |.@i. #) x NB. price forecast
buyers =. p < pf * 1 - avgs NB. agents, which buy
np =. buyers * p * 1 + avgs NB. buy price
cb =. buyers * (1 { y) % np NB. maximum amount the current gold can buy
sellers =. p > pf * 1 + avgs NB. agents, which sell
np =. np + sellers * p * 1 - avgs NB. sell price
cb =. cb - sellers * (0 { y) NB. sell all inventory
y , cb ,: np
)
NB. statebids =: 1 1 1 aprod pi
NB. bids =: 2 }. statebids
NB. plot (([: +/\&.|. (* 0&<)) ,: ([: +/\ (-@* 0&>))) {. (|: |:@/: {:) bids
NB. The auction verb "prices auction (states and bids)" accepts the
NB. historical prices and the agents bids to return the price of the
NB. asset.
auction=: 4 : 0
sorted =. (|: |:@/: {:) 2 }. y
svol =. {. sorted
demand =. ([: +/\&.|. (* 0&<)) svol
supply =. ([: +/\ (-@* 0&>)) svol
if. ({. demand) = {: supply do.
{: prices NB. the price is unchanged
else.
((] i. 1:) (demand < supply)) { (, {:) {: sorted
end.
)
NB. The trade function "price trade (states and bids)" implements the
NB. actual trading and returns the new agent states after the trade at
NB. a specified price (which should be determined by the auction) verb.
trade=: 4 : 0
sa =. ((x >: 3&{) * (0 > 2&{)) y NB. acting sell orders
if. (+/sa) = 0 do. 2 {. y return. end. NB. no sellers no trade
ba =. ((x <: 3&{) * (0 < 2&{)) y NB. acting buy orders
if. (+/ba) = 0 do. 2 {. y return. end. NB. no buyers no trade
d =. (+/@(sa&*) + +/@(ba&*)) 2&{ y NB. unfulfilled portion
of =. 0 { y NB. food amounts before trading
og =. 1 { y NB. gold amounts before trading
if. d ~: 0 do. NB. there is an excess amount
if. d < 0 do. NB. excess amount is in sell orders
i =. (i.>./) sa * 3&{ y NB. index of the cheapest sell
else. NB. excess amount is in buy orders
i =. (i.<./) ba %~ 3&{ y NB. index of the most generous buy
end.
nf =. ((i { 0 { y) - d) i} 0 { y NB. patch food
ng =. ((i { 1 { y) + x * d) i} 1 { y NB. patch gold
else.
nf =. 0 { y
ng =. 1 { y
end.
NB. after patching all orders can be applied in full
v =. (sa * 2 { y) + ba * 2 { y
nf =. nf + v
ng =. ng - x * v
nf =. (0.000001 < nf) * nf NB. round the food amount very close to 0
ng =. (0.000001 < ng) * ng NB. round the gold amount very close to 0
assert. 0.0001 > (+/ of) - +/ nf NB. check that total food if conserved
assert. 0.0001 > (+/ og) - +/ ng NB. check that total gold is conserved
assert. 0 <: nf NB. check that all food amounts are positive
assert. 0 <: ng NB. check that all gold amounts are positive
nf ,: ng
)
NB. simulation iteration "it (prices; states)" performs a single
NB. iteration of the simulation and returns again the
NB. (prices; states) pair, but with the new state and price,
NB. appended at the end.
it=: 3 : 0
('op';'os') =. y NB. old prices old states
cs =. {: os NB. current state
prods =. np {."1 cs NB. states of producer agents
prodb =. op aprod prods NB. producers evolve and formulate bids
ds =. (np + i. nder) {"1 cs NB. states of DER agents
as =. (nder + np + i. navg) {"1 cs NB. states of AVG agents
if. specturn < # op do.
db =. op ader ds NB. DER agents formulate bids
ab =. op aavg as NB. AVG agents formulate bids
else.
db =. ds , (nder # 0) ,: (nder # 0) NB. empty bids for DER agents
ab =. as , (navg # 0) ,: (navg # 0) NB. empty bids for AVG agents
end.
b =. prodb ,. db ,. ab NB. all bids by all agents
p =. op auction b NB. find out new price
ns =. p trade b NB. perform the trades
(op,p);(os , ns)
)
NB. initial agent states
pi =: ((np # 29), (nder # 0), (navg # 0) ) ,: ((np # 30), (nder # 10), (navg # 10))
NB. simulation data
NB. sim =: it (^:1000) (1; ,: pi)
NB. some useful verbs (applicable to computed simulation data)
price =: >@{.
agentwealth =: >@{. (([: +/ ] * 1 ,~ [)"0 2) >@{:
totalwealth =: [: +/"1 agentwealth
prodwealth =: [: +/"1 np {."1 agentwealth
derwealth =: [: +/"1 (np + i. nder) {"1 agentwealth
avgwealth =: [: +/"1 (nder + np + i. navg) {"1 agentwealth
prodwealthbyfoodskill =: (/: 0 { ps) {"1 np {."1 agentwealth
prodwealthbygoldskill =: (/: 1 { ps) {"1 np {."1 agentwealth
foodstocks =: [: {."2 >@{:
foodstock =: [: +/"1 foodstocks
goldstock =: [: +/"1 [: {:"2 >@{:
production =: [: ([: +/ 2 -/\ ])"1 foodstocks
spectrade =: [: ([: +/ [: | 2 -/\ ])"1 np }."1 foodstocks
NB. plots
NB. ==== farmer age
NB. plot 200 {. price sim NB. price in farmer age
NB. plot _100 (100 %~ +/)\ 200 {. prodwealthbyfoodskill sim
NB. ==== speculation age
NB. plot 800 {. price sim NB. price
NB. plot 800 {. totalwealth sim
NB. plot 800 {."1 (derwealth,: avgwealth) sim NB. speculator wealth
NB. poor get poorer, rich get richer
NB. plot _80 (80 %~ +/)\ 600 {. _800 {. prodwealthbyfoodskill sim
NB. ==== bubble
NB. plot price sim NB. price
NB. plot (900 + i. 50) { price sim NB. closer look
NB. plot (900 + i. 50) {"1 (derwealth,: avgwealth) sim NB. speculator wealth
NB. price and stocks at bubble
NB. plot (900 + i. 50) {"1 (price, (goldstock % 2000"_),:(foodstock % 100"_)) sim
NB. plot (900 + i. 50) {"1 (production,: price) sim
NB. speculators trade volume and price
NB. plot (900 + i. 50) {"1 (price ,: (spectrade % 50"_)) sim
NB. social inequality is dramatically increased by bubble
NB. plot _80 (80 %~ +/)\ _800 {. prodwealthbyfoodskill sim