globals [nAgents price1-tod price2-tod price1-tmw price2-tmw priceList1 priceList2 NNlist1 NNlist2 threshold1 threshold2 temp exit-ticks unsatisfied_1 unsatisfied_2] breed [agents agent] breed [dumbAgents dumbAgent] turtles-own[initial_wealth stock1 stock2 cash wealth out-of-market buyer1 buyer2 seller1 seller2 mimicking purchases1 sales1 return1 purchases2 sales2 return2 beenImitator transaction1 transaction2 NN] agents-own[intelligence riskAversion decision-value forecasting-price1 forecasting-price2] to setup ca random-seed new-seed ;;loading input files (containing time series of stock prices generated by a stationary AR(2) for stock 1 and a non-stationary AR(1) process, i.e. random walk, for stock 2) file-close-all set priceList1 [] set priceList2 [] set NNlist1 [] set NNlist2 [] set exit-ticks [] set unsatisfied_1 [] set unsatisfied_2 [] file-open Input-file-price1 while [not file-at-end?][set priceList1 lput file-read priceList1] file-close ;print priceList1 file-open Input-file-price2 while [not file-at-end?][set priceList2 lput file-read priceList2] file-close ;print priceList2 file-open Input-NN-file-price1 while [not file-at-end?][set NNlist1 lput file-read NNlist1] file-close file-open Input-NN-file-price2 while [not file-at-end?][set NNlist2 lput file-read NNlist2] file-close set nAgents nTurtles - int ((nTurtles * %_dumbAgents) / 100) ; agents with forecasting skills create-agents nAgents create-dumbAgents int ((nTurtles * %_dumbAgents) / 100) ;agents with no forecasting skills: just pick stocks randomly let side sqrt nTurtles let step max-pxcor / side set price1-tod item 0 priceList1 set price2-tod item 0 priceList2 ask turtles [ set shape "person" set color 95 set out-of-market False set size 2 set stock1 0 set stock2 0 set cash initialCash set stock1 n_stocks set stock2 n_stocks set wealth (cash + stock1 * price1-tod + stock2 * price2-tod) set initial_wealth wealth set purchases1 (n_stocks * price1-tod) set sales1 0 set purchases2 (n_stocks * price2-tod) set sales2 0 set beenImitator false set transaction1 0 set transaction2 0 set NN false ] ask dumbAgents[ set size 3 ] ask agents [ set intelligence degree_intelligence set NN false set riskAversion 10 set threshold1 7 set threshold2 7 ] ask n-of (%_highlyRiskAverse_Agents * nAgents / 100) agents [ ;creating heterogeneity concerning agents risk aversion set riskAversion 20 ] let an 0 let x 0 let y 0 while [an < nTurtles] [ if x > (side - 1) * step [set y y + step set x 0 ] ask turtle an [setxy x y] set x x + step set an an + 1 ] if NN_agent = true [ask n-of 1 agents [set NN true set shape "star"]] end to go if exchange_transaction and n_stocks = 0 [output-print "ERROR -> Turtles don't hold any stock" stop] if ticks > length priceList1 - 3 [ output-data ask turtles with-max [wealth][set color 46] stop] set price1-tod item ticks priceList1 ;updating prices using the lists created using the input files set price2-tod item ticks priceList2 set price1-tmw item (ticks + 1) priceList1 set price2-tmw item (ticks + 1) priceList2 let action-list [] ; creating a list of the previous turn actions for the wealthiest agent ask turtles with-max [wealth][ set action-list lput buyer1 action-list set action-list lput buyer2 action-list set action-list lput seller1 action-list set action-list lput seller2 action-list] ;print action-list ask turtles with [out-of-market = false][ ;initializing the buyer and seller agent's variables set buyer1 false set buyer2 false set seller1 false set seller2 false if wealth >= initial_wealth and mimicking = true [set mimicking false ; if wealth gets back to its initial value (= initial cash), agents stop mimicking set shape "person" if NN = true [set shape "star"] ] ifelse wealth >= initial_wealth [set color 65][set color 15] ] ask dumbAgents [ ;setting up the decision process for dumb agents if out-of-market = false [ let random_value random 3 pick_stock random_value 1 set random_value random 3 pick_stock random_value 2 ] ] ask agents with [NN = false][ if out-of-market = false [ ;Building forecasting-price value let randValue 0 ifelse random 2 = 0[set randValue random-float intelligence][set randValue random-float ( - intelligence)] set forecasting-price1 price1-tmw + randValue;random-normal price1-tmw intelligence ;creating forecast for intelligent agents ifelse random 2 = 0[set randValue random-float (intelligence)][set randValue random-float ( - intelligence)] set forecasting-price2 price2-tmw + randValue;random-normal price2-tmw (intelligence / 10) ;divide the degree of intelligence by 10 in order to make it uniform wrt the std. dev. of the time series of stock 2 (less volatile) ;print price1-tod print price1-tmw ;Given the forecast the agent decide whether to buy or sell by means of the decision function decision forecasting-price1 price1-tod 1 decision forecasting-price2 price2-tod 2 ] ] ask agents with [NN = true][ if out-of-market = false [ set forecasting-price1 item (ticks + 1) NNlist1 set forecasting-price2 item (ticks + 1) NNlist2 decisionNN forecasting-price1 price1-tod 1 %_transacting1 decisionNN forecasting-price2 price2-tod 2 %_transacting2 ] ] ask turtles [ if out-of-market = false [ set wealth cash + stock1 * price1-tod + stock2 * price2-tod ;update wealth and check if out of market exit if out-of-market = true [set color white] ]] ask turtles with [wealth < initial_wealth - (%_lost_wealth * initial_wealth / 100) ][set shape "sheep 2" set mimicking true set beenImitator true] ask turtles with [mimicking = true][mimick action-list] ;using function mimick for imitation purposes ;transact set nAgents count agents ;print nAgents let n_decision_value1 count turtles with [seller1 = true or buyer1 = true] let n_decision_value2 count turtles with [seller2 = true or buyer2 = true] ;print "inizio" update-threshold ifelse exchange_transaction [exchange ] [transact] ;print "threshold1" print threshold1 ;print "threshold2" print threshold2 if Events [ if random 1000 < 3 [unlikely_event] ] set unsatisfied_1 lput (count turtles with [seller1 = true or buyer1 = true] / n_decision_value1 * 100) unsatisfied_1 set unsatisfied_2 lput (count turtles with [seller2 = true or buyer2 = true] / n_decision_value2 * 100) unsatisfied_2 graph tick end to decision[forecastingPrice priceTOD stock] let diff forecastingPrice - priceTOD ifelse diff > 0 ;If diff > 0 -> buy or pass; If diff < 0 -> sell or pass; If diff = 0 then it's an automatic pass since it is at the numerator [ set decision-value 1000 * (diff / priceTOD) / riskAversion ; BUY OR PASS DECISION if decision-value > threshold stock [ buyer stock ;Notice that threshold is not a variable but a function and it's is the same for buying or selling since the parameters are the same ] ] [ ;print "SELL!!!" set decision-value 10 * (- diff / priceTOD) * riskAversion ;SELL OR PASS DECISION if decision-value > threshold stock [ seller stock ] ] end to decisionNN[forecastingPrice priceTOD stock %_transacting] let diff forecastingPrice - priceTOD ifelse diff > 0 ;If diff > 0 -> buy or pass; If diff < 0 -> sell or pass; If diff = 0 then it's an automatic pass since it is at the numerator [ if random-float 100 < %_transacting [ buyer stock ;Notice that threshold is not a variable but a function and it's is the same for buying or selling since the parameters are the same ] ] [ ;print "SELL!!!" if random-float 100 < %_transacting [ seller stock ] ] end to transact ; agents actually buy/sell ask turtles[ if buyer1 = true[buy 1] if seller1 = true [sell 1] if buyer2 = true[buy 2] if seller2 = true [sell 2] ] end to-report threshold[stock] if stock = 1[report threshold1] if stock = 2[report threshold2] end to buyer[stock] if stock = 1[set buyer1 true] if stock = 2[set buyer2 true] end to seller[stock] if stock = 1[set seller1 true] if stock = 2[set seller2 true] end to update-threshold ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! count turtles o count agents????????????????!!!!!!!!!!???????? let n1 count agents with [buyer1 = true and out-of-market = false] + count agents with [seller1 = true and out-of-market = false] let n2 count agents with [buyer2 = true and out-of-market = false] + count agents with [seller2 = true and out-of-market = false] let tot count agents with [out-of-market = false] if tot > 0[ ifelse (n1 * 100 ) / tot > %_transacting1 [set threshold1 threshold1 * 1.05 ] ;based on the chosen amount of transacting agents the threshold is updated upward or downward [set threshold1 threshold1 * 0.95] ifelse (n2 * 100 ) / tot > %_transacting2 [set threshold2 threshold2 * 1.05 ] [set threshold2 threshold2 * 0.95] ] end to buy[stock] ifelse stock = 1 [ if cash > price1-tod [set stock1 stock1 + 1 set cash cash - price1-tod set purchases1 purchases1 + price1-tod set transaction1 transaction1 + 1 ] ] [ if cash > price2-tod [set stock2 stock2 + 1 set cash cash - price2-tod set purchases2 purchases2 + price2-tod set transaction2 transaction2 + 1 ] ] end to sell[stock] ifelse stock = 1 [ if stock1 > 0 [set stock1 stock1 - 1 set cash cash + price1-tod set sales1 sales1 + price1-tod set transaction1 transaction1 + 1 ] ] [ if stock2 > 0 [set stock2 stock2 - 1 set cash cash + price2-tod set sales2 sales2 + price2-tod set transaction2 transaction2 + 1 ] ] end to pick_stock[value stock] ;decision on whether buying or selling for dumb agents if value = 1[buyer stock] if value = 2[seller stock] end to exit ;terminal conditions to exit the market if (wealth < (initial_wealth * 0.4)) [set out-of-market true] if wealth >= (3 * initial_wealth) and NN = false [set out-of-market true set exit-ticks lput ticks exit-ticks] if wealth >= (3 * initial_wealth) and NN = true [set out-of-market true output-type "NN agent exit tick: " output-print ticks] end to mimick[action-list] ; setting action-list of mimicking agents if item 0 action-list = true [set buyer1 true] if item 2 action-list = true [set seller1 true] if item 1 action-list = true [set buyer2 true] if item 3 action-list = true [set seller2 true] end to unlikely_event ; randomly decide which event will occur let randomNumber random 2 if randomNumber = 0[stock1Boom] if randomNumber = 1[stock1Crash] plot-events ticks end to stock1Boom ; random event -> rising price for stock 1 output-type "Tick: " output-type ticks output-print " -> FORECASTED STOCK BOOM" ask agents[ ; based on the probability that they will believe the forecasts about the unlikely event, agents make their decision on whether they shall believe it or not if out-of-market = false [ if random 100 < prob_follow [while [cash > price1-tod][buy 1] ] ] ] ask dumbAgents[ ; probability to believe is higher for dumb agents if out-of-market = false [ if random 100 < prob_follow + 20 [while [cash > price1-tod][buy 1] ] ]] end to stock1Crash ; random event -> falling price for stock 1 output-type "Tick: " output-type ticks output-print " -> FORECASTED STOCK CRASH" ask agents[ ;based on their probability to believe, agents make their unusual transactions if out-of-market = false [ if random 100 < prob_follow [repeat stock1 [sell 1] ] ] ] ask dumbAgents[ if out-of-market = false [ if random 100 < prob_follow + 20 [repeat stock1 [sell 1] ] ]] end to graph let n1 count turtles with [buyer1 = true] let n3 count turtles with [buyer2 = true] let n2 count turtles with [seller1 = true] let n4 count turtles with [seller2 = true] set-current-plot "stocks" set-current-plot-pen "price1" plot price1-tod set-current-plot-pen "price2" plot price2-tod set-current-plot "buyers and sellers" set-current-plot-pen "buyers1" if what_plot = "Buyers" or what_plot = "Stock1" [plot n1] set-current-plot-pen "sellers1" if what_plot = "Sellers" or what_plot = "Stock1" [plot n2] set-current-plot-pen "buyers2" if what_plot = "Buyers" or what_plot = "Stock2" [plot n3] set-current-plot-pen "sellers2" if what_plot = "Sellers" or what_plot = "Stock2" [plot n4] set-current-plot "Thresholds" set-current-plot-pen "threshold-stock1" plot threshold1 set-current-plot-pen "threshold-stock2" plot threshold2 ;print item 0 [forecasting-price1] of agents with [NN = true] ;if ticks > 0 [ ;set-current-plot "NN prices forecasts" ;set-current-plot-pen "price1" ;plot price1-tod ;set-current-plot-pen "price1 NN" ;plot item 0 [forecasting-price1] of agents with [NN = true] ;set-current-plot-pen "price2" ;plot price2-tod ;set-current-plot-pen "price2 NN" ;plot item 0 [forecasting-price2] of agents with [NN = true] ;] ;Computing the ex-post mean returns ask agents [ return ] let meanReturn1 0 let meanReturn2 0 if count agents with [purchases1 != 0] != 0 [ set meanReturn1 mean [return1] of agents with [purchases1 != 0]] if count agents with [purchases2 != 0] != 0[ set meanReturn2 mean [return2] of agents with [purchases2 != 0]] ask dumbAgents [ return ] let meanReturnDumb1 0 let meanReturnDumb2 0 if count dumbAgents with [purchases1 != 0] != 0 and count dumbAgents != 0[ set meanReturnDumb1 mean [return1] of dumbAgents with [purchases1 != 0]] if count dumbAgents with [purchases2 != 0] != 0 and count dumbAgents != 0[ set meanReturnDumb2 mean [return2] of dumbAgents with [purchases2 != 0]] ; Plotting returns set-current-plot "Mean returns" set-current-plot-pen "return1" plot meanReturn1 set-current-plot-pen "return2" plot meanReturn2 ;print meanReturn2 if count dumbAgents != 0[ set-current-plot-pen "return1dumb" plot meanReturnDumb1 set-current-plot-pen "return2dumb" plot meanReturnDumb2 ] ;Plotting wealth let meanWealth mean [wealth] of agents set-current-plot "Mean wealth" set-current-plot-pen "wealth" plot meanWealth if count dumbAgents != 0 [ let meanWealthDumb mean [wealth] of dumbAgents set-current-plot-pen "wealth dumb" plot meanWealthDumb] end to output-data ; Sending the stastics and data to the output display in the interface if exit-ticks != [] [output-type "Mean exit ticks: " output-print mean exit-ticks] output-print "" let n1 count turtles with [out-of-market = true and wealth < initial_wealth * 0.4 ] let n2 count turtles with [out-of-market = true and wealth > initial_wealth] if exchange_transaction[ output-type "Unsatisfied demand stock 1: " output-type mean unsatisfied_1 output-print " %" output-type "Unsatisfied demand stock 2: " output-type mean unsatisfied_2 output-print " %" output-print "" ] output-type "Losers: " output-print n1 ; losers went out-of-market because of heavy losses (none at the moment: too strict condition?!?) output-type "Winners: " output-print n2 ; winners exit the market because they gained enough to spend a very comfortable retirement output-print "" output-type "% imitators_agents: " output-print (count agents with [beenImitator = true]) / count agents * 100 ; number of agents that have been mimicking at least once if count dumbAgents != 0[output-type "% imitators_dumb: " output-print (count dumbAgents with [beenImitator = true]) / count dumbAgents * 100 ]; number of dumb agents that have been mimicking at least once output-print "" output-type "Mean Agents' wealth: " output-print mean [wealth] of agents if count dumbAgents != 0[output-type "Mean dumb Agents' wealth: " output-print mean [wealth] of dumbAgents] if count agents with [NN = true] != 0 [output-type "NN Agent's wealth: " output-print item 0 [wealth] of agents with [NN = true]] output-print "" output-print "Agents'average n. transaction stock 1" ; number of transactions depending on risk aversion: does it affect agents' choice on whether transacting or passing output-type "High risk aversion: " output-print mean [transaction1] of agents with [riskAversion = 20] output-type "Low risk aversion: " output-print mean [transaction1] of agents with [riskAversion = 10] if count agents with [NN = true] != 0 [output-type "NN agent: " output-print item 0 [transaction1] of agents with [NN = true]] output-print "" output-print "Agents'average n. transaction stock 2" output-type "High risk aversion: " output-print mean [transaction2] of agents with [riskAversion = 20] output-type "Low risk aversion: " output-print mean [transaction2] of agents with [riskAversion = 10] if count agents with [NN = true] != 0 [output-type "NN agent: " output-print item 0 [transaction2] of agents with [NN = true]] output-print "" if count dumbAgents != 0[ output-print "Dumb agents'average n. transaction " output-type "stock 1: " output-print mean [transaction1] of dumbAgents output-type "stock 2: " output-print mean [transaction2] of dumbAgents output-print ""] let meanReturn1 mean [return1] of agents with [purchases1 != 0] let meanReturn2 mean [return2] of agents with [purchases2 != 0] let std-dev-Return1 standard-deviation [return1] of agents with [purchases1 != 0] let std-dev-Return2 standard-deviation [return2] of agents with [purchases2 != 0] let maxReturn1 max [return1] of agents with [purchases1 != 0] let maxReturn2 max [return2] of agents with [purchases2 != 0] let minReturn1 min [return1] of agents with [purchases1 != 0] let minReturn2 min [return2] of agents with [purchases2 != 0] output-print "Agents, stock1: " ; statistics regarding returns for agents output-type "% Mean return: " output-type meanReturn1 output-type " standard deviation: " output-print std-dev-Return1 output-type "max: " output-type maxReturn1 output-type " min: " output-print minReturn1 output-print "" output-print "Agents, stock2: " output-type "% Mean return: " output-type meanReturn2 output-type " standard deviation: " output-print std-dev-Return2 output-type "max: " output-type maxReturn2 output-type " min: " output-print minReturn2 output-print "" if count dumbAgents != 0[ set meanReturn1 mean [return1] of dumbAgents with [purchases1 != 0] set meanReturn2 mean [return2] of dumbAgents with [purchases2 != 0] set std-dev-Return1 standard-deviation [return1] of dumbAgents with [purchases1 != 0] set std-dev-Return2 standard-deviation [return2] of dumbAgents with [purchases2 != 0] set maxReturn1 max [return1] of dumbAgents with [purchases1 != 0] set maxReturn2 max [return2] of dumbAgents with [purchases2 != 0] set minReturn1 min [return1] of dumbAgents with [purchases1 != 0] set minReturn2 min [return2] of dumbAgents with [purchases2 != 0] output-print "dumbAgents, stock1: " ; statistics regarding returns for dumb agents output-type "% Mean return: " output-type meanReturn1 output-type " standard deviation: " output-print std-dev-Return1 output-type "max: " output-type maxReturn1 output-type " min: " output-print minReturn1 output-print "" output-print "dumbAgents, stock2: " output-type "% Mean return: " output-type meanReturn2 output-type " standard deviation: " output-print std-dev-Return2 output-type "max: " output-type maxReturn2 output-type " min: " output-print minReturn2 output-print ""] if count agents with [NN = true] != 0 [ output-print "NN Agent, stock1: " output-type "% Return:" output-type item 0 [return1] of agents with [NN = true] output-print "" output-print "NN Agent, stock2: " output-type "% Return:" output-type item 0 [return2] of agents with [NN = true] ] end to plot-events [x] set-current-plot "Mean returns" set-current-plot-pen "Event" auto-plot-off plotxy x -100 plotxy x 100 auto-plot-on end to return ; defining return measure if purchases1 != 0 [ set return1 ((sales1 + stock1 * price1-tod) - purchases1) / purchases1 * 100 ] if purchases2 != 0 [ set return2 ((sales2 + stock2 * price2-tod) - purchases2) / purchases2 * 100 ] end to exchange let logB [] let logS [] ask turtles[ if buyer1 = true and cash > price1-tod[ set logB lput who logB ] if seller1 = true and stock1 > 0 [ set logS lput who logS] ] while[ logS != [] and logB != []][ ask turtle (item 0 logB)[buy 1 set buyer1 false] ask turtle (item 0 logS) [sell 1 set seller1 false] set logB remove-item 0 logB set logS remove-item 0 logS ] set logB [] set logS [] ask turtles[ if buyer2 = true and cash > price2-tod[ set logB lput who logB ] if seller2 = true and stock2 > 0 [ set logS lput who logS] ] while[ logS != [] and logB != []][ ask turtle (item 0 logB)[buy 2 set buyer2 false ] ask turtle (item 0 logS) [sell 2 set seller2 false ] set logB remove-item 0 logB set logS remove-item 0 logS ] ;type "Tick: " print ticks ;print logB ;print logS ;type "unsatisfied sellers " print count turtles with [seller2 = true] ;type "unsatisfied buyers " print count turtles with [buyer2 = true] end @#$#@#$#@ GRAPHICS-WINDOW 341 10 667 357 -1 -1 9.6 1 10 1 1 1 0 1 1 1 0 32 0 32 1 1 1 ticks BUTTON 21 10 84 43 setup setup NIL 1 T OBSERVER NIL NIL NIL NIL BUTTON 102 11 165 44 go go T 1 T OBSERVER NIL NIL NIL NIL SLIDER 2 49 174 82 nTurtles nTurtles 10 300 99 1 1 NIL HORIZONTAL SLIDER 3 128 175 161 initialCash initialCash 0 1000 503 1 1 NIL HORIZONTAL INPUTBOX 676 10 882 70 Input-file-price1 random walk risky sd=1_negative trend.txt 1 0 String INPUTBOX 675 80 882 140 Input-file-price2 random walk less risky sd=0.1_stationary trend.txt 1 0 String PLOT 441 540 711 688 buyers and sellers Tick NIL 0.0 10.0 0.0 30.0 true true PENS "buyers1" 1.0 0 -10899396 true "sellers1" 1.0 0 -2674135 true "buyers2" 1.0 0 -8630108 true "sellers2" 1.0 0 -1184463 true SLIDER 3 205 175 238 %_transacting1 %_transacting1 0 100 40 1 1 NIL HORIZONTAL SLIDER 1 247 173 280 %_transacting2 %_transacting2 0 100 65 1 1 NIL HORIZONTAL SLIDER 3 167 173 200 %_highlyRiskAverse_Agents %_highlyRiskAverse_Agents 0 90 50 5 1 NIL HORIZONTAL SLIDER 6 300 176 333 degree_intelligence degree_intelligence 1 100 8 1 1 NIL HORIZONTAL SLIDER 1 89 173 122 %_dumbAgents %_dumbAgents 0 90 30 5 1 NIL HORIZONTAL TEXTBOX 195 308 345 368 notice that the lower the better since this value refers to a forecasting error 12 0.0 1 TEXTBOX 199 199 336 289 these indexes, beyond being used to update the \"threshold\", also provide further indications about the perceived riskyness of the two stocks 12 0.0 1 SLIDER 5 343 177 376 %_lost_wealth %_lost_wealth 1 59 30 1 1 NIL HORIZONTAL OUTPUT 889 10 1253 700 10 SLIDER 7 426 179 459 prob_follow prob_follow 0 80 20 1 1 NIL HORIZONTAL PLOT 236 540 428 688 Thresholds Tick NIL 0.0 10.0 0.0 10.0 true false PENS "threshold-stock1" 1.0 0 -2674135 true "threshold-stock2" 1.0 0 -13791810 true PLOT 498 378 812 530 Mean returns Tick % return 0.0 10.0 0.0 10.0 true true PENS "return1" 1.0 0 -2674135 true "return2" 1.0 0 -10899396 true "return1dumb" 1.0 0 -16777216 true "return2dumb" 1.0 0 -13345367 true "Event" 1.0 1 -16777216 true PLOT 201 379 470 529 Mean wealth Tick NIL 0.0 10.0 0.0 10.0 true true PENS "wealth" 1.0 0 -2674135 true "wealth dumb" 1.0 0 -16777216 true INPUTBOX 193 57 322 117 Input-NN-file-price1 random walk risky sd=1_negative trend forecast.txt 1 0 String INPUTBOX 194 128 321 188 Input-NN-file-price2 random walk less risky sd=0.1_stationary trend forecast.txt 1 0 String SWITCH 201 19 313 52 NN_Agent NN_Agent 0 1 -1000 PLOT 674 161 881 356 Stocks Tick price 0.0 10.0 0.0 10.0 true true PENS "price1" 1.0 0 -13345367 true "price2" 1.0 0 -2674135 true SWITCH 12 471 179 504 exchange_transaction exchange_transaction 0 1 -1000 SLIDER 14 518 178 551 n_stocks n_stocks 0 20 5 1 1 NIL HORIZONTAL SWITCH 8 389 111 422 Events Events 1 1 -1000 CHOOSER 727 541 865 586 What_plot What_plot "Buyers" "Sellers" "Stock1" "Stock2" 2 @#$#@#$#@ WHAT IS IT? ----------- The model simulates the decision process and transactions of agents in an Artificial Stock Market. There are 3 classes of agents, each differentiated by their degree of "intelligence" and forecasting skills about the future prices of the stocks considered. In particular, one agent (represented by a star) uses an Artificial Neural Network (ANN) to make its forecasts (trained on a simulated time series using Python). HOW IT WORKS ------------ Each turn, agents have to take a decision on whether buying or selling the two stocks, or just doing nothing. The decisions are based on the next day's price forecast made by each agent, except the "dumb" ones, who just make their decision randomly. After the decision is taken, the transaction (purchase or sale) actually takes place if the agent's expected return and risk aversion make him able to exceed a "threshold", equal for any agent, but different for the two stocks. Please notice that the stocks are not exchanged among the agents, but they are just bought and sold in the "market" (at most one stock for each type): hence, there are no supply-demand dynamics to be satisfied; the only constraints for the transactions are the amount of cash available (that should at least be equal to the minimum stock price to perform a purchase)and ,of course, the individual preference of agents (which are an increasing function of returns and a decreasing function of volatility the stock prices, as captured in the decision process). The objective of the agents if maximizing their wealth. If their wealth falls below a certain percentage of the initial cash (decided by the user through a slider), agents start following the same strategy that the wealthiest agent followed in the previous turn. HOW TO USE IT ------------- First of all the input boxes must be filled with the name of a file containing a time series of stock prices for the stocks. If you want to include an agent using an ANN the boxes on the left must contain the forecasts provided by the ANN. Notice that, though the model can be fully used with series provided by us (generated using R, with the forecasts made using Python), you are free to use any time series you like (even actual ones of course!). Click the SETUP button to set up the agents. Click the GO button to run the simulation. The sliders allow the users to decide: the number of traders; the percentage of less skilled (dumb) agents (represented in a biggers size); the percentage of agents with high risk aversion; the percentage of transacting agents in the two stocks (this is helpful in order to adjust the "threshold"); the degree of intelligence of agents with forecasting skills (except the one using the ANN); the percentage of initial cash to be lost before starting imitation. Pressing the "unlikely event" button, you give agents some "hints" on a forecasted market boom or crash, that may change their way of acting with a certain probability (prob_follow), leading them to buy or sell an unusual (i.e. more than one) amount of stocks in order to take advantage or hedge against the weird market conditions. THINGS TO NOTICE ---------------- You could notice, as the simulation is running, the agents who are currently above their initial wealth (displayed in green) and those who are losing (in red). Agents who exit the market because of very high gains or losses are displayed in white. Imitators are displayed with the shape of a sheep. The graphs plot the time series of prices of the two stocks, the mean return (defined as amount gained or lost per unit of cash spent to buy stocks) and wealth of the two classes of agents, and the amount of buyers and sellers. At the end of the simulation the output panel on the right of the interface displays some useful terminal value and information; the yellow agent is the wealthiest one . One of the most important things to notice is the different performances of the classes of agents (normal, dumb and ANN agent). Moreover, try and guess whether the imitation will lead the imitating agent to a better financial condition. THINGS TO TRY ------------- Try and use the sliders you have at your disposal to see how different settings change the final result. Does the difference between dumb and normal agents fade away if we decrease the level of intelligence of the latter? Does the percentage of highly risk-averse agents change the number of transactions and performances of agents? How does the performances change if you use other time series of prices? EXTENDING THE MODEL ------------------- Instead of plotting only the stock prices, it might be interesting to plot also the returns. Some further interactions among the agents could be introduced. Moreover, instead of using previously generated time series, the model could be changed and extended by setting up a procedure for the exchange of stocks among agents and a mechanism (for example, based on supply and demand) for the determination of the stock price. Also, in order to add a bit more economic technicality, it might be interesting to set up the agents as they were DARA (Decreasing Absolute Risk Aversion) investors, with risk aversion decreasing with wealth (i.e. they are assumed to have an isoelastic utility function describing their preferences), while in our model their risk aversion is assumed to be constant. Furthermore, it may be interesting to remove the short-sale constraint on the agents: will their strategies become more aggressive? How would that affect their performances? @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 airplane true 0 Polygon -7500403 true true 150 0 135 15 120 60 120 105 15 165 15 195 120 180 135 240 105 270 120 285 150 270 180 285 210 270 165 240 180 180 285 195 285 165 180 105 180 60 165 15 arrow true 0 Polygon -7500403 true true 150 0 0 150 105 150 105 293 195 293 195 150 300 150 box false 0 Polygon -7500403 true true 150 285 285 225 285 75 150 135 Polygon -7500403 true true 150 135 15 75 150 15 285 75 Polygon -7500403 true true 15 75 15 225 150 285 150 135 Line -16777216 false 150 285 150 135 Line -16777216 false 150 135 15 75 Line -16777216 false 150 135 285 75 bug true 0 Circle -7500403 true true 96 182 108 Circle -7500403 true true 110 127 80 Circle -7500403 true true 110 75 80 Line -7500403 true 150 100 80 30 Line -7500403 true 150 100 220 30 butterfly true 0 Polygon -7500403 true true 150 165 209 199 225 225 225 255 195 270 165 255 150 240 Polygon -7500403 true true 150 165 89 198 75 225 75 255 105 270 135 255 150 240 Polygon -7500403 true true 139 148 100 105 55 90 25 90 10 105 10 135 25 180 40 195 85 194 139 163 Polygon -7500403 true true 162 150 200 105 245 90 275 90 290 105 290 135 275 180 260 195 215 195 162 165 Polygon -16777216 true false 150 255 135 225 120 150 135 120 150 105 165 120 180 150 165 225 Circle -16777216 true false 135 90 30 Line -16777216 false 150 105 195 60 Line -16777216 false 150 105 105 60 car false 0 Polygon -7500403 true true 300 180 279 164 261 144 240 135 226 132 213 106 203 84 185 63 159 50 135 50 75 60 0 150 0 165 0 225 300 225 300 180 Circle -16777216 true false 180 180 90 Circle -16777216 true false 30 180 90 Polygon -16777216 true false 162 80 132 78 134 135 209 135 194 105 189 96 180 89 Circle -7500403 true true 47 195 58 Circle -7500403 true true 195 195 58 circle false 0 Circle -7500403 true true 0 0 300 circle 2 false 0 Circle -7500403 true true 0 0 300 Circle -16777216 true false 30 30 240 cow false 0 Polygon -7500403 true true 200 193 197 249 179 249 177 196 166 187 140 189 93 191 78 179 72 211 49 209 48 181 37 149 25 120 25 89 45 72 103 84 179 75 198 76 252 64 272 81 293 103 285 121 255 121 242 118 224 167 Polygon -7500403 true true 73 210 86 251 62 249 48 208 Polygon -7500403 true true 25 114 16 195 9 204 23 213 25 200 39 123 cylinder false 0 Circle -7500403 true true 0 0 300 dot false 0 Circle -7500403 true true 90 90 120 face happy false 0 Circle -7500403 true true 8 8 285 Circle -16777216 true false 60 75 60 Circle -16777216 true false 180 75 60 Polygon -16777216 true false 150 255 90 239 62 213 47 191 67 179 90 203 109 218 150 225 192 218 210 203 227 181 251 194 236 217 212 240 face neutral false 0 Circle -7500403 true true 8 7 285 Circle -16777216 true false 60 75 60 Circle -16777216 true false 180 75 60 Rectangle -16777216 true false 60 195 240 225 face sad false 0 Circle -7500403 true true 8 8 285 Circle -16777216 true false 60 75 60 Circle -16777216 true false 180 75 60 Polygon -16777216 true false 150 168 90 184 62 210 47 232 67 244 90 220 109 205 150 198 192 205 210 220 227 242 251 229 236 206 212 183 fish false 0 Polygon -1 true false 44 131 21 87 15 86 0 120 15 150 0 180 13 214 20 212 45 166 Polygon -1 true false 135 195 119 235 95 218 76 210 46 204 60 165 Polygon -1 true false 75 45 83 77 71 103 86 114 166 78 135 60 Polygon -7500403 true true 30 136 151 77 226 81 280 119 292 146 292 160 287 170 270 195 195 210 151 212 30 166 Circle -16777216 true false 215 106 30 flag false 0 Rectangle -7500403 true true 60 15 75 300 Polygon -7500403 true true 90 150 270 90 90 30 Line -7500403 true 75 135 90 135 Line -7500403 true 75 45 90 45 flower false 0 Polygon -10899396 true false 135 120 165 165 180 210 180 240 150 300 165 300 195 240 195 195 165 135 Circle -7500403 true true 85 132 38 Circle -7500403 true true 130 147 38 Circle -7500403 true true 192 85 38 Circle -7500403 true true 85 40 38 Circle -7500403 true true 177 40 38 Circle -7500403 true true 177 132 38 Circle -7500403 true true 70 85 38 Circle -7500403 true true 130 25 38 Circle -7500403 true true 96 51 108 Circle -16777216 true false 113 68 74 Polygon -10899396 true false 189 233 219 188 249 173 279 188 234 218 Polygon -10899396 true false 180 255 150 210 105 210 75 240 135 240 house false 0 Rectangle -7500403 true true 45 120 255 285 Rectangle -16777216 true false 120 210 180 285 Polygon -7500403 true true 15 120 150 15 285 120 Line -16777216 false 30 120 270 120 leaf false 0 Polygon -7500403 true true 150 210 135 195 120 210 60 210 30 195 60 180 60 165 15 135 30 120 15 105 40 104 45 90 60 90 90 105 105 120 120 120 105 60 120 60 135 30 150 15 165 30 180 60 195 60 180 120 195 120 210 105 240 90 255 90 263 104 285 105 270 120 285 135 240 165 240 180 270 195 240 210 180 210 165 195 Polygon -7500403 true true 135 195 135 240 120 255 105 255 105 285 135 285 165 240 165 195 line true 0 Line -7500403 true 150 0 150 300 line half true 0 Line -7500403 true 150 0 150 150 pentagon false 0 Polygon -7500403 true true 150 15 15 120 60 285 240 285 285 120 person false 0 Circle -7500403 true true 110 5 80 Polygon -7500403 true true 105 90 120 195 90 285 105 300 135 300 150 225 165 300 195 300 210 285 180 195 195 90 Rectangle -7500403 true true 127 79 172 94 Polygon -7500403 true true 195 90 240 150 225 180 165 105 Polygon -7500403 true true 105 90 60 150 75 180 135 105 plant false 0 Rectangle -7500403 true true 135 90 165 300 Polygon -7500403 true true 135 255 90 210 45 195 75 255 135 285 Polygon -7500403 true true 165 255 210 210 255 195 225 255 165 285 Polygon -7500403 true true 135 180 90 135 45 120 75 180 135 210 Polygon -7500403 true true 165 180 165 210 225 180 255 120 210 135 Polygon -7500403 true true 135 105 90 60 45 45 75 105 135 135 Polygon -7500403 true true 165 105 165 135 225 105 255 45 210 60 Polygon -7500403 true true 135 90 120 45 150 15 180 45 165 90 sheep false 0 Rectangle -7500403 true true 151 225 180 285 Rectangle -7500403 true true 47 225 75 285 Rectangle -7500403 true true 15 75 210 225 Circle -7500403 true true 135 75 150 Circle -16777216 true false 165 76 116 sheep 2 false 0 Polygon -7500403 true true 209 183 194 198 179 198 164 183 164 174 149 183 89 183 74 168 59 198 44 198 29 185 43 151 28 121 44 91 59 80 89 80 164 95 194 80 254 65 269 80 284 125 269 140 239 125 224 153 209 168 Rectangle -7500403 true true 180 195 195 225 Rectangle -7500403 true true 45 195 60 225 Rectangle -16777216 true false 180 225 195 240 Rectangle -16777216 true false 45 225 60 240 Polygon -7500403 true true 245 60 250 72 240 78 225 63 230 51 Polygon -7500403 true true 25 72 40 80 42 98 22 91 Line -16777216 false 270 137 251 122 Line -16777216 false 266 90 254 90 square false 0 Rectangle -7500403 true true 30 30 270 270 square 2 false 0 Rectangle -7500403 true true 30 30 270 270 Rectangle -16777216 true false 60 60 240 240 star false 0 Polygon -7500403 true true 151 1 185 108 298 108 207 175 242 282 151 216 59 282 94 175 3 108 116 108 target false 0 Circle -7500403 true true 0 0 300 Circle -16777216 true false 30 30 240 Circle -7500403 true true 60 60 180 Circle -16777216 true false 90 90 120 Circle -7500403 true true 120 120 60 tree false 0 Circle -7500403 true true 118 3 94 Rectangle -6459832 true false 120 195 180 300 Circle -7500403 true true 65 21 108 Circle -7500403 true true 116 41 127 Circle -7500403 true true 45 90 120 Circle -7500403 true true 104 74 152 triangle false 0 Polygon -7500403 true true 150 30 15 255 285 255 triangle 2 false 0 Polygon -7500403 true true 150 30 15 255 285 255 Polygon -16777216 true false 151 99 225 223 75 224 truck false 0 Rectangle -7500403 true true 4 45 195 187 Polygon -7500403 true true 296 193 296 150 259 134 244 104 208 104 207 194 Rectangle -1 true false 195 60 195 105 Polygon -16777216 true false 238 112 252 141 219 141 218 112 Circle -16777216 true false 234 174 42 Rectangle -7500403 true true 181 185 214 194 Circle -16777216 true false 144 174 42 Circle -16777216 true false 24 174 42 Circle -7500403 false true 24 174 42 Circle -7500403 false true 144 174 42 Circle -7500403 false true 234 174 42 turtle true 0 Polygon -10899396 true false 215 204 240 233 246 254 228 266 215 252 193 210 Polygon -10899396 true false 195 90 225 75 245 75 260 89 269 108 261 124 240 105 225 105 210 105 Polygon -10899396 true false 105 90 75 75 55 75 40 89 31 108 39 124 60 105 75 105 90 105 Polygon -10899396 true false 132 85 134 64 107 51 108 17 150 2 192 18 192 52 169 65 172 87 Polygon -10899396 true false 85 204 60 233 54 254 72 266 85 252 107 210 Polygon -7500403 true true 119 75 179 75 209 101 224 135 220 225 175 261 128 261 81 224 74 135 88 99 wheel false 0 Circle -7500403 true true 3 3 294 Circle -16777216 true false 30 30 240 Line -7500403 true 150 285 150 15 Line -7500403 true 15 150 285 150 Circle -7500403 true true 120 120 60 Line -7500403 true 216 40 79 269 Line -7500403 true 40 84 269 221 Line -7500403 true 40 216 269 79 Line -7500403 true 84 40 221 269 x false 0 Polygon -7500403 true true 270 75 225 30 30 225 75 270 Polygon -7500403 true true 30 75 75 30 270 225 225 270 @#$#@#$#@ NetLogo 4.1.3 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ default 0.0 -0.2 0 1.0 0.0 0.0 1 1.0 0.0 0.2 0 1.0 0.0 link direction true 0 Line -7500403 true 150 150 90 180 Line -7500403 true 150 150 210 180 @#$#@#$#@ 0 @#$#@#$#@