Archetype-Based Population Synthesis
Generating thousands of individually unique synthetic agents from a handful of named archetypes, while keeping the aggregate population's statistics faithful to a target distribution. Verified across two different domains, sharing one underlying pattern.
The pattern, in plain terms
Define a small number of archetypes (four poker player types; six market regimes). Give each archetype a center point and a spread for the traits that matter. Sample individuals from those distributions, with noise so no two are identical, and — where the archetype's parameters call for it — real correlation between traits, not independent noise on each one. The result: a population where every individual is genuinely unique, but the aggregate breakdown matches whatever mix you configured.
Verified by direct execution — 10,000 real agents, not a described result
Generated a 10,000-agent poker player pool with a configured 50/35/12/3% split across Fish/Reg/Shark/GTO:
Fish: target 50%, actual 50.1% (5007 agents) Reg: target 35%, actual 34.5% (3447 agents) Shark: target 12%, actual 12.3% (1230 agents) GTO: target 3%, actual 3.2% (316 agents) Fish VPIP uniqueness: 4991 distinct values across 4991 Fish agents — zero duplicates
The aggregate proportions land within a point of target at 10,000 agents, and every individual's specific behavioral parameters are genuinely unique — not the same handful of templates repeated. Confirmed directly, not assumed from the code.
The same pattern, a second domain
The market-regime version uses the identical structure — six regimes (Immature through Trapped) instead of four poker archetypes, nine market-signal vectors instead of behavioral stats. Generated 500 synthetic markets and measured the within-regime correlation the code claims to inject:
Mature regime (correlation_scale=0.85, correlation-injection triggers above 0.5): Real measured V1-V2 correlation within the regime: 0.564
The correlation is genuinely present in the generated data, not just asserted in a docstring — measured directly on the output, not read off the generating code.
Set your own distribution and generate a real population yourself, in your browser →
Update — correlation bug fixed in the library itself
The interactive version of this page found that the real poker generator drew VPIP, PFR, and aggression as fully independent uniforms — no correlation at all, which didn't match the actual goal of preserving realistic variable correlation. That fix has now been applied to the actual library source, not just the browser demo — verified directly against the fixed file: VPIP-PFR r=−0.837 on the Reg archetype at 20,000-agent scale, ranges still correctly respected.
The honest caveat that applies to both
Every archetype's specific numbers — a Fish's exact VPIP range, a Mature market's exact volatility — are hardcoded constants in the generator, not values fit from historical data. There's no data-loading step, no fitting procedure, anywhere in either file. That's a legitimate way to build and test a generator, but it means any downstream performance number computed on this synthetic population reflects how well a detection method finds patterns the generator was built to contain — not necessarily how it would perform on real, unstructured data. Worth stating plainly rather than letting "realistic populations" imply "calibrated to real history," which hasn't been established for either version.