Skip to main content
Version: 1.0.0

Agents

The agent field allows you to create agents in the simulator and map them to an address on the chain. The agent has to be assigned a class which tells the simulator what kind of actions the agent will be performing.

Besides that you can also specify holdings for the agent. The holdings have to specify three fields:

  • token
  • amount
  • mint

The token field has to be set to a string that maps to the name of an ERC20 token. This token has to also be specified in the tokens field.

An amount will tell the simulator how much this user is holding (if the mint field is set to False we assume the user already has this). Make sure the user has the specified amount of tokens available at the specified starting block.

The mint function will tell the simulator that it needs to mint the position, if the user already has some tokens on the specified starting block this will be overwritten. If this is set to true the simulator will always set the user to the specified amount.

Agents also support code blocks. The supported code blocks are preStep, featureVector, step and postStep. These are configured at the top-level of the agent. So on the same level as holdings and address you can add an entry for these to overwrite the agent class and top level code blocks on an agent level. This can be usefull for having one rogue agent in the Liquidity Provider class that does everything on an extreme and provides liquidity completely different from all the other Liquidity Providers. To see how to write these code blocks please refer to the code page.

Format

nametype
typearray of
{
    class: string,
    address: string,
    holdings?: {
        token: string,
        amount: int,
        mint: boolean
    }
}
requiredtrue

Example

agents:
- class: "lp"
address: "0x6429FEe053768Ffa90a59cAfb98Ca9E8F6471211"
holdings:
- token: "bnWBTC"
amount: 4338109590
mint: false
- token: "ETH"
amount: 2847843290371928722
mint: true
- token: "DAI"
amount: 2847843290371928722
mint: true
preStep: |
def custom_agent_class_pre_step(agent, environment, metric_collector):
pass

custom_agent_class_pre_step(a, b, metric_collector)
featureVector: |
def agent_feature_vector(agent, token, environment):
coins_abr = {
'BNT': 0,
'LINK': 1,
'ETH': 2,
'DAI': 3,
'WBTC': 4
}

# same as for traders, calculate asset specific features
vol = environment.get_state().token_states[token].volatility
change = environment.get_state().token_states[token].price_change

# calculate asset share
share = agent.get_wallet().get_token_share(token)
return np.array([coins_abr[token], change, vol, share])
step: |
def custom_agent_class_step(agent, token, action, quantity, environment, metric_collector):
try:
token_address = get_token_address(environment, token)
quantity = int(quantity)
if action == 1:
agent.set_latest_action("deposit")
agent.get_client().bancor_network.deposit(token_address, quantity).transact(generate_tx_details(agent.get_address()))
elif action == 2:
pending_withdrawals = agent.get_variable('withdrawal_request_ids_by_token')[token]

if len(pending_withdrawals) > 0:
agent.set_latest_action("withdrawal")
environment.get_client().bancor_network.withdraw(pending_withdrawals[0]).transact({'from': agent.get_address()})
else:
agent.set_latest_action("cooldown")
withdrawal_request_id = environment.get_client().bancor_network.initWithdrawal(
token_address, quantity).transact({'from': agent.get_address()})
agent.get_variable('withdrawal_request_ids_by_token')[token].append(withdrawal_request_id)
else:
agent.set_latest_action('nothing')
except:
agent.set_latest_action('nothing')

custom_agent_class_step(a, b, c, d, e, metric_collector)
postStep: |
def custom_agent_class_post_step(agent, environment, metric_collector):
pass

custom_agent_class_post_step(a, b, metric_collector)