bamengine 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. bamengine-0.1.0/LICENSE +21 -0
  2. bamengine-0.1.0/PKG-INFO +388 -0
  3. bamengine-0.1.0/README.md +338 -0
  4. bamengine-0.1.0/pyproject.toml +188 -0
  5. bamengine-0.1.0/setup.cfg +4 -0
  6. bamengine-0.1.0/src/bamengine/__init__.py +282 -0
  7. bamengine-0.1.0/src/bamengine/config/__init__.py +88 -0
  8. bamengine-0.1.0/src/bamengine/config/default_pipeline.yml +169 -0
  9. bamengine-0.1.0/src/bamengine/config/defaults.yml +110 -0
  10. bamengine-0.1.0/src/bamengine/config/schema.py +127 -0
  11. bamengine-0.1.0/src/bamengine/config/validator.py +907 -0
  12. bamengine-0.1.0/src/bamengine/core/__init__.py +101 -0
  13. bamengine-0.1.0/src/bamengine/core/agent.py +137 -0
  14. bamengine-0.1.0/src/bamengine/core/decorators.py +373 -0
  15. bamengine-0.1.0/src/bamengine/core/event.py +314 -0
  16. bamengine-0.1.0/src/bamengine/core/pipeline.py +512 -0
  17. bamengine-0.1.0/src/bamengine/core/registry.py +289 -0
  18. bamengine-0.1.0/src/bamengine/core/relationship.py +484 -0
  19. bamengine-0.1.0/src/bamengine/core/role.py +188 -0
  20. bamengine-0.1.0/src/bamengine/economy.py +112 -0
  21. bamengine-0.1.0/src/bamengine/events/__init__.py +165 -0
  22. bamengine-0.1.0/src/bamengine/events/_internal/__init__.py +129 -0
  23. bamengine-0.1.0/src/bamengine/events/_internal/bankruptcy.py +292 -0
  24. bamengine-0.1.0/src/bamengine/events/_internal/credit_market.py +784 -0
  25. bamengine-0.1.0/src/bamengine/events/_internal/goods_market.py +505 -0
  26. bamengine-0.1.0/src/bamengine/events/_internal/labor_market.py +680 -0
  27. bamengine-0.1.0/src/bamengine/events/_internal/planning.py +347 -0
  28. bamengine-0.1.0/src/bamengine/events/_internal/production.py +311 -0
  29. bamengine-0.1.0/src/bamengine/events/_internal/revenue.py +379 -0
  30. bamengine-0.1.0/src/bamengine/events/bankruptcy.py +213 -0
  31. bamengine-0.1.0/src/bamengine/events/credit_market.py +769 -0
  32. bamengine-0.1.0/src/bamengine/events/economy_stats.py +83 -0
  33. bamengine-0.1.0/src/bamengine/events/goods_market.py +427 -0
  34. bamengine-0.1.0/src/bamengine/events/labor_market.py +702 -0
  35. bamengine-0.1.0/src/bamengine/events/planning.py +379 -0
  36. bamengine-0.1.0/src/bamengine/events/production.py +333 -0
  37. bamengine-0.1.0/src/bamengine/events/revenue.py +282 -0
  38. bamengine-0.1.0/src/bamengine/logging.py +139 -0
  39. bamengine-0.1.0/src/bamengine/logging.pyi +49 -0
  40. bamengine-0.1.0/src/bamengine/ops.py +1017 -0
  41. bamengine-0.1.0/src/bamengine/py.typed +0 -0
  42. bamengine-0.1.0/src/bamengine/relationships/__init__.py +59 -0
  43. bamengine-0.1.0/src/bamengine/relationships/loanbook.py +722 -0
  44. bamengine-0.1.0/src/bamengine/roles/__init__.py +91 -0
  45. bamengine-0.1.0/src/bamengine/roles/borrower.py +115 -0
  46. bamengine-0.1.0/src/bamengine/roles/consumer.py +101 -0
  47. bamengine-0.1.0/src/bamengine/roles/employer.py +103 -0
  48. bamengine-0.1.0/src/bamengine/roles/lender.py +99 -0
  49. bamengine-0.1.0/src/bamengine/roles/producer.py +104 -0
  50. bamengine-0.1.0/src/bamengine/roles/worker.py +129 -0
  51. bamengine-0.1.0/src/bamengine/simulation.py +1118 -0
  52. bamengine-0.1.0/src/bamengine/typing.py +110 -0
  53. bamengine-0.1.0/src/bamengine/utils.py +394 -0
  54. bamengine-0.1.0/src/bamengine.egg-info/PKG-INFO +388 -0
  55. bamengine-0.1.0/src/bamengine.egg-info/SOURCES.txt +56 -0
  56. bamengine-0.1.0/src/bamengine.egg-info/dependency_links.txt +1 -0
  57. bamengine-0.1.0/src/bamengine.egg-info/requires.txt +23 -0
  58. bamengine-0.1.0/src/bamengine.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Konstantinos Ganitis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,388 @@
1
+ Metadata-Version: 2.4
2
+ Name: bamengine
3
+ Version: 0.1.0
4
+ Summary: High-performance agent-based framework for the BAM macroeconomic model
5
+ Author-email: Kostas Ganitis <ganitiskostas@gmail.com>
6
+ Maintainer-email: Kostas Ganitis <ganitiskostas@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: homepage, https://kganitis.github.io/bam-engine/
9
+ Project-URL: source, https://github.com/kganitis/bam-engine
10
+ Project-URL: tracker, https://github.com/kganitis/bam-engine/issues
11
+ Project-URL: changelog, https://github.com/kganitis/bam-engine/blob/main/CHANGELOG.md
12
+ Keywords: agent-based-modeling,macroeconomics,economic-simulation,computational-economics,complex-adaptive-systems,heterogeneous-agents,entity-component-system,simulation,scientific-computing,bam-model
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Intended Audience :: Financial and Insurance Industry
16
+ Classifier: Intended Audience :: Education
17
+ Classifier: Natural Language :: English
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Scientific/Engineering
25
+ Classifier: Topic :: Office/Business :: Financial
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.10
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy>=1.26
31
+ Requires-Dist: PyYAML>=6.0.2
32
+ Provides-Extra: dev
33
+ Requires-Dist: bamengine[docs,lint,test]; extra == "dev"
34
+ Provides-Extra: test
35
+ Requires-Dist: pytest>=8.3; extra == "test"
36
+ Requires-Dist: pytest-cov>=5.0; extra == "test"
37
+ Requires-Dist: hypothesis>=6.131.9; extra == "test"
38
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == "test"
39
+ Requires-Dist: snakeviz>=2.2.0; extra == "test"
40
+ Provides-Extra: lint
41
+ Requires-Dist: black>=24.1; extra == "lint"
42
+ Requires-Dist: ruff>=0.4; extra == "lint"
43
+ Requires-Dist: mypy>=1.9; extra == "lint"
44
+ Provides-Extra: docs
45
+ Requires-Dist: mkdocs>=1.5.0; extra == "docs"
46
+ Requires-Dist: mkdocs-material>=9.5.0; extra == "docs"
47
+ Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
48
+ Requires-Dist: mkdocs-autorefs>=0.5.0; extra == "docs"
49
+ Dynamic: license-file
50
+
51
+ # BAM Engine
52
+
53
+ **Bottom-Up Adaptive Macroeconomics Simulation Framework**
54
+
55
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/)
56
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
57
+
58
+ BAM Engine is a high-performance Python implementation of the BAM model from *Macroeconomics from the Bottom-up* (Delli Gatti et al., 2011, Chapter 3). It provides a modular, extensible agent-based macroeconomic simulation framework built on ECS (Entity-Component-System) architecture with fully vectorized NumPy operations.
59
+
60
+ ## Features
61
+
62
+ **Complete BAM Model**: 3 agent types (firms, households, banks) interacting in 3 markets (labor, credit, consumption goods)
63
+
64
+ **High Performance**: Fully vectorized NumPy operations enable simulations of large economies (500+ firms, 2500+ households) with minimal overhead
65
+
66
+ **ECS Architecture**: Modular Entity-Component-System design separates agent state (Roles) from behavior (Events), enabling easy customization and extension of economic mechanisms
67
+
68
+ **User-Friendly API**: Simplified decorators, NumPy-free operations module, and three-tier configuration system for researchers without deep Python expertise
69
+
70
+ **Research-Ready**: Deterministic RNG, comprehensive validation, extensive testing suite
71
+
72
+ **Flexible Configuration**: Three-tier system (BAM defaults → user YAML → kwargs parameters) with customizable event pipeline
73
+
74
+ ## Quick Start
75
+
76
+ ### Installation
77
+
78
+ ```bash
79
+ pip install bamengine
80
+ ```
81
+
82
+ Or install from source:
83
+
84
+ ```bash
85
+ git clone https://github.com/yourusername/bam-engine.git
86
+ cd bam-engine
87
+ pip install -e ".[dev]"
88
+ ```
89
+
90
+ ### Basic Usage
91
+
92
+ ```python
93
+ import bamengine as bam
94
+
95
+ # Initialize simulation with default configuration
96
+ sim = bam.Simulation.init(seed=42)
97
+
98
+ # Run (1000 periods by default)
99
+ sim.run()
100
+
101
+ # Access results
102
+ unemployment = sim.ec.unemp_rate_history[-1]
103
+ avg_price = sim.ec.price_history[-1]
104
+ print(f"Final unemployment: {unemployment:.2%}")
105
+ print(f"Final average price: {avg_price:.2f}")
106
+ ```
107
+
108
+ ### Custom Configuration
109
+
110
+ ```python
111
+ # Via keyword arguments
112
+ sim = bam.Simulation.init(
113
+ n_firms=200,
114
+ n_households=1000,
115
+ n_banks=20,
116
+ seed=42
117
+ )
118
+
119
+ # Via custom YAML file
120
+ sim = bam.Simulation.init(config="my_config.yml", seed=42)
121
+
122
+ # Step-by-step execution
123
+ sim = bam.Simulation.init(seed=42)
124
+ for period in range(100):
125
+ sim.step()
126
+ # Analyze state after each period
127
+ print(f"Period {period}: unemployment = {sim.ec.unemp_rate:.2%}")
128
+ ```
129
+
130
+ ## Architecture
131
+
132
+ BAM Engine uses an **ECS (Entity-Component-System)** architecture for modularity and performance:
133
+
134
+ - **Agents**: Lightweight entities with immutable IDs and types (FIRM, HOUSEHOLD, BANK)
135
+ - **Roles (Components)**: Dataclasses storing agent state as NumPy arrays (Producer, Worker, Lender, etc.)
136
+ - **Events (Systems)**: Pure functions operating on roles, executed in pipeline order
137
+ - **Relationships**: Many-to-many connections with sparse COO format (e.g., LoanBook for loans)
138
+ - **Pipeline**: YAML-configurable event execution with special syntax (repeat, interleave)
139
+
140
+ ### Agent Roles
141
+
142
+ - **Firms**: Producer + Employer + Borrower
143
+ - **Households**: Worker + Consumer
144
+ - **Banks**: Lender
145
+
146
+ ### Event Pipeline
147
+
148
+ Each period executes 39 events across 8 economic phases:
149
+
150
+ 1. **Planning**: Production targets, pricing, labor needs
151
+ 2. **Labor Market**: Wage setting, job search, hiring (4 rounds)
152
+ 3. **Credit Market**: Loan supply/demand, matching (2 rounds)
153
+ 4. **Production**: Wage payments, production execution
154
+ 5. **Goods Market**: Consumption decisions, shopping (2 rounds)
155
+ 6. **Revenue**: Revenue collection, debt repayment, dividends
156
+ 7. **Bankruptcy**: Insolvency detection, exit
157
+ 8. **Entry**: Replacement firm/bank spawning
158
+
159
+ ## Creating Custom Components
160
+
161
+ ### Custom Role
162
+
163
+ ```python
164
+ from bamengine import role
165
+ from bamengine.typing import Float, Int
166
+
167
+ @role
168
+ class Inventory:
169
+ """Custom inventory management role."""
170
+ goods_on_hand: Float
171
+ reorder_point: Float
172
+ days_until_delivery: Int
173
+ ```
174
+
175
+ ### Custom Event
176
+
177
+ ```python
178
+ from bamengine import event, ops, Simulation
179
+
180
+ @event
181
+ class CustomPricingEvent:
182
+ """Apply markup pricing to all producers."""
183
+
184
+ def execute(self, sim: Simulation) -> None:
185
+ prod = sim.get_role("Producer")
186
+ emp = sim.get_role("Employer")
187
+
188
+ # Calculate unit labor cost
189
+ unit_cost = ops.divide(emp.wage_offered, prod.labor_prod)
190
+
191
+ # Apply 50% markup
192
+ new_price = ops.multiply(unit_cost, 1.5)
193
+
194
+ # Update prices in-place
195
+ ops.assign(prod.price, new_price)
196
+ ```
197
+
198
+ ### Custom Relationship
199
+
200
+ ```python
201
+ from bamengine import relationship, get_role
202
+ from bamengine.typing import Float, Int
203
+
204
+ @relationship(source=get_role("Worker"), target=get_role("Employer"))
205
+ class GigEmployment:
206
+ """Many-to-many employment relationship."""
207
+ wage: Float
208
+ contract_duration: Int
209
+ start_period: Int
210
+ ```
211
+
212
+ ## Configuration
213
+
214
+ ### Three-Tier System
215
+
216
+ 1. **Package defaults** (`src/bamengine/config/defaults.yml`)
217
+ 2. **User YAML file** (custom configuration)
218
+ 3. **Keyword arguments** (highest priority)
219
+
220
+ ### Example Configuration
221
+
222
+ Parameters not specified in your YAML file automatically fall back to package defaults (`src/bamengine/config/defaults.yml`).
223
+
224
+ ```yaml
225
+ # config.yml
226
+ n_firms: 200
227
+ n_households: 1000
228
+ n_banks: 20
229
+ seed: 42
230
+
231
+ # Custom pipeline
232
+ pipeline_path: "custom_pipeline.yml"
233
+
234
+ # Logging configuration
235
+ logging:
236
+ default_level: INFO
237
+ events:
238
+ workers_send_one_round: WARNING
239
+ firms_hire_workers: DEBUG
240
+ ```
241
+
242
+ ```python
243
+ sim = bam.Simulation.init(
244
+ config="config.yml",
245
+ n_firms=250, # Overrides YAML
246
+ seed=123 # Overrides YAML
247
+ )
248
+ ```
249
+
250
+ ## Performance
251
+
252
+ BAM Engine achieves excellent performance through vectorization:
253
+
254
+ | Configuration | Firms | Households | Throughput |
255
+ |--------------|-------|------------|------------|
256
+ | Small | 100 | 500 | 172 periods/s |
257
+ | Medium | 200 | 1,000 | 96 periods/s |
258
+ | Large | 500 | 2,500 | 40 periods/s |
259
+
260
+ **Benchmarks** (1000 periods, Apple M4 Pro, macOS 15.1, Python 3.13):
261
+
262
+ - Small: 5.8s
263
+ - Medium: 10.4s
264
+ - Large: 24.5s
265
+
266
+ Performance scales sub-linearly with agent count due to NumPy vectorization efficiency.
267
+
268
+ ## Development
269
+
270
+ ### Setup
271
+
272
+ ```bash
273
+ # Clone repository
274
+ git clone https://github.com/kganitis/bam-engine.git
275
+ cd bam-engine
276
+
277
+ # Install in editable mode with dev dependencies
278
+ pip install -e ".[dev]"
279
+ ```
280
+
281
+ ### Code Quality
282
+
283
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
284
+ [![Type Checked](https://img.shields.io/badge/type%20checked-mypy-blue)](http://mypy-lang.org/)
285
+ [![Linter: Ruff](https://img.shields.io/badge/linter-ruff-orange)](https://github.com/astral-sh/ruff)
286
+
287
+ ```bash
288
+ # Format code
289
+ black src/ tests/
290
+
291
+ # Lint code
292
+ ruff check --fix src/ tests/
293
+
294
+ # Type checking
295
+ mypy src/
296
+ ```
297
+
298
+ ## Testing
299
+
300
+ [![Tests](https://img.shields.io/badge/tests-99%25%20coverage-brightgreen)]()
301
+
302
+ ```bash
303
+ # Run all tests
304
+ pytest
305
+
306
+ # Run with coverage
307
+ pytest --cov=src/bamengine
308
+
309
+ # Run specific test categories
310
+ pytest tests/unit/ # Unit tests
311
+ pytest tests/integration/ # Integration tests
312
+ pytest tests/property/ # Property-based tests
313
+ pytest -m "not slow" # Skip slow tests
314
+ ```
315
+
316
+ ### Benchmarking
317
+
318
+ ```bash
319
+ # Run macro-benchmarks (full simulation)
320
+ python benchmarks/bench_full_simulation.py
321
+
322
+ # Profile with cProfile
323
+ python benchmarks/profile_simulation.py
324
+
325
+ # Performance regression tests
326
+ pytest tests/performance/ -v
327
+ ```
328
+
329
+ ## Documentation
330
+
331
+ Not yet available. Coming soon!
332
+
333
+ ## Project Status
334
+
335
+ **Version**: 0.1.0
336
+
337
+ This release is feature-complete for the core BAM model but APIs may change in future releases. Designed for academic research and policy analysis experiments.
338
+
339
+ ## Citation
340
+
341
+ If you use BAM Engine in your research, please also cite the original BAM model:
342
+
343
+ ```bibtex
344
+ @inbook{DelliGatti2011Chapter,
345
+ author = {Delli Gatti, Domenico and Desiderio, Saul and Gaffeo, Edoardo and Cirillo,
346
+ Pasquale and Gallegati, Mauro},
347
+ title = {Macroeconomics from the Bottom-up},
348
+ chapter = {The BAM model at work},
349
+ year = {2011},
350
+ publisher = {Springer Milano},
351
+ series = {New Economic Windows},
352
+ volume = {1},
353
+ doi = {10.1007/978-88-470-1971-3},
354
+ isbn = {978-88-470-1971-3}
355
+ }
356
+ ```
357
+
358
+ ## License
359
+
360
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
361
+
362
+ ## Contributing
363
+
364
+ Contributions are welcome! Please:
365
+
366
+ 1. Fork the repository
367
+ 2. Create a feature branch (`git checkout -b feat/feature-name`)
368
+ 3. Commit your changes (`git commit -m 'feat: description'`)
369
+ 4. Push to the branch (`git push origin feat/feature-name`)
370
+ 5. Open a Pull Request
371
+
372
+ Please ensure:
373
+
374
+ - Code is formatted (`black src/ tests/`)
375
+ - Linting passes (`ruff check src/ tests/`)
376
+ - Type checking passes (`mypy src/`)
377
+ - All tests pass (`pytest`)
378
+ - Test coverage remains >95%
379
+
380
+ ## Acknowledgments
381
+
382
+ - **The BAM model**: Delli Gatti, D., Desiderio, S., Gaffeo, E., Cirillo, P., & Gallegati, M. (2011). The BAM model at work. In Macroeconomics from the Bottom-up (New Economic Windows). Springer Milano. [10.1007/978-88-470-1971-3](https://doi.org/10.1007/978-88-470-1971-3)
383
+
384
+ - **Built with**: NumPy, Python 3.10+
385
+
386
+ ---
387
+
388
+ **Issues?** Open an issue on [GitHub](https://github.com/kganitis/bam-engine/issues)