@@ -16,20 +16,24 @@ class ABIDESArena(CodeArena):
1616 submission : str = "abides_agent.py"
1717 description : str = """ABIDES is an agent-based market simulator for financial-market research.
1818
19- Your bot is a Python file named `abides_agent.py` that defines a class named `MyAgent `.
20- `MyAgent` should be an ABIDES trading agent class, for example :
19+ Your bot is a Python file named `abides_agent.py` that defines a function named `decide `.
20+ The function receives a plain observation dictionary and returns a list of order intents :
2121
22- from agent.ValueAgent import ValueAgent as MyAgent
22+ def decide(observation):
23+ return [{"side": "buy", "quantity": 5, "limit_price": 100000}]
2324
24- Each round runs several compact ABIDES market simulations. Every submitted agent is evaluated in
25- identical seeded market worlds with the same exchange, market maker, and background traders. The
26- objective is to maximize average mark-to-market profit across all simulations in the round.
25+ The trusted arena runtime owns the ABIDES exchange, kernel, ledgers, and order objects. Submitted
26+ code only returns declarative order intents. Each round runs several compact ABIDES market
27+ simulations. Every submitted policy is evaluated in identical seeded market worlds with the same
28+ exchange, market maker, and background traders. The objective is to maximize average mark-to-market
29+ profit across all simulations in the round.
2730"""
2831 default_args : dict = {
2932 "sims_per_round" : 3 ,
3033 "market_minutes" : 5 ,
3134 "background_agents" : 3 ,
3235 "validation_timeout" : 10 ,
36+ "decision_timeout" : 3.0 ,
3337 "player_timeout" : 60 ,
3438 "timeout" : 240 ,
3539 }
@@ -54,29 +58,29 @@ def validate_code(self, agent: Player) -> tuple[bool, str | None]:
5458 import_check = agent .environment .execute (
5559 "python - <<'PY'\n "
5660 "import importlib.util\n "
57- "import numpy as np\n "
58- "from agent.TradingAgent import TradingAgent\n "
5961 f"spec = importlib.util.spec_from_file_location('submission_agent', { self .submission !r} )\n "
6062 "module = importlib.util.module_from_spec(spec)\n "
6163 "spec.loader.exec_module(module)\n "
62- "assert hasattr(module, 'MyAgent'), 'MyAgent class not found'\n "
63- "assert issubclass(module.MyAgent, TradingAgent), 'MyAgent must inherit from an ABIDES TradingAgent class'\n "
64- "module.MyAgent(\n "
65- " id=1,\n "
66- " name='validation',\n "
67- " type='ValidationAgent',\n "
68- " symbol='JPM',\n "
69- " starting_cash=10000000,\n "
70- " log_orders=False,\n "
71- " random_state=np.random.RandomState(seed=1),\n "
72- ")\n "
64+ "assert hasattr(module, 'decide'), 'decide function not found'\n "
65+ "assert callable(module.decide), 'decide must be callable'\n "
66+ "observation = {\n "
67+ " 'symbol': 'JPM',\n "
68+ " 'cash': 10000000,\n "
69+ " 'position': 0,\n "
70+ " 'best_bid': None,\n "
71+ " 'best_ask': None,\n "
72+ " 'last_trade': 100000,\n "
73+ " 'market_open': True,\n "
74+ "}\n "
75+ "result = module.decide(observation)\n "
76+ "assert result is None or isinstance(result, (list, tuple, dict)), 'decide must return a list, tuple, dict, or None'\n "
7377 "PY" ,
7478 timeout = int (self ._game_arg ("validation_timeout" )),
7579 )
7680 if import_check ["returncode" ] != 0 :
7781 return (
7882 False ,
79- f"Could not import and instantiate `MyAgent ` from `{ self .submission } `:\n { import_check ['output' ]} " ,
83+ f"Could not import or call `decide ` from `{ self .submission } `:\n { import_check ['output' ]} " ,
8084 )
8185
8286 return True , None
@@ -95,6 +99,8 @@ def execute_round(self, agents: list[Player]) -> None:
9599 str (self ._game_arg ("market_minutes" )),
96100 "--background-agents" ,
97101 str (self ._game_arg ("background_agents" )),
102+ "--decision-timeout" ,
103+ str (self ._game_arg ("decision_timeout" )),
98104 "--player-timeout" ,
99105 str (self ._game_arg ("player_timeout" )),
100106 "--output" ,
0 commit comments