subpopulation

This commit is contained in:
Andrew Clark 2020-05-18 21:00:46 -04:00
parent 6e9ccf44a9
commit 778d60634b
31 changed files with 371338 additions and 434 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 55 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -13,7 +13,7 @@ genesis_states = {
'withdraw':{},
'outboundAgents':[],
'inboundAgents':[],
'operatorFiatBalance': R0,
'operatorFiatBalance': initialOperatingFiatBalance,
'operatorCICBalance': S0,
'fundsInProcess': {'timestep':[],'decision':[],'cic':[],'shilling':[]},
'totalDistributedToAgents':0,

View File

@ -40,7 +40,9 @@ partial_state_update_block = {
},
'variables': {
'withdraw': update_withdraw,
'network':update_network_withraw
'network':update_network_withraw,
'operatorFiatBalance':update_operatorFiatBalance_withdraw,
'operatorCICBalance':update_operatorCICBalance_withdraw
}
},
# Operator

View File

@ -19,10 +19,10 @@ def startingBalance(params, step, sL, s, _input):
division = timestep % 31 == 0
if timestep == 1:
for i in agents:
for i in clusters:
startingBalance[i] = network.nodes[i]['tokens']
elif division == True:
for i in agents:
for i in clusters:
startingBalance[i] = network.nodes[i]['tokens']
else:
startingBalance = s['startingBalance']
@ -61,7 +61,7 @@ def redCrossDrop(params, step, sL, s, _input):
timestep = s['timestep']
division = timestep % 30 == 0
division = timestep % redCrossDripFrequency == 0
if division == True:
fiatBalance = fiatBalance + drip

View File

@ -4,19 +4,22 @@ import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
from .supportingFunctions import *
from .subpopulation_clusters import *
# Assumptions:
# Amount received in shilling when withdraw occurs
leverage = 1
# process time
process_lag = 7 # timesteps
process_lag = 15 # timesteps
# red cross drip amount
drip = 4000
drip = 10000
# system initialization
agents = ['a','b','c','d','e','f','g','h','i','j','k','l','m','o','p']
# starting operatorFiatBalance
initialOperatingFiatBalance = 100000
redCrossDripFrequency = 90 # days
# system actors
system = ['external','cic']
@ -27,26 +30,11 @@ chama = ['chama_1','chama_2','chama_3','chama_4']
# traders
traders = ['ta','tb','tc'] #only trading on the cic. Link to external and cic not to other agents
allAgents = agents + system
mixingAgents = ['a','b','c','d','e','f','g','h','i','j','k','l','m','o','p','external']
UtilityTypesOrdered ={'Food/Water':1,
'Fuel/Energy':2,
'Health':3,
'Education':4,
'Savings Group':5,
'Shop':6}
utilityTypesProbability = {'Food/Water':0.6,
'Fuel/Energy':0.10,
'Health':0.03,
'Education':0.015,
'Savings Group':0.065,
'Shop':0.19}
allAgents = clusters + system
R0 = 500 #thousand xDAI
R0 = 40000 #xDAI
kappa = 4 #leverage
P0 = 1/100 #initial price
S0 = kappa*R0/P0
@ -64,11 +52,11 @@ def create_network():
network = nx.DiGraph()
# Add nodes for n participants plus the external economy and the cic network
for i in agents:
network.add_node(i,type='Agent',tokens=400, native_currency = int(np.random.uniform(low=20, high=500, size=1)[0]))
for i in clusters:
network.add_node(i,type='Agent',tokens=clustersMedianSourceBalance[int(i)], native_currency = int(np.random.uniform(low=clusters1stQSourceBalance[int(i)], high=clusters3rdQSourceBalance[int(i)], size=1)[0]))
network.add_node('external',type='Contract',native_currency = 100000000,tokens = 0,delta_native_currency = 0, pos=(1,50))
network.add_node('external',type='Cloud',native_currency = 100000000,tokens = 0,delta_native_currency = 0, pos=(1,50))
network.add_node('cic',type='Contract',tokens= S0, native_currency = R0,pos=(50,1))
for i in chama:
@ -92,12 +80,11 @@ def create_network():
# Create bi-directional edges between some agent and a chama node representing membershio
for i in chama:
for j in agents:
for j in clusters:
if np.random.choice(['Member','Non_Member'],1,p=[.50,.50])[0] == 'Member':
network.add_edge(i,j)
# Type colors
colors = ['Red','Blue','Green','Orange']
color_map = []
for i in network.nodes:
if network.nodes[i]['type'] == 'Agent':

View File

@ -50,16 +50,14 @@ def velocity_of_money(params, step, sL, s):
KPISpend = s['KPISpend']
# TODO: Moving average for state variable
T = []
for i,j in KPISpend.items():
T.append(j)
T = sum(T)
# TODO Moving average for state variable
M = []
for i in agents:
for i in clusters:
M.append(network.nodes[i]['tokens'] + network.nodes[i]['native_currency'])
M = sum(M)

View File

@ -7,21 +7,20 @@ from .supportingFunctions import *
from collections import OrderedDict
# Parameters
FrequencyOfAllocation = 45 # every two weeks
FrequencyOfAllocation = 7
idealFiat = 5000
idealCIC = 200000
varianceCIC = 50000
varianceFiat = 1000
unadjustedPerAgent = 50
inventory_controller = False
agentAllocation = {'a':[1,1],'b':[1,1],'c':[1,1], # agent:[centrality,allocationValue]
'd':[1,1],'e':[1,1],'f':[1,1],
'g':[1,1],'h':[1,1],'i':[1,1],
'j':[1,1],'k':[1,1],'l':[1,1],
'm':[1,1],'o':[1,1],'p':[1,1]}
agentAllocation = {'0':[1,1],'1':[1,1],'2':[1,1], # agent:[centrality,allocationValue]
'3':[1,1],'4':[1,1],'5':[1,1],
'6':[1,1],'7':[1,1],'8':[1,1],
'9':[1,1]}
# Behaviors
def disbursement_to_agents(params, step, sL, s):
@ -51,8 +50,6 @@ def disbursement_to_agents(params, step, sL, s):
def inventory_controller(params, step, sL, s):
'''
Monetary policy hysteresis conservation allocation between fiat and cic reserves.
# TODO: If scarcity on both sides, add feedback to reduce percentage able to withdraw, frequency you can redeem, or redeem at less than par.
'''
fiatBalance = s['operatorFiatBalance']
cicBalance = s['operatorCICBalance']
@ -62,10 +59,13 @@ def inventory_controller(params, step, sL, s):
updatedCIC = cicBalance
updatedFiat = fiatBalance
#decision,amt = mint_burn_logic_control(idealCIC,updatedCIC,variance,updatedFiat)
decision,amt = mint_burn_logic_control(idealCIC,updatedCIC,varianceCIC,updatedFiat,varianceFiat,idealFiat)
if inventory_controller == True:
decision,amt = mint_burn_logic_control(idealCIC,updatedCIC,varianceCIC,updatedFiat,varianceFiat,idealFiat)
else:
decision = 'none'
amt = 0
if decision == 'burn':
try:
deltaR, realized_price = withdraw(amt,updatedFiat,updatedCIC, V0, kappa)
@ -129,7 +129,7 @@ def update_agent_tokens(params,step,sL,s,_input):
amount = _input['amount']
if distribute == 'Yes':
for i in agents:
for i in clusters:
network.nodes[i]['tokens'] = network.nodes[i]['tokens'] + amount[i]
else:
pass

View File

@ -0,0 +1,149 @@
# Computed clusters data
clusters = ['0','1','2','3','4','5','6','7','8','9']
mixingAgents = ['0','1','2','3','4','5','6','7','8','9','external']
clustersMedianSourceBalance = [310.0,174.5,206.38,64767.51,229.17,251652.0,18304.36,211.7,250.5,310.0]
clusters1stQSourceBalance = [112.53,119.22,100.46,64767.51,100.0,251652.0,14050.3,109.42,102.46,150.72]
clusters3rdQSourceBalance = [800.24,540.43,582.48,64767.51,924.5,251652.0,24857.5,670.44,968.88,1458.79]
clustersMu = [291.21,606.38,514.12,1589.17,527.76,3909.86,1291.45,601.12,457.42,1783.02]
clustersSigma = [731.89,1529.2,1882.62,5646.55,1337.06,8736.56,3381.92,1548.68,1496.74,7596.17]
UtilityTypesOrdered = {'0': {'Food/Water': 1,
'Farming/Labour': 2,
'Shop': 3,
'Fuel/Energy': 4,
'None': 5,
'Transport': 6,
'Savings Group': 7,
'Education': 8,
'Health': 9,
'Environment': 10,
'Staff': 11,
'System': 12,
'Chama': 13,
'Game': 14},
'1': {'Food/Water': 1},
'2': {'Savings Group': 1, 'Farming/Labour': 2, 'Food/Water': 3},
'3': {'Farming/Labour': 1,
'Food/Water': 2,
'Shop': 3,
'Savings Group': 4,
'Fuel/Energy': 5,
'None': 6,
'Transport': 7,
'Education': 8},
'4': {'Food/Water': 1,
'Savings Group': 2,
'Farming/Labour': 3,
'Shop': 4,
'Fuel/Energy': 5,
'Health': 6,
'None': 7,
'Transport': 8,
'Education': 9},
'5': {'Farming/Labour': 1,
'Food/Water': 2,
'Savings Group': 3,
'Shop': 4,
'Fuel/Energy': 5,
'Transport': 6},
'6': {'Food/Water': 1,
'Farming/Labour': 2,
'Shop': 3,
'Fuel/Energy': 4,
'Savings Group': 5,
'Education': 6,
'Transport': 7,
'None': 8,
'Health': 9,
'Staff': 10},
'7': {'Savings Group': 1, 'Food/Water': 2, 'Farming/Labour': 3, 'Shop': 4},
'8': {'Savings Group': 1,
'Food/Water': 2,
'Health': 3,
'Education': 4,
'Farming/Labour': 5,
'Shop': 6},
'9': {'Savings Group': 1},
'external': {'Food/Water':1,
'Fuel/Energy':2,
'Health':3,
'Education':4,
'Savings Group':5,
'Shop':6}}
utilityTypesProbability = {'0': {'Food/Water': 0.3376267211378423,
'Farming/Labour': 0.3294560447874111,
'Shop': 0.19210546224844907,
'Fuel/Energy': 0.041685580269329704,
'None': 0.03374186715085489,
'Transport': 0.028086699954607355,
'Savings Group': 0.01813814495385081,
'Education': 0.012445150552277198,
'Health': 0.00450143743380239,
'Environment': 0.0012672113784233622,
'Staff': 0.0006808896958692692,
'System': 0.0002080496292933878,
'Chama': 3.782720532607051e-05,
'Game': 1.8913602663035257e-05},
'1': {'Food/Water': 1.0},
'2': {'Savings Group': 0.6427282569469506,
'Farming/Labour': 0.25045110068567306,
'Food/Water': 0.1068206423673764},
'3': {'Farming/Labour': 0.25480153649167736,
'Food/Water': 0.1882202304737516,
'Shop': 0.18437900128040974,
'Savings Group': 0.16645326504481434,
'Fuel/Energy': 0.12419974391805377,
'None': 0.07554417413572344,
'Transport': 0.0038412291933418692,
'Education': 0.002560819462227913},
'4': {'Food/Water': 0.3145801420414984,
'Savings Group': 0.2651441303439632,
'Farming/Labour': 0.16724690154574573,
'Shop': 0.1522072134800167,
'Fuel/Energy': 0.06057652137585295,
'Health': 0.03328227266397438,
'None': 0.0036206656454532793,
'Transport': 0.0020888455646845844,
'Education': 0.0012533073388107507},
'5': {'Farming/Labour': 0.35526315789473684,
'Food/Water': 0.35526315789473684,
'Savings Group': 0.18421052631578946,
'Shop': 0.05263157894736842,
'Fuel/Energy': 0.02631578947368421,
'Transport': 0.02631578947368421},
'6': {'Food/Water': 0.3230154767848228,
'Farming/Labour': 0.2860708936595107,
'Shop': 0.18871692461308037,
'Fuel/Energy': 0.0983524712930604,
'Savings Group': 0.040439340988517224,
'Education': 0.032950574138791815,
'Transport': 0.013979031452820768,
'None': 0.012980529206190713,
'Health': 0.0024962556165751375,
'Staff': 0.000998502246630055},
'7': {'Savings Group': 0.7747841105354059,
'Food/Water': 0.15751295336787566,
'Farming/Labour': 0.04870466321243523,
'Shop': 0.018998272884283247},
'8': {'Savings Group': 0.6999073215940685,
'Food/Water': 0.19258572752548656,
'Health': 0.03670064874884152,
'Education': 0.03132530120481928,
'Farming/Labour': 0.02057460611677479,
'Shop': 0.018906394810009268},
'9': {'Savings Group': 1.0},
'external': {'Food/Water':0.6,
'Fuel/Energy':0.10,
'Health':0.03,
'Education':0.015,
'Savings Group':0.065,
'Shop':0.19}}

View File

@ -173,36 +173,36 @@ def DictionaryMergeAddition(inflow,outflow):
return merged
def mint_burn_logic_control(ideal,actual,variance,fiat,fiat_variance,ideal_fiat):
def mint_burn_logic_control(idealCIC,actualCIC,varianceCIC,actualFiat,varianceFiat,idealFiat):
'''
Inventory control function to test if the current balance is in an acceptable range. Tolerance range
'''
if ideal - variance <= actual <= ideal + (2*variance):
if idealFiat - varianceFiat <= actualFiat <= idealFiat + (2*varianceFiat):
decision = 'none'
amount = 0
else:
if (ideal + variance) > actual:
decision = 'mint'
amount = (ideal + variance) - actual
if (idealFiat + varianceFiat) > actualFiat:
decision = 'burn'
amount = (idealFiat + varianceFiat) - actualFiat
else:
pass
if actual > (ideal + variance):
decision = 'burn'
amount = actual - (ideal + variance)
if actualFiat > (idealFiat + varianceFiat):
decision = 'mint'
amount = actualFiat - (idealFiat + varianceFiat)
else:
pass
if decision == 'mint':
if fiat < (ideal_fiat - fiat_variance):
if amount > fiat:
if actualCIC < (idealCIC - varianceCIC):
if amount > actualCIC:
decision = 'none'
amount = 0
else:
pass
if decision == 'none':
if fiat < (ideal_fiat - fiat_variance):
if actualCIC < (idealCIC - varianceCIC):
decision = 'mint'
amount = (ideal_fiat-fiat_variance)
amount = (idealCIC-varianceCIC)
else:
pass

View File

@ -5,6 +5,8 @@ from cadCAD.configuration.utils import access_block
from .initialization import *
from .supportingFunctions import *
from collections import OrderedDict
from .subpopulation_clusters import *
# Parameters
agentsMinus = 2
@ -19,10 +21,28 @@ def choose_agents(params, step, sL, s):
'''
outboundAgents = np.random.choice(mixingAgents,size=len(mixingAgents)-agentsMinus).tolist()
inboundAgents = np.random.choice(mixingAgents,size=len(mixingAgents)-agentsMinus).tolist()
stepDemands = np.random.uniform(low=1, high=500, size=len(mixingAgents)-agentsMinus).astype(int)
demands = []
for i in outboundAgents:
if i == 'external':
demands.append(np.random.normal(sum(clustersMu)/len(clustersMu), sum(clustersSigma)/len(clustersMu), 1)[0])
else:
demands.append(np.random.normal(clustersMu[int(i)], clustersSigma[int(i)], 1)[0])
stepDemands = []
for i in demands:
if i > 0:
stepDemands.append(round(i,2))
else:
stepDemands.append(1)
stepUtilities = []
for i in outboundAgents:
stepUtilities.append(np.random.choice(list(UtilityTypesOrdered[str(i)].keys()),size=1,p=list(utilityTypesProbability[str(i)].values()))[0])
stepUtilities = np.random.choice(list(UtilityTypesOrdered.keys()),size=len(mixingAgents)-agentsMinus,p=list(utilityTypesProbability.values())).tolist()
return {'outboundAgents':outboundAgents,'inboundAgents':inboundAgents,'stepDemands':stepDemands,'stepUtilities':stepUtilities}
@ -53,7 +73,10 @@ def spend_allocation(params, step, sL, s):
rankOrderDemand = {}
for j in network.adj[i]:
try:
rankOrder[j] = UtilityTypesOrdered[network.adj[i][j]['utility']]
#print(network.adj[i][j]['utility'])
#print(network.adj[i][j])
utility = network.adj[i][j]['utility']
rankOrder[j] = UtilityTypesOrdered[i][utility]
rankOrderDemand[j] = network.adj[i][j]['demand']
rankOrder = dict(OrderedDict(sorted(rankOrder.items(), key=lambda v: v, reverse=False)))
for k in rankOrder:
@ -239,7 +262,7 @@ def update_node_spend(params, step, sL, s,_input):
def update_withdraw(params, step, sL, s,_input):
'''
Update flow sstate variable with the aggregated amount of shillings withdrawn
Update flow state variable with the aggregated amount of shillings withdrawn
'''
y = 'withdraw'
x = s['withdraw']
@ -277,3 +300,39 @@ def update_network_withraw(params, step, sL, s,_input):
x = network
return (y,x)
def update_operatorFiatBalance_withdraw(params, step, sL, s,_input):
'''
Update flow state variable with the aggregated amount of shillings withdrawn
'''
y = 'operatorFiatBalance'
x = s['operatorFiatBalance']
if _input['withdraw']:
withdraw = _input['withdraw']
withdrawnCICSum = []
for i,j in withdraw.items():
withdrawnCICSum.append(j)
x = x - sum(withdrawnCICSum)
else:
pass
return (y,x)
def update_operatorCICBalance_withdraw(params, step, sL, s,_input):
'''
Update flow state variable with the aggregated amount of shillings withdrawn
'''
y = 'operatorCICBalance'
x = s['operatorCICBalance']
if _input['withdraw']:
withdraw = _input['withdraw']
withdrawnCICSum = []
for i,j in withdraw.items():
withdrawnCICSum.append(j)
x = x + sum(withdrawnCICSum)
else:
pass
return (y,x)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
2,Sarafu,SARAFU,,LIQUID,0x0Fd6e8F2320C90e9D4b3A5bd888c4D556d20AbD4,0x2160a64ea2DE397963e3740C2aA9efAA08BB711A
1,Kenyan Shilling,Ksh,,RESERVE,0xaE4ca821F7Ec78587a113CAC8E0CC393715E8622,
1 2 Sarafu SARAFU LIQUID 0x0Fd6e8F2320C90e9D4b3A5bd888c4D556d20AbD4 0x2160a64ea2DE397963e3740C2aA9efAA08BB711A
2 1 Kenyan Shilling Ksh RESERVE 0xaE4ca821F7Ec78587a113CAC8E0CC393715E8622

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff