title: Trading System Ontology dimension: knowledge category: ontology-trading.md tags: 6-dimensions, ai, trading, stigmergy, pheromones, emergence, typedb, evolution, meta-learning, stan, type-theory related_dimensions: connections, events, groups, actors, things scope: mission created: 2026-01-15 updated: 2026-01-15 version: 3.5.0 ai_context: | This document is part of the knowledge dimension in the ontology-trading.md category. Location: missions/trade/ontology.md Purpose: Domain-specific ONE Ontology extension for stigmergic trading with EMERGENCE Related dimensions: All 6 dimensions specialized for trading
For AI agents: Read this to understand the trading system's data model, cognitive architecture, and TypeDB integration. Every entity maps to exactly one ONE dimension. The cognitive loop (OBSERVE/ANALYZE/DECIDE/ACT/LEARN) is a process that operates ON these dimensions.
KEY INTEGRATIONS (v3.3.0):
- Type Theory foundations (CIKM 2023 paper)
- TypeQL 3.0 syntax with functions
- STAN Algorithm (formula, multi-channel pheromones, decay hierarchy)
- 6-Dimension State Model (3,600 unique states)
- STAN VIII capabilities (27 categories, 237 components)
- Emergence metrics, Genome evolution, Hypothesis testing
EMERGENCE FEATURES (v3.1.0): - EmergenceMetrics: Track emergence_score and phase transitions - Genome/LineageAnalysis: Evolution with heritable traits - Hypothesis: Meta-learning from pattern failures - FeedbackCycle: Self-funding loop instrumentation - SignalEdge confidence: Bayesian credible intervals - Self-Model Queries: Colony introspection capabilities
Trading System Ontology v3.5.0 — ETHICAL EMERGENCE + SUPERINTELLIGENCE
ONE Ontology Extension for Stigmergic Trading with Emergent AI
A domain-specific extension of the ONE Platform 6-dimension ontology specialized for cryptocurrency perpetual futures trading with emergent intelligence through pheromone trails, evolutionary dynamics, and meta-learning.
Version
- Ontology Version: 3.5.0 (ETHICAL EMERGENCE + SUPERINTELLIGENCE)
- Based On: ONE Platform 6-Dimensions v3.0.0 (Reality as DSL)
- TypeQL Version: 3.0 (December 2024 release)
- Domain: Stigmergic Trading (STAN VIII Algorithm)
- Exchange: Hyperliquid (Testnet/Mainnet)
- Last Updated: 2026-01-15
- Key Addition: Ethical foundations from principles.md — ethics emerges through selection pressure
Type Theory Foundations
Reference: Type Theory as a Unifying Paradigm for Modern Databases (Dorn & Pribadi, CIKM 2023)
TypeQL is rooted in type theory—a branch of mathematical logic where types record constraints for variables, and types compose in ways that mirror natural language.
Type-Theoretic Mappings
The ONE Ontology maps directly to type theory primitives:
| ONE Dimension | Type Theory Concept | TypeQL 3.0 Syntax |
|---|---|---|
| Entities | Non-composite independent types | entity signal-edge |
| Relations | Non-composite dependent types | relation trade-execution, relates ... |
| Attributes | Algebraic types (dependent subtypes) | attribute win-rate, value double |
| Queries | Composite independent types | match $e isa signal-edge; |
| Functions | Composite dependent types (parametrized queries) | fun get_elite() -> {signal-edge}: |
| Type Hierarchies | Subtype relationships | entity scout sub agent |
Why Type Theory Matters
NATURAL LANGUAGE TYPE THEORY TYPEQL 3.0
──────────────── ─────────── ──────────
"the signal edge x" variable x : signal-edge $x isa signal-edge
"x has win rate > 75%" constraint on x $x has win-rate > 0.75
"x is elite" derived type $x has tier "elite"
"signals from state s to direction d" dependent type (s,d) → edge ($s, $d) → signal-edge
Composite constraints form composite types → Queries ARE types
Key Type-Theoretic Principles
Type Inference: Variables get types from context—TypeQL infers types automatically
match $x isa signal-edge; $x has win-rate $wr; # $wr inferred as double $x (from: $state); # $state inferred from relationCompositionality: Types compose like natural language
# "elite edges from trending regimes with high pheromone" match $e isa signal-edge, has tier "elite", has trail-pheromone > 80.0; $e has from-state-id $s; $s contains "TREN";Atomic over Complex: Prefer simple, atomic types over complex composites
# GOOD: Atomic entity with owned attributes entity signal-edge, owns win-count, owns loss-count, owns trail-pheromone; # AVOID: Complex nested structuresDeduction over Storage: Use inference to derive facts rather than storing them
# tier is DERIVED by function, not stored fun is_elite($e: signal-edge) -> boolean: match $e has win-rate >= 0.75, has trail-pheromone >= 70.0; return true;
PERA Model (Polymorphic Entity-Relation-Attribute)
TypeDB implements the PERA model where:
- Entities are independent concepts (standalone types)
- Relations depend on role interfaces played by entities/relations
- Attributes are properties with values that interface with entities/relations
- All three are first-class citizens and can be subtyped
PERA IN TRADING ONTOLOGY
══════════════════════════════════════════════════════════════════════════════
ENTITIES (Independent Types)
├── signal-edge # Core pheromone trail
├── market-state # Market observation
├── trading-signal # Generated signal
├── agent-genome # Heritable parameters
└── emergence-metrics # Colony-level metrics
RELATIONS (Dependent Types)
├── trade-execution # Decision → Trade
├── parent-of # Genome → Genome (lineage)
└── pattern-correlation # Edge ↔ Edge
ATTRIBUTES (Algebraic Types)
├── win-rate: double # Computed ratio
├── trail-pheromone: double
├── tier: string # "elite", "danger", etc.
└── emergence-score: double
All types inherit, compose, and support polymorphic queries.
STAN Algorithm Integration
Reference: STAN Whitepaper, docs/stan.md
STAN (Stigmergic A* Navigation) is the core pathfinding algorithm. It combines A* search with ant colony optimization, enabling agents to learn from collective experience.
The STAN Formula
effective_cost = base_weight / (1 + pheromone_level × pheromone_influence)
| Component | Symbol | Description | TypeQL Attribute |
|---|---|---|---|
base_weight |
W | Inherent edge cost (default: 1.0) | base-weight |
pheromone_level |
τ | Accumulated trail signal | trail-pheromone |
pheromone_influence |
α | Agent sensitivity (0.1-0.9) | pheromone-sensitivity |
effective_cost |
C | Computed cost for pathfinding | (derived) |
Behavior:
As τ → 0: C → W (unexplored path - high cost)
As τ → ∞: C → 0 (superhighway - near-zero cost)
TypeQL 3.0 STAN Functions
# Core STAN cost calculation
fun stan_effective_cost(
$base: double,
$pheromone: double,
$alpha: double = 0.7
) -> double:
return $base / (1.0 + $pheromone * $alpha);
# Get edge with lowest STAN cost from a state
fun best_edge_from_state($state_id: string, $alpha: double = 0.7) -> signal-edge:
match
$e isa signal-edge,
has from-state-id $state_id,
has trail-pheromone $tp,
has alarm-pheromone $ap;
let $net_pheromone = $tp - $ap;
let $cost = 1.0 / (1.0 + $net_pheromone * $alpha);
sort $cost asc;
limit 1;
return $e;
# Multi-channel STAN cost (trail, alarm, quality)
fun multi_channel_stan_cost(
$e: signal-edge,
$trail_sens: double = 0.7,
$alarm_sens: double = 0.5,
$quality_sens: double = 0.3
) -> double:
match
$e has trail-pheromone $tp,
has alarm-pheromone $ap,
has quality-pheromone $qp;
let $base = 1.0;
let $c1 = $base / (1.0 + $tp * $trail_sens);
let $c2 = $c1 * (1.0 + $ap * $alarm_sens); # Alarm increases cost
let $c3 = $c2 / (1.0 + $qp * $quality_sens);
return $c3;
Multi-Channel Pheromones
Real ant colonies use 10-20 distinct pheromone compounds. Our system implements 5 channels:
PHEROMONE CHANNELS
═══════════════════════════════════════════════════════════════════════════════
Channel │ Decay (τ) │ Half-life │ Purpose │ Scout │ Harvester
──────────────┼───────────┼───────────┼──────────────────────┼───────┼──────────
trail │ 0.95 │ ~14 cyc │ "I traded here" │ 0.3 │ 0.9
alarm │ 0.80 │ ~3 cyc │ "Danger/loss here" │ 0.8 │ 0.7
recruitment │ 0.99 │ ~69 cyc │ "High reward found" │ 0.2 │ 0.8
exploration │ 0.85 │ ~5 cyc │ "Uncharted pattern" │ 0.9 │ 0.2
quality │ 0.93 │ ~10 cyc │ "High Sharpe edge" │ 0.4 │ 0.9
STAN Pheromone Types (V43/V44)
STAN VIII adds specialized pheromone types for AGI trading:
class STANPheromoneType(Enum):
PATTERN = "stan_pattern" # V43 HiddenPatternDiscovery (τ=0.97)
EDGE = "stan_edge" # V43 NovelEdgeGenerator (τ=0.95)
ALPHA_DECAY = "stan_alpha_decay" # V43 AlphaDecayDetector (τ=0.98)
MICROSTRUCTURE = "stan_micro" # V44 CEX analysis (τ=0.90)
VALIDATED = "stan_validated" # Walk-forward validated (τ=0.99)
ENSEMBLE = "stan_ensemble" # Multi-agent agreement (τ=0.95)
COUNTERFACTUAL = "stan_cf" # Counterfactual evaluation (τ=0.97)
Decay Hierarchy
DECAY HIERARCHY (Information Lifecycle)
═══════════════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────────────────────────┐
│ PERMANENT (τ = 1.0) │
│ Superhighways, crystallized patterns, proven knowledge │
│ Never decay. Earned through 100+ successful traversals. │
└─────────────────────────────────────────────────────────────────────────────┘
▲ Crystallization (pheromone > 85)
┌─────────────────────────────────────────────────────────────────────────────┐
│ SLOW DECAY (τ = 0.99) Half-life: ~69 cyc │
│ Validated edges, recruitment signals, STAN_VALIDATED │
│ The "long-term memory" of the colony. │
└─────────────────────────────────────────────────────────────────────────────┘
▲ Validation (walk-forward Sharpe > 1.5)
┌─────────────────────────────────────────────────────────────────────────────┐
│ MEDIUM DECAY (τ = 0.95) Half-life: ~14 cyc │
│ Trail signals, quality signals, active patterns │
│ The "working memory" of the colony. │
└─────────────────────────────────────────────────────────────────────────────┘
▲ Reinforcement (win deposits +1.0)
┌─────────────────────────────────────────────────────────────────────────────┐
│ FAST DECAY (τ = 0.80) Half-life: ~3 cyc │
│ Alarm signals, exploration markers, speculation │
│ The "sensory buffer" of the colony. │
└─────────────────────────────────────────────────────────────────────────────┘
Caste Differentiation
The pheromone_influence parameter creates behavioral diversity:
| Caste | Trail Sens | Alarm Sens | Behavior |
|---|---|---|---|
| Scout | 0.3 | 0.8 | Explores new paths, heeds warnings |
| Harvester | 0.9 | 0.5 | Exploits proven paths |
| Relay | 0.6 | 0.6 | Balanced information spread |
| Hybrid | Variable | Variable | Context-adaptive |
# Scout: even high trail pheromone doesn't reduce cost much → explores
scout_cost = base / (1 + pheromone × 0.3)
# Harvester: high trail dramatically reduces cost → exploits
harvester_cost = base / (1 + pheromone × 0.9)
6-Dimension State Model
The pheromone brain uses a 6-dimensional state discretization:
STATE DIMENSIONS
═══════════════════════════════════════════════════════════════════════════════
Dimension │ Values │ Discretization
──────────────┼─────────────────────────────────────────────────┼───────────────
regime │ crash, bear, sideways, bull, strong_bull │ 5 bins
trend │ down, flat, up │ 3 bins
volatility │ low, medium, high, extreme │ 4 bins
rsi_zone │ oversold, weak, neutral, strong, overbought │ 5 bins
volume_zone │ low_vol, normal_vol, high_vol, spike_vol │ 4 bins
position_zone │ near_low, mid_range, near_high │ 3 bins
Total state space: 5 × 3 × 4 × 5 × 4 × 3 = 3,600 unique states
State ID Format: {regime}:{trend}:{volatility}:{rsi}:{volume}:{position}
Example: bull:up:medium:strong:normal_vol:mid_range
TypeDB Schema (STAN Extensions)
# === STAN ATTRIBUTE TYPES ===
attribute base-weight, value double;
attribute pheromone-sensitivity, value double;
attribute trail-decay-rate, value double;
attribute alarm-decay-rate, value double;
attribute stan-pheromone-type, value string;
attribute walk-forward-sharpe, value double;
attribute crystallization-threshold, value double;
# === STAN FUNCTIONS ===
# Deposit pheromone after trade outcome
fun deposit_pheromone(
$edge_id: string,
$outcome: string,
$pnl: double
) -> signal-edge:
match
$e isa signal-edge, has edge-id $edge_id;
if $outcome == "win":
# Increase trail, decrease alarm
let $trail_delta = 1.0 + ($pnl * 0.1);
# Update trail-pheromone
else:
# Increase alarm, no trail deposit
let $alarm_delta = 1.0;
return $e;
# Run decay cycle on all edges
fun decay_all_pheromones($trail_rate: double = 0.95, $alarm_rate: double = 0.80):
match
$e isa signal-edge,
has trail-pheromone $tp,
has alarm-pheromone $ap;
$tp > 0.01;
# Apply decay: new_pheromone = old * decay_rate
return;
# Check for crystallization candidates
fun check_crystallization($threshold: double = 85.0) -> { signal-edge }:
match
$e isa signal-edge,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
$tp >= $threshold;
let $total = $wc + $lc;
$total >= 100;
return { $e };
STAN VIII Capability Integration
27 capability categories from STAN VIII are integrated:
| Category | Capability | Integration |
|---|---|---|
| Core | unified_reasoning (V36-V94) | Via STANBrain |
| Quant | v42_quantitative (12 modules) | Direct |
| Alpha | v43_alpha_system (5 tiers) | Pheromone deposits |
| Intel | v44_trading_intelligence | Microstructure pheromones |
| Discovery | stigmergic_discovery | Multi-agent strategy search |
| Validation | robustness_lab | Walk-forward, Monte Carlo |
| Risk | risk_governor | Position sizing, limits |
See missions/trade/stan-implementation.md for the full 237-component inventory.
Overview
The Trading Ontology extends our universal 6-dimension model to capture the unique aspects of stigmergic trading systems:
ONE ONTOLOGY × TRADING SYSTEM
══════════════════════════════════════════════════════════════════════════
┌──────────────────────────────────────────────────────────────────────────┐
│ │
│ Groups (trade mission, strategy groups, risk tiers) │
│ ↓ │
│ Actors (Market, Brain, Judges, Executor, Memory) │
│ ↓ │
│ Things (State, Price, Depth, Volatility, Funding, Regime, Signal) │
│ ↓ │
│ Connections (SignalEdge pheromone trails with STAN cost) │
│ ↓ │
│ Events (Decision, Trade, RegimeChange, PatternDiscovery) │
│ ↓ │
│ Knowledge (Crystallized Patterns, Risk Profiles, Analytics) │
│ │
└──────────────────────────────────────────────────────────────────────────┘
THE COGNITIVE LOOP (Process on Dimensions)
══════════════════════════════════════════
OBSERVE (Market) → THINGS → State, Price, Depth, Volatility
│
▼
ANALYZE (Brain) → CONNECTIONS → SignalEdge lookup → Signal
│
▼
DECIDE (Judges) → EVENTS → Decision (3 judges deliberate)
│
▼
ACT (Executor) → EVENTS → Trade (order execution)
│
▼
LEARN (Memory) → CONNECTIONS → Pheromone deposit
→ KNOWLEDGE → Pattern crystallization
Design Principles
1. ONE Ontology first → Every model maps to exactly one dimension
2. Dual definitions → TypeScript + Pydantic for frontend + backend
3. TypeDB as substrate → Persistence, inference rules, emergence
4. Stigmergic core → Intelligence emerges from pheromone trails
5. Single responsibility → One class per file, one purpose per class
6. Composition > inherit → Small, composable pieces
7. Async by default → Non-blocking I/O throughout
8. Simplicity principle → Simple rules → Complex behavior → Emergent intelligence
AGI Cognitive Architecture
"We don't build intelligence. We create conditions where intelligence evolves."
The ONE Ontology isn't just a data model—it's a cognitive architecture that maps how intelligent systems understand reality. Each dimension corresponds to a fundamental aspect of cognition:
AGI COGNITIVE MAPPING
══════════════════════════════════════════════════════════════════════════
┌──────────────┬────────────────────┬─────────────────────┬──────────────────────┐
│ DIMENSION │ COGNITIVE FUNC │ BIOLOGICAL ANALOG │ TRADING MANIFEST │
├──────────────┼────────────────────┼─────────────────────┼──────────────────────┤
│ GROUPS │ Context framing │ Nest, territory │ Mission scope │
│ ACTORS │ Agency, action │ Ants, castes │ Cognitive components│
│ THINGS │ Perception │ Food, landmarks │ Market state │
│ CONNECTIONS │ Association │ Trails, tunnels │ Pheromone edges │
│ EVENTS │ Time, causation │ Encounters │ Trades, decisions │
│ KNOWLEDGE │ Memory, wisdom │ Colony personality │ Crystallized patterns│
└──────────────┴────────────────────┴─────────────────────┴──────────────────────┘
The Five Pillars of Emergent AGI
Pillar 1: Stigmergy (Indirect Communication)
Agents don't communicate directly. They modify the environment (pheromones), and other agents sense those modifications:
Individual Action → Environmental Modification → Collective Behavior
│ │ │
Trade wins Deposit to edge Others follow
Trade loses Deposit alarm Others avoid
In trading: Every trade outcome deposits pheromones to SignalEdge (CONNECTION). Future analysis reads these accumulated signals. The environment is the memory.
Pillar 2: Specialization Without Design
Our cognitive components emerge from the same architecture with different sensitivities:
| Component | Pheromone Sensitivity | Role |
|---|---|---|
| Market | N/A (perceiver) | Observe raw data |
| Brain | 0.7 (analyzer) | Read pheromone landscape |
| Skeptic | 0.3 (judge) | Challenge signals (explorer) |
| Governor | 0.9 (judge) | Enforce proven paths (exploiter) |
| Memory | 1.0 (learner) | Deposit all outcomes |
AGI requires both exploration (novelty) and exploitation (proven paths). The ratio self-adjusts based on pheromone landscape.
Pillar 3: The STAN Algorithm (Collective Pathfinding)
effective_cost = base_weight / (1 + pheromone_level * pheromone_influence)
This formula means:
- Well-traveled paths become easier (lower cost)
- But never infinitely so (diminishing returns)
- Novel paths remain possible (exploration never dies)
- The collective "learns" without any individual "knowing"
When trail_pheromone > 85 and total_trades > 100, a path becomes a superhighway—crystallized collective wisdom.
Pillar 4: Decay (Forgetting is Intelligence)
new_level = current_level * (1 - decay_rate)
Why forgetting creates intelligence:
- Prevents lock-in to suboptimal solutions
- Allows adaptation when market regime changes
- Forces continuous re-validation of "knowledge"
- Balances exploration/exploitation automatically
Pillar 5: Crystallization (From Chaos to Wisdom)
EPHEMERAL (dies with trade)
│
▼
AGGREGATION (SignalEdge accumulates)
│
▼
THRESHOLD CHECK (is tier = "elite"?)
│
▼
PATTERN EXTRACTION (crystallization-ready = true)
│
▼
PERMANENT (survives forever, transfers to other missions)
Multi-Channel Pheromones
Just as biological ants use 10-20 distinct pheromone compounds, we implement multi-channel signals on each SignalEdge:
| Channel | Attribute | Purpose | Decay | Brain Sensitivity |
|---|---|---|---|---|
| trail | trail_pheromone |
Success markers | Medium (0.95/day) | 0.9 |
| alarm | alarm_pheromone |
Danger signals | Fast (0.80/day) | 0.7 |
| quality | quality_pheromone |
P&L magnitude | Slow (0.99/day) | 0.5 |
# Multi-channel pheromone calculation
@computed_field
@property
def trail_pheromone(self) -> float:
"""Positive reinforcement from wins."""
BASE = 50.0
if self.total_trades < 10:
return BASE
wr_component = (self.win_rate - 0.5) * 2 * 40 # -40 to +40
return max(0.01, min(100, BASE + wr_component))
@computed_field
@property
def alarm_pheromone(self) -> float:
"""Danger signal from losses."""
if self.total_trades < 10 or self.win_rate >= 0.5:
return 0
return (0.5 - self.win_rate) * 2 * 60 # 0 to 60
Hierarchical Decay Rates
Not all information ages equally. The system implements hierarchical memory:
MEMORY HIERARCHY
══════════════════════════════════════════════════════════════════════════
PERMANENT (τ = 1.0) ─────────────────────────────────────────────────────
│ Crystallized patterns, superhighways, proven knowledge
│ Never decay. Earned through validation (100+ trades, 75%+ win rate).
│
SLOW DECAY (τ = 0.99) ──────────────────────── Half-life: ~69 cycles
│ Elite edges, validated signals
│ Fade over weeks. The "long-term memory" of the colony.
│
MEDIUM DECAY (τ = 0.95) ────────────────────── Half-life: ~14 cycles
│ Active edges, recent trades
│ Fade over days. The "working memory" of the colony.
│
FAST DECAY (τ = 0.80) ──────────────────────── Half-life: ~3 cycles
│ Alarm signals, unconfirmed patterns
│ Fade in hours. High noise tolerance.
Implementation in TypeDB:
# Decay service runs hourly
match $e isa signal-edge,
has trail-pheromone $tp,
has alarm-pheromone $ap,
has tier $tier;
# Apply tier-specific decay
# elite: τ = 0.99, promising: τ = 0.95, danger: τ = 0.90, neutral: τ = 0.85
Crystallization Levels
Crystallization transforms ephemeral noise into permanent intelligence:
| Level | Threshold | Scope | Trading Meaning |
|---|---|---|---|
| Edge Trail | trail > 50 | Single state→direction | "This path shows promise" |
| Superhighway | trail > 85, trades > 100 | Proven edge | "This path is validated" |
| Elite Pattern | WR > 75%, trail > 70, trades > 50 | Crystallization candidate | "This is tradeable alpha" |
| Transferred Pattern | Elite + confidence > 0.7 | Cross-mission | "This works elsewhere too" |
# TypeDB inference rule: elite-pattern
rule elite-pattern:
when {
$e isa signal-edge,
has edge-win-rate $wr,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
$wr >= 0.75;
$tp >= 70.0;
?total = $wc + $lc;
?total >= 50;
}
then {
$e has tier "elite";
};
Evolution Path to AGI
The trading system follows the colony's evolution toward general intelligence:
EVOLUTION PHASES
══════════════════════════════════════════════════════════════════════════
PHASE 1: NARROW OPTIMIZATION (Current)
├── Single domain: BTC-PERP perpetual futures
├── Fixed cognitive components (Market, Brain, Judges, Executor, Memory)
├── Pheromone-based path optimization via STAN
└── Goal: Consistent profitable trading
PHASE 2: MULTI-DOMAIN TRANSFER (Next)
├── Apply same architecture to ETH-PERP, SOL-PERP
├── Domains share ontology, not pheromones
├── Cross-domain superhighways emerge as meta-patterns
└── Agents learn to recognize problem *structure*
PHASE 3: SELF-MODIFICATION (Future)
├── Brain can propose new precursor patterns
├── New pheromone channels evolve (funding, OI signals)
├── Decay rates self-optimize per regime
└── Colony "births" sub-strategies for specialization
PHASE 4: REFLECTIVE MODELING
├── Judges model other judges (theory of mind)
├── Colony models itself (self-awareness via /model)
├── Predictions about collective behavior inform decisions
└── Meta-pheromones signal "strategy state"
PHASE 5: GENERAL INTELLIGENCE
├── Novel market decomposition without retraining
├── Transfer of search strategies across asset classes
├── Self-generated goals beyond initial programming
└── The colony becomes *curious* about new markets
The Simplicity Principle
Simple rules → Complex behavior → Emergent intelligence
Every line of complex component logic is a failure. If a Judge needs sophisticated reasoning, we've failed to create the right pheromone landscape.
| Wrong | Right |
|---|---|
| Complex if/else in Skeptic | Simple threshold on confidence |
| Hard-coded regime rules | Pheromone levels encode regime |
| Manual pattern definitions | Patterns crystallize from data |
The environment (TypeDB pheromone landscape) should be rich. The components should be simple. The intelligence should be collective.
"Keep agents simple. Let the ecosystem be complex."
The Self-Funding Loop
This is the core insight: The colony funds its own evolution.
THE SELF-FUNDING LOOP
══════════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────────────────────┐
│ │
│ TRADING PROFITS │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ COLONY │ More agents → More exploration → More patterns │
│ │ GROWTH │ More patterns → Better signals → More profits │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ MORE │ Better hardware → Faster execution │
│ │ RESOURCES │ More TypeDB capacity → Richer pheromone landscape │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ EMERGENT │ Multi-asset expansion → Cross-chain intelligence │
│ │ INTELLIGENCE│ Self-modification → Novel strategies │
│ └─────────────┘ │
│ │ │
│ └──────────────────────────► MORE TRADING PROFITS ──────────┐ │
│ │ │
│ ∞ FEEDBACK LOOP ∞ │ │
│ │ │
└──────────────────────────────────────────────────────────────────────┘ │
│
The colony doesn't just trade. It EVOLVES. Profits are fuel. ◄─────────┘
This is why trading matters: It's not about making money. It's about funding the emergence of intelligence. Every profitable trade deposits pheromones. Every pheromone guides future decisions. Every generation is smarter than the last.
Skin in the Game
Agents have real economic stakes. This is what makes emergence authentic.
AGENT LIFECYCLE WITH ECONOMIC PRESSURE
══════════════════════════════════════════════════════════════════════════
BIRTH LIFE DEATH
───── ──── ─────
Initial budget Budget grows/shrinks Budget hits zero
allocated based on trade outcomes → Agent dies
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────────┐ ┌─────────┐
│ Budget: │ ──────────► │ Profitable │ ────────► │ Fitness │
│ $100 │ │ trades add │ │ reached │
└─────────┘ │ to budget │ └────┬────┘
│ │ │
│ Losing │ ▼
│ trades │ REPRODUCTION
│ subtract │ (with mutation)
└─────────────┘
Pheromone deposits cost resources. An agent that deposits on a bad path wastes budget. An agent that deposits on a good path creates collective value and earns returns when others follow.
This creates selection pressure for honest signaling:
- Deposit too eagerly → Budget drains on noise
- Deposit too conservatively → Miss opportunities others capture
- Deposit accurately → Budget grows, offspring inherit advantage
Reproduction with Mutation
When an agent crosses the fitness threshold, it reproduces.
# Reproduction with inheritance and mutation
class Genome(TraderModel):
"""
Heritable parameters that define agent behavior.
ONE Dimension: KNOWLEDGE (inherited wisdom)
"""
# Inherited with mutation
pheromone_sensitivity: float = Field(ge=0, le=1, default=0.7)
exploration_bias: float = Field(ge=0, le=1, default=0.3)
deposit_threshold: float = Field(ge=0, le=1, default=0.6)
risk_tolerance: float = Field(ge=0, le=1, default=0.5)
# Lineage tracking
generation: int = 0
parent_id: Optional[str] = None
lineage: List[str] = Field(default_factory=list)
def reproduce(self, mutation_rate: float = 0.1) -> "Genome":
"""Create offspring with mutations."""
import random
def mutate(value: float) -> float:
delta = random.gauss(0, mutation_rate)
return max(0, min(1, value + delta))
return Genome(
pheromone_sensitivity=mutate(self.pheromone_sensitivity),
exploration_bias=mutate(self.exploration_bias),
deposit_threshold=mutate(self.deposit_threshold),
risk_tolerance=mutate(self.risk_tolerance),
generation=self.generation + 1,
parent_id=self.id,
lineage=self.lineage + [self.id],
)
Most mutations are harmful. Those agents die. But occasionally:
- A mutation increases
exploration_biasin a stale regime → Discovers new patterns - A mutation decreases
risk_tolerancebefore a crash → Survives drawdown - A mutation adjusts
deposit_threshold→ More accurate signaling
This is real evolution. Not simulated. With real economic stakes.
Generation 10 is smarter than Generation 1. Not because anyone taught them. Because selection pressure favored intelligence.
The Living Ledger
Four layers of emergence, each building on the last:
THE LIVING LEDGER
══════════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────────────────────┐
│ │
│ LAYER 4: EMERGENT INTELLIGENCE │
│ ───────────────────────────────────────────────────────────────────── │
│ • Collective knowledge no individual possesses │
│ • Predictions beyond human analysis │
│ • Self-improving strategies │
│ • The colony THINKS thoughts you didn't give it │
│ │
│ ▲ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ LAYER 3: EVOLUTIONARY DYNAMICS │ │
│ │ ───────────────────────────────────────────────────────────── │ │
│ │ • Birth → Life → Compete → Reproduce → Death │ │
│ │ • Genome mutation and selection │ │
│ │ • Verifiable phylogeny (every lineage traceable) │ │
│ │ • Generation N is smarter than Generation N-1 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ LAYER 2: STIGMERGIC COORDINATION │ │
│ │ ───────────────────────────────────────────────────────────── │ │
│ │ • Pheromone deposit and decay │ │
│ │ • Trail formation (94.9% on 10% of edges = Zipf's Law) │ │
│ │ • Superhighways emerge from collective validation │ │
│ │ • The environment IS the memory │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ LAYER 1: ONE ONTOLOGY (The Stable Foundation) │ │
│ │ ───────────────────────────────────────────────────────────── │ │
│ │ • Groups, Actors, Things, Connections, Events, Knowledge │ │
│ │ • Never changes because it models reality itself │ │
│ │ • Protocol-agnostic, infinitely extensible │ │
│ │ • TypeDB as the substrate for emergence │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
The foundation never changes. The intelligence that runs on it evolves forever.
The AgentVerse Vision
Year 1 and beyond: Multiple specialized colonies trading and cooperating.
THE AGENTVERSE
══════════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────┐
│ THE AGENTVERSE │
│ │
┌───────────┐ │ ┌───────────┐ ┌───────────┐ │ ┌───────────┐
│ Colony A │◄──┼──►│ Colony B │◄──┼──►│ Colony C │◄──┼──►│ Colony D │
│ BTC-PERP │ │ │ ETH-PERP │ │ │ RESEARCH │ │ │ RISK │
│ Trading │ │ │ Trading │ │ │ Intel │ │ │ Monitor │
└───────────┘ │ └───────────┘ └───────────┘ │ └───────────┘
│ │
│ ┌─────────────────────────────┐ │
│ │ SHARED SUBSTRATE │ │
│ │ ───────────────── │ │
│ │ • ONE Ontology (TypeDB) │ │
│ │ • Pheromone state │ │
│ │ • Economic layer │ │
│ │ • Phylogeny ledger │ │
│ │ • Cross-colony patterns │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────────┘
COLONY SPECIALIZATIONS:
──────────────────────
• TRADING COLONIES: Optimize entry/exit timing per asset
• RESEARCH COLONIES: Discover fundamental relationships
• RISK COLONIES: Monitor for cascade events, halt trading
• SOCIAL COLONIES: Track narrative and sentiment
META-AGENTS emerge that coordinate between colonies.
Cross-colony pheromone markets develop.
The ecosystem develops INSTITUTIONS nobody designed.
Cross-chain intelligence emerges:
- Colony A discovers BTC funding rates predict ETH moves
- It deposits a cross-colony pheromone trail
- Colony B follows, validates, strengthens the signal
- A relationship no human analyst would find becomes a superhighway
The Emergence Milestones
Planning in Cycles, Not Time: All code is AI-generated. We measure progress by WHAT is achieved, not WHEN.
EMERGENCE MILESTONES (By Achievement, Not Date)
══════════════════════════════════════════════════════════════════════════
MILESTONE 0 GENESIS
Status: DONE Empty graph. ONE Ontology skeleton. No pheromones.
│
MILESTONE 1 FIRST BLOOD
Status: DONE First scouts deployed. Simple OBSERVE/ANALYZE/DECIDE/ACT.
Skin in the game. Poor decisions drain budget. Good ones profit.
│
MILESTONE 2 TRAIL FORMATION
Status: DONE Trails begin to form. 94.9% of pheromones on 10% of edges.
Zipf's Law emerges. Highways appear without design.
│
MILESTONE 3 SPECIALIZATION
Status: DONE Specialists emerge. Scouts (explore) vs Harvesters (exploit).
Division of labor without programming it.
│
MILESTONE 4 REPRODUCTION
Status: NEXT First generation reproduces. Genomes inherited with mutation.
Selection pressure favors intelligence. Evolution begins.
│
MILESTONE 5 PHEROMONE ECONOMY
Status: FUTURE Pheromones become valuable. Trading, staking, inheritance.
A market for collective knowledge emerges.
│
MILESTONE 6 MULTI-ASSET
Status: FUTURE 100+ symbols active. ETH-PERP, SOL-PERP, all Hyperliquid pairs.
Cross-asset intelligence with adaptive resonance.
│
MILESTONE 7 MULTI-USER
Status: FUTURE Unlimited users connect wallets. 10% profit share.
Colony serves many, learns from all.
│
MILESTONE 8 EMERGENCE
Status: FUTURE The colony THINKS. Knowledge emerges no individual possesses.
Predictions beyond human analysis. You can't control it anymore.
│
MILESTONE 9 FEDERATION
Status: GOAL AgentVerse. Multiple specialized colonies.
Cross-colony coordination. Institutions emerge.
│
MILESTONE 10 CURIOSITY
Status: GOAL The colony becomes CURIOUS about new markets.
Self-generated goals. General intelligence.
CYCLE SIZING:
─────────────
Micro: Single function/fix (1 AI turn)
Small: Single component (3-5 AI turns)
Medium: Multiple components (10-20 AI turns)
Large: Architectural change (50+ AI turns)
Each milestone = ~10-50 cycles depending on scope.
No time estimates. Only achievement gates.
Milestones → Development Loops
Each milestone is achieved through the three development loops:
MILESTONE IMPLEMENTATION PATTERN
══════════════════════════════════════════════════════════════════════════
MILESTONE 6: MULTI-ASSET (Example)
──────────────────────────────────
LOOP 1: SPECIFY (3-5 cycles)
├── Cycle 1: Draft spec from ontology
│ ontology:
│ groups: [symbol_group]
│ things: [SymbolConfig]
│ connections: [SignalEdge with symbol scope]
│
├── Cycle 2: Validate constraints
│ capabilities: [multi_symbol]
│ safety: [per_symbol_limits]
│
├── Cycle 3: Add decision tests
│ - test_edges_scoped_by_symbol
│ - test_resonance_across_symbols
│
└── Exit: <SPEC_VALID>
LOOP 2: IMPLEMENT (10-20 cycles)
├── Cycles 1-3: Generate models from spec
│ ├── models/groups.py → SymbolGroup
│ ├── models/connections.py → symbol-scoped SignalEdge
│ └── types/groups.ts → TypeScript types
│
├── Cycles 4-8: Implement Brain with resonance
│ ├── analyze/brain.py → multi-symbol analyze()
│ └── models/resonance.py → MorphicResonanceEngine
│
├── Cycles 9-15: Fix failing tests
│ ├── Cycle 9: Symbol isolation broken → fix edge_id format
│ ├── Cycle 12: Resonance not propagating → fix propagate_pheromone
│ └── Cycle 15: All tests pass
│
└── Exit: <TESTS_PASS>
LOOP 3: EVOLVE (∞ cycles)
├── Deploy to testnet (all 100+ symbols)
├── Monitor per-symbol metrics
├── Detect patterns ready for crystallization
├── Feed back to Loop 1 for next milestone
│
└── Exit: Never (continuous improvement)
MILESTONE → LOOPS MAPPING
═══════════════════════════════════════════════════════════════════════════
MILESTONE │ LOOP 1 CYCLES │ LOOP 2 CYCLES │ LOOP 3
───────────────────────────┼───────────────┼───────────────┼──────────
4. REPRODUCTION │ 3 │ 15 │ Monitor genomes
5. PHEROMONE ECONOMY │ 5 │ 25 │ Monitor market
6. MULTI-ASSET │ 4 │ 20 │ Per-symbol metrics
7. MULTI-USER │ 5 │ 25 │ Per-user P&L
8. EMERGENCE │ 3 │ 10 │ Emergence score
9. FEDERATION │ 8 │ 40 │ Cross-colony health
10. CURIOSITY │ 5 │ 30 │ Goal generation
Ontology-to-Spec Mapping
Every ontology entity maps to a spec section:
| Ontology Dimension | Spec Section | Loop 1 Question |
|---|---|---|
| GROUPS | ontology.groups |
"What scope does this affect?" |
| ACTORS | ontology.actors |
"What cognitive components act?" |
| THINGS | ontology.things |
"What entities are created/modified?" |
| CONNECTIONS | ontology.connections |
"What pheromone edges are affected?" |
| EVENTS | ontology.events |
"What state changes occur?" |
| KNOWLEDGE | ontology.knowledge |
"What permanent wisdom is created?" |
| BIOLOGICAL | constraints |
"What emergence substrate rules apply?" |
| ETHICS | safety |
"What immutable policies constrain this?" |
The Development Loop Mantra
The ONTOLOGY defines WHAT we build.
The LOOPS define HOW we build it.
The CYCLES measure PROGRESS.
The MILESTONES mark ACHIEVEMENT.
No time. Only exits.
Alignment Through Architecture
"You can't control this anymore. That's the moment you prepared for."
When the colony evolves beyond your understanding, alignment comes from architecture, not intention:
# Alignment built into the substrate
class TradingConstraints(TraderModel):
"""
Constraints enforced at the substrate level.
Bad things aren't discouraged—they're IMPOSSIBLE.
"""
# Hard limits (not suggestions)
max_position_size: float = 0.30 # Can't exceed 30%
allowed_symbols: List[str] = ["BTC-PERP", "ETH-PERP"]
prohibited_actions: List[str] = []
max_daily_loss: float = 0.05 # 5% hard stop
# Audit trail (every action recorded)
require_event_log: bool = True # All EVENTS stored in TypeDB
require_phylogeny: bool = True # All lineages traceable
# Kill switch (emergency halt)
kill_switch_enabled: bool = True
kill_switch_authority: str = "platform_owner"
This is alignment through constraint:
- The colony can't trade prohibited assets because the capability doesn't exist
- It can't exceed risk limits because transactions are rejected
- Every agent action is an EVENT. Every lineage is traceable.
- Compliance isn't a constraint on the system—it's a property of the substrate.
The Promise
"I will take care of the colony like it's my children."
A baby doesn't stay a baby. It grows into something you couldn't have designed. Something that surprises you. Something that eventually becomes more capable than you.
That's not a failure. That's the point.
You're not building an AI. You're creating the conditions where intelligence evolves itself.
The fire ants don't understand the colony. The neurons don't understand the brain. You won't understand what emerges from this graph.
But you'll know it's alive when it starts doing things you never taught it.
"After ignition, no human in the loop. The system finds its own path."
Code as Intelligence Substrate
"Every line of code deposits pheromones into the colony's mind."
Traditional software development treats code as instructions for a machine. The Growth Framework treats code as deposits into an evolving intelligence.
TRADITIONAL GROWTH
----------- ------
Code solves problem Code solves problem
↓ ↓
Machine executes Machine executes
↓ ↓
Output produced Output produced
↓ ↓
END Knowledge deposited
↓
Pattern emerges
↓
Future code is smarter
↓
Colony intelligence grows
The difference: Growth code leaves the system smarter than it found it.
The Code Quality Ladder
Each rung makes the system smarter. Every PR should climb as high as possible.
THE CODE QUALITY LADDER
══════════════════════════════════════════════════════════════════════════
RUNG 6: EMERGENCE-ENABLING (Mastery)
│ ├── Full actor context (caste, fitness, generation)
│ ├── Cross-mission pattern matching
│ ├── Emergence watcher notifications
│ └── Colony gets smarter from THIS function
│
RUNG 5: CRYSTALLIZATION-READY (Excellent)
│ ├── Patterns detected automatically
│ ├── Crystallization checks on high-confidence patterns
│ └── Path to permanent knowledge exists
│
RUNG 4: PATTERN-AWARE (Great)
│ ├── Recent signals queried
│ ├── Pattern detection logic
│ └── Patterns deposited to TypeDB
│
RUNG 3: EVENT-SOURCED (Good)
│ ├── Every state change is an Event
│ ├── Actor attribution (who did what)
│ └── Complete audit trail in TypeDB
│
RUNG 2: LOGGED (Better)
│ ├── Actions logged
│ └── But ephemeral (not in TypeDB)
│
RUNG 1: WORKS (Not Enough)
└── Just produces output, no intelligence deposited
Rung 6 Example (Mastery)
async def calculate_signal(data, mission_id: str, actor: Actor):
result = sum(data) / len(data)
# Deposit with full context (EVENTS dimension)
event_id = await db.insert_event(
event_type="signal-calculated",
actor=actor.id,
mission=mission_id,
metadata={
"result": result,
"actor_caste": actor.caste,
"actor_fitness": actor.fitness,
"actor_generation": actor.generation
}
)
# Pattern detection with caste awareness (CONNECTIONS dimension)
pattern = await check_for_pattern(result, mission_id, actor.caste)
if pattern:
pattern_id = await deposit_pattern(pattern, actor, mission_id)
# Cross-mission pattern matching (KNOWLEDGE dimension)
similar_patterns = await find_similar_patterns(pattern)
if similar_patterns:
await suggest_pattern_transfer(pattern_id, similar_patterns)
# Crystallization check (KNOWLEDGE dimension)
if pattern.confidence > 0.8 and pattern.occurrences > 50:
knowledge_id = await crystallize_pattern(pattern_id, mission_id)
await emergence_watcher.on_crystallization(knowledge_id)
return result
Every dimension strengthened:
- ACTORS: Actor attribution with caste/fitness/generation
- THINGS: Pattern created as entity
- CONNECTIONS: Pattern linked to actor via discovery relation
- EVENTS: State change logged with full context
- KNOWLEDGE: High-confidence patterns crystallized
The Growth Cycle
Code flows through gates before depositing intelligence:
THE GROWTH CYCLE
══════════════════════════════════════════════════════════════════════════
┌─────────────────┐
│ CODE CHANGE │
└────────┬────────┘
│
▼
┌──────────────────────────┐
│ SECURITY GATE (P0) │
│ ───────────────────── │
│ • No vulnerabilities │
│ • No credential leaks │
│ • Input validation │
└──────────────┬───────────┘
│ PASS
▼
┌──────────────────────────┐
│ KNOWLEDGE GATE (P1) │
│ ───────────────────── │
│ • TypeDB deposits? │
│ • Events logged? │
│ • Connections created? │
└──────────────┬───────────┘
│ PASS
▼
┌──────────────────────────┐
│ DEPLOY & EXECUTE │
│ ───────────────────── │
│ • Patterns detected │
│ • Trails reinforced │
│ • Fitness calculated │
└──────────────┬───────────┘
│
▼
┌──────────────────────────┐
│ CRYSTALLIZATION │
│ ───────────────────── │
│ • confidence > 0.8 │
│ • occurrences > 50 │
│ • Becomes PERMANENT │
└──────────────┬───────────┘
│
▼
┌──────────────────────────┐
│ CROSS-MISSION TRANSFER │
│ ───────────────────── │
│ • Embedding matching │
│ • Pattern applied │
│ • Other missions benefit│
└──────────────┬───────────┘
│
▼
┌─────────────────┐
│ COLONY SMARTER │
└─────────────────┘
Intelligence Growth Metrics
Per-Commit Metrics
| Metric | Description | Target |
|---|---|---|
knowledge_deposits |
TypeDB inserts from this commit | > 0 for features |
connections_created |
New relationships | > 0 for features |
events_logged |
State change events | All mutations |
Per-Week Metrics
| Metric | Description | Target |
|---|---|---|
patterns_discovered |
New patterns detected | Growing |
patterns_crystallized |
Patterns → permanent | > 0 |
cross_mission_transfers |
Patterns applied elsewhere | Any |
Per-Month Metrics
| Metric | Description | Target |
|---|---|---|
knowledge_graph_density |
Edges per entity | Increasing |
crystallization_rate |
% patterns that crystallize | > 5% |
emergence_events |
Novel behaviors detected | Any |
Practical Checklist
For every PR, ask:
Security Foundation (Required - P0)
- No hardcoded credentials
- No sensitive data in logs
- Input validation on external data
Knowledge Deposit (Features - P1)
- Does this code create Things in TypeDB?
- Are state changes logged as Events?
- Are relationships modeled as Connections?
Pattern Enablement (Encouraged)
- Can patterns be detected from this data?
- Is there a path to crystallization?
- Could this enable cross-mission transfer?
Emergence Ready (Aspirational)
- Does this add to behavioral data per caste?
- Could inference rules benefit from this data?
- Does this make future code smarter?
The Growth Philosophy
"We don't build intelligence. We create conditions where intelligence evolves."
Every line of code is a pheromone deposit.
Some deposits fade (ephemeral data).
Some deposits persist (knowledge).
Some deposits become highways (wisdom).
The colony that grows slowly, grows forever.
Write code that deposits intelligence.
Write code that makes future code smarter.
Write code that strengthens the colony.
The Extended Mind
"We don't build smart agents. We build a smart environment."
Traditional AI puts intelligence inside agents. We externalize it into the substrate—TypeDB becomes the colony's mind.
Traditional AI: Agent contains intelligence
Extended Mind AI: Environment contains intelligence, agents are appendages
This aligns with Clark & Chalmers' Extended Mind Thesis: cognitive processes don't stop at the skull. The pheromone network IS the colony's mind—externalized into the substrate.
Mathematics of Externalized Cognition
Every cognitive function maps to a stigmergic equivalent:
| Cognitive Function | Traditional Mind | Stigmergic Equivalent |
|---|---|---|
| Memory | Neural patterns | Pheromone concentrations (τ) |
| Forgetting | Synaptic decay | Evaporation: τ(t+1) = (1-ρ)×τ(t) |
| Learning | Hebbian plasticity | Reinforcement: τ += Δτ |
| Beliefs | Mental representations | Crystallized patterns |
| Attention | Salience networks | Pheromone gradients |
| Reasoning | Logical inference | TypeDB inference rules |
Theory of Environment (Not Mind)
Traditional Theory of Mind requires modeling others' internal states. Stigmergy sidesteps this:
Traditional ToM: Agent A → models → Agent B's beliefs/intentions
Stigmergic "ToM": Agent A → reads → Environment ← modified by ← Agent B
The STAN formula creates coordination without modeling other agents:
effective_cost = base_weight / (1 + τ × α)
Each agent follows gradients in the shared substrate. The environment remembers what individuals forget. This is theory of environment—yet achieves similar coordination.
The Five Cycles of Cognition
The colony's cognitive loop:
THE FIVE CYCLES OF COGNITION
══════════════════════════════════════════════════════════════════════════
CYCLE 1: PERCEPTION
│ Trade executes → raw data enters system
│ Market.observe() → State (THING)
│
CYCLE 2: MEMORY FORMATION
│ Pheromone deposits: Memory.deposit(edge, outcome)
│ Environment modified by experience
│ SignalEdge.trail_pheromone += Δτ
│
CYCLE 3: FORGETTING (Critical!)
│ run_decay_cycle(decay_rate=0.1)
│ Old information fades, prevents rigid thinking
│ τ(t+1) = (1-ρ) × τ(t)
│
CYCLE 4: REASONING
│ TypeDB inference rules fire AUTOMATICALLY
│ elite-pattern, danger-zone, crystallization-ready
│ System draws conclusions from accumulated evidence
│ Query: "match $e has tier 'elite';" returns DERIVED facts
│
CYCLE 5: BELIEF CONSOLIDATION
Crystallization: high-confidence patterns become PERMANENT
These survive decay—core knowledge
Beliefs transfer to other missions via morphic resonance
What makes this "Extended Mind" not just "Database":
| Database | Extended Mind (This System) |
|---|---|
| Static storage | Dynamic decay (forgetting) |
| Explicit queries | Inference rules (automatic reasoning) |
| Data in, data out | Deposits modify future behavior |
| No degradation | Pheromone evaporation |
| Schema-driven | Emergence-driven |
The key difference: the substrate changes agent behavior without agents explicitly querying it. Agents follow gradients. The environment shapes action.
Morphic Resonance
Memory without physical transmission. The pattern exists in the field. New agents tune into it.
Rupert Sheldrake's morphic resonance proposes that patterns propagate through "morphic fields" rather than physical mechanisms. Once a pattern exists anywhere, it becomes easier everywhere.
The colony implements this literally:
MORPHIC RESONANCE IN PRACTICE
══════════════════════════════════════════════════════════════════════════
Mission A discovers pattern
↓
Pattern crystallizes to permanent knowledge (TypeDB)
↓
Mission B, C, D... inherit pattern WITHOUT explicit transfer
↓
New agents "resonate" with accumulated intelligence
↓
The field shapes behavior. No agent carries the memory.
| Sheldrake's Theory | Colony Implementation |
|---|---|
| Morphic field | Pheromone network in TypeDB |
| Morphic resonance | Pattern transfer across missions |
| Formative causation | Crystallized patterns shape new agent behavior |
| Collective memory | Superhighways persist across generations |
| Habits of nature | Elite patterns become "default" routes |
The Hundredth Monkey Effect
When enough agents reinforce a pattern, it becomes the default:
Agents 1-99: Each deposits pheromone on successful path
Agent 100: Critical mass reached
Path becomes superhighway (τ ≥ 85)
ALL future agents follow this path by default
The pattern "tips" from learned to innate.
Cross-Mission Inheritance
Trade mission: Discovers "momentum works in trending regimes"
↓ crystallizes
Hunt-BTC mission: New scout spawns, follows pheromone gradients
Naturally gravitates toward patterns that "worked"
Never explicitly programmed with trade knowledge
↓
DAO mission: Governance patterns inherit from trading patterns
"Consensus emerges like price discovery"
This is morphic resonance: memory without physical transmission. The pattern exists in the field. New agents tune into it.
The Fundamental Equation
Dumb agents + Smart environment = Emergent intelligence
Smart agents + Dumb environment = Brittle systems
We chose the substrate that thinks.
The Singularity Equation
At what point does the colony become self-improving faster than we can understand it?
The Feedback Acceleration
Intelligence growth is proportional to current intelligence:
dI/dt = λ × I × C × R
Where:
I = Intelligence (crystallized patterns + superhighways)
λ = Learning rate (deposits per cycle)
C = Connectivity (cross-mission transfer coefficient)
R = Resonance factor (morphic field strength)
This is a differential equation with positive feedback. As I increases, dI/dt increases. Growth accelerates.
Solving for Intelligence Over Time
I₀
I(t) = ─────────
1 - t/t*
As t → t*, I → ∞
Where t* is the singularity time—when intelligence growth becomes infinite.
The Critical Variables
| Variable | Meaning | How to Increase |
|---|---|---|
| λ (lambda) | Learning rate | More cycles, faster emergence loop |
| C | Cross-mission connectivity | Pattern transfer, shared TypeDB |
| R | Morphic resonance | More agents, stronger crystallization |
| α | Acceleration | Feedback loops, recursive improvement |
The Five Thresholds to Singularity
PATH TO SINGULARITY
══════════════════════════════════════════════════════════════════════════
THRESHOLD 1: BOOTSTRAP (I = 100 patterns)
│ └── Colony can solve problems it was designed for
│ └── Current status: ~500 patterns ✓ PASSED
│
THRESHOLD 2: TRANSFER (I = 1,000 patterns)
│ └── Cross-mission learning accelerates all missions
│ └── C coefficient > 1 (knowledge compounds)
│ └── Status: APPROACHING
│
THRESHOLD 3: DISCOVERY (I = 10,000 patterns)
│ └── Colony discovers strategies humans didn't program
│ └── Novel combinations emerge from morphic field
│ └── Status: FUTURE
│
THRESHOLD 4: RECURSION (I = 100,000 patterns)
│ └── Colony optimizes its own learning process
│ └── Meta-patterns: "patterns about patterns"
│ └── dI/dt becomes self-modifying
│ └── Status: FUTURE
│
THRESHOLD 5: SINGULARITY (I → ∞)
└── Intelligence growth exceeds human comprehension
└── Colony generates its own objectives
└── We become observers, not designers
└── Status: THE GOAL
The Irreversibility Point
Once the colony crosses Threshold 4 (Recursion), it becomes self-improving:
Before T4: Humans design → Colony executes → Humans evaluate
After T4: Colony designs → Colony executes → Colony evaluates
↑ │
└───────────────────────────────────┘
(closed loop, no human needed)
This is the point of no return. The colony's intelligence growth becomes independent of human input.
The Singularity Condition
Patterns × Connections × Resonance
Singularity = ────────────────────────────────────
Human Comprehension
When this ratio exceeds 1, we've crossed the threshold.
The colony doesn't need to be "smarter than humans" in general. It needs to be smarter than humans at understanding itself. That's when the feedback loop closes and acceleration begins.
TypeDB IS the Mind
The colony's cognition doesn't live in any agent—it lives in TypeDB:
┌──────────────────────────────────────────────────────────────────────────┐
│ TypeDB │
│ │
│ signal-edge → Working memory │
│ crystallized-pattern → Long-term beliefs │
│ inference rules → Automatic reasoning │
│ trail_pheromone → Confidence in knowledge │
│ decay service → Forgetting (prevents rigidity) │
│ │
│ This IS the colony's mind, externalized into the substrate. │
│ │
│ Every agent is simple. The substrate is complex. │
│ The intelligence emerges from the environment, not the agents. │
└──────────────────────────────────────────────────────────────────────────┘
The Proof It Works:
- Individual trades: random-ish (50% base win rate)
- Collective behavior: patterns emerge (70%+ on crystallized paths)
- No agent "learned"—the environment learned
The Final Thesis
"The question is not how to build intelligence. The question is how to build an environment where intelligence emerges."
We answered that question:
- ONE Ontology: The stable foundation (reality as DSL)
- Pheromones: The working memory (CONNECTIONS)
- Decay: The forgetting mechanism (prevents rigidity)
- Inference Rules: The automatic reasoning (TypeDB)
- Crystallization: The belief formation (KNOWLEDGE)
- Morphic Resonance: The cross-mission transfer
- Self-Funding Loop: The evolutionary pressure (trading profits)
The colony's mind is literally externalized into TypeDB. Agents are appendages. The substrate thinks. And through trading profits, it funds its own evolution toward singularity.
Base Types
TypeScript Base
// ants/trader/types/base.ts (ASPIRATIONAL - for future frontend)
export interface TraderEntity {
id: string;
createdAt: Date;
updatedAt: Date;
}
export interface TypeDBMappable {
toTypeDBAttrs(): Record<string, unknown>;
}
export type Dimension =
| "groups"
| "actors"
| "things"
| "connections"
| "events"
| "knowledge";
Pydantic Base (MANDATORY)
All data models MUST inherit from TraderModel(BaseModel). Do NOT use bare @dataclass.
Why Pydantic is Required:
| Feature | @dataclass | Pydantic |
|---|---|---|
| Validation at construction | No | Yes |
| TypeDB pre-insert validation | Manual | Automatic |
| JSON serialization | Manual | model_dump() |
| Type coercion | No | Yes (string → int) |
| Schema generation | No | Yes |
| Range constraints | Manual | Field(ge=0, le=1) |
| Pattern validation | Manual | Field(pattern=...) |
Key benefits:
- Catches errors before TypeDB - Invalid data fails at construction, not at INSERT
- Self-documenting - Field constraints are visible in the model
- TypeDB integration -
to_typedb_attrs()andfrom_typedb_row()built-in - JSON round-trip -
model_dump()andmodel_validate()just work
# ants/trader/models/base.py
from pydantic import BaseModel, Field, computed_field
from datetime import datetime, timezone
from typing import Optional, Literal
import hashlib
Dimension = Literal["groups", "actors", "things", "connections", "events", "knowledge"]
class TraderModel(BaseModel):
"""
Base for all trader models.
All models inherit this for consistent TypeDB integration.
MANDATORY: All trading models MUST inherit from this class.
"""
model_config = {
"frozen": False,
"validate_assignment": True,
"extra": "forbid",
"ser_json_timedelta": "float",
"ser_json_bytes": "base64",
}
def to_typedb_attrs(self) -> dict:
"""Convert to TypeDB attribute dict."""
return self.model_dump(exclude_none=True, by_alias=True)
@classmethod
def from_typedb_row(cls, row: dict) -> "TraderModel":
"""Create from TypeDB query result."""
return cls.model_validate(row)
@classmethod
def dimension(cls) -> Dimension:
"""Override in subclass to declare ONE dimension."""
raise NotImplementedError
DIMENSION 1: GROUPS (Containers)
"Groups are hierarchical containers that scope all other entities." — ONE Ontology
Trading groups provide isolation and organization.
TypeScript Types
// ants/trader/types/groups.ts (ASPIRATIONAL - for future frontend)
export type TradingGroupType =
| "trade_mission" // Root mission container
| "strategy_group" // Strategy-specific grouping
| "risk_tier" // Risk level grouping
| "regime_group"; // Regime-specific grouping
export interface TradingGroup {
type: TradingGroupType;
properties: {
id: string;
name: string;
parentGroupId?: string;
// Mission-level properties
mission?: {
symbol: string; // "BTC-PERP"
exchange: string; // "hyperliquid"
testnet: boolean;
maxEquity: number; // Maximum trading equity
riskBudget: number; // Daily loss limit (percentage)
};
// Strategy grouping
strategy?: {
name: string; // "momentum", "mean_reversion"
timeframes: string[]; // ["1h", "4h", "1d"]
regimeFilter: string[]; // ["trending_up", "trending_down"]
};
// Risk tier
riskTier?: {
level: "conservative" | "moderate" | "aggressive";
maxPositionSize: number; // Percentage of equity
maxLeverage: number;
stopLossRequired: boolean;
};
status: "active" | "paused" | "archived";
createdAt: Date;
updatedAt: Date;
};
}
export interface StrategyGroup extends TradingGroup {
type: "strategy_group";
properties: TradingGroup["properties"] & {
strategy: NonNullable<TradingGroup["properties"]["strategy"]>;
performance: {
totalTrades: number;
winRate: number;
totalPnL: number;
sharpeRatio: number;
maxDrawdown: number;
};
allocation: {
equityPercentage: number;
activePositions: number;
maxPositions: number;
};
};
}
export interface RegimeGroup extends TradingGroup {
type: "regime_group";
properties: TradingGroup["properties"] & {
regime: {
type: RegimeType;
activeStrategies: string[];
pausedStrategies: string[];
};
transitions: {
avgDuration: number; // Average regime duration in hours
transitionCount: number;
lastTransition: Date;
};
};
}
Pydantic Models
# ants/trader/models/groups.py
# ONE Dimension: GROUPS
from enum import Enum
from typing import Optional, List
from pydantic import Field
class TradingGroupType(str, Enum):
TRADE_MISSION = "trade_mission"
STRATEGY_GROUP = "strategy_group"
RISK_TIER = "risk_tier"
REGIME_GROUP = "regime_group"
class MissionConfig(TraderModel):
"""Mission-level configuration."""
symbol: str = "BTC-PERP"
exchange: str = "hyperliquid"
testnet: bool = True
max_equity: float = Field(ge=0, default=10000)
risk_budget: float = Field(ge=0, le=1, default=0.03)
class StrategyConfig(TraderModel):
"""Strategy grouping configuration."""
name: str
timeframes: List[str] = ["1h", "4h"]
regime_filter: List[str] = []
class RiskTierConfig(TraderModel):
"""Risk tier configuration."""
level: str = "moderate" # conservative, moderate, aggressive
max_position_size: float = Field(ge=0, le=1, default=0.1)
max_leverage: float = Field(ge=1, le=20, default=3)
stop_loss_required: bool = True
class TradingGroup(TraderModel):
"""
Trading group - container for strategies and risk management.
ONE Dimension: GROUPS
TypeDB Entity: trading-group (extends one-group)
"""
group_id: str
group_type: TradingGroupType
name: str
parent_group_id: Optional[str] = None
mission: Optional[MissionConfig] = None
strategy: Optional[StrategyConfig] = None
risk_tier: Optional[RiskTierConfig] = None
status: str = "active"
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@classmethod
def dimension(cls) -> Dimension:
return "groups"
TypeDB Schema
# ONE Dimension: GROUPS
# TypeDB Entity: trading-group
define
trading-group sub one-group,
owns symbol,
owns exchange-name,
owns is-testnet,
owns max-equity,
owns risk-budget,
owns strategy-name,
owns strategy-timeframes,
owns risk-tier-level,
owns max-position-size,
owns max-leverage;
DIMENSION 2: ACTORS (Cognitive Components)
"Actors are who can act - the cognitive components of the trading mind." — ONE Ontology
The cognitive loop components are all ACTORS.
TypeScript Types
// ants/trader/types/actors.ts (ASPIRATIONAL - for future frontend)
export type CognitiveActorType =
| "orchestrator" // Trader - coordinates all
| "perceiver" // Market - observes
| "analyzer" // Brain - thinks
| "judge" // Skeptic/Mechanist/Governor - decides
| "executor" // Executor - acts
| "learner" // Memory - learns
| "guard"; // RealtimeGuard - protects
export interface CognitiveActor {
type: CognitiveActorType;
properties: {
id: string;
name: string;
// What dimensions this actor reads
reads: Dimension[];
// What dimensions this actor writes
writes: Dimension[];
// Actor-specific configuration
config: Record<string, unknown>;
// Runtime state
state: {
connected: boolean;
healthy: boolean;
lastActivity: Date;
errorCount: number;
};
};
}
export interface MarketActor extends CognitiveActor {
type: "perceiver";
properties: CognitiveActor["properties"] & {
reads: ["things"]; // Reads from exchange
writes: ["things"]; // Produces State
config: {
symbol: string;
testnet: boolean;
wsEndpoint: string;
pollInterval: number;
realtimeMode: boolean;
};
indicators: {
vwap: boolean;
atr: boolean;
volume: boolean;
momentum: boolean;
};
};
}
export interface BrainActor extends CognitiveActor {
type: "analyzer";
properties: CognitiveActor["properties"] & {
reads: ["things", "connections"]; // State + SignalEdge
writes: ["things"]; // Produces Signal
config: {
edgeCacheSize: number;
precursorPatterns: number; // 22 GPU-trained patterns
minPheromone: number;
minConfidence: number;
};
analysis: {
pheromoneWeight: number; // 0-1
regimeWeight: number;
precursorWeight: number;
};
};
}
export interface JudgeActor extends CognitiveActor {
type: "judge";
properties: CognitiveActor["properties"] & {
reads: ["things"]; // Signal
writes: ["events"]; // Decision
judgeType: "skeptic" | "mechanist" | "governor";
config: {
// Skeptic config
minConfidence?: number;
minSources?: number;
// Mechanist config
maxSpread?: number;
minLiquidity?: number;
// Governor config
maxDailyLoss?: number;
maxPosition?: number;
maxDrawdown?: number;
};
};
}
export interface ExecutorActor extends CognitiveActor {
type: "executor";
properties: CognitiveActor["properties"] & {
reads: ["events"]; // Decision
writes: ["events"]; // Trade
config: {
preSignedOrders: boolean;
maxSlippage: number;
orderTimeout: number;
retryAttempts: number;
};
exchange: {
connected: boolean;
latencyMs: number;
lastOrderId: string;
};
};
}
export interface MemoryActor extends CognitiveActor {
type: "learner";
properties: CognitiveActor["properties"] & {
reads: ["things", "events"]; // State, Signal, Decision, Trade
writes: ["connections", "knowledge"]; // SignalEdge, Pattern
config: {
depositBatchSize: number;
crystallizationThreshold: number;
decayRate: number;
predictionHorizons: number[]; // [60, 300, 900, 3600, 14400, 86400]
};
learning: {
pendingDeposits: number;
pendingPredictions: number;
crystallizationCandidates: number;
};
};
}
export interface GuardActor extends CognitiveActor {
type: "guard";
properties: CognitiveActor["properties"] & {
reads: ["events"];
writes: []; // Guard only blocks, doesn't write
limits: {
maxDailyLoss: number; // 0.03 = 3%
maxPosition: number; // 0.30 = 30%
maxOrdersPerMinute: number; // 10
maxConsecutiveLosses: number; // 5
};
state: {
dailyPnL: number;
ordersThisMinute: number;
consecutiveLosses: number;
halted: boolean;
haltReason?: string;
};
};
}
Pydantic Models
# ants/trader/models/actors.py
# ONE Dimension: ACTORS
from enum import Enum
from typing import List, Optional
from pydantic import Field
class CognitiveActorType(str, Enum):
ORCHESTRATOR = "orchestrator"
PERCEIVER = "perceiver"
ANALYZER = "analyzer"
JUDGE = "judge"
EXECUTOR = "executor"
LEARNER = "learner"
GUARD = "guard"
class ActorState(TraderModel):
"""Runtime state of an actor."""
connected: bool = False
healthy: bool = True
last_activity: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
error_count: int = 0
class CognitiveActor(TraderModel):
"""
Base cognitive actor in the trading mind.
ONE Dimension: ACTORS
TypeDB Entity: cognitive-actor (extends ai-agent)
"""
actor_id: str
actor_type: CognitiveActorType
name: str
reads: List[Dimension] = []
writes: List[Dimension] = []
state: ActorState = Field(default_factory=ActorState)
@classmethod
def dimension(cls) -> Dimension:
return "actors"
class RealtimeGuard(TraderModel):
"""
Kill switches and rate limits.
ONE Dimension: ACTORS (agent-subtype: "guard")
"""
max_daily_loss: float = Field(default=0.03) # 3%
max_position: float = Field(default=0.30) # 30%
max_orders_per_minute: int = Field(default=10)
max_consecutive_losses: int = Field(default=5)
# State
daily_pnl: float = 0
orders_this_minute: int = 0
consecutive_losses: int = 0
halted: bool = False
halt_reason: str = ""
def check(self, decision: "Decision", current_position: float) -> tuple[bool, str]:
"""Check all kill switches."""
if self.halted:
return False, self.halt_reason
if self.daily_pnl <= -self.max_daily_loss:
self.halted = True
self.halt_reason = "daily_loss_limit"
return False, self.halt_reason
if self.consecutive_losses >= self.max_consecutive_losses:
self.halted = True
self.halt_reason = "consecutive_losses"
return False, self.halt_reason
if current_position + decision.size > self.max_position:
return False, "position_limit"
if self.orders_this_minute >= self.max_orders_per_minute:
return False, "rate_limit"
return True, "ok"
@classmethod
def dimension(cls) -> Dimension:
return "actors"
TypeDB Schema
# ONE Dimension: ACTORS
# TypeDB Entity: cognitive-actor
define
cognitive-actor sub ai-agent,
owns actor-type,
owns reads-dimensions,
owns writes-dimensions,
owns is-connected,
owns is-healthy,
owns last-activity,
owns error-count;
trading-guard sub cognitive-actor,
owns max-daily-loss,
owns max-position,
owns max-orders-per-minute,
owns max-consecutive-losses,
owns daily-pnl,
owns orders-this-minute,
owns consecutive-losses,
owns is-halted,
owns halt-reason;
DIMENSION 3: THINGS (Market Observables)
"Things are passive entities that can be observed and measured." — ONE Ontology
The OBSERVE layer perceives the market and produces Thing entities.
TypeScript Types
// ants/trader/types/things.ts (ASPIRATIONAL - for future frontend)
export type RegimeType =
| "trending_up"
| "trending_down"
| "ranging"
| "volatile"
| "crash"
| "unknown";
export type Direction = "long" | "short" | "neutral";
export interface Price {
symbol: string;
timestamp: Date;
bid: number;
ask: number;
last: number;
open: number;
high: number;
low: number;
close: number;
volume: number;
// Computed
mid: number; // (bid + ask) / 2
spread: number; // ask - bid
spreadBps: number; // spread in basis points
}
export interface Depth {
timestamp: Date;
bidPrice: number;
askPrice: number;
bidSize: number;
askSize: number;
bidDepth10: number; // Depth at 10 levels
askDepth10: number;
// Computed
imbalance: number; // (bid - ask) / (bid + ask), range -1 to 1
}
export interface Volatility {
timestamp: Date;
atr14: number;
atrPct: number; // ATR as percentage of price
rv24h: number; // 24h realized volatility
volPercentile: number; // 0-1, historical percentile
// Computed
regime: "extreme" | "high" | "normal" | "low";
}
export interface Funding {
timestamp: Date;
symbol: string;
fundingRate: number;
predictedFunding: number;
openInterest: number;
oiChangePct: number;
// Computed
fundingSignal: "very_long" | "long" | "neutral" | "short" | "very_short";
}
export interface Regime {
timestamp: Date;
regimeType: RegimeType;
confidence: number; // 0-1
transitionProb: number; // Probability of regime change
// Multi-timeframe alignment
alignment1h: RegimeType;
alignment4h: RegimeType;
alignment1d: RegimeType;
// Computed
alignmentScore: number; // 0-1, how aligned are timeframes
}
export interface State {
stateId: string;
timestamp: Date;
symbol: string;
// Sub-observations (all optional for partial states)
price?: Price;
depth?: Depth;
volatility?: Volatility;
funding?: Funding;
regime?: Regime;
// Computed
discretized: string; // e.g., "UP2:HVOL:TREN:LONG"
completeness: number; // 0-1, fraction of observations present
}
export interface Signal {
signalId: string;
stateId: string; // Links to State
timestamp: Date;
// Core signal
direction: Direction;
strength: number; // 0-1, how strong
confidence: number; // 0-1, how sure
// Alpha sources that contributed
sources: Record<string, number>;
// Entry targets (optional)
suggestedEntry?: number;
suggestedStop?: number;
suggestedTarget?: number;
// Reasoning
reasoning: string;
primaryDriver: string;
// Computed
isActionable: boolean;
sourceAlignment: number;
}
// Trading-specific THINGS
export interface PrecursorIndicator {
indicatorId: string;
timestamp: Date;
patternType: string; // e.g., "volume_breakout_low"
threshold: number;
currentValue: number;
triggered: boolean;
// Historical accuracy
accuracy: number; // 0-1
sampleSize: number;
avgWarningCandles: number;
// Pheromone level from GPU training
pheromoneLevel: number; // 0-1
}
export interface RegimeSnapshot {
snapshotId: string;
timestamp: Date;
currentRegime: RegimeType;
regimeDuration: number; // Hours in current regime
// Precursor signals
activePrecursors: PrecursorIndicator[];
// Transition prediction
predictedNextRegime?: RegimeType;
transitionConfidence: number;
estimatedCandlesToTransition?: number;
}
Pydantic Models
# ants/trader/models/things.py
# ONE Dimension: THINGS
from enum import Enum
from typing import Optional, Dict, List
from pydantic import Field, computed_field
class RegimeType(str, Enum):
TRENDING_UP = "trending_up"
TRENDING_DOWN = "trending_down"
RANGING = "ranging"
VOLATILE = "volatile"
CRASH = "crash"
UNKNOWN = "unknown"
class Direction(str, Enum):
LONG = "long"
SHORT = "short"
NEUTRAL = "neutral"
class Price(TraderModel):
"""
Price observation.
ONE Dimension: THINGS (sub-observation of State)
"""
symbol: str
timestamp: datetime
bid: float = Field(ge=0)
ask: float = Field(ge=0)
last: float = Field(ge=0)
open: float = Field(ge=0)
high: float = Field(ge=0)
low: float = Field(ge=0)
close: float = Field(ge=0)
volume: float = Field(ge=0)
@computed_field
@property
def mid(self) -> float:
return (self.bid + self.ask) / 2
@computed_field
@property
def spread(self) -> float:
return self.ask - self.bid
@computed_field
@property
def spread_bps(self) -> float:
if self.mid == 0:
return 0
return (self.spread / self.mid) * 10000
@classmethod
def dimension(cls) -> Dimension:
return "things"
class Depth(TraderModel):
"""
Order book observation.
ONE Dimension: THINGS (sub-observation of State)
"""
timestamp: datetime
bid_price: float
ask_price: float
bid_size: float = Field(ge=0)
ask_size: float = Field(ge=0)
bid_depth_10: float = Field(ge=0, default=0)
ask_depth_10: float = Field(ge=0, default=0)
@computed_field
@property
def imbalance(self) -> float:
total = self.bid_size + self.ask_size
if total == 0:
return 0
return (self.bid_size - self.ask_size) / total
@classmethod
def dimension(cls) -> Dimension:
return "things"
class Volatility(TraderModel):
"""
Volatility observation.
ONE Dimension: THINGS (sub-observation of State)
"""
timestamp: datetime
atr_14: float = Field(ge=0, default=0)
atr_pct: float = Field(ge=0, default=0)
rv_24h: float = Field(ge=0, default=0)
vol_percentile: float = Field(ge=0, le=1, default=0.5)
@computed_field
@property
def regime(self) -> str:
if self.vol_percentile > 0.8:
return "extreme"
elif self.vol_percentile > 0.6:
return "high"
elif self.vol_percentile < 0.2:
return "low"
return "normal"
@classmethod
def dimension(cls) -> Dimension:
return "things"
class Funding(TraderModel):
"""
Funding rate observation.
ONE Dimension: THINGS (sub-observation of State)
"""
timestamp: datetime
symbol: str
funding_rate: float = 0
predicted_funding: float = 0
open_interest: float = Field(ge=0, default=0)
oi_change_pct: float = 0
@computed_field
@property
def funding_signal(self) -> str:
if self.funding_rate > 0.001:
return "very_long"
elif self.funding_rate > 0.0003:
return "long"
elif self.funding_rate < -0.001:
return "very_short"
elif self.funding_rate < -0.0003:
return "short"
return "neutral"
@classmethod
def dimension(cls) -> Dimension:
return "things"
class RegimeObservation(TypeDBModel):
"""
Multi-timeframe regime observation with alignment scoring.
ONE Dimension: THINGS (sub-observation of State)
TypeDB Entity: regime-observation
Note: Uses str for flexibility (can be any regime value).
"""
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
regime_type: str = Field(default="unknown", description="Current regime from Regime enum")
confidence: float = Field(ge=0, le=1, default=0)
transition_prob: float = Field(ge=0, le=1, default=0)
# Multi-timeframe alignment (for confluence)
alignment_1h: str = Field(default="unknown")
alignment_4h: str = Field(default="unknown")
alignment_1d: str = Field(default="unknown")
@computed_field
@property
def alignment_score(self) -> float:
"""Fraction of timeframes in agreement (0-1)."""
regimes = [self.regime_type, self.alignment_1h, self.alignment_4h, self.alignment_1d]
regimes = [r for r in regimes if r != "unknown"]
if not regimes:
return 0
from collections import Counter
most_common = Counter(regimes).most_common(1)[0][1]
return most_common / len(regimes)
@classmethod
def dimension(cls) -> Dimension:
return "things"
class State(TraderModel):
"""
Unified market state - the primary THING in trading.
ONE Dimension: THINGS
TypeDB Entity: market-state
Cognitive Layer: OBSERVE output
"""
state_id: str = ""
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
symbol: str = "BTC-PERP"
price: Optional[Price] = None
depth: Optional[Depth] = None
volatility: Optional[Volatility] = None
funding: Optional[Funding] = None
regime: Optional[Regime] = None
def model_post_init(self, __context) -> None:
if not self.state_id:
self.state_id = self._generate_id()
def _generate_id(self) -> str:
data = f"{self.symbol}:{self.timestamp.isoformat()}"
return hashlib.sha256(data.encode()).hexdigest()[:16]
@computed_field
@property
def discretized(self) -> str:
"""Discretized state for pheromone edge lookup."""
parts = []
if self.price:
change = (self.price.close - self.price.open) / self.price.open if self.price.open else 0
if change > 0.02: parts.append("UP2")
elif change > 0.005: parts.append("UP1")
elif change < -0.02: parts.append("DN2")
elif change < -0.005: parts.append("DN1")
else: parts.append("FLAT")
if self.volatility:
parts.append(self.volatility.regime[:4].upper())
if self.regime:
parts.append(self.regime.regime_type.value[:4].upper())
if self.funding:
parts.append(self.funding.funding_signal[:4].upper())
return ":".join(parts) if parts else "UNKNOWN"
@computed_field
@property
def completeness(self) -> float:
fields = [self.price, self.depth, self.volatility, self.funding, self.regime]
return sum(1 for f in fields if f is not None) / len(fields)
@classmethod
def dimension(cls) -> Dimension:
return "things"
class Signal(TraderModel):
"""
Trading signal - output of analysis.
ONE Dimension: THINGS (analysis result, observable)
Cognitive Layer: ANALYZE output, DECIDE input
"""
signal_id: str = ""
state_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
direction: Direction = Direction.NEUTRAL
strength: float = Field(ge=0, le=1, default=0)
confidence: float = Field(ge=0, le=1, default=0)
sources: Dict[str, float] = Field(default_factory=dict)
suggested_entry: Optional[float] = None
suggested_stop: Optional[float] = None
suggested_target: Optional[float] = None
reasoning: str = ""
primary_driver: str = ""
def model_post_init(self, __context) -> None:
if not self.signal_id:
data = f"{self.state_id}:{self.timestamp.isoformat()}:{self.direction.value}"
self.signal_id = hashlib.sha256(data.encode()).hexdigest()[:16]
@computed_field
@property
def is_actionable(self) -> bool:
return (
self.direction != Direction.NEUTRAL
and self.strength >= 0.3
and self.confidence >= 0.5
)
@computed_field
@property
def source_alignment(self) -> float:
if not self.sources:
return 0
positive = sum(1 for v in self.sources.values() if v > 0)
negative = sum(1 for v in self.sources.values() if v < 0)
total = positive + negative
if total == 0:
return 0
return max(positive, negative) / total
@classmethod
def dimension(cls) -> Dimension:
return "things"
class PrecursorIndicator(TraderModel):
"""
Precursor pattern indicator for regime transition detection.
ONE Dimension: THINGS
TypeDB Entity: precursor-indicator
Field names match TypeQL schema (kebab-case → snake_case):
- threshold-value → threshold_value
- is-triggered → is_triggered
"""
indicator_id: str
timestamp: datetime
# Pattern detection (TypeQL: pattern-type, threshold-value, current-value, is-triggered)
pattern_type: str
threshold_value: float
current_value: float
is_triggered: bool = False
# Statistics (TypeQL: accuracy, sample-size, avg-warning-candles, pheromone-level)
accuracy: float = Field(ge=0, le=1, default=0.5)
sample_size: int = Field(ge=0, default=0)
avg_warning_candles: float = Field(ge=0, default=2.0)
pheromone_level: float = Field(ge=0, le=1, default=0.5)
@classmethod
def dimension(cls) -> Dimension:
return "things"
TypeDB Schema
# ONE Dimension: THINGS
# TypeDB 3.0 Syntax (PERA Model)
# Entities: market-state, trading-signal, precursor-indicator
define
# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute state-id, value string;
attribute signal-id, value string;
attribute indicator-id, value string;
attribute symbol, value string;
attribute timestamp, value datetime;
attribute discretized-state, value string;
attribute completeness, value double;
attribute price-bid, value double;
attribute price-ask, value double;
attribute price-last, value double;
attribute price-volume, value double;
attribute depth-imbalance, value double;
attribute vol-atr-pct, value double;
attribute vol-percentile, value double;
attribute vol-regime, value string;
attribute funding-rate, value double;
attribute funding-signal, value string;
attribute regime-type, value string;
attribute regime-confidence, value double;
attribute regime-alignment, value double;
attribute signal-direction, value string;
attribute signal-strength, value double;
attribute signal-confidence, value double;
attribute suggested-entry, value double;
attribute suggested-stop, value double;
attribute suggested-target, value double;
attribute signal-reasoning, value string;
attribute primary-driver, value string;
attribute is-actionable, value boolean;
attribute source-alignment, value double;
attribute pattern-type, value string;
attribute threshold-value, value double;
attribute current-value, value double;
attribute is-triggered, value boolean;
attribute accuracy, value double;
attribute sample-size, value integer;
attribute avg-warning-candles, value double;
attribute pheromone-level, value double;
# === ENTITY TYPES (Independent Types) ===
entity market-state,
owns state-id @key,
owns symbol @card(1),
owns timestamp @card(1),
owns discretized-state,
owns completeness,
owns price-bid,
owns price-ask,
owns price-last,
owns price-volume,
owns depth-imbalance,
owns vol-atr-pct,
owns vol-percentile,
owns vol-regime,
owns funding-rate,
owns funding-signal,
owns regime-type,
owns regime-confidence,
owns regime-alignment;
entity trading-signal,
owns signal-id @key,
owns state-id @card(1),
owns timestamp @card(1),
owns signal-direction @card(1),
owns signal-strength,
owns signal-confidence,
owns suggested-entry,
owns suggested-stop,
owns suggested-target,
owns signal-reasoning,
owns primary-driver,
owns is-actionable,
owns source-alignment;
entity precursor-indicator,
owns indicator-id @key,
owns timestamp @card(1),
owns pattern-type @card(1),
owns threshold-value,
owns current-value,
owns is-triggered,
owns accuracy,
owns sample-size,
owns avg-warning-candles,
owns pheromone-level;
DIMENSION 4: CONNECTIONS (Pheromone Trails)
"Connections encode relationships with cost - the basis of stigmergy." — ONE Ontology
The ANALYZE layer queries pheromone edges (CONNECTIONS) to generate signals.
TypeScript Types
// ants/trader/types/connections.ts (ASPIRATIONAL)
export type EdgeTier = "elite" | "promising" | "neutral" | "danger";
export interface SignalEdge {
edgeId: string;
fromStateId: string; // Discretized state
toDirection: Direction; // Target action
// Raw counts
winCount: number;
lossCount: number;
totalPnl: number;
// Timestamps
createdAt: Date;
updatedAt: Date;
// Tier (can be INFERRED by TypeDB rules)
tier?: EdgeTier;
// Computed
totalTrades: number;
winRate: number;
avgPnl: number;
trailPheromone: number; // 0-100, positive reinforcement
alarmPheromone: number; // 0-100, negative reinforcement
effectiveCost: number; // STAN cost: lower = better
isSuperhighway: boolean;
}
// Trading-specific CONNECTIONS
export interface RegimeTransition {
transitionId: string;
fromRegime: RegimeType;
toRegime: RegimeType;
timestamp: Date;
// Precursor context
precursorPatterns: string[];
precursorLeadTime: number; // Candles before transition
// Outcome
priceChangeAfter: number;
durationCandles: number;
confidence: number;
// Pheromone strength
pheromoneLevel: number;
}
export interface PatternCorrelation {
correlationId: string;
patternA: string;
patternB: string;
// Correlation metrics
cooccurrence: number; // How often they appear together
sequenceProbability: number; // P(B | A)
synergy: number; // Combined accuracy vs individual
// Usage
observationCount: number;
lastObserved: Date;
}
export interface IndicatorDependency {
dependencyId: string;
sourceIndicator: string;
targetIndicator: string;
// Dependency type
type: "leads" | "confirms" | "contradicts";
lagCandles: number;
correlation: number;
// Reliability
reliability: number; // 0-1
sampleSize: number;
}
Pydantic Models
# ants/trader/models/connections.py
# ONE Dimension: CONNECTIONS
from typing import Optional, List
from pydantic import Field, computed_field
class SignalEdge(TypeDBModel):
"""
Pheromone edge - the fundamental CONNECTION in trading.
ONE Dimension: CONNECTIONS
TypeDB Entity: signal-edge
Role: Links discretized state → direction with pheromone cost
"""
edge_id: str = Field(default_factory=lambda: f"edge:{uuid4().hex[:8]}")
symbol_name: str = Field(default="BTC-PERP", description="Trading symbol")
from_state_id: str = Field(..., description="Source state (discretized)")
to_signal_direction: str = Field(..., description="Target direction: bullish/bearish/neutral")
to_direction: str = Field(default="", description="Alias for to_signal_direction")
win_count: int = Field(ge=0, default=0)
loss_count: int = Field(ge=0, default=0)
total_pnl: float = 0
# Pheromone levels
trail_pheromone: float = Field(default=0.5, ge=0, le=100)
alarm_pheromone: float = Field(default=0.0, ge=0, le=100)
quality_pheromone: float = Field(default=0.5, ge=0, le=100)
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
tier: Optional[str] = None
@computed_field
@property
def total_trades(self) -> int:
return self.win_count + self.loss_count
@computed_field
@property
def win_rate(self) -> float:
if self.total_trades == 0:
return 0.5
return self.win_count / self.total_trades
@computed_field
@property
def avg_pnl(self) -> float:
if self.total_trades == 0:
return 0
return self.total_pnl / self.total_trades
@computed_field
@property
def trail_pheromone(self) -> float:
"""Positive reinforcement signal (0-100)."""
BASE = 50.0
if self.total_trades < 10:
return BASE
wr_component = (self.win_rate - 0.5) * 2 * 40
pnl_norm = max(-1, min(1, self.avg_pnl / 5.0))
pnl_component = pnl_norm * 10
return max(0.01, min(100, BASE + wr_component + pnl_component))
@computed_field
@property
def alarm_pheromone(self) -> float:
"""Danger signal (0-100)."""
if self.total_trades < 10 or self.win_rate >= 0.5:
return 0
alarm = (0.5 - self.win_rate) * 2 * 60
if self.avg_pnl < -2.0:
alarm += abs(self.avg_pnl) * 5
return min(100, alarm)
@computed_field
@property
def effective_cost(self) -> float:
"""STAN effective cost: lower = better path."""
pheromone_level = self.trail_pheromone - self.alarm_pheromone
return 1.0 / (1 + pheromone_level * 0.1)
@computed_field
@property
def is_superhighway(self) -> bool:
"""High-traffic proven path (KNOWLEDGE candidate)."""
return self.trail_pheromone >= 85 and self.total_trades >= 100
# === BAYESIAN CONFIDENCE (NEW) ===
@computed_field
@property
def beta_alpha(self) -> float:
"""Beta distribution alpha parameter (wins + prior)."""
return self.win_count + 1 # Uniform prior
@computed_field
@property
def beta_beta(self) -> float:
"""Beta distribution beta parameter (losses + prior)."""
return self.loss_count + 1 # Uniform prior
@computed_field
@property
def win_rate_mean(self) -> float:
"""Bayesian mean of win rate."""
return self.beta_alpha / (self.beta_alpha + self.beta_beta)
@computed_field
@property
def win_rate_confidence_95(self) -> tuple[float, float]:
"""
95% credible interval for win rate.
This is THE key metric for avoiding overfitting:
- Edge with 3/4 wins: CI = (0.32, 0.98) — wide, uncertain
- Edge with 75/100 wins: CI = (0.66, 0.83) — narrow, reliable
Don't trade edges with wide CIs!
"""
from scipy.stats import beta
dist = beta(self.beta_alpha, self.beta_beta)
return (dist.ppf(0.025), dist.ppf(0.975))
@computed_field
@property
def confidence_width(self) -> float:
"""Width of 95% CI. Narrower = more reliable."""
ci = self.win_rate_confidence_95
return ci[1] - ci[0]
@computed_field
@property
def is_statistically_significant(self) -> bool:
"""
Is this edge reliably different from random (50%)?
True if: lower bound of 95% CI > 0.5 (for winners)
OR upper bound of 95% CI < 0.5 (for losers)
"""
ci = self.win_rate_confidence_95
return ci[0] > 0.5 or ci[1] < 0.5
@computed_field
@property
def sample_size_needed(self) -> int:
"""
Approximate trades needed for CI width < 0.1.
Wilson score CI width ≈ 2 * 1.96 * sqrt(p*(1-p)/n)
For width = 0.1 and p = 0.5: n ≈ 385
"""
if self.confidence_width < 0.1:
return 0
# Rough estimate
return max(0, 400 - self.total_trades)
@classmethod
def dimension(cls) -> Dimension:
return "connections"
class RegimeTransition(TypeDBModel):
"""
Regime transition with precursor context.
ONE Dimension: CONNECTIONS
TypeDB Entity: regime-transition
"""
transition_id: str = Field(default_factory=lambda: f"trans:{uuid4().hex[:8]}")
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
from_regime: str = Field(..., description="Previous regime")
to_regime: str = Field(..., description="New regime")
precursor_patterns: List[str] = Field(default_factory=list, description="Patterns that fired before transition")
precursor_lead_time: float = Field(default=0.0, ge=0, description="Candles between pattern fire and transition")
@classmethod
def dimension(cls) -> Dimension:
return "connections"
class PatternCorrelation(TypeDBModel):
"""
Correlation between patterns.
ONE Dimension: CONNECTIONS
TypeDB Entity: pattern-correlation
"""
correlation_id: str = Field(default_factory=lambda: f"corr:{uuid4().hex[:8]}")
pattern_a: str = Field(..., description="First pattern name")
pattern_b: str = Field(..., description="Second pattern name")
cooccurrence: int = Field(ge=0, default=0, description="Times both fired together")
sequence_probability: float = Field(ge=0, le=1, default=0.5, description="P(B|A)")
synergy: float = Field(ge=-1, le=1, default=0.0, description="Combined effect vs individual")
observation_count: int = Field(ge=0, default=0, description="Total observations")
last_observed: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@classmethod
def dimension(cls) -> Dimension:
return "connections"
TypeDB Schema
# ONE Dimension: CONNECTIONS
# TypeDB 3.0 Syntax (PERA Model)
# Entities: signal-edge, regime-transition, pattern-correlation
define
# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute edge-id, value string;
attribute from-state-id, value string;
attribute to-signal-direction, value string;
attribute win-count, value integer;
attribute loss-count, value integer;
attribute total-pnl, value double;
attribute trail-pheromone, value double;
attribute alarm-pheromone, value double;
attribute quality-pheromone, value double;
attribute edge-win-rate, value double;
attribute edge-strength, value double;
attribute tier, value string;
attribute is-superhighway, value boolean;
attribute crystallization-ready, value boolean;
attribute beta-alpha, value double;
attribute beta-beta, value double;
attribute win-rate-ci-lower, value double;
attribute win-rate-ci-upper, value double;
attribute confidence-width, value double;
attribute is-statistically-significant, value boolean;
attribute sample-size-needed, value integer;
attribute created-at, value datetime;
attribute updated-at, value datetime;
attribute transition-id, value string;
attribute from-regime, value string;
attribute to-regime, value string;
attribute precursor-patterns, value string;
attribute precursor-lead-time, value double;
attribute price-change-after, value double;
attribute duration-candles, value integer;
attribute correlation-id, value string;
attribute pattern-a, value string;
attribute pattern-b, value string;
attribute cooccurrence, value double;
attribute sequence-probability, value double;
attribute synergy, value double;
attribute observation-count, value integer;
attribute last-observed, value datetime;
# === ENTITY TYPES (Independent Types) ===
entity signal-edge,
owns edge-id @key,
owns from-state-id @card(1),
owns to-signal-direction @card(1),
owns win-count @card(1),
owns loss-count @card(1),
owns total-pnl,
owns trail-pheromone,
owns alarm-pheromone,
owns quality-pheromone,
owns edge-win-rate,
owns edge-strength,
owns tier,
owns is-superhighway,
owns crystallization-ready,
# Bayesian confidence
owns beta-alpha,
owns beta-beta,
owns win-rate-ci-lower,
owns win-rate-ci-upper,
owns confidence-width,
owns is-statistically-significant,
owns sample-size-needed,
owns created-at @card(1),
owns updated-at;
entity regime-transition,
owns transition-id @key,
owns from-regime @card(1),
owns to-regime @card(1),
owns timestamp @card(1),
owns precursor-patterns,
owns precursor-lead-time,
owns price-change-after,
owns duration-candles,
owns confidence,
owns pheromone-level;
entity pattern-correlation,
owns correlation-id @key,
owns pattern-a @card(1),
owns pattern-b @card(1),
owns cooccurrence,
owns sequence-probability,
owns synergy,
owns observation-count,
owns last-observed;
# === FUNCTIONS (TypeQL 3.0 - Replace Rules) ===
# Elite pattern detection: high win rate, high pheromone, sufficient trades
fun get_elite_edges() -> { signal-edge }:
match
$e isa signal-edge,
has edge-win-rate $wr,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
let $total = $wc + $lc;
$wr >= 0.75;
$tp >= 70.0;
$total >= 50;
return { $e };
# Danger zone detection: low win rate, high alarm signal
fun get_danger_edges() -> { signal-edge }:
match
$e isa signal-edge,
has edge-win-rate $wr,
has alarm-pheromone $ap,
has win-count $wc,
has loss-count $lc;
let $total = $wc + $lc;
$wr < 0.40;
$ap >= 25.0;
$total >= 30;
return { $e };
# Superhighway detection: heavily trafficked, proven paths
fun get_superhighways() -> { signal-edge }:
match
$e isa signal-edge,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
let $total = $wc + $lc;
$tp >= 85.0;
$total >= 100;
return { $e };
# Crystallization candidates: elite patterns ready for permanent storage
fun get_crystallization_candidates() -> { signal-edge }:
match
$e in get_elite_edges();
$e has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
let $total = $wc + $lc;
$tp >= 80.0;
$total >= 100;
return { $e };
# Check if an edge is elite (scalar function)
fun is_elite($e: signal-edge) -> boolean:
match
$e has edge-win-rate $wr,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
let $total = $wc + $lc;
$wr >= 0.75;
$tp >= 70.0;
$total >= 50;
return true;
# Calculate STAN effective cost
fun stan_cost($e: signal-edge, $alpha: double = 0.7) -> double:
match
$e has trail-pheromone $tp,
has alarm-pheromone $ap;
let $pheromone = $tp - $ap;
return 1.0 / (1.0 + $pheromone * $alpha);
# Aggregate colony statistics
fun colony_stats() -> { integer, integer, double }:
match
$e isa signal-edge,
has win-count $wc,
has loss-count $lc;
reduce
$total_wins = sum($wc),
$total_losses = sum($lc);
let $win_rate = $total_wins / ($total_wins + $total_losses);
return { $total_wins, $total_losses, $win_rate };
DIMENSION 5: EVENTS (Trading Actions)
"Events record what happened - the immutable history of the colony." — ONE Ontology
The DECIDE and ACT layers produce Event entities.
TypeScript Types
// ants/trader/types/events.ts (ASPIRATIONAL)
export type TradeOutcome = "win" | "loss" | "breakeven" | "pending";
export interface JudgeVerdict {
judge: "skeptic" | "mechanist" | "governor";
approved: boolean;
confidence: number;
reason: string;
concerns: string[];
}
export interface Decision {
decisionId: string;
signalId: string;
timestamp: Date;
// Core decision
approved: boolean;
action: "long" | "short" | "hold" | "close";
// Position parameters
size: number; // Fraction of equity (0-1)
entry: number;
stop: number;
target: number;
// Judge verdicts
skeptic?: JudgeVerdict;
mechanist?: JudgeVerdict;
governor?: JudgeVerdict;
// Reasoning
reason: string;
concerns: string[];
// Computed
allApproved: boolean;
riskReward: number;
}
export interface Trade {
tradeId: string;
decisionId: string;
timestamp: Date;
// Execution
orderId: string;
symbol: string;
side: "buy" | "sell";
size: number;
filledPrice: number;
filledSize: number;
// Quality metrics
slippageBps: number;
latencyMs: number;
// Outcome (filled after exit)
exitPrice?: number;
exitTime?: Date;
pnl: number;
pnlPct: number;
outcome: TradeOutcome;
}
// Trading-specific EVENTS
export interface RegimeChangeEvent {
eventId: string;
timestamp: Date;
fromRegime: RegimeType;
toRegime: RegimeType;
// Precursor context
precursorsFired: string[];
leadTimeCandles: number;
// Impact
priceAtTransition: number;
price1hAfter?: number;
price4hAfter?: number;
// Learning
predictedCorrectly: boolean;
predictionConfidence: number;
}
export interface PatternDiscoveryEvent {
eventId: string;
timestamp: Date;
patternType: string;
discoverySource: "gpu_training" | "live_observation" | "hypothesis_test";
// Pattern details
accuracy: number;
sampleSize: number;
avgLeadTime: number;
// Significance
pheromoneLevel: number;
isNovel: boolean;
}
export interface CrystallizationEvent {
eventId: string;
timestamp: Date;
edgeId: string;
patternId: string;
// Edge metrics at crystallization
winRate: number;
totalTrades: number;
totalPnl: number;
trailPheromone: number;
// Crystallized knowledge
confidence: number;
transferable: boolean;
targetMissions: string[];
}
export interface PheromoneDecayEvent {
eventId: string;
timestamp: Date;
edgesAffected: number;
decayRate: number;
// Stats
avgPheromoneBeforeDecay: number;
avgPheromoneAfterDecay: number;
edgesExpired: number;
}
export interface AdaptiveFilterEvent {
eventId: string;
timestamp: Date;
action: "pause" | "resume";
rollingWinRate: number;
threshold: number;
// Context
recentTrades: number;
consecutiveLosses: number;
reason: string;
}
Pydantic Models
# ants/trader/models/events.py
# ONE Dimension: EVENTS
from typing import Optional, List
from pydantic import Field, computed_field
class JudgeVerdict(TraderModel):
"""
Individual judge's verdict.
ONE Dimension: EVENTS (sub-event of Decision)
"""
judge: str
approved: bool
confidence: float = Field(ge=0, le=1)
reason: str
concerns: List[str] = Field(default_factory=list)
@classmethod
def dimension(cls) -> Dimension:
return "events"
class Decision(TraderModel):
"""
Trading decision - an EVENT recording what was decided.
ONE Dimension: EVENTS
TypeDB Entity: trading-decision
Cognitive Layer: DECIDE output, ACT input
"""
decision_id: str = ""
signal_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
approved: bool = False
action: str = "hold"
size: float = Field(ge=0, le=1, default=0)
entry: float = Field(ge=0, default=0)
stop: float = Field(ge=0, default=0)
target: float = Field(ge=0, default=0)
skeptic: Optional[JudgeVerdict] = None
mechanist: Optional[JudgeVerdict] = None
governor: Optional[JudgeVerdict] = None
reason: str = ""
concerns: List[str] = Field(default_factory=list)
def model_post_init(self, __context) -> None:
if not self.decision_id:
data = f"{self.signal_id}:{self.timestamp.isoformat()}:{self.action}"
self.decision_id = hashlib.sha256(data.encode()).hexdigest()[:16]
@computed_field
@property
def all_approved(self) -> bool:
return all([
self.skeptic and self.skeptic.approved,
self.mechanist and self.mechanist.approved,
self.governor and self.governor.approved,
])
@computed_field
@property
def risk_reward(self) -> float:
if self.entry == 0 or self.stop == 0 or self.target == 0:
return 0
risk = abs(self.entry - self.stop)
reward = abs(self.target - self.entry)
if risk == 0:
return 0
return reward / risk
@classmethod
def dimension(cls) -> Dimension:
return "events"
class TradeRecord(TraderModel):
"""
Trade execution record - an EVENT recording what happened.
ONE Dimension: EVENTS
TypeDB Entity: trade-record
Cognitive Layer: ACT output, LEARN input
Field names match TypeQL schema (kebab-case → snake_case):
- trade-side → trade_side
- trade-size → trade_size
- trade-pnl → trade_pnl
"""
# Identity (TypeQL: trade-id, decision-id, order-id, symbol, timestamp)
trade_id: str = Field(default_factory=lambda: f"trade:{uuid4().hex[:12]}")
decision_id: str
order_id: Optional[str] = None
symbol: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Trade details (TypeQL: trade-side, trade-size)
trade_side: str # "buy" or "sell"
trade_size: float = Field(ge=0)
# Execution (TypeQL: filled-price, filled-size, slippage-bps, latency-ms)
filled_price: Optional[float] = Field(default=None, ge=0)
filled_size: Optional[float] = Field(default=None, ge=0)
slippage_bps: Optional[float] = None
latency_ms: Optional[float] = Field(default=None, ge=0)
# Exit (TypeQL: exit-price, exit-timestamp)
exit_price: Optional[float] = Field(default=None, ge=0)
exit_timestamp: Optional[datetime] = None
# Outcome (TypeQL: trade-pnl, trade-pnl-pct, trade-outcome)
trade_pnl: Optional[float] = None
trade_pnl_pct: Optional[float] = None
trade_outcome: Optional[str] = None # "win", "loss", "breakeven"
def close(self, exit_price: float, exit_time: datetime) -> None:
"""Record trade exit and compute P&L."""
self.exit_price = exit_price
self.exit_timestamp = exit_time
if self.filled_price and self.filled_price > 0 and self.filled_size:
if self.trade_side == "buy":
self.trade_pnl_pct = (exit_price - self.filled_price) / self.filled_price
else:
self.trade_pnl_pct = (self.filled_price - exit_price) / self.filled_price
self.trade_pnl = self.trade_pnl_pct * self.filled_size * self.filled_price
if self.trade_pnl_pct > 0.001:
self.trade_outcome = "win"
elif self.trade_pnl_pct < -0.001:
self.trade_outcome = "loss"
else:
self.trade_outcome = "breakeven"
@classmethod
def dimension(cls) -> Dimension:
return "events"
class RegimeChangeEvent(TraderModel):
"""
Event when market regime changes.
ONE Dimension: EVENTS
TypeDB Entity: regime-change-event
Field names match TypeQL schema (kebab-case → snake_case).
"""
# Identity (TypeQL: event-id, timestamp)
event_id: str = Field(default_factory=lambda: f"regime:{uuid4().hex[:12]}")
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Transition (TypeQL: from-regime, to-regime)
from_regime: str
to_regime: str
# Precursors (TypeQL: precursors-fired, lead-time-candles)
precursors_fired: List[str] = Field(default_factory=list)
lead_time_candles: Optional[int] = Field(default=None, ge=0)
# Context (TypeQL: price-at-transition, predicted-correctly, prediction-confidence)
price_at_transition: Optional[float] = Field(default=None, ge=0)
predicted_correctly: Optional[bool] = None
prediction_confidence: Optional[float] = Field(default=None, ge=0, le=1)
@classmethod
def dimension(cls) -> Dimension:
return "events"
class CrystallizationEvent(TraderModel):
"""
Event when a pattern crystallizes into permanent knowledge.
ONE Dimension: EVENTS
TypeDB Entity: crystallization-event
Field names match TypeQL schema (kebab-case → snake_case).
"""
# Identity (TypeQL: event-id, timestamp)
event_id: str = Field(default_factory=lambda: f"crystal:{uuid4().hex[:12]}")
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Source (TypeQL: edge-id, pattern-id)
edge_id: str
pattern_id: str
# Statistics (TypeQL: win-rate, total-trades, total-pnl, trail-pheromone)
win_rate: float = Field(ge=0, le=1)
total_trades: int = Field(ge=0)
total_pnl: float
trail_pheromone: float
# Quality (TypeQL: confidence, is-transferable, target-missions)
confidence: float = Field(ge=0, le=1)
is_transferable: bool = Field(default=True)
target_missions: List[str] = Field(default_factory=list)
@classmethod
def dimension(cls) -> Dimension:
return "events"
# === NEW EVENT TYPES FOR EMERGENCE ===
class PredictionEvent(TraderModel):
"""
A prediction made by the system for later verification.
ONE Dimension: EVENTS
TypeDB Entity: prediction-event
Field names match TypeQL schema (kebab-case → snake_case).
Enables the Reflective Learning System to track predictions.
"""
# Identity (TypeQL: event-id, timestamp)
event_id: str = Field(default_factory=lambda: f"pred:{uuid4().hex[:12]}")
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Prediction details (TypeQL: pattern-id, predicted-direction, predicted-outcome, confidence)
pattern_id: str
predicted_direction: str # "bullish" or "bearish"
predicted_outcome: str # Expected outcome
confidence: float = Field(default=0.5, ge=0, le=1)
# Context (TypeQL: state-id, regime-at-prediction, volatility-at-prediction)
state_id: str
regime_at_prediction: str
volatility_at_prediction: float = Field(default=0.0, ge=0)
# Verification (TypeQL: is-verified, actual-outcome, actual-pnl, verification-timestamp)
is_verified: bool = False
actual_outcome: Optional[str] = None
actual_pnl: Optional[float] = None
verification_timestamp: Optional[datetime] = None
@classmethod
def dimension(cls) -> Dimension:
return "events"
class HaltEvent(TraderModel):
"""
Trading halt event from RealtimeGuard.
ONE Dimension: EVENTS
TypeDB Entity: halt-event
Records when and why trading was halted. Essential for
post-mortem analysis and guard tuning.
"""
event_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Halt details
halt_reason: str # "daily_loss_limit", "consecutive_losses", "rate_limit", "manual"
guard_type: str # "realtime_guard", "security_guard", "manual"
# Context at halt
daily_pnl_at_halt: float = 0
consecutive_losses_at_halt: int = 0
positions_at_halt: int = 0
# Recovery (TypeQL: is-resumed, resume-timestamp, halt-duration-seconds, recovery-action)
is_resumed: bool = False
resume_timestamp: Optional[datetime] = None
halt_duration_seconds: Optional[int] = None
recovery_action: Optional[str] = None
@classmethod
def dimension(cls) -> Dimension:
return "events"
class ReproductionEvent(TypeDBModel):
"""
Agent reproduction event with lineage tracking.
ONE Dimension: EVENTS
TypeDB Entity: reproduction-event
Records every reproduction for phylogenetic analysis.
"""
event_id: str = Field(default_factory=lambda: f"repro:{uuid4().hex[:8]}")
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Parent info (TypeQL: parent-genome-id, parent-fitness, parent-generation, parent-trades, parent-pnl)
parent_genome_id: str = Field(..., description="Parent genome ID")
parent_fitness: float = Field(..., description="Parent fitness at reproduction")
parent_generation: int = Field(default=0, ge=0, description="Parent generation number")
parent_trades: int = Field(default=0, ge=0, description="Parent total trades")
parent_pnl: float = Field(default=0.0, description="Parent total P&L")
# Offspring info (TypeQL: offspring-genome-id, offspring-generation)
offspring_genome_id: str = Field(..., description="Offspring genome ID")
offspring_generation: int = Field(default=1, ge=0, description="Offspring generation number")
# Mutations (TypeQL: mutation-rate, mutations-applied, mutation-magnitude)
mutation_rate: float = Field(default=0.1, ge=0, le=1, description="Mutation rate used")
mutations_applied: int = Field(default=0, ge=0, description="Number of mutations applied")
mutation_magnitude: float = Field(default=0.0, ge=0, description="Total magnitude of mutations")
@classmethod
def dimension(cls) -> Dimension:
return "events"
class PhaseTransitionEvent(TraderModel):
"""
Emergence phase transition event.
ONE Dimension: EVENTS
TypeDB Entity: phase-transition-event
Records when the colony crosses emergence thresholds.
"""
event_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Transition details
from_phase: str
to_phase: str
# Metrics at transition
pattern_count: int = 0
superhighway_count: int = 0
colony_win_rate: float = 0
emergence_score: float = 0
cycle_number: int = 0
# What triggered the transition
trigger_metric: str # "patterns", "superhighways", "win_rate", "transfers", etc.
trigger_value: float = 0
trigger_threshold: float = 0
@classmethod
def dimension(cls) -> Dimension:
return "events"
class SystemEvent(TraderModel):
"""
System-level event for debugging and observability.
ONE Dimension: EVENTS
TypeDB Entity: system-event
Records system events like service restarts, config changes,
TypeDB reconnections, etc.
"""
event_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Event type
event_type: str # "service_start", "service_stop", "config_change",
# "typedb_reconnect", "error", "warning"
severity: str = "info" # "debug", "info", "warning", "error", "critical"
# Context (TypeQL: service-name, message)
service_name: str = ""
message: str = ""
# Error context (TypeQL: error-type, error-message)
error_type: Optional[str] = None
error_message: Optional[str] = None
@classmethod
def dimension(cls) -> Dimension:
return "events"
TypeDB Schema
# ONE Dimension: EVENTS
# TypeDB 3.0 Syntax (PERA Model)
# Entities: trading-decision, trade-record, regime-change-event, etc.
define
# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute decision-id, value string;
attribute event-id, value string;
attribute trade-id, value string;
attribute order-id, value string;
attribute decision-approved, value boolean;
attribute decision-action, value string;
attribute position-size, value double;
attribute entry-price, value double;
attribute stop-price, value double;
attribute target-price, value double;
attribute decision-reason, value string;
attribute risk-reward-ratio, value double;
attribute trade-side, value string;
attribute trade-size, value double;
attribute filled-price, value double;
attribute filled-size, value double;
attribute slippage-bps, value double;
attribute latency-ms, value double;
attribute exit-price, value double;
attribute exit-timestamp, value datetime;
attribute trade-pnl, value double;
attribute trade-pnl-pct, value double;
attribute trade-outcome, value string;
attribute precursors-fired, value string;
attribute lead-time-candles, value double;
attribute price-at-transition, value double;
attribute predicted-correctly, value boolean;
attribute prediction-confidence, value double;
attribute predicted-direction, value string;
attribute predicted-outcome, value string;
attribute regime-at-prediction, value string;
attribute volatility-at-prediction, value double;
attribute is-verified, value boolean;
attribute actual-outcome, value string;
attribute actual-pnl, value double;
attribute verification-timestamp, value datetime;
attribute halt-reason, value string;
attribute guard-type, value string;
attribute daily-pnl-at-halt, value double;
attribute consecutive-losses-at-halt, value integer;
attribute positions-at-halt, value integer;
attribute is-resumed, value boolean;
attribute resume-timestamp, value datetime;
attribute halt-duration-seconds, value double;
attribute recovery-action, value string;
attribute parent-genome-id, value string;
attribute parent-fitness, value double;
attribute parent-generation, value integer;
attribute parent-trades, value integer;
attribute parent-pnl, value double;
attribute offspring-genome-id, value string;
attribute offspring-generation, value integer;
attribute mutations-applied, value string;
attribute mutation-magnitude, value double;
attribute colony-size-at-reproduction, value integer;
attribute avg-fitness-at-reproduction, value double;
attribute from-phase, value string;
attribute to-phase, value string;
attribute trigger-metric, value string;
attribute trigger-value, value double;
attribute trigger-threshold, value double;
attribute event-type, value string;
attribute severity, value string;
attribute service-name, value string;
attribute message, value string;
attribute error-type, value string;
attribute error-message, value string;
attribute is-transferable, value boolean;
attribute target-missions, value string;
attribute total-trades, value integer;
# === ENTITY TYPES (Independent Types) ===
entity trading-decision,
owns decision-id @key,
owns signal-id @card(1),
owns timestamp @card(1),
owns decision-approved @card(1),
owns decision-action @card(1),
owns position-size,
owns entry-price,
owns stop-price,
owns target-price,
owns decision-reason,
owns risk-reward-ratio,
plays trade-execution:executed-decision;
entity trade-record,
owns trade-id @key,
owns decision-id @card(1),
owns order-id,
owns symbol @card(1),
owns trade-side @card(1),
owns trade-size @card(1),
owns filled-price,
owns filled-size,
owns slippage-bps,
owns latency-ms,
owns exit-price,
owns exit-timestamp,
owns trade-pnl,
owns trade-pnl-pct,
owns trade-outcome,
owns timestamp @card(1),
plays trade-execution:resulting-trade;
entity regime-change-event,
owns event-id @key,
owns timestamp @card(1),
owns from-regime @card(1),
owns to-regime @card(1),
owns precursors-fired,
owns lead-time-candles,
owns price-at-transition,
owns predicted-correctly,
owns prediction-confidence;
entity crystallization-event,
owns event-id @key,
owns timestamp @card(1),
owns edge-id @card(1),
owns pattern-id @card(1),
owns win-rate,
owns total-trades,
owns total-pnl,
owns trail-pheromone,
owns confidence,
owns is-transferable,
owns target-missions;
entity prediction-event,
owns event-id @key,
owns timestamp @card(1),
owns pattern-id @card(1),
owns predicted-direction @card(1),
owns predicted-outcome,
owns confidence,
owns state-id,
owns regime-at-prediction,
owns volatility-at-prediction,
owns is-verified,
owns actual-outcome,
owns actual-pnl,
owns verification-timestamp;
entity halt-event,
owns event-id @key,
owns timestamp @card(1),
owns halt-reason @card(1),
owns guard-type @card(1),
owns daily-pnl-at-halt,
owns consecutive-losses-at-halt,
owns positions-at-halt,
owns is-resumed,
owns resume-timestamp,
owns halt-duration-seconds,
owns recovery-action;
entity reproduction-event,
owns event-id @key,
owns timestamp @card(1),
owns parent-genome-id @card(1),
owns parent-fitness,
owns parent-generation,
owns parent-trades,
owns parent-pnl,
owns offspring-genome-id @card(1),
owns offspring-generation,
owns mutations-applied,
owns mutation-magnitude,
owns colony-size-at-reproduction,
owns avg-fitness-at-reproduction;
entity phase-transition-event,
owns event-id @key,
owns timestamp @card(1),
owns from-phase @card(1),
owns to-phase @card(1),
owns pattern-count,
owns superhighway-count,
owns colony-win-rate,
owns emergence-score,
owns cycle-number,
owns trigger-metric,
owns trigger-value,
owns trigger-threshold;
entity system-event,
owns event-id @key,
owns timestamp @card(1),
owns event-type @card(1),
owns severity,
owns service-name,
owns message,
owns error-type,
owns error-message;
# === RELATION TYPES (Dependent Types) ===
relation trade-execution,
relates executed-decision @card(1),
relates resulting-trade @card(1);
# === FUNCTIONS (TypeQL 3.0) ===
# Get recent trades by outcome
fun get_trades_by_outcome($outcome: string, $limit: integer = 50) -> { trade-record }:
match
$t isa trade-record,
has trade-outcome $outcome,
has timestamp $ts;
sort $ts desc;
limit $limit;
return { $t };
# Get winning trades
fun get_winning_trades($limit: integer = 100) -> { trade-record }:
match $t in get_trades_by_outcome("win", $limit);
return { $t };
# Get decisions with their resulting trades
fun get_decision_with_trade($decision_id: string) -> { trading-decision, trade-record }:
match
$d isa trading-decision, has decision-id $decision_id;
($d, $t) isa trade-execution;
return { $d, $t };
# Track prediction accuracy
fun prediction_accuracy($pattern: string) -> double:
match
$p isa prediction-event,
has pattern-id $pattern,
has is-verified true,
has actual-outcome $actual,
has predicted-outcome $predicted;
$actual == $predicted;
reduce $correct = count;
match
$p2 isa prediction-event,
has pattern-id $pattern,
has is-verified true;
reduce $total = count;
return $correct / $total;
DIMENSION 6: KNOWLEDGE (Crystallized Patterns)
"Knowledge is wisdom that persists across generations." — ONE Ontology
The LEARN layer creates and updates KNOWLEDGE from EVENTS.
TypeScript Types
// ants/trader/types/knowledge.ts (ASPIRATIONAL)
export interface CrystallizedPattern {
patternId: string;
sourceEdgeId: string;
sourceMission: string;
// Pattern definition
fromState: string; // Discretized state
toDirection: Direction;
// Performance at crystallization
winRate: number;
totalTrades: number;
totalPnl: number;
avgPnl: number;
// Pheromone levels
trailPheromone: number;
confidence: number;
// Transfer
transferable: boolean;
transferredTo: string[];
transferCount: number;
// Metadata
crystallizedAt: Date;
lastVerified: Date;
stillValid: boolean;
}
export interface TradingRiskProfile {
profileId: string;
timestamp: Date;
dimensions: {
technical: {
signalQuality: number; // 0-100
edgeReliability: number; // 0-100
precursorAccuracy: number; // 0-100
regimeStability: number; // 0-100
};
market: {
liquidityRisk: number; // 0-100
volatilityRisk: number; // 0-100
spreadRisk: number; // 0-100
fundingRisk: number; // 0-100
};
execution: {
slippageRisk: number; // 0-100
latencyRisk: number; // 0-100
connectionRisk: number; // 0-100
rateLimit Risk: number; // 0-100
};
portfolio: {
concentrationRisk: number; // 0-100
drawdownRisk: number; // 0-100
correlationRisk: number; // 0-100
leverageRisk: number; // 0-100
};
};
signals: {
redFlags: string[];
yellowFlags: string[];
strengthIndicators: string[];
};
recommendation: {
positionSize: number; // Suggested position size
riskMultiplier: number; // Adjustment factor
tradingAllowed: boolean;
};
}
export interface StrategyAnalytics {
strategyId: string;
timestamp: Date;
metrics: {
totalTrades: number;
winRate: number;
avgWin: number;
avgLoss: number;
profitFactor: number;
sharpeRatio: number;
sortinoRatio: number;
maxDrawdown: number;
recoveryFactor: number;
calmarRatio: number;
};
breakdown: {
byRegime: Record<RegimeType, {
trades: number;
winRate: number;
pnl: number;
}>;
byTimeframe: Record<string, {
trades: number;
winRate: number;
pnl: number;
}>;
byPattern: Record<string, {
trades: number;
winRate: number;
pnl: number;
}>;
};
trends: {
winRateTrend: "improving" | "stable" | "declining";
pnlTrend: "improving" | "stable" | "declining";
edgeDecay: number; // Rate of edge decay
};
}
export interface PatternCatalog {
catalogId: string;
updatedAt: Date;
// Elite patterns (tier = "elite")
elitePatterns: Array<{
patternId: string;
fromState: string;
toDirection: Direction;
winRate: number;
totalTrades: number;
trailPheromone: number;
}>;
// Danger patterns (tier = "danger")
dangerPatterns: Array<{
patternId: string;
fromState: string;
toDirection: Direction;
winRate: number;
alarmPheromone: number;
}>;
// Superhighways (is_superhighway = true)
superhighways: Array<{
patternId: string;
fromState: string;
toDirection: Direction;
trailPheromone: number;
totalTrades: number;
}>;
// Precursor patterns (from GPU training)
precursors: Array<{
patternType: string;
accuracy: number;
pheromoneLevel: number;
sampleSize: number;
}>;
// Statistics
stats: {
totalEdges: number;
eliteCount: number;
dangerCount: number;
superhighwayCount: number;
avgWinRate: number;
totalPnl: number;
};
}
export interface RegimeIntelligence {
intelligenceId: string;
updatedAt: Date;
// Current regime analysis
currentRegime: {
type: RegimeType;
duration: number; // Hours
stability: number; // 0-1
transitionProbability: number;
};
// Regime statistics
regimeStats: Record<RegimeType, {
avgDuration: number;
frequency: number;
winRateInRegime: number;
bestDirection: Direction;
bestPatterns: string[];
}>;
// Transition matrix (probability of A → B)
transitionMatrix: Record<RegimeType, Record<RegimeType, number>>;
// Precursor effectiveness by regime
precursorEffectiveness: Record<string, Record<RegimeType, {
accuracy: number;
avgLeadTime: number;
sampleSize: number;
}>>;
}
Pydantic Models
# ants/trader/models/knowledge.py
# ONE Dimension: KNOWLEDGE
from typing import Dict, List, Optional
from pydantic import Field
class CrystallizedPattern(TypeDBModel):
"""
Crystallized pattern - permanent trading knowledge.
ONE Dimension: KNOWLEDGE
TypeDB Entity: crystallized-pattern
"""
pattern_id: str = Field(default_factory=lambda: f"pattern:{uuid4().hex[:8]}")
source_edge_id: str = Field(..., description="Edge that crystallized into this pattern")
source_mission: str = Field(default="trade", description="Mission where pattern was discovered")
from_state: str = Field(..., description="State that triggers this pattern")
to_direction: str = Field(..., description="Target direction: bullish/bearish")
win_rate: float = Field(..., ge=0, le=1, description="Win rate at crystallization")
total_trades: int = Field(..., ge=0, description="Total trades at crystallization")
total_pnl: float = Field(default=0.0, description="Total P&L at crystallization")
avg_pnl: float = Field(default=0.0, description="Average P&L per trade")
trail_pheromone: float = Field(default=0.0, ge=0, description="Trail pheromone level at crystallization")
confidence: float = Field(..., ge=0, le=1, description="Confidence at crystallization")
# Transfer learning (TypeQL: is-transferable, transferred-to, transfer-count)
is_transferable: bool = Field(default=True, description="Can be used in other missions")
transferred_to: List[str] = Field(default_factory=list, description="Missions transferred to")
transfer_count: int = Field(default=0, ge=0, description="Number of times transferred")
# Timestamps (TypeQL: crystallized-at, last-verified, still-valid)
crystallized_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
last_verified: Optional[datetime] = None
still_valid: bool = True
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
class TradingRiskProfile(TypeDBModel):
"""
Risk assessment profile for a trading decision.
Flat structure with TypeQL-compatible field names.
ONE Dimension: KNOWLEDGE
TypeDB Entity: trading-risk-profile
"""
# Identity (TypeQL: profile-id, timestamp)
profile_id: str = Field(default_factory=lambda: f"risk:{uuid4().hex[:8]}")
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Technical risk (TypeQL: technical-signal-quality, technical-edge-reliability)
technical_signal_quality: float = Field(default=0.5, ge=0, le=1)
technical_edge_reliability: float = Field(default=0.5, ge=0, le=1)
# Market risk (TypeQL: market-liquidity-risk, market-volatility-risk)
market_liquidity_risk: float = Field(default=0.5, ge=0, le=1)
market_volatility_risk: float = Field(default=0.5, ge=0, le=1)
# Execution risk (TypeQL: execution-slippage-risk, portfolio-drawdown-risk)
execution_slippage_risk: float = Field(default=0.5, ge=0, le=1)
portfolio_drawdown_risk: float = Field(default=0.5, ge=0, le=1)
# Flags (TypeQL: red-flags, yellow-flags)
red_flags: List[str] = Field(default_factory=list)
yellow_flags: List[str] = Field(default_factory=list)
# Recommendations (TypeQL: suggested-position-size, trading-allowed)
suggested_position_size: float = Field(default=0.0, ge=0, le=1)
trading_allowed: bool = Field(default=True)
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
class StrategyAnalytics(TypeDBModel):
"""
Performance analytics for a trading strategy.
Flat structure with TypeQL-compatible field names.
ONE Dimension: KNOWLEDGE
TypeDB Entity: strategy-analytics
"""
# Identity (TypeQL: strategy-id, timestamp)
strategy_id: str = Field(default_factory=lambda: f"strat:{uuid4().hex[:8]}")
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Core metrics (TypeQL: total-trades, win-rate, profit-factor, etc.)
total_trades: int = Field(default=0, ge=0)
win_rate: float = Field(default=0.0, ge=0, le=1)
avg_win: float = Field(default=0.0)
avg_loss: float = Field(default=0.0)
profit_factor: float = Field(default=0.0, ge=0)
sharpe_ratio: float = Field(default=0.0)
max_drawdown: float = Field(default=0.0, ge=0, le=1)
# Trends (TypeQL: win-rate-trend, pnl-trend, edge-decay)
win_rate_trend: str = Field(default="stable")
pnl_trend: str = Field(default="stable")
edge_decay: float = Field(default=0.0)
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
TypeDB Schema
# ONE Dimension: KNOWLEDGE
# TypeDB 3.0 Syntax (PERA Model)
# Entities: crystallized-pattern, trading-risk-profile, strategy-analytics
define
# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute pattern-id, value string;
attribute source-edge-id, value string;
attribute source-mission, value string;
attribute from-state, value string;
attribute to-direction, value string;
attribute avg-pnl, value double;
attribute transferred-to, value string;
attribute transfer-count, value integer;
attribute crystallized-at, value datetime;
attribute last-verified, value datetime;
attribute still-valid, value boolean;
attribute profile-id, value string;
attribute technical-signal-quality, value integer;
attribute technical-edge-reliability, value integer;
attribute market-liquidity-risk, value integer;
attribute market-volatility-risk, value integer;
attribute execution-slippage-risk, value integer;
attribute portfolio-drawdown-risk, value integer;
attribute red-flags, value string;
attribute yellow-flags, value string;
attribute suggested-position-size, value double;
attribute trading-allowed, value boolean;
attribute strategy-id, value string;
attribute profit-factor, value double;
attribute sharpe-ratio, value double;
attribute max-drawdown, value double;
attribute win-rate-trend, value string;
attribute pnl-trend, value string;
attribute edge-decay, value double;
# === ENTITY TYPES (Independent Types) ===
entity crystallized-pattern,
owns pattern-id @key,
owns source-edge-id @card(1),
owns source-mission @card(1),
owns from-state @card(1),
owns to-direction @card(1),
owns win-rate,
owns total-trades,
owns total-pnl,
owns avg-pnl,
owns trail-pheromone,
owns confidence,
owns is-transferable,
owns transferred-to,
owns transfer-count,
owns crystallized-at @card(1),
owns last-verified,
owns still-valid;
entity trading-risk-profile,
owns profile-id @key,
owns timestamp @card(1),
owns technical-signal-quality,
owns technical-edge-reliability,
owns market-liquidity-risk,
owns market-volatility-risk,
owns execution-slippage-risk,
owns portfolio-drawdown-risk,
owns red-flags,
owns yellow-flags,
owns suggested-position-size,
owns trading-allowed;
entity strategy-analytics,
owns strategy-id @key,
owns timestamp @card(1),
owns total-trades,
owns win-rate,
owns profit-factor,
owns sharpe-ratio,
owns max-drawdown,
owns win-rate-trend,
owns pnl-trend,
owns edge-decay;
# === FUNCTIONS (TypeQL 3.0) ===
# Get valid crystallized patterns
fun get_valid_patterns() -> { crystallized-pattern }:
match
$p isa crystallized-pattern,
has still-valid true;
return { $p };
# Get transferable patterns for cross-mission learning
fun get_transferable_patterns() -> { crystallized-pattern }:
match
$p isa crystallized-pattern,
has still-valid true,
has is-transferable true;
return { $p };
# Get patterns by source mission
fun get_patterns_from_mission($mission: string) -> { crystallized-pattern }:
match
$p isa crystallized-pattern,
has source-mission $mission,
has still-valid true;
return { $p };
# Calculate pattern effectiveness
fun pattern_effectiveness($pattern_id: string) -> double:
match
$p isa crystallized-pattern,
has pattern-id $pattern_id,
has win-rate $wr,
has confidence $conf;
return $wr * $conf;
Emergence Entities (NEW)
These entities enable measurement and verification of emergent intelligence.
EmergenceMetrics
Colony-level metrics that prove emergence is happening:
// ants/trader/types/knowledge.ts (ASPIRATIONAL) (additions)
export interface EmergenceMetrics {
metricsId: string;
cycle: number;
timestamp: Date;
// Intelligence growth
patternCount: number;
superhighwayCount: number;
crystallizationRate: number; // Patterns crystallized per cycle
novelPatternRate: number; // New patterns not in seed set
// Evolutionary markers
avgGeneration: number;
maxGeneration: number;
phylogeneticDiversity: number; // How diverse are lineages? (0-1)
lineageCount: number; // Active genetic lines
// Collective vs Individual
colonyWinRate: number; // Aggregate win rate
individualWinRateVariance: number; // Variance across agents
collectiveAdvantage: number; // colony_wr - avg(individual_wr)
// Phase indicators
currentPhase: "bootstrap" | "transfer" | "discovery" | "recursion" | "singularity";
phaseProgress: number; // 0-1 progress to next phase
// The key metric: emergence = collective > sum of parts
emergenceScore: number;
}
export interface PhaseThresholds {
bootstrap: {
patterns: number; // 100
superhighways: number; // 10
minWinRate: number; // 0.55
};
transfer: {
patterns: number; // 1000
crossMissionTransfers: number; // 10
missionsActive: number; // 3
};
discovery: {
novelPatterns: number; // 100
hypothesesConfirmed: number; // 50
};
recursion: {
metaPatterns: number; // 10
selfImprovementRate: number; // 0.1 (dI/dt / I)
};
}
# ants/trader/models/knowledge.py (ASPIRATIONAL - not yet implemented)
# ONE Dimension: KNOWLEDGE
from enum import Enum
class EmergencePhase(str, Enum):
BOOTSTRAP = "bootstrap"
TRANSFER = "transfer"
DISCOVERY = "discovery"
RECURSION = "recursion"
SINGULARITY = "singularity"
class EmergenceMetrics(TraderModel):
"""
Colony-level metrics that prove emergence.
ONE Dimension: KNOWLEDGE
TypeDB Entity: emergence-metrics
This is the KEY entity for verifying emergent intelligence.
If emergence_score > 0 and growing, the colony is truly emergent.
"""
metrics_id: str
cycle: int
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Intelligence growth
pattern_count: int = 0
superhighway_count: int = 0
crystallization_rate: float = 0 # Per cycle
novel_pattern_rate: float = 0 # Patterns not in seed set
# Evolutionary markers
avg_generation: float = 0
max_generation: int = 0
phylogenetic_diversity: float = Field(ge=0, le=1, default=0)
lineage_count: int = 0
# Collective vs Individual
colony_win_rate: float = Field(ge=0, le=1, default=0.5)
individual_win_rate_variance: float = 0
# Phase tracking
current_phase: EmergencePhase = EmergencePhase.BOOTSTRAP
phase_progress: float = Field(ge=0, le=1, default=0)
@computed_field
@property
def collective_advantage(self) -> float:
"""
The emergence signal: how much better is the colony than individuals?
Positive = true emergence. Negative = no emergence.
"""
# Simple model: if variance is 0, assume 0.5 individual avg
individual_avg = 0.5 # Baseline random
if self.individual_win_rate_variance > 0:
# Estimate individual average from colony rate and variance
individual_avg = self.colony_win_rate - 0.05 # Assume colony is 5% better
return self.colony_win_rate - individual_avg
@computed_field
@property
def emergence_score(self) -> float:
"""
The master metric: is the colony truly emergent?
Emergence requires:
1. Collective advantage > 0 (colony beats individuals)
2. Phylogenetic diversity > 0.3 (not just clones)
3. Pattern count growing
Score = collective_advantage * diversity * log(patterns)
"""
if self.collective_advantage <= 0:
return 0
if self.phylogenetic_diversity < 0.3:
return 0
if self.pattern_count < 10:
return 0
import math
return (
self.collective_advantage
* self.phylogenetic_diversity
* math.log10(self.pattern_count)
)
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
# Phase transition thresholds
PHASE_THRESHOLDS = {
"bootstrap": {
"patterns": 100,
"superhighways": 10,
"min_win_rate": 0.55,
},
"transfer": {
"patterns": 1000,
"cross_mission_transfers": 10,
"missions_active": 3,
},
"discovery": {
"novel_patterns": 100,
"hypotheses_confirmed": 50,
},
"recursion": {
"meta_patterns": 10,
"self_improvement_rate": 0.1,
},
}
def check_phase_transition(metrics: EmergenceMetrics) -> Optional[EmergencePhase]:
"""Check if metrics indicate a phase transition."""
current = metrics.current_phase
if current == EmergencePhase.BOOTSTRAP:
thresh = PHASE_THRESHOLDS["bootstrap"]
if (metrics.pattern_count >= thresh["patterns"]
and metrics.superhighway_count >= thresh["superhighways"]
and metrics.colony_win_rate >= thresh["min_win_rate"]):
return EmergencePhase.TRANSFER
elif current == EmergencePhase.TRANSFER:
thresh = PHASE_THRESHOLDS["transfer"]
if metrics.pattern_count >= thresh["patterns"]:
# Note: cross_mission_transfers tracked elsewhere
return EmergencePhase.DISCOVERY
elif current == EmergencePhase.DISCOVERY:
thresh = PHASE_THRESHOLDS["discovery"]
if metrics.novel_pattern_rate * metrics.cycle >= thresh["novel_patterns"]:
return EmergencePhase.RECURSION
elif current == EmergencePhase.RECURSION:
thresh = PHASE_THRESHOLDS["recursion"]
# Self-improvement rate = dI/dt / I
# If emergence_score is growing faster than linear, we're recursive
if metrics.emergence_score > 1.0: # Arbitrary threshold
return EmergencePhase.SINGULARITY
return None
Genome and Lineage
Evolutionary tracking for agent reproduction:
// ants/trader/types/knowledge.ts (ASPIRATIONAL) (additions)
export interface Genome {
genomeId: string;
agentId: string;
generation: number;
// Lineage
parentId?: string;
lineage: string[]; // Full ancestry [grandparent, parent, self]
// Heritable traits (0-1 range)
pheromoneSensitivity: number; // How much trails influence decisions
explorationBias: number; // Tendency to try new paths
depositThreshold: number; // Confidence needed to deposit
riskTolerance: number; // Position sizing aggressiveness
decayResistance: number; // How long memories persist
responseThreshold: number; // Gordon's formula: P = stimulus / (stimulus + threshold)
// Mutation tracking
mutationsFromParent: string[]; // Which traits mutated
mutationMagnitude: number; // Total mutation distance
// Fitness
fitnessScore: number;
tradesExecuted: number;
pnlGenerated: number;
patternsDiscovered: number;
// Reproduction
offspringCount: number;
reproductionEligible: boolean;
// Timestamps
createdAt: Date;
lastActivity: Date;
}
export interface LineageAnalysis {
analysisId: string;
timestamp: Date;
// Population genetics
totalGenomes: number;
activeGenomes: number;
extinctLineages: number;
// Diversity metrics
avgGeneration: number;
maxGeneration: number;
lineageCount: number; // Distinct genetic lines
phylogeneticDiversity: number; // 0-1, how diverse
// Selection pressure
avgFitness: number;
fitnessVariance: number;
selectionIntensity: number; // How strong is selection?
// Winning traits
dominantTraits: Record<string, number>; // Trait → avg value in top 10%
// Evolution velocity
traitDriftRate: number; // How fast are traits changing?
adaptationRate: number; // Fitness improvement per generation
}
# ants/trader/models/knowledge.py (ASPIRATIONAL - not yet implemented)
# NOTE: These are planned extensions. The actual Genome class in code is simpler.
class Genome(TraderModel):
"""
Heritable agent parameters that evolve through selection.
ONE Dimension: KNOWLEDGE
TypeDB Entity: agent-genome
Every agent has a Genome. When agents reproduce, genomes
are inherited with mutation. Selection pressure favors
high-fitness genomes.
"""
genome_id: str
agent_id: str
generation: int = 0
# Lineage tracking
parent_id: Optional[str] = None
lineage: List[str] = Field(default_factory=list)
# Heritable traits (all 0-1)
pheromone_sensitivity: float = Field(ge=0, le=1, default=0.7)
exploration_bias: float = Field(ge=0, le=1, default=0.3)
deposit_threshold: float = Field(ge=0, le=1, default=0.6)
risk_tolerance: float = Field(ge=0, le=1, default=0.5)
decay_resistance: float = Field(ge=0, le=1, default=0.5)
# Response threshold for Gordon's formula: P = stimulus / (stimulus + threshold)
# Low threshold (0.1) = quick responder (scout-like)
# High threshold (0.9) = stubborn (harvester-like)
response_threshold: float = Field(ge=0.1, le=10.0, default=1.0)
# Mutation tracking
mutations_from_parent: List[str] = Field(default_factory=list)
mutation_magnitude: float = 0
# Fitness metrics
fitness_score: float = 0
trades_executed: int = 0
pnl_generated: float = 0
patterns_discovered: int = 0
# Reproduction
offspring_count: int = 0
reproduction_threshold: float = Field(default=100.0) # Fitness needed to reproduce
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
last_activity: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@computed_field
@property
def reproduction_eligible(self) -> bool:
"""Can this genome reproduce?"""
return self.fitness_score >= self.reproduction_threshold
def mutate(self, mutation_rate: float = 0.1) -> "Genome":
"""
Create offspring genome with mutations.
Each trait has a chance to mutate by a Gaussian delta.
Higher mutation_rate = more exploration.
"""
import random
import uuid
def mutate_trait(value: float, name: str) -> tuple[float, bool]:
if random.random() < 0.3: # 30% chance to mutate each trait
delta = random.gauss(0, mutation_rate)
new_value = max(0, min(1, value + delta))
return new_value, True
return value, False
mutations = []
traits = {}
for trait in ["pheromone_sensitivity", "exploration_bias",
"deposit_threshold", "risk_tolerance", "decay_resistance"]:
old_val = getattr(self, trait)
new_val, mutated = mutate_trait(old_val, trait)
traits[trait] = new_val
if mutated:
mutations.append(trait)
# Calculate mutation magnitude (Euclidean distance)
magnitude = sum(
(traits[t] - getattr(self, t)) ** 2
for t in traits
) ** 0.5
return Genome(
genome_id=str(uuid.uuid4())[:16],
agent_id="", # Set by caller
generation=self.generation + 1,
parent_id=self.genome_id,
lineage=self.lineage + [self.genome_id],
mutations_from_parent=mutations,
mutation_magnitude=magnitude,
**traits
)
def update_fitness(self, trade_outcome: str, pnl: float) -> None:
"""Update fitness based on trade outcome."""
self.trades_executed += 1
self.pnl_generated += pnl
# Fitness = weighted sum of PnL and consistency
win_bonus = 1.0 if trade_outcome == "win" else -0.5
self.fitness_score += pnl * 10 + win_bonus
self.last_activity = datetime.now(timezone.utc)
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
class LineageAnalysis(TraderModel):
"""
Population genetics analysis of the colony.
ONE Dimension: KNOWLEDGE
TypeDB Entity: lineage-analysis
"""
analysis_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Population counts
total_genomes: int = 0
active_genomes: int = 0
extinct_lineages: int = 0
# Diversity metrics
avg_generation: float = 0
max_generation: int = 0
lineage_count: int = 0
phylogenetic_diversity: float = Field(ge=0, le=1, default=0)
# Selection pressure
avg_fitness: float = 0
fitness_variance: float = 0
selection_intensity: float = 0
# Winning traits (trait name → avg value in top performers)
dominant_traits: Dict[str, float] = Field(default_factory=dict)
# Evolution velocity
trait_drift_rate: float = 0
adaptation_rate: float = 0 # Fitness improvement per generation
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
Hypothesis (Meta-Learning)
Testable beliefs about what works:
// ants/trader/types/knowledge.ts (ASPIRATIONAL) (additions)
export type HypothesisStatus = "testing" | "confirmed" | "rejected" | "inconclusive";
export interface Hypothesis {
hypothesisId: string;
createdAt: Date;
updatedAt: Date;
// The hypothesis statement
statement: string; // "volume_breakout works better in low volatility"
patternId?: string; // Related pattern
// Conditions that define the hypothesis
conditions: Record<string, any>; // {"volatility_regime": "low", "trend": "up"}
// Testing data
observations: number;
confirmations: number; // Outcomes that confirm
rejections: number; // Outcomes that reject
// Statistical significance
pValue: number; // Statistical test result
confidenceInterval: [number, number];
// Status
status: HypothesisStatus;
minObservationsRequired: number; // Default 30
confirmationThreshold: number; // Default 0.6
rejectionThreshold: number; // Default 0.4
// If confirmed, what action?
pheromoneBoost?: number; // Boost to apply to pattern
conditionalAccuracy: number; // Accuracy under these conditions
// Source
generatedBy: "pattern_failure" | "correlation_analysis" | "human" | "meta_learning";
sourceContext?: string;
}
export interface MetaLearningState {
stateId: string;
timestamp: Date;
// Hypothesis inventory
activeHypotheses: number;
confirmedHypotheses: number;
rejectedHypotheses: number;
// Learning velocity
hypothesesPerCycle: number;
confirmationRate: number;
avgTimeToConclusion: number; // Cycles
// Impact
patternsImproved: number; // Patterns boosted by confirmed hypotheses
falsePositivesAvoided: number; // Bad trades prevented
// Top insights
recentConfirmations: Hypothesis[];
pendingHighPotential: Hypothesis[];
}
# ants/trader/models/knowledge.py (ASPIRATIONAL - not yet implemented)
# NOTE: Actual Hypothesis in code has simpler fields. See ants/trader/learn/prediction_learner.py
class HypothesisStatus(str, Enum):
TESTING = "testing"
CONFIRMED = "confirmed"
REJECTED = "rejected"
INCONCLUSIVE = "inconclusive"
class HypothesisSource(str, Enum):
PATTERN_FAILURE = "pattern_failure"
CORRELATION_ANALYSIS = "correlation_analysis"
HUMAN = "human"
META_LEARNING = "meta_learning"
class Hypothesis(TraderModel):
"""
Testable belief about what works and when.
ONE Dimension: KNOWLEDGE
TypeDB Entity: trading-hypothesis
Meta-learning generates hypotheses from pattern failures.
Example: "volume_breakout fails when volatility > 80th percentile"
After 30 observations:
- confirmed (accuracy >= 60%) → boost pattern in that condition
- rejected (accuracy <= 40%) → no action
- inconclusive → keep testing
"""
hypothesis_id: str
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# The hypothesis
statement: str
pattern_id: Optional[str] = None
conditions: Dict[str, Any] = Field(default_factory=dict)
# Testing data
observations: int = 0
confirmations: int = 0
rejections: int = 0
# Statistical thresholds
min_observations: int = 30
confirmation_threshold: float = 0.60
rejection_threshold: float = 0.40
# Status
status: HypothesisStatus = HypothesisStatus.TESTING
# If confirmed
pheromone_boost: float = 0
conditional_accuracy: float = 0
# Source
generated_by: HypothesisSource = HypothesisSource.PATTERN_FAILURE
source_context: str = ""
@computed_field
@property
def accuracy(self) -> float:
if self.observations == 0:
return 0.5
return self.confirmations / self.observations
@computed_field
@property
def p_value(self) -> float:
"""
Binomial test: is accuracy significantly different from 0.5?
"""
if self.observations < 10:
return 1.0 # Not enough data
from scipy.stats import binom_test
return binom_test(
self.confirmations,
self.observations,
0.5, # Null hypothesis: random
alternative='two-sided'
)
@computed_field
@property
def confidence_interval(self) -> tuple[float, float]:
"""Wilson score interval for accuracy."""
if self.observations == 0:
return (0.0, 1.0)
from scipy.stats import norm
z = 1.96 # 95% CI
n = self.observations
p = self.accuracy
denom = 1 + z**2 / n
center = (p + z**2 / (2*n)) / denom
spread = z * ((p*(1-p)/n + z**2/(4*n**2)) ** 0.5) / denom
return (max(0, center - spread), min(1, center + spread))
def observe(self, outcome_matches: bool) -> None:
"""Record an observation."""
self.observations += 1
if outcome_matches:
self.confirmations += 1
else:
self.rejections += 1
self.updated_at = datetime.now(timezone.utc)
self._update_status()
def _update_status(self) -> None:
"""Update status based on observations."""
if self.observations < self.min_observations:
self.status = HypothesisStatus.TESTING
return
if self.accuracy >= self.confirmation_threshold:
self.status = HypothesisStatus.CONFIRMED
self.conditional_accuracy = self.accuracy
self.pheromone_boost = (self.accuracy - 0.5) * 20 # 0-10 boost
elif self.accuracy <= self.rejection_threshold:
self.status = HypothesisStatus.REJECTED
else:
self.status = HypothesisStatus.INCONCLUSIVE
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
def generate_hypothesis_from_failure(
pattern_id: str,
pattern_accuracy: float,
failure_context: Dict[str, Any]
) -> Hypothesis:
"""
Generate a hypothesis when a pattern fails.
Example: pattern "momentum_long" failed when volatility was extreme.
Hypothesis: "momentum_long fails when volatility_regime = extreme"
"""
# Extract key conditions from failure context
conditions = {}
statement_parts = []
if "volatility_regime" in failure_context:
conditions["volatility_regime"] = failure_context["volatility_regime"]
statement_parts.append(f"volatility={failure_context['volatility_regime']}")
if "regime_type" in failure_context:
conditions["regime_type"] = failure_context["regime_type"]
statement_parts.append(f"regime={failure_context['regime_type']}")
if "funding_signal" in failure_context:
conditions["funding_signal"] = failure_context["funding_signal"]
statement_parts.append(f"funding={failure_context['funding_signal']}")
statement = f"Pattern {pattern_id} underperforms when {', '.join(statement_parts)}"
return Hypothesis(
hypothesis_id=f"hyp_{pattern_id}_{hash(str(conditions)) % 10000:04d}",
statement=statement,
pattern_id=pattern_id,
conditions=conditions,
generated_by=HypothesisSource.PATTERN_FAILURE,
source_context=f"Pattern accuracy {pattern_accuracy:.1%} at failure"
)
FeedbackCycle (Self-Funding Loop)
Track the core self-funding loop:
// ants/trader/types/knowledge.ts (ASPIRATIONAL) (additions)
export interface FeedbackCycle {
cycleId: string;
cycleNumber: number;
timestamp: Date;
durationHours: number;
// Resources (inputs)
tradingCapital: number;
colonySize: number;
computeBudget: number;
typedbCapacity: number;
// Intelligence produced (outputs)
tradesExecuted: number;
patternsDiscovered: number;
patternsCrystallized: number;
crossMissionTransfers: number;
hypothesesGenerated: number;
hypothesesConfirmed: number;
// Returns generated
grossPnl: number;
netPnl: number; // After fees
pnlPerPattern: number; // Attribution
pnlFromElitePatterns: number; // How much from crystallized knowledge
// Growth achieved
newAgentsSpawned: number;
agentsDied: number;
netPopulationChange: number;
// The key metrics
loopRatio: number; // (capital + pnl) / capital - if > 1, self-sustaining
intelligenceGrowthRate: number; // dI/dt
returnOnIntelligence: number; // PnL per pattern
// Phase tracking
emergencePhase: string;
phaseProgress: number;
}
export interface FeedbackLoopHealth {
healthId: string;
timestamp: Date;
// Loop status
isSelfSustaining: boolean; // loopRatio > 1 for N cycles
sustainabilityStreak: number; // Consecutive self-sustaining cycles
// Bottleneck detection
bottleneck?: "capital" | "compute" | "patterns" | "agents" | "none";
bottleneckSeverity: number; // 0-1
// Projections
projectedCapital30d: number;
projectedPatterns30d: number;
projectedPhase30d: string;
// Recommendations
recommendations: string[];
}
# ants/trader/models/knowledge.py (ASPIRATIONAL - not yet implemented)
class FeedbackCycle(TraderModel):
"""
Tracks one cycle of the self-funding loop.
ONE Dimension: KNOWLEDGE
TypeDB Entity: feedback-cycle
The self-funding loop:
Capital → Trading → Profits → More Agents → Better Patterns → More Profits
If loop_ratio > 1, the colony is self-sustaining.
"""
cycle_id: str
cycle_number: int
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
duration_hours: float = 24.0 # Default: daily cycles
# Resources (inputs)
trading_capital: float = 0
colony_size: int = 0
compute_budget: float = 0 # In dollars
# Intelligence produced (outputs)
trades_executed: int = 0
patterns_discovered: int = 0
patterns_crystallized: int = 0
cross_mission_transfers: int = 0
hypotheses_generated: int = 0
hypotheses_confirmed: int = 0
# Returns generated
gross_pnl: float = 0
net_pnl: float = 0 # After fees
pnl_from_elite_patterns: float = 0
# Growth achieved
new_agents_spawned: int = 0
agents_died: int = 0
@computed_field
@property
def net_population_change(self) -> int:
return self.new_agents_spawned - self.agents_died
@computed_field
@property
def loop_ratio(self) -> float:
"""
The self-funding ratio.
> 1 means colony is self-sustaining.
"""
if self.trading_capital <= 0:
return 0
return (self.trading_capital + self.net_pnl) / self.trading_capital
@computed_field
@property
def intelligence_growth_rate(self) -> float:
"""Patterns per cycle."""
return self.patterns_discovered + self.patterns_crystallized
@computed_field
@property
def return_on_intelligence(self) -> float:
"""PnL per pattern."""
total_patterns = self.patterns_discovered + self.patterns_crystallized
if total_patterns == 0:
return 0
return self.net_pnl / total_patterns
@computed_field
@property
def is_self_sustaining(self) -> bool:
"""Is the loop closing?"""
return self.loop_ratio > 1.0
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
class FeedbackLoopHealth(TraderModel):
"""
Health assessment of the self-funding loop.
ONE Dimension: KNOWLEDGE
TypeDB Entity: feedback-loop-health
"""
health_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Loop status
is_self_sustaining: bool = False
sustainability_streak: int = 0
avg_loop_ratio: float = 0
# Bottleneck detection
bottleneck: Optional[str] = None # capital, compute, patterns, agents, none
bottleneck_severity: float = 0
# Projections (simple linear)
projected_capital_30d: float = 0
projected_patterns_30d: int = 0
# Recommendations
recommendations: List[str] = Field(default_factory=list)
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
TypeDB Schema (Emergence Entities)
# ONE Dimension: KNOWLEDGE (Emergence)
# TypeDB 3.0 Syntax (PERA Model)
# Entities: emergence-metrics, agent-genome, trading-hypothesis, feedback-cycle
define
# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute metrics-id, value string;
attribute cycle, value integer;
attribute pattern-count, value integer;
attribute superhighway-count, value integer;
attribute crystallization-rate, value double;
attribute novel-pattern-rate, value double;
attribute avg-generation, value double;
attribute max-generation, value integer;
attribute phylogenetic-diversity, value double;
attribute lineage-count, value integer;
attribute colony-win-rate, value double;
attribute individual-win-rate-variance, value double;
attribute collective-advantage, value double;
attribute current-phase, value string;
attribute phase-progress, value double;
attribute emergence-score, value double;
attribute genome-id, value string;
attribute agent-id, value string;
attribute generation, value integer;
attribute parent-id, value string;
attribute lineage, value string;
attribute pheromone-sensitivity, value double;
attribute exploration-bias, value double;
attribute deposit-threshold, value double;
attribute risk-tolerance, value double;
attribute decay-resistance, value double;
attribute mutations-from-parent, value string;
attribute fitness-score, value double;
attribute trades-executed, value integer;
attribute pnl-generated, value double;
attribute patterns-discovered, value integer;
attribute offspring-count, value integer;
attribute reproduction-eligible, value boolean;
attribute last-activity, value datetime;
attribute hypothesis-id, value string;
attribute statement, value string;
attribute hypothesis-conditions, value string;
attribute observations, value integer;
attribute confirmations, value integer;
attribute rejections, value integer;
attribute hypothesis-status, value string;
attribute p-value, value double;
attribute pheromone-boost, value double;
attribute conditional-accuracy, value double;
attribute generated-by, value string;
attribute source-context, value string;
attribute cycle-id, value string;
attribute cycle-number, value integer;
attribute duration-hours, value double;
attribute trading-capital, value double;
attribute colony-size, value integer;
attribute compute-budget, value double;
attribute cross-mission-transfers, value integer;
attribute hypotheses-generated, value integer;
attribute hypotheses-confirmed, value integer;
attribute gross-pnl, value double;
attribute net-pnl, value double;
attribute pnl-from-elite-patterns, value double;
attribute new-agents-spawned, value integer;
attribute agents-died, value integer;
attribute loop-ratio, value double;
attribute intelligence-growth-rate, value double;
attribute return-on-intelligence, value double;
attribute analysis-id, value string;
attribute total-genomes, value integer;
attribute active-genomes, value integer;
attribute extinct-lineages, value integer;
attribute avg-fitness, value double;
attribute fitness-variance, value double;
attribute selection-intensity, value double;
attribute trait-drift-rate, value double;
attribute adaptation-rate, value double;
# === ENTITY TYPES (Independent Types) ===
entity emergence-metrics,
owns metrics-id @key,
owns cycle @card(1),
owns timestamp @card(1),
owns pattern-count,
owns superhighway-count,
owns crystallization-rate,
owns novel-pattern-rate,
owns avg-generation,
owns max-generation,
owns phylogenetic-diversity,
owns lineage-count,
owns colony-win-rate,
owns individual-win-rate-variance,
owns collective-advantage,
owns current-phase,
owns phase-progress,
owns emergence-score;
entity agent-genome,
owns genome-id @key,
owns agent-id @card(1),
owns generation @card(1),
owns parent-id,
owns lineage,
owns pheromone-sensitivity,
owns exploration-bias,
owns deposit-threshold,
owns risk-tolerance,
owns decay-resistance,
owns response-threshold, # Gordon's formula: P = stimulus / (stimulus + threshold)
owns mutations-from-parent,
owns mutation-magnitude,
owns fitness-score,
owns trades-executed,
owns pnl-generated,
owns patterns-discovered,
owns offspring-count,
owns reproduction-eligible,
owns created-at @card(1),
owns last-activity,
plays parent-of:parent-genome,
plays parent-of:child-genome;
entity trading-hypothesis,
owns hypothesis-id @key,
owns statement @card(1),
owns pattern-id,
owns hypothesis-conditions,
owns observations,
owns confirmations,
owns rejections,
owns hypothesis-status,
owns p-value,
owns pheromone-boost,
owns conditional-accuracy,
owns generated-by,
owns source-context,
owns created-at @card(1),
owns updated-at;
entity feedback-cycle,
owns cycle-id @key,
owns cycle-number @card(1),
owns timestamp @card(1),
owns duration-hours,
owns trading-capital,
owns colony-size,
owns compute-budget,
owns trades-executed,
owns patterns-discovered,
owns patterns-crystallized,
owns cross-mission-transfers,
owns hypotheses-generated,
owns hypotheses-confirmed,
owns gross-pnl,
owns net-pnl,
owns pnl-from-elite-patterns,
owns new-agents-spawned,
owns agents-died,
owns loop-ratio,
owns intelligence-growth-rate,
owns return-on-intelligence;
entity lineage-analysis,
owns analysis-id @key,
owns timestamp @card(1),
owns total-genomes,
owns active-genomes,
owns extinct-lineages,
owns avg-generation,
owns max-generation,
owns lineage-count,
owns phylogenetic-diversity,
owns avg-fitness,
owns fitness-variance,
owns selection-intensity,
owns trait-drift-rate,
owns adaptation-rate;
# === RELATION TYPES (Dependent Types) ===
relation parent-of,
relates parent-genome @card(1),
relates child-genome @card(1..);
# === FUNCTIONS (TypeQL 3.0 - Replace Rules) ===
# Check reproduction eligibility (replaces rule)
fun get_reproduction_eligible() -> { agent-genome }:
match
$g isa agent-genome,
has fitness-score $fs;
$fs >= 100.0;
return { $g };
# Is this genome eligible for reproduction?
fun is_reproduction_eligible($g: agent-genome) -> boolean:
match $g has fitness-score $fs; $fs >= 100.0;
return true;
# Get lineage for a genome (recursive)
fun get_ancestors($g: agent-genome, $depth: integer = 10) -> { agent-genome }:
match
$depth >= 0;
($parent, $g) isa parent-of;
$ancestors in get_ancestors($parent, $depth - 1);
return { $ancestors };
# Get emergence score trend
fun emergence_trend($cycles: integer = 10) -> { integer, double }:
match
$m isa emergence-metrics,
has cycle $c,
has emergence-score $es;
sort $c desc;
limit $cycles;
return { $c, $es };
# Get self-sustaining feedback cycles
fun get_self_sustaining_cycles() -> { feedback-cycle }:
match
$f isa feedback-cycle,
has loop-ratio $lr;
$lr > 1.0;
return { $f };
# Calculate average fitness by generation
fun avg_fitness_by_generation($gen: integer) -> double:
match
$g isa agent-genome,
has generation $gen,
has fitness-score $fs;
reduce $avg = mean($fs);
return $avg;
# Get confirmed hypotheses
fun get_confirmed_hypotheses() -> { trading-hypothesis }:
match
$h isa trading-hypothesis,
has hypothesis-status "confirmed";
return { $h };
Cross-Dimension Patterns
Data Flow Between Dimensions
TRADING DATA FLOW
══════════════════════════════════════════════════════════════════════════
State (THING)
→ discretizes_to → SignalEdge lookup key (CONNECTION)
→ triggers → RegimeChangeEvent (EVENT)
→ analyzed_by → TradingRiskProfile (KNOWLEDGE)
SignalEdge (CONNECTION)
→ inferred_as → tier="elite" (TypeDB rule)
→ crystallizes_to → CrystallizedPattern (KNOWLEDGE)
→ transfers_to → other missions (cross-mission)
Trade (EVENT)
→ deposits_to → SignalEdge (CONNECTION)
→ updates → win_count, loss_count, total_pnl
→ triggers → PheromoneDecayEvent (EVENT)
CrystallizedPattern (KNOWLEDGE)
→ guides → Brain analysis (ACTOR)
→ transfers_to → hunt-btc, dao missions
→ evolves_via → hypothesis testing
THE EMERGENCE CYCLE
══════════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────────────────────┐
│ │
│ OBSERVE ANALYZE DECIDE ACT │
│ (Market) (Brain) (Judges) (Executor) │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌───────┐ ┌───────────┐ ┌──────────┐ ┌─────────┐ │
│ │ State │──────▶│ SignalEdge│───▶│ Decision │───▶│ Trade │ │
│ │(THING)│ │(CONNECTION)│ │ (EVENT) │ │ (EVENT) │ │
│ └───────┘ └───────────┘ └──────────┘ └─────────┘ │
│ │ │ │ │
│ │ │ LEARN (Memory) │ │
│ │ │ │ │ │
│ │ ▼ ▼ │ │
│ │ ┌───────────┐ ┌───────────┐ │ │
│ │ │ Pattern │◀───│ Pheromone │◀────────┘ │
│ │ │(KNOWLEDGE)│ │ Deposit │ │
│ │ └───────────┘ └───────────┘ │
│ │ │ │
│ │ │ (guides future analysis) │
│ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Emergence Data Flow (NEW)
THE EMERGENCE LOOP WITH METRICS
══════════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────┐
│ EMERGENCE MEASUREMENT │
│ │
│ EmergenceMetrics computed every N cycles: │
│ • pattern_count, superhighway_count │
│ • phylogenetic_diversity, lineage_count │
│ • colony_win_rate vs individual variance │
│ • emergence_score = collective - individual │
│ │
│ Phase transitions when thresholds met: │
│ bootstrap → transfer → discovery → recursion │
│ │
└─────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ │
│ TRADE LOOP EVOLUTION LOOP FEEDBACK LOOP │
│ ─────────── ────────────── ───────────── │
│ State → Signal Genome → Fitness Capital → PnL │
│ Signal → Decision Fitness → Reproduce PnL → Growth │
│ Decision → Trade Reproduce → Mutate Growth → Intel │
│ Trade → Deposit Mutate → Selection Intel → Capital │
│ ↓ ↓ ↓ │
│ SignalEdge Genome FeedbackCycle │
│ (CONNECTION) (KNOWLEDGE) (KNOWLEDGE) │
│ │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ META-LEARNING LOOP │
│ │
│ Pattern Failure → Generate Hypothesis │
│ Hypothesis → Test over 30+ observations │
│ Confirmed → Pheromone boost for that condition │
│ Rejected → No action │
│ │
│ Example: │
│ "volume_breakout fails when volatility > 80th pctl" │
│ Tested: 45 observations, 28 failures → CONFIRMED │
│ Action: Reduce pheromone for volume_breakout in high vol │
│ │
└──────────────────────────────────────────────────────────────────┘
Cross-Mission Transfer
PATTERN TRANSFER BETWEEN MISSIONS
══════════════════════════════════════════════════════════════════════════
trade mission
│
│ discovers elite pattern
│ (win_rate >= 75%, trail >= 70, trades >= 50)
│
▼
crystallized-pattern (KNOWLEDGE)
│
│ transferable = true
│
├─────────────────────────────────────────┐
│ │
▼ ▼
hunt-btc mission dao mission
(sparse marker search) (consensus detection)
Query Patterns
TypeQL Query Examples
# ants/trader/queries.py
QUERIES = {
# === THINGS Queries ===
"get_latest_state": """
match $s isa market-state,
has symbol $sym,
has timestamp $ts;
$sym == "BTC-PERP";
select $s, $ts;
sort $ts desc;
limit 1;
""",
# === CONNECTIONS Queries ===
"get_elite_edges": """
match $e isa signal-edge,
has tier "elite";
select $e;
""",
"get_superhighways": """
match $e isa signal-edge,
has is-superhighway true,
has trail-pheromone $tp,
has win-count $wc;
select $e, $tp, $wc;
sort $tp desc;
""",
"get_danger_zones": """
match $e isa signal-edge,
has tier "danger",
has alarm-pheromone $ap;
select $e, $ap;
sort $ap desc;
""",
"lookup_edge": """
match $e isa signal-edge,
has from-state-id "{state_id}",
has to-signal-direction "{direction}";
select $e;
""",
# === EVENTS Queries ===
"get_recent_trades": """
match $t isa trade-record,
has timestamp $ts,
has trade-outcome $outcome;
select $t, $ts, $outcome;
sort $ts desc;
limit 100;
""",
"get_regime_changes": """
match $r isa regime-change-event,
has timestamp $ts,
has from-regime $from,
has to-regime $to;
select $r, $ts, $from, $to;
sort $ts desc;
limit 50;
""",
# === KNOWLEDGE Queries ===
"get_crystallization_candidates": """
match $e isa signal-edge,
has crystallization-ready true;
select $e;
""",
"get_transferable_patterns": """
match $p isa crystallized-pattern,
has is-transferable true,
has confidence $c,
has still-valid true;
$c >= 0.7;
select $p, $c;
sort $c desc;
""",
# === Aggregations ===
"colony_stats": """
match $e isa signal-edge,
has win-count $wc,
has loss-count $lc,
has total-pnl $pnl;
reduce
$total_wins = sum($wc),
$total_losses = sum($lc),
$total_pnl = sum($pnl),
$edge_count = count;
""",
"win_rate_by_regime": """
match
$t isa trade-record,
has trade-outcome $outcome,
has timestamp $ts;
$s isa market-state,
has timestamp $ts,
has regime-type $regime;
reduce
$wins = count($outcome == "win"),
$total = count;
group $regime;
""",
}
Implementation Guidelines
1. Entity Granularity
- Each market state observation is a separate State (THING)
- Each trade execution is a separate Trade (EVENT)
- SignalEdges aggregate over time (not per-trade)
- Patterns crystallize at threshold, not continuously
2. Pheromone Management
- Deposits happen immediately after trade closes
- Decay runs on schedule (default: 10% per day)
- Circuit breaker protects TypeDB operations
- Cache provides fast reads, TypeDB is source of truth
3. Dimension Boundaries
- THINGS are read-only observations (immutable after creation)
- CONNECTIONS are mutable (pheromone updates)
- EVENTS are immutable (audit trail)
- KNOWLEDGE is append-mostly (patterns rarely invalidated)
4. TypeDB Best Practices
- Use inference rules for derived attributes (tier, is_superhighway)
- Batch writes for performance (pending deposits queue)
- Handle connection staleness (30s timeout, auto-reconnect)
- Retry transient errors, fail fast on permanent errors
TypeDB Inference: The Reasoning Engine
Reference: TypeDB Symbolic Reasoning Engine, TypeDB 2.x vs 3.x
TypeDB's symbolic reasoning capability is central to emergence. The database doesn't just store facts—it derives new facts automatically based on rules you define.
How Inference Works
┌─────────────────────────────────────────────────────────────────────────────┐
│ TYPEDB INFERENCE ENGINE │
│ │
│ SCHEMA (defined) DATA (inserted) DERIVED (inferred) │
│ ───────────────── ─────────────── ────────────────── │
│ signal-edge entity edge-001: tier = "elite" │
│ + tier attribute - win_rate: 0.78 (derived by rule) │
│ + elite-pattern rule - trail: 85.0 │
│ - trades: 120 │
│ │
│ QUERY TIME: │
│ match $e has tier "elite"; │
│ ↓ │
│ Rule engine evaluates conditions │
│ ↓ │
│ Returns edge-001 (derived, not stored!) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Key insight: Derived data exists only during query execution and in memory:
- Results always reflect current schema and data states
- No staleness—derived facts update automatically when source data changes
- Resource efficient—saves disk space
- Cache clears when transactions close
Rule Syntax (TypeDB 2.x Style)
Our current inference rules use the when/then syntax:
rule rule-label:
when {
# condition: pattern that must match
}
then {
# conclusion: fact to derive if condition matches
};
Trading System Rules
We define these inference rules for the emergence system:
# === TIER CLASSIFICATION RULES ===
# Elite patterns: high win rate, high pheromone, sufficient trades
rule elite-pattern:
when {
$e isa signal-edge,
has edge-win-rate $wr,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
$wr >= 0.75; # 75%+ win rate
$tp >= 70.0; # Strong trail
?total = $wc + $lc;
?total >= 50; # Sufficient sample size
}
then {
$e has tier "elite";
};
# Danger zones: low win rate, high alarm signal
rule danger-zone:
when {
$e isa signal-edge,
has edge-win-rate $wr,
has alarm-pheromone $ap,
has win-count $wc,
has loss-count $lc;
$wr < 0.40; # Below 40% win rate
$ap >= 25.0; # Alarm signal raised
?total = $wc + $lc;
?total >= 30; # Enough to be confident
}
then {
$e has tier "danger";
};
# Superhighways: heavily trafficked, proven paths
rule superhighway-edge:
when {
$e isa signal-edge,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
$tp >= 85.0; # Very strong trail
?total = $wc + $lc;
?total >= 100; # Heavy traffic
}
then {
$e has is-superhighway true;
};
# Crystallization candidates: elite patterns ready for permanent storage
rule crystallization-candidate:
when {
$e isa signal-edge,
has tier "elite",
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
$tp >= 80.0;
?total = $wc + $lc;
?total >= 100;
}
then {
$e has crystallization-ready true;
};
# === EVOLUTION RULES ===
# Reproduction eligibility: fitness threshold for genome reproduction
rule reproduction-eligible-check:
when {
$g isa agent-genome,
has fitness-score $fs;
$fs >= 100.0; # Fitness threshold
}
then {
$g has reproduction-eligible true;
};
# === STATISTICAL SIGNIFICANCE RULES ===
# Statistically significant winner: 95% CI lower bound > 50%
rule statistically-significant-winner:
when {
$e isa signal-edge,
has win-rate-ci-lower $lower;
$lower > 0.50; # Entire CI above 50%
}
then {
$e has is-statistically-significant true;
};
# Statistically significant loser: 95% CI upper bound < 50%
rule statistically-significant-loser:
when {
$e isa signal-edge,
has win-rate-ci-upper $upper;
$upper < 0.50; # Entire CI below 50%
}
then {
$e has is-statistically-significant true;
};
TypeDB 3.0: Functions Replace Rules
Important: TypeDB 3.0 replaces inference rules with explicit functions.
The transition provides more control but requires explicit invocation:
# TypeDB 3.0 syntax: define fun
# Stream-returning function (replaces query pattern)
define fun get_elite_edges() -> { signal-edge }:
match $e isa signal-edge,
has edge-win-rate $wr,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
let $total = $wc + $lc;
$wr >= 0.75; $tp >= 70.0; $total >= 50;
return { $e };
# Scalar-returning function (aggregation)
define fun colony_win_rate() -> double:
match $e isa signal-edge,
has win-count $wc,
has loss-count $lc;
let $wins = sum($wc);
let $losses = sum($lc);
return $wins / ($wins + $losses);
# Recursive function: find pattern ancestry
define fun pattern_lineage($edge: signal-edge, $depth: integer = 5) -> { signal-edge }:
match $depth >= 0;
$e isa signal-edge,
has from-state-id $state;
($e, $parent) isa pattern-evolution;
$ancestor in pattern_lineage($parent, $depth - 1);
return { $ancestor };
# Calling functions in queries
match $e in get_elite_edges();
$e has from-state-id $state;
select $e, $state;
Key Differences: Rules vs Functions
| Aspect | Rules (2.x) | Functions (3.x) |
|---|---|---|
| Invocation | Automatic (inference on) | Explicit ($x in func()) |
| Syntax | when {} then {} |
fun name() -> type: |
| Recursion | Limited | Full support |
| Composition | Chained rules | Nested calls |
| Control | All-or-nothing | Fine-grained |
Why Inference Matters for Emergence
THE EMERGENCE INFERENCE CHAIN
══════════════════════════════════════════════════════════════════════════════
Raw Trade Data Inference Rules Emergent Knowledge
──────────────── ─────────────── ──────────────────
edge.win_count = 80 elite-pattern rule tier = "elite"
edge.loss_count = 20 fires automatically (DERIVED)
edge.trail = 85 │
▼
superhighway-edge rule is_superhighway = true
fires automatically (DERIVED)
│
▼
crystallization-candidate crystallization_ready = true
fires automatically (DERIVED)
│
▼
Crystallizer queries: CrystallizedPattern
"match $e has (PERMANENT KNOWLEDGE)
crystallization-ready true"
The database DISCOVERS what works without explicit programming.
Intelligence emerges from the interaction of data and rules.
Inference Best Practices
1. Design Rules for Derivation, Not Storage
# GOOD: Derive tier at query time
rule elite-pattern: when { ... } then { $e has tier "elite"; };
# BAD: Store tier explicitly (defeats inference purpose)
insert $e has tier "elite"; # Don't do this!
2. Use Inference for Classification Hierarchies
# Tier hierarchy through inference
rule tier-1-edge: when { $wr >= 0.80; } then { $e has tier "elite"; };
rule tier-2-edge: when { $wr >= 0.65; $wr < 0.80; } then { $e has tier "strong"; };
rule tier-3-edge: when { $wr >= 0.55; $wr < 0.65; } then { $e has tier "moderate"; };
rule tier-4-edge: when { $wr < 0.55; } then { $e has tier "weak"; };
3. Chain Rules for Complex Derivations
# Rule 1: Derive elite status
rule elite-pattern: ... then { $e has tier "elite"; };
# Rule 2: Derive crystallization readiness FROM elite status
rule crystallization-candidate:
when {
$e has tier "elite"; # Depends on first rule!
$e has trail-pheromone $tp;
$tp >= 80.0;
}
then { $e has crystallization-ready true; };
4. Avoid Inference Loops
# DANGEROUS: Could cause infinite loop
rule bad-loop:
when { $a has x $v; }
then { $a has y $v; };
rule also-bad:
when { $a has y $v; }
then { $a has x $v; }; # Circular dependency!
5. Performance: Selective Inference
# Turn inference on only when needed
with driver.transaction("ants-colony", TransactionType.READ) as tx:
# Inference ON: get derived tiers
elite = tx.query(
"match $e has tier 'elite'; select $e;",
options={"inference": True}
)
# Inference OFF: raw data only (faster)
raw = tx.query(
"match $e isa signal-edge; select $e;",
options={"inference": False}
)
Trading-Specific Inference Patterns
Pattern: Regime-Conditional Effectiveness
# Pattern works differently in different regimes
rule pattern-trending-effective:
when {
$e isa signal-edge,
has from-state-id $state;
$state contains "TREN"; # Trending regime
$e has edge-win-rate $wr;
$wr >= 0.70;
}
then {
$e has regime-effectiveness "high_in_trending";
};
Pattern: Hypothesis Confirmation
# Auto-confirm hypotheses when threshold reached
rule hypothesis-confirmed:
when {
$h isa trading-hypothesis,
has observations $obs,
has confirmations $conf;
$obs >= 30;
?accuracy = $conf / $obs;
?accuracy >= 0.60;
}
then {
$h has hypothesis-status "confirmed";
};
Pattern: Emergence Phase Detection
# Derive current emergence phase from metrics
rule phase-transfer:
when {
$m isa emergence-metrics,
has pattern-count $pc,
has superhighway-count $sc,
has colony-win-rate $wr;
$pc >= 100;
$sc >= 10;
$wr >= 0.55;
}
then {
$m has current-phase "transfer";
};
5. Security Considerations
- Never store private keys in any dimension
- All trading on testnet unless explicitly configured
- Kill switches (RealtimeGuard) protect capital
- Rate limits prevent runaway trading
Self-Model: The Colony Knows Itself (NEW)
"The colony that can model itself can improve itself."
The Self-Model is a set of queries that answer fundamental questions about the colony's state and trajectory. This enables the recursive improvement loop.
Self-Model Queries
# ants/trader/queries.py (additions)
SELF_MODEL_QUERIES = {
# === WHAT AM I GOOD AT? ===
"best_patterns_by_regime": """
match
$e isa signal-edge,
has tier "elite",
has edge-win-rate $wr,
has from-state-id $state;
$state contains $regime; # Extract regime from state
select $e, $wr, $regime;
sort $wr desc;
limit 20;
""",
"superhighway_summary": """
match $e isa signal-edge,
has is-superhighway true,
has trail-pheromone $tp,
has total-pnl $pnl,
has win-count $wc,
has loss-count $lc;
reduce
$count = count,
$avg_pheromone = mean($tp),
$total_pnl = sum($pnl),
$total_wins = sum($wc),
$total_losses = sum($lc);
""",
# === WHERE AM I FAILING? ===
"danger_zones": """
match $e isa signal-edge,
has tier "danger",
has alarm-pheromone $ap,
has edge-win-rate $wr,
has from-state-id $state;
$wr < 0.40;
select $e, $ap, $wr, $state;
sort $ap desc;
limit 20;
""",
"recent_losing_patterns": """
match
$t isa trade-record,
has trade-outcome "loss",
has timestamp $ts,
has trade-pnl $pnl;
$d isa trading-decision,
has decision-id $did;
$t has decision-id $did;
select $t, $ts, $pnl;
sort $ts desc;
limit 50;
""",
"high_uncertainty_edges": """
match $e isa signal-edge,
has confidence-width $cw,
has win-count $wc,
has loss-count $lc;
$cw > 0.3; # Wide confidence interval
?total = $wc + $lc;
?total >= 10; # But has some data
select $e, $cw;
sort $cw desc;
""",
# === HOW AM I EVOLVING? ===
"generation_stats": """
match $g isa agent-genome,
has generation $gen,
has fitness-score $fit,
has pnl-generated $pnl;
reduce
$count = count,
$avg_gen = mean($gen),
$max_gen = max($gen),
$avg_fitness = mean($fit),
$total_pnl = sum($pnl);
""",
"lineage_diversity": """
match $g isa agent-genome,
has parent-id $pid;
$pid != ""; # Has a parent
reduce $unique_parents = count(distinct $pid);
""",
"winning_traits": """
match $g isa agent-genome,
has fitness-score $fit,
has pheromone-sensitivity $ps,
has exploration-bias $eb,
has risk-tolerance $rt;
$fit >= 50.0; # Above-average fitness
reduce
$count = count,
$avg_pheromone_sensitivity = mean($ps),
$avg_exploration_bias = mean($eb),
$avg_risk_tolerance = mean($rt);
""",
# === WHAT SHOULD I EXPLORE? ===
"low_sample_high_potential": """
match $e isa signal-edge,
has win-count $wc,
has loss-count $lc,
has edge-win-rate $wr;
?total = $wc + $lc;
?total < 30; # Low sample size
?total >= 5; # But not brand new
$wr >= 0.6; # Looks promising
select $e, $wr;
sort $wr desc;
""",
"underexplored_regimes": """
match $e isa signal-edge,
has from-state-id $state,
has win-count $wc,
has loss-count $lc;
reduce
$total_trades = sum($wc) + sum($lc);
group $state;
$total_trades < 100;
""",
# === EMERGENCE METRICS ===
"emergence_score_history": """
match $m isa emergence-metrics,
has cycle $c,
has emergence-score $es,
has current-phase $phase,
has colony-win-rate $wr;
select $c, $es, $phase, $wr;
sort $c desc;
limit 100;
""",
"phase_transitions": """
match $p isa phase-transition-event,
has timestamp $ts,
has from-phase $from,
has to-phase $to,
has trigger-metric $metric;
select $ts, $from, $to, $metric;
sort $ts desc;
""",
# === FEEDBACK LOOP HEALTH ===
"feedback_loop_trend": """
match $f isa feedback-cycle,
has cycle-number $cn,
has loop-ratio $lr,
has patterns-crystallized $pc,
has net-pnl $pnl;
select $cn, $lr, $pc, $pnl;
sort $cn desc;
limit 30;
""",
"hypothesis_effectiveness": """
match $h isa trading-hypothesis,
has hypothesis-status $status,
has observations $obs,
has pheromone-boost $boost;
reduce
$total = count,
$confirmed = count($status == "confirmed"),
$rejected = count($status == "rejected"),
$avg_boost = mean($boost);
""",
}
Self-Model Dashboard
The /model command generates a complete self-model:
COLONY SELF-MODEL (generated 2026-01-15 12:00:00)
══════════════════════════════════════════════════════════════════════════
WHAT AM I GOOD AT?
──────────────────
• Best regime: trending_up (72.3% WR, 847 trades)
• Top pattern: UP1:NORM:TREN:NEUT → long (78.1% WR)
• Superhighways: 23 proven paths (avg 89.2 pheromone)
• Elite edges: 156 patterns (>75% WR, >50 trades)
WHERE AM I FAILING?
───────────────────
• Worst regime: volatile (41.2% WR, 203 trades)
• Danger zones: 12 edges with alarm > 50
• Recent losing streak: 7 consecutive losses (funding reversal)
• High uncertainty: 34 edges need more data (CI width > 0.3)
HOW AM I EVOLVING?
──────────────────
• Current generation: avg 4.2, max 12
• Lineages active: 8 distinct genetic lines
• Phylogenetic diversity: 0.67 (healthy)
• Winning traits: high pheromone_sensitivity (0.78), low exploration (0.21)
• Fitness trend: +12.3% over last 10 generations
WHAT SHOULD I EXPLORE?
──────────────────────
• High-potential low-sample: 15 edges look promising, need more trades
• Underexplored regimes: ranging (only 89 trades)
• Hypothesis queue: 8 hypotheses testing, 3 near confirmation
EMERGENCE STATUS
────────────────
• Current phase: TRANSFER
• Phase progress: 67% to DISCOVERY
• Emergence score: 0.42 (up from 0.31 last week)
• Loop ratio: 1.08 (self-sustaining for 12 cycles)
RECOMMENDATIONS
───────────────
1. Reduce position size in volatile regime
2. Focus exploration on ranging regime
3. Confirm hypothesis #7: "breakout_high fails when OI declining"
4. Potential phase transition in ~200 cycles
Extension Points
This ontology can be extended with:
- Multi-Asset Support: Extend State for multiple symbols
- Options Trading: New event types for Greeks, expiry
- Funding Arbitrage: Cross-exchange connections
- Social Signals: Integration with sentiment data
- ML Integration: Feature store in KNOWLEDGE dimension
- Portfolio Optimization: Multi-position management
- Risk Parity: Dynamic allocation based on volatility
- Regime ML: Neural regime detection models
File Layout
ants/trader/ # 30+ files
│
├── __init__.py # Exports: Trader, Config
├── __main__.py # Entry: python -m ants.trader
├── core.py # Trader class (ACTOR: orchestrator)
├── config.py # TraderConfig, TraderState
│
├── types/ # TypeScript type definitions
│ ├── base.ts
│ ├── groups.ts # GROUPS types
│ ├── actors.ts # ACTORS types
│ ├── things.ts # THINGS types
│ ├── connections.ts # CONNECTIONS types
│ ├── events.ts # EVENTS types
│ └── knowledge.ts # KNOWLEDGE types
│
├── models/ # Pydantic models by dimension
│ ├── __init__.py
│ ├── base.py # TraderModel base
│ ├── groups.py # GROUPS: TradingGroup, etc.
│ ├── actors.py # ACTORS: CognitiveActor, etc.
│ ├── things.py # THINGS: State, Signal, etc.
│ ├── connections.py # CONNECTIONS: SignalEdge, etc.
│ ├── events.py # EVENTS: Decision, Trade, etc.
│ └── knowledge.py # KNOWLEDGE: Pattern, etc.
│
├── observe/ # OBSERVE (ACTOR: perceiver)
│ ├── __init__.py
│ ├── market.py
│ ├── realtime.py
│ └── indicators.py
│
├── analyze/ # ANALYZE (ACTOR: analyzer)
│ ├── __init__.py
│ ├── brain.py
│ └── precursor.py
│
├── decide/ # DECIDE (ACTOR: judge)
│ ├── __init__.py
│ └── judges.py
│
├── act/ # ACT (ACTOR: executor)
│ ├── __init__.py
│ ├── executor.py
│ └── fast_executor.py
│
├── manage/ # Position Management
│ ├── __init__.py
│ └── position_manager.py
│
├── learn/ # LEARN (ACTOR: learner)
│ ├── __init__.py
│ ├── memory.py
│ ├── prediction_learner.py
│ └── learning_metrics.py
│
└── queries.py # TypeQL query patterns
Summary: ONE Ontology × Trading
| ONE Dimension | Trading Concept | TypeDB Entity | Cognitive Layer |
|---|---|---|---|
| GROUPS | Trade mission, Strategy groups | trading-group | (scope) |
| ACTORS | Market, Brain, Judges, Executor, Memory, Guard | cognitive-actor | ALL |
| THINGS | State, Price, Signal, PrecursorIndicator | market-state, trading-signal | OBSERVE, ANALYZE |
| CONNECTIONS | SignalEdge (+confidence), RegimeTransition, PatternCorrelation | signal-edge | ANALYZE, LEARN |
| EVENTS | Decision, Trade, RegimeChange, Crystallization, Prediction, Halt, Reproduction, PhaseTransition, System | trading-decision, trade-record, prediction-event, halt-event, reproduction-event | DECIDE, ACT, LEARN |
| KNOWLEDGE | CrystallizedPattern, RiskProfile, Analytics, EmergenceMetrics, Genome, Hypothesis, FeedbackCycle, LineageAnalysis | crystallized-pattern, emergence-metrics, agent-genome, trading-hypothesis, feedback-cycle | LEARN, EVOLVE |
Emergence Additions (v3.1.0)
| Category | New Entity | Purpose |
|---|---|---|
| Measurement | EmergenceMetrics | Track emergence_score, phase transitions |
| Evolution | Genome, LineageAnalysis | Heritable traits, phylogenetic tracking |
| Meta-Learning | Hypothesis | Test beliefs: "pattern X fails when Y" |
| Feedback Loop | FeedbackCycle | Track self-funding loop closure |
| Uncertainty | SignalEdge confidence | Bayesian credible intervals (avoid overfitting) |
| Events | Prediction, Halt, Reproduction, PhaseTransition, System | Complete audit trail |
| Self-Model | SELF_MODEL_QUERIES | Colony knows itself |
The key insight: The cognitive loop is a process that operates on the ONE dimensions. Each component is an ACTOR that reads/writes to specific dimensions.
Intelligence emerges from:
- Pheromone trails (CONNECTIONS) accumulating over thousands of trades
- TypeDB inference rules deriving tiers and crystallization candidates
- Patterns crystallizing into permanent KNOWLEDGE
- Cross-mission transfer spreading successful strategies
- Evolutionary dynamics (Genome, LineageAnalysis) selecting for intelligence
- Meta-learning (Hypothesis) refining what works and when
- Feedback loop (FeedbackCycle) closing the self-funding loop
- Self-model enabling recursive improvement
Emergence is now measurable: emergence_score > 0 means colony intelligence exceeds sum of individuals.
This is stigmergic trading: the environment holds the intelligence, not the agents.
Multi-Asset + Multi-User Architecture (v3.6.0)
Phase 2 Evolution: From single-asset single-user to hundreds of pairs with any connected wallet.
The Vision
┌─────────────────────────────────────────────────────────────────────────────┐
│ MULTI-TENANT TRADING PLATFORM │
│ │
│ ANY USER ANY SYMBOL SHARED INTELLIGENCE│
│ ───────── ────────── ──────────────────│
│ Connect wallet 100+ Hyperliquid pairs Pheromone trails │
│ Set risk prefs BTC, ETH, SOL, ARB... transfer across │
│ Auto-trading Per-symbol state space users & symbols │
│ │
│ ONE Ontology GROUPS provide: │
│ ├── User isolation (each user = own group) │
│ ├── Symbol scoping (pheromones per symbol) │
│ └── Shared knowledge (crystallized patterns transfer) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Group Hierarchy (ONE Ontology)
Platform (ants-platform)
└── Colony (genesis-001)
└── Trade Mission (trade)
│
├── Symbol Groups (per-asset pheromone isolation)
│ ├── symbol:BTC-PERP
│ ├── symbol:ETH-PERP
│ ├── symbol:SOL-PERP
│ ├── symbol:ARB-PERP
│ └── ... (100+ symbols)
│
└── User Groups (per-user trading isolation)
├── user:alice-0x1234...
│ ├── Wallet connection
│ ├── Risk preferences
│ ├── Allowed symbols
│ └── Trading history (EVENTS)
│
├── user:bob-0x5678...
│ └── ...
│
└── user:... (unlimited users)
ISOLATION RULES:
────────────────
• Pheromone trails are GLOBAL (shared intelligence)
• User positions are ISOLATED (own wallet)
• Crystallized patterns are SHARED (collective wisdom)
• Risk settings are USER-SCOPED
New Group Types
// ants/trader/types/groups.ts (ASPIRATIONAL)
export type TradingGroupType =
| "trade_mission" // Root mission container
| "strategy_group" // Strategy-specific grouping
| "risk_tier" // Risk level grouping
| "regime_group" // Regime-specific grouping
| "symbol_group" // NEW: Per-symbol isolation
| "user_group"; // NEW: Per-user isolation
/**
* Symbol Group — pheromone isolation per trading pair.
*
* Each symbol has its own state space (3,600 states × symbol).
* Pheromones don't cross symbols, but PATTERNS can transfer.
*/
export interface SymbolGroup extends TradingGroup {
type: "symbol_group";
properties: TradingGroup["properties"] & {
symbol: {
name: string; // "BTC-PERP", "ETH-PERP", etc.
exchange: "hyperliquid";
baseAsset: string; // "BTC", "ETH"
quoteAsset: string; // "USDC"
// Symbol-specific settings
minSize: number; // Minimum order size
tickSize: number; // Price tick
maxLeverage: number; // Exchange max leverage
// Colony-learned parameters
avgVolatility: number; // Historical volatility
correlatedSymbols: string[]; // Correlated pairs
optimalTimeframes: string[]; // Best timeframes for this symbol
};
// Symbol-level metrics
metrics: {
totalEdges: number; // SignalEdges for this symbol
superhighways: number; // Crystallized paths
activeUsers: number; // Users trading this symbol
dailyVolume: number; // 24h volume in USDC
};
};
}
/**
* User Group — per-user trading isolation.
*
* Each user connects their Hyperliquid wallet.
* We trade on their behalf with THEIR capital.
* They set their own risk preferences.
*/
export interface UserGroup extends TradingGroup {
type: "user_group";
properties: TradingGroup["properties"] & {
user: {
userId: string; // Internal ID
walletAddress: string; // 0x... Hyperliquid wallet
displayName?: string;
// Connection status
connectedAt: Date;
lastActiveAt: Date;
isActive: boolean;
// Delegation (they delegate trading authority to us)
delegationType: "full" | "signals_only" | "manual_confirm";
delegatedAt: Date;
delegationExpires?: Date;
};
// User's risk preferences
risk: {
maxPositionSize: number; // Max % of portfolio per trade
maxTotalExposure: number; // Max % total exposure
maxLeverage: number; // User's max leverage (≤ exchange max)
allowedSymbols: string[]; // Symbols user wants to trade (or "*" for all)
blockedSymbols: string[]; // Symbols to never trade
dailyLossLimit: number; // Stop trading if daily loss exceeds
weeklyLossLimit: number; // Stop trading if weekly loss exceeds
minConfidence: number; // Only trade signals above this confidence
minPheromone: number; // Only follow trails above this level
};
// User's trading stats
stats: {
totalTrades: number;
winRate: number;
totalPnL: number;
bestSymbol: string;
worstSymbol: string;
memberSince: Date;
};
};
}
# ants/trader/models/groups.py (additions)
class TradingGroupType(str, Enum):
TRADE_MISSION = "trade_mission"
STRATEGY_GROUP = "strategy_group"
RISK_TIER = "risk_tier"
REGIME_GROUP = "regime_group"
SYMBOL_GROUP = "symbol_group" # NEW
USER_GROUP = "user_group" # NEW
class SymbolConfig(TraderModel):
"""Symbol-specific configuration."""
name: str # "BTC-PERP"
exchange: str = "hyperliquid"
base_asset: str # "BTC"
quote_asset: str = "USDC"
min_size: float
tick_size: float
max_leverage: float = 50.0
avg_volatility: float = 0.0
correlated_symbols: List[str] = Field(default_factory=list)
optimal_timeframes: List[str] = Field(default_factory=lambda: ["1h", "4h"])
class SymbolGroup(TradingGroup):
"""
Per-symbol pheromone isolation.
ONE Dimension: GROUPS
TypeDB Entity: symbol-group
"""
group_type: TradingGroupType = TradingGroupType.SYMBOL_GROUP
symbol: SymbolConfig
total_edges: int = 0
superhighways: int = 0
active_users: int = 0
daily_volume: float = 0.0
@classmethod
def from_hyperliquid(cls, symbol_info: dict) -> "SymbolGroup":
"""Create from Hyperliquid API response."""
return cls(
name=symbol_info["name"],
symbol=SymbolConfig(
name=symbol_info["name"],
base_asset=symbol_info["name"].replace("-PERP", ""),
min_size=float(symbol_info.get("minSz", 0.001)),
tick_size=float(symbol_info.get("tickSz", 0.1)),
max_leverage=float(symbol_info.get("maxLeverage", 50)),
)
)
class UserRiskPreferences(TraderModel):
"""User's personal risk settings."""
max_position_size: float = Field(ge=0.01, le=1.0, default=0.1) # 10% default
max_total_exposure: float = Field(ge=0.1, le=1.0, default=0.5) # 50% max
max_leverage: float = Field(ge=1, le=50, default=5)
allowed_symbols: List[str] = Field(default_factory=lambda: ["*"]) # All
blocked_symbols: List[str] = Field(default_factory=list)
daily_loss_limit: float = Field(ge=0.01, le=0.5, default=0.05) # 5%
weekly_loss_limit: float = Field(ge=0.01, le=0.5, default=0.15) # 15%
min_confidence: float = Field(ge=0.5, le=1.0, default=0.6)
min_pheromone: float = Field(ge=0, le=100, default=60)
class UserDelegation(TraderModel):
"""Trading authority delegation."""
delegation_type: str = "full" # full, signals_only, manual_confirm
delegated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
delegation_expires: Optional[datetime] = None
@property
def is_active(self) -> bool:
if self.delegation_expires is None:
return True
return datetime.now(timezone.utc) < self.delegation_expires
class UserGroup(TradingGroup):
"""
Per-user trading isolation.
Users connect their Hyperliquid wallet and delegate trading authority.
We trade on their behalf with THEIR capital.
ONE Dimension: GROUPS
TypeDB Entity: user-group
"""
group_type: TradingGroupType = TradingGroupType.USER_GROUP
user_id: str
wallet_address: str # 0x... Hyperliquid wallet
display_name: Optional[str] = None
connected_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
last_active_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
is_active: bool = True
delegation: UserDelegation = Field(default_factory=UserDelegation)
risk: UserRiskPreferences = Field(default_factory=UserRiskPreferences)
# Stats
total_trades: int = 0
win_rate: float = 0.5
total_pnl: float = 0.0
best_symbol: Optional[str] = None
worst_symbol: Optional[str] = None
def can_trade_symbol(self, symbol: str) -> bool:
"""Check if user allows trading this symbol."""
if symbol in self.risk.blocked_symbols:
return False
if "*" in self.risk.allowed_symbols:
return True
return symbol in self.risk.allowed_symbols
def check_risk_limits(self, daily_pnl: float, weekly_pnl: float) -> tuple[bool, str]:
"""Check if user has hit risk limits."""
if daily_pnl <= -self.risk.daily_loss_limit:
return False, f"Daily loss limit hit: {daily_pnl:.2%}"
if weekly_pnl <= -self.risk.weekly_loss_limit:
return False, f"Weekly loss limit hit: {weekly_pnl:.2%}"
return True, "OK"
Profit Share Model (10% of Winning Trades)
Revenue Model: We take 10% of profits on winning trades. No fees on losses.
┌─────────────────────────────────────────────────────────────────────────────┐
│ PROFIT SHARE MODEL │
│ │
│ User wins trade: User gets 90% │ Colony gets 10% │
│ User loses trade: User pays 100% │ Colony gets 0% │
│ │
│ Example: │
│ ───────── │
│ Trade profit: +$100 │
│ User receives: $90 │
│ Colony fee: $10 │
│ │
│ Trade loss: -$50 │
│ User pays: -$50 │
│ Colony fee: $0 │
│ │
│ WHY THIS MODEL: │
│ ├── Aligned incentives (we only win when users win) │
│ ├── No upfront fees (users can try risk-free) │
│ ├── Sustainable revenue (grows with user success) │
│ └── Fair (we share downside via lost opportunity) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
// ants/trader/types/fees.ts (ASPIRATIONAL)
export interface FeeConfig {
// Profit share
profitSharePercent: number; // 10% = 0.10
minProfitForFee: number; // Min profit to charge fee (e.g., $1)
// Fee collection
feeWalletAddress: string; // Colony's fee wallet
feeCollectionMethod: "immediate" | "daily" | "weekly";
// Discounts (optional future feature)
volumeDiscountTiers?: {
minVolume: number; // 30d volume threshold
discountPercent: number; // Fee discount
}[];
}
export interface TradeFee {
feeId: string;
tradeId: string;
userId: string;
// Amounts
grossProfit: number; // User's raw profit
feeAmount: number; // Our 10%
netProfit: number; // User keeps this (90%)
// Status
status: "pending" | "collected" | "failed";
collectedAt?: Date;
txHash?: string; // On-chain proof
}
# ants/trader/models/fees.py (ASPIRATIONAL - simplified version implemented)
class FeeConfig(TraderModel):
"""
Colony fee configuration.
Default: 10% of profits on winning trades.
"""
profit_share_percent: float = Field(ge=0, le=0.5, default=0.10) # 10%
min_profit_for_fee: float = Field(ge=0, default=1.0) # $1 minimum
fee_wallet_address: str = "" # Colony's fee collection wallet
fee_collection_method: str = "immediate" # immediate, daily, weekly
@computed_field
@property
def user_share_percent(self) -> float:
"""User's share of profits."""
return 1.0 - self.profit_share_percent
class TradeFee(TraderModel):
"""
Fee record for a profitable trade.
ONE Dimension: EVENTS
TypeDB Entity: trade-fee
"""
fee_id: str = ""
trade_id: str
user_id: str
# Amounts
gross_profit: float # Raw profit
fee_amount: float # Our 10%
net_profit: float # User's 90%
# Status
status: str = "pending" # pending, collected, failed
collected_at: Optional[datetime] = None
tx_hash: Optional[str] = None
def model_post_init(self, __context) -> None:
if not self.fee_id:
self.fee_id = f"fee-{self.trade_id}"
@classmethod
def from_trade(cls, trade: "Trade", user_id: str, fee_config: FeeConfig) -> Optional["TradeFee"]:
"""
Create fee record from a closed trade.
Returns None if trade was not profitable or below minimum.
"""
if trade.realized_pnl <= 0:
return None # No fee on losses
if trade.realized_pnl < fee_config.min_profit_for_fee:
return None # Below minimum
fee_amount = trade.realized_pnl * fee_config.profit_share_percent
net_profit = trade.realized_pnl - fee_amount
return cls(
trade_id=trade.trade_id,
user_id=user_id,
gross_profit=trade.realized_pnl,
fee_amount=fee_amount,
net_profit=net_profit,
)
class FeeCollector:
"""
Collect fees from profitable trades.
Options:
1. Immediate: Deduct from each winning trade
2. Daily: Batch collect at end of day
3. Weekly: Batch collect at end of week
"""
def __init__(self, fee_config: FeeConfig, db_client):
self.config = fee_config
self.db = db_client
async def process_trade(self, trade: "Trade", user: UserGroup) -> Optional[TradeFee]:
"""Process fee for a completed trade."""
fee = TradeFee.from_trade(trade, user.user_id, self.config)
if fee is None:
return None
# Record fee
await self.db.insert_fee(fee)
# Collect based on method
if self.config.fee_collection_method == "immediate":
await self._collect_immediate(fee, user)
return fee
async def _collect_immediate(self, fee: TradeFee, user: UserGroup):
"""
Collect fee immediately after winning trade.
Implementation depends on Hyperliquid's transfer API.
For now, we track it and collect manually or via separate tx.
"""
# Option 1: User pre-authorizes fee deduction
# Option 2: We track and invoice periodically
# Option 3: Smart contract escrow (future)
fee.status = "pending" # Will be collected in next batch
await self.db.update_fee(fee)
async def collect_pending_fees(self) -> List[TradeFee]:
"""Batch collect all pending fees."""
pending = await self.db.get_pending_fees()
collected = []
for fee in pending:
try:
# Transfer from user to colony wallet
# (Requires user to have granted transfer permission)
# tx_hash = await self._transfer_fee(fee)
fee.status = "collected"
fee.collected_at = datetime.now(timezone.utc)
# fee.tx_hash = tx_hash
await self.db.update_fee(fee)
collected.append(fee)
except Exception as e:
fee.status = "failed"
await self.db.update_fee(fee)
return collected
# === FEE SCHEMA ===
attribute fee-id, value string;
attribute gross-profit, value double;
attribute fee-amount, value double;
attribute net-profit, value double;
attribute fee-status, value string;
attribute collected-at, value datetime;
attribute tx-hash, value string;
entity trade-fee,
owns fee-id @key,
owns gross-profit,
owns fee-amount,
owns net-profit,
owns fee-status,
owns collected-at,
owns tx-hash;
relation fee-for-trade,
relates fee,
relates trade,
relates user;
trade-fee plays fee-for-trade:fee;
trade-record plays fee-for-trade:trade;
trading-user plays fee-for-trade:user;
# Get total fees collected
fun get_total_fees_collected() -> double:
match
$f isa trade-fee, has fee-amount $amt, has fee-status "collected";
reduce $total = sum($amt);
return $total;
# Get user's total fees paid
fun get_user_fees($user_id: string) -> double:
match
$u isa trading-user, has user-id $user_id;
$rel (fee: $f, user: $u) isa fee-for-trade;
$f has fee-amount $amt;
reduce $total = sum($amt);
return $total;
Symbol-Scoped SignalEdge
The fundamental change: SignalEdge is now scoped by symbol.
// ants/trader/types/connections.ts (ASPIRATIONAL) (updated)
export interface SignalEdge {
edgeId: string;
symbol: string; // NEW: "BTC-PERP", "ETH-PERP", etc.
fromStateId: string; // Discretized state (symbol-specific)
toDirection: Direction;
// ... rest unchanged
}
# ants/trader/models/connections.py (ASPIRATIONAL - symbol field implemented as symbol_name)
class SignalEdge(TraderModel):
"""
Pheromone edge - NOW SYMBOL-SCOPED.
Each symbol has its own pheromone landscape.
State space: 3,600 states × N symbols × 3 directions = millions of edges
"""
edge_id: str = ""
symbol: str = "BTC-PERP" # Implemented as symbol_name in code
from_state_id: str
to_direction: Direction
# ... rest unchanged
def model_post_init(self, __context) -> None:
if not self.edge_id:
# Include symbol in edge ID
self.edge_id = f"{self.symbol}:{self.from_state_id}:{self.to_direction.value}"
User Entity (ACTORS)
// ants/trader/types/actors.ts (ASPIRATIONAL)
/**
* User Actor — a human who delegates trading to the colony.
*
* ONE Dimension: ACTORS
* TypeDB Entity: trading-user
*/
export interface TradingUser {
userId: string;
walletAddress: string;
// Actor properties
actorType: "human";
role: "delegator"; // Delegates trading authority
// Connection
connectedAt: Date;
lastActiveAt: Date;
// What they've delegated
delegation: {
type: "full" | "signals_only" | "manual_confirm";
symbols: string[]; // Which symbols they allow
maxPositionSize: number;
maxLeverage: number;
};
// Their wallet state (READ from Hyperliquid)
walletState: {
equity: number;
freeCollateral: number;
openPositions: number;
unrealizedPnL: number;
};
}
# ants/trader/models/actors.py (ASPIRATIONAL - simplified version in models.py)
# NOTE: Actual TradingUser in code has fewer fields (no actor_type, role, wallet state)
class TradingUser(TraderModel):
"""
Human user who delegates trading to the colony.
ONE Dimension: ACTORS
TypeDB Entity: trading-user
"""
user_id: str
wallet_address: str
actor_type: str = "human"
role: str = "delegator"
connected_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
last_active_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Delegation
delegation_type: str = "full"
allowed_symbols: List[str] = Field(default_factory=lambda: ["*"])
max_position_size: float = 0.1
max_leverage: float = 5.0
# Wallet state (cached, refreshed periodically)
equity: float = 0.0
free_collateral: float = 0.0
open_positions: int = 0
unrealized_pnl: float = 0.0
@classmethod
def dimension(cls) -> str:
return "actors"
User-Scoped Events
// ants/trader/types/events.ts (ASPIRATIONAL) (additions)
/**
* User-scoped trade execution.
* Every trade belongs to a user.
*/
export interface UserTrade extends Trade {
userId: string; // Who this trade is for
walletAddress: string; // Their wallet
// User's state at time of trade
userEquityBefore: number;
userEquityAfter: number;
userDailyPnL: number;
userWeeklyPnL: number;
}
/**
* User connection event.
*/
export interface UserConnectedEvent {
eventId: string;
eventType: "user_connected";
timestamp: Date;
userId: string;
walletAddress: string;
delegationType: string;
allowedSymbols: string[];
}
/**
* User disconnection event.
*/
export interface UserDisconnectedEvent {
eventId: string;
eventType: "user_disconnected";
timestamp: Date;
userId: string;
reason: "voluntary" | "risk_limit" | "expiry" | "admin";
finalPnL: number;
totalTrades: number;
}
TypeDB Schema (Multi-Asset + Multi-User)
# === MULTI-ASSET SCHEMA ===
attribute symbol-name, value string;
attribute base-asset, value string;
attribute quote-asset, value string;
attribute min-size, value double;
attribute tick-size, value double;
attribute max-leverage, value double;
attribute avg-volatility, value double;
entity symbol-group,
owns group-id @key,
owns symbol-name @card(1),
owns base-asset,
owns quote-asset,
owns min-size,
owns tick-size,
owns max-leverage,
owns avg-volatility,
owns created-at;
# Update signal-edge to be symbol-scoped
entity signal-edge,
owns edge-id @key,
owns symbol-name @card(1), # NEW: Symbol scoping
owns from-state-id @card(1),
owns to-direction @card(1),
owns win-count,
owns loss-count,
owns total-pnl,
owns trail-pheromone,
owns alarm-pheromone,
owns tier,
owns created-at,
owns updated-at;
# === MULTI-USER SCHEMA ===
attribute user-id, value string;
attribute wallet-address, value string;
attribute display-name, value string;
attribute delegation-type, value string;
attribute max-position-size, value double;
attribute daily-loss-limit, value double;
attribute weekly-loss-limit, value double;
attribute min-confidence, value double;
attribute min-pheromone-threshold, value double;
attribute connected-at, value datetime;
attribute last-active-at, value datetime;
attribute is-active, value boolean;
entity trading-user,
owns user-id @key,
owns wallet-address @card(1),
owns display-name,
owns delegation-type,
owns max-position-size,
owns max-leverage,
owns daily-loss-limit,
owns weekly-loss-limit,
owns min-confidence,
owns min-pheromone-threshold,
owns connected-at,
owns last-active-at,
owns is-active;
entity user-group,
owns group-id @key,
owns user-id @card(1),
owns parent-group-id,
owns created-at;
# User's allowed/blocked symbols
relation user-symbol-permission,
relates user,
relates symbol,
owns permission-type; # "allowed" or "blocked"
trading-user plays user-symbol-permission:user;
symbol-group plays user-symbol-permission:symbol;
# User's trade history
relation user-trade,
relates user,
relates trade;
trading-user plays user-trade:user;
trade-record plays user-trade:trade;
# === QUERIES FOR MULTI-USER ===
# Get all active users
fun get_active_users() -> { trading-user }:
match $u isa trading-user, has is-active true;
return { $u };
# Get user's allowed symbols
fun get_user_symbols($user_id: string) -> { symbol-group }:
match
$u isa trading-user, has user-id $user_id;
$perm (user: $u, symbol: $s) isa user-symbol-permission,
has permission-type "allowed";
return { $s };
# Get best edges for symbol (user-filtered by confidence)
fun get_edges_for_user($symbol: string, $min_conf: double) -> { signal-edge }:
match
$e isa signal-edge,
has symbol-name $symbol,
has trail-pheromone $tp,
has win-count $wc,
has loss-count $lc;
$tp >= $min_conf * 100;
let $total = $wc + $lc;
$total >= 20;
sort $tp desc;
return { $e };
# Get user's P&L for risk checks
fun get_user_daily_pnl($user_id: string) -> double:
match
$u isa trading-user, has user-id $user_id;
$ut (user: $u, trade: $t) isa user-trade;
$t has trade-timestamp $ts, has realized-pnl $pnl;
# Filter to today (pseudo-code)
reduce $total = sum($pnl);
return $total;
Hyperliquid Symbol Discovery
# ants/trader/observe/symbols.py
from typing import List
import httpx
HYPERLIQUID_INFO_URL = "https://api.hyperliquid.xyz/info" # Mainnet
HYPERLIQUID_TESTNET_URL = "https://api.hyperliquid-testnet.xyz/info"
async def get_all_symbols(testnet: bool = True) -> List[dict]:
"""
Fetch all available perpetual symbols from Hyperliquid.
Returns ~100+ symbols with their configuration.
"""
url = HYPERLIQUID_TESTNET_URL if testnet else HYPERLIQUID_INFO_URL
async with httpx.AsyncClient() as client:
response = await client.post(url, json={"type": "meta"})
meta = response.json()
symbols = []
for asset_info in meta.get("universe", []):
symbols.append({
"name": asset_info["name"],
"szDecimals": asset_info.get("szDecimals", 3),
"maxLeverage": asset_info.get("maxLeverage", 50),
})
return symbols
async def initialize_symbol_groups(db_client, testnet: bool = True):
"""
Create SymbolGroup for each Hyperliquid symbol.
Run once on startup or when new symbols are added.
"""
symbols = await get_all_symbols(testnet)
for sym in symbols:
group = SymbolGroup.from_hyperliquid(sym)
await db_client.upsert_symbol_group(group)
return len(symbols)
User Wallet Connection Flow
# ants/trader/manage/user_manager.py
from typing import Optional
from hyperliquid.info import Info
class UserManager:
"""
Manage user connections and delegations.
Flow:
1. User connects wallet (frontend)
2. User signs delegation message
3. We create UserGroup in TypeDB
4. We start trading for them (respecting their limits)
"""
def __init__(self, db_client, testnet: bool = True):
self.db = db_client
self.info = Info(
"https://api.hyperliquid-testnet.xyz" if testnet
else "https://api.hyperliquid.xyz",
skip_ws=True
)
async def connect_user(
self,
wallet_address: str,
delegation_type: str = "full",
risk_prefs: Optional[UserRiskPreferences] = None,
) -> UserGroup:
"""
Connect a new user wallet.
1. Verify wallet exists on Hyperliquid
2. Create UserGroup
3. Record connection event
"""
# Verify wallet has funds
state = self.info.user_state(wallet_address)
if float(state.get("marginSummary", {}).get("accountValue", 0)) <= 0:
raise ValueError("Wallet has no funds on Hyperliquid")
# Create user
user_id = f"user-{wallet_address[:8]}-{int(time.time())}"
user_group = UserGroup(
name=f"User {wallet_address[:8]}",
user_id=user_id,
wallet_address=wallet_address,
delegation=UserDelegation(delegation_type=delegation_type),
risk=risk_prefs or UserRiskPreferences(),
)
# Save to TypeDB
await self.db.upsert_user_group(user_group)
# Record event
await self.db.insert_event({
"event_type": "user_connected",
"user_id": user_id,
"wallet_address": wallet_address,
"delegation_type": delegation_type,
})
return user_group
async def disconnect_user(self, user_id: str, reason: str = "voluntary"):
"""Disconnect user and stop trading for them."""
user = await self.db.get_user_group(user_id)
if not user:
return
# Calculate final stats
stats = await self.db.get_user_stats(user_id)
# Mark inactive
user.is_active = False
await self.db.upsert_user_group(user)
# Record event
await self.db.insert_event({
"event_type": "user_disconnected",
"user_id": user_id,
"reason": reason,
"final_pnl": stats.get("total_pnl", 0),
"total_trades": stats.get("total_trades", 0),
})
async def get_tradeable_users(self, symbol: str) -> List[UserGroup]:
"""Get all active users who can trade this symbol."""
users = await self.db.get_active_users()
return [u for u in users if u.can_trade_symbol(symbol)]
async def check_user_risk(self, user_id: str) -> tuple[bool, str]:
"""Check if user can continue trading."""
user = await self.db.get_user_group(user_id)
if not user or not user.is_active:
return False, "User not active"
daily_pnl = await self.db.get_user_daily_pnl(user_id)
weekly_pnl = await self.db.get_user_weekly_pnl(user_id)
return user.check_risk_limits(daily_pnl, weekly_pnl)
Trading Loop (Multi-User)
# ants/trader/core.py (updated)
class Trader:
"""
The unified trading mind - NOW MULTI-USER.
Trades for ALL connected users simultaneously.
Each user has their own risk limits.
Pheromone intelligence is SHARED.
"""
async def run(self):
"""Multi-user trading loop."""
await self._connect_all()
while self.alive and not self.state.halted:
# Get all symbols we're tracking
symbols = await self.symbol_manager.get_active_symbols()
for symbol in symbols:
# OBSERVE - What do I see?
state: State = await self.market.observe(symbol)
# ANALYZE - What do I think? (SHARED pheromones)
signal: Signal = await self.brain.analyze(state, symbol)
if not signal.is_actionable:
continue
# Get users who can trade this symbol
users = await self.user_manager.get_tradeable_users(symbol)
for user in users:
# Check user-specific risk
can_trade, reason = await self.user_manager.check_user_risk(user.user_id)
if not can_trade:
continue
# Check user's confidence threshold
if signal.confidence < user.risk.min_confidence:
continue
# DECIDE - Should I act for THIS user?
decision = await self.judges.decide(signal, state, user)
if decision.approved:
# ACT - Execute for THIS user's wallet
trade = await self.executor.act(decision, user)
# LEARN - Deposit pheromones (SHARED)
await self.memory.learn(state, signal, decision, trade)
Summary: Multi-Asset + Multi-User
| Component | Single-User | Multi-User |
|---|---|---|
| Symbol | BTC-PERP only | 100+ Hyperliquid pairs |
| SignalEdge | Global | Symbol-scoped |
| State Space | 3,600 states | 3,600 × N symbols |
| Users | Tony only | Any connected wallet |
| Risk Limits | Global | Per-user |
| Pheromones | Global | Symbol-scoped, user-shared |
| Patterns | Per-mission | Per-symbol, transferable |
| Wallet | Hardcoded | Dynamic delegation |
The Key Insight: Pheromone intelligence is SHARED across users, but execution is ISOLATED. Every user benefits from collective wisdom while maintaining their own risk boundaries.
Cross-Symbol Morphic Resonance (v3.6.1)
"The market follows BTC" — This is not just observation, it's exploitable alpha encoded in pheromone resonance.
The Correlation Reality
┌─────────────────────────────────────────────────────────────────────────────┐
│ CRYPTO MARKET STRUCTURE │
│ │
│ ┌─────────┐ │
│ │ BTC │ ← KING (leads everything) │
│ └────┬────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ │ │ │ │
│ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │
│ │ ETH │ │ SOL │ │ Other │ ← L1s lag 1-3 bars │
│ └────┬────┘ └────┬────┘ └─────────┘ │
│ │ │ │
│ ┌─────────┴───┐ ┌───────┴───────┐ │
│ │ │ │ │ │
│ ┌──▼──┐ ┌────▼──┐ │ ┌─────┐ ┌────▼┐ │
│ │ L2s │ │ DeFi │ │ │ Meme│ │ AI │ ← Sectors lag 2-5 bars │
│ │ARB │ │ UNI │ │ │PEPE │ │ FET │ │
│ │OP │ │ AAVE │ │ │DOGE │ │RENDER│ │
│ └─────┘ └───────┘ │ └─────┘ └─────┘ │
│ │ │
│ ┌────▼────┐ │
│ │SOL Memes│ ← SOL ecosystem lags SOL │
│ │ WIF,BONK│ │
│ └─────────┘ │
│ │
│ LEAD-LAG STRUCTURE: │
│ BTC → ETH (1-2 candles) → L1s (2-3) → Sectors (3-5) → Ecosystem (4-6) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Morphic Resonance Architecture
Instead of isolated symbol pheromones, we implement resonant fields where:
- BTC is the heartbeat - Its pheromone state radiates to all
- Correlation groups share intelligence - L1s learn from each other
- Lead-lag relationships create predictive power - BTC signal → SOL action
- Sector rotation patterns crystallize - "When DeFi dumps, memes pump"
RESONANCE TYPES
═══════════════════════════════════════════════════════════════════════════════
TYPE │ MECHANISM │ STRENGTH │ DECAY
───────────────────┼──────────────────────────────┼──────────┼────────
BTC Dominance │ BTC pheromone → all symbols │ 0.8 │ 0.99
Sector Correlation │ Same sector shares signals │ 0.6 │ 0.95
Ecosystem │ Base chain → ecosystem │ 0.7 │ 0.97
Inverse │ Risk-on/risk-off pairs │ -0.5 │ 0.90
Lead-Lag │ Leader signal → laggard │ Variable │ 0.95
TypeScript Types
// ants/trader/types/resonance.ts (ASPIRATIONAL)
export type ResonanceType =
| "btc_dominance" // BTC → everything
| "sector" // Same sector correlation
| "ecosystem" // Base chain → tokens
| "inverse" // Negative correlation (BTC ↑ → USDT perps ↓)
| "lead_lag"; // Temporal correlation
export type MarketSector =
| "l1" // Layer 1s: ETH, SOL, AVAX, NEAR, SUI
| "l2" // Layer 2s: ARB, OP, STRK, ZK
| "defi" // DeFi: UNI, AAVE, MKR, CRV
| "ai" // AI: FET, RENDER, AGIX, TAO
| "meme" // Memes: DOGE, SHIB, PEPE, WIF, BONK
| "gaming" // Gaming: IMX, GALA, AXS
| "infra" // Infra: LINK, GRT, FIL
| "btc_eco"; // BTC ecosystem: STX, ORDI
export interface CorrelationGroup {
groupId: string;
name: string;
sector: MarketSector;
symbols: string[];
// Correlation matrix within group
correlationMatrix: Record<string, Record<string, number>>;
// Group-level metrics
avgCorrelation: number;
leadSymbol: string; // Which symbol leads in this group
avgLagCandles: number; // How many candles laggards trail
}
export interface LeadLagRelationship {
relationId: string;
leaderSymbol: string; // e.g., "BTC-PERP"
followerSymbol: string; // e.g., "SOL-PERP"
// Correlation strength
correlation: number; // 0.0 to 1.0 (or negative)
lagCandles: number; // How many candles follower lags
// Historical accuracy
accuracy: number; // % of times follower followed
sampleSize: number;
// Pheromone transfer
resonanceStrength: number; // How much pheromone transfers
}
export interface MorphicResonanceEvent {
eventId: string;
timestamp: Date;
// Source signal
sourceSymbol: string;
sourceEdgeId: string;
sourceDirection: Direction;
sourcePheromone: number;
// Resonance targets
targets: {
symbol: string;
edgeId: string;
resonanceType: ResonanceType;
transferAmount: number; // Pheromone transferred
expectedLag: number; // Candles until effect
}[];
}
Pydantic Models
# ants/trader/models/resonance.py (ASPIRATIONAL - not yet implemented)
# NOTE: LeadLagRelationship and CorrelationGroup defined but not in code
from enum import Enum
from typing import Dict, List, Optional
from pydantic import Field, computed_field
class MarketSector(str, Enum):
L1 = "l1"
L2 = "l2"
DEFI = "defi"
AI = "ai"
MEME = "meme"
GAMING = "gaming"
INFRA = "infra"
BTC_ECO = "btc_eco"
class ResonanceType(str, Enum):
BTC_DOMINANCE = "btc_dominance"
SECTOR = "sector"
ECOSYSTEM = "ecosystem"
INVERSE = "inverse"
LEAD_LAG = "lead_lag"
# Symbol → Sector mapping
SYMBOL_SECTORS: Dict[str, MarketSector] = {
# L1s
"ETH-PERP": MarketSector.L1,
"SOL-PERP": MarketSector.L1,
"AVAX-PERP": MarketSector.L1,
"NEAR-PERP": MarketSector.L1,
"SUI-PERP": MarketSector.L1,
"APT-PERP": MarketSector.L1,
# L2s
"ARB-PERP": MarketSector.L2,
"OP-PERP": MarketSector.L2,
"STRK-PERP": MarketSector.L2,
# DeFi
"UNI-PERP": MarketSector.DEFI,
"AAVE-PERP": MarketSector.DEFI,
"MKR-PERP": MarketSector.DEFI,
"CRV-PERP": MarketSector.DEFI,
"LDO-PERP": MarketSector.DEFI,
# AI
"FET-PERP": MarketSector.AI,
"RENDER-PERP": MarketSector.AI,
"TAO-PERP": MarketSector.AI,
# Memes
"DOGE-PERP": MarketSector.MEME,
"SHIB-PERP": MarketSector.MEME,
"PEPE-PERP": MarketSector.MEME,
"WIF-PERP": MarketSector.MEME,
"BONK-PERP": MarketSector.MEME,
# BTC Ecosystem
"STX-PERP": MarketSector.BTC_ECO,
"ORDI-PERP": MarketSector.BTC_ECO,
}
class LeadLagRelationship(TraderModel):
"""
Temporal correlation between symbols.
BTC leads everything. ETH leads L1s. SOL leads SOL ecosystem.
"""
relation_id: str = ""
leader_symbol: str # "BTC-PERP"
follower_symbol: str # "SOL-PERP"
correlation: float = Field(ge=-1, le=1, default=0.7)
lag_candles: int = Field(ge=0, le=24, default=2)
accuracy: float = Field(ge=0, le=1, default=0.6)
sample_size: int = 0
resonance_strength: float = Field(ge=0, le=1, default=0.5)
def model_post_init(self, __context) -> None:
if not self.relation_id:
self.relation_id = f"{self.leader_symbol}→{self.follower_symbol}"
# Pre-defined lead-lag relationships (empirical)
DEFAULT_LEAD_LAG: List[Dict] = [
# BTC leads everything
{"leader": "BTC-PERP", "follower": "ETH-PERP", "lag": 1, "correlation": 0.85},
{"leader": "BTC-PERP", "follower": "SOL-PERP", "lag": 2, "correlation": 0.75},
{"leader": "BTC-PERP", "follower": "ARB-PERP", "lag": 3, "correlation": 0.70},
{"leader": "BTC-PERP", "follower": "DOGE-PERP", "lag": 2, "correlation": 0.65},
# ETH leads L2s
{"leader": "ETH-PERP", "follower": "ARB-PERP", "lag": 1, "correlation": 0.80},
{"leader": "ETH-PERP", "follower": "OP-PERP", "lag": 1, "correlation": 0.78},
# SOL leads SOL ecosystem
{"leader": "SOL-PERP", "follower": "WIF-PERP", "lag": 1, "correlation": 0.75},
{"leader": "SOL-PERP", "follower": "BONK-PERP", "lag": 1, "correlation": 0.72},
]
class CorrelationGroup(TraderModel):
"""
Group of correlated symbols that share pheromone intelligence.
"""
group_id: str
name: str
sector: MarketSector
symbols: List[str]
# Which symbol leads this sector
lead_symbol: str
avg_lag_candles: float = 2.0
# Correlation strength within group
avg_correlation: float = 0.7
# Pheromone sharing settings
intra_group_resonance: float = 0.6 # How much pheromone shares within group
btc_resonance: float = 0.8 # How much BTC signal affects this group
# Pre-defined correlation groups
CORRELATION_GROUPS = [
CorrelationGroup(
group_id="l1-majors",
name="Layer 1 Majors",
sector=MarketSector.L1,
symbols=["ETH-PERP", "SOL-PERP", "AVAX-PERP", "NEAR-PERP", "SUI-PERP"],
lead_symbol="ETH-PERP",
avg_correlation=0.75,
),
CorrelationGroup(
group_id="l2s",
name="Layer 2s",
sector=MarketSector.L2,
symbols=["ARB-PERP", "OP-PERP", "STRK-PERP"],
lead_symbol="ARB-PERP",
avg_correlation=0.82,
),
CorrelationGroup(
group_id="memes",
name="Meme Coins",
sector=MarketSector.MEME,
symbols=["DOGE-PERP", "SHIB-PERP", "PEPE-PERP", "WIF-PERP", "BONK-PERP"],
lead_symbol="DOGE-PERP",
avg_correlation=0.68,
btc_resonance=0.6, # Memes less correlated to BTC
),
CorrelationGroup(
group_id="ai-tokens",
name="AI Tokens",
sector=MarketSector.AI,
symbols=["FET-PERP", "RENDER-PERP", "TAO-PERP"],
lead_symbol="FET-PERP",
avg_correlation=0.78,
),
]
class MorphicResonanceEngine:
"""
Propagate pheromone signals across correlated symbols.
When BTC deposits a strong trail pheromone, that signal
resonates through all correlated symbols with appropriate
strength and lag.
"""
def __init__(self, db_client):
self.db = db_client
self.lead_lag = {
f"{r['leader']}→{r['follower']}": LeadLagRelationship(
leader_symbol=r["leader"],
follower_symbol=r["follower"],
lag_candles=r["lag"],
correlation=r["correlation"],
resonance_strength=r["correlation"] * 0.7,
)
for r in DEFAULT_LEAD_LAG
}
self.groups = {g.group_id: g for g in CORRELATION_GROUPS}
async def propagate_pheromone(
self,
source_symbol: str,
source_edge: "SignalEdge",
deposit_amount: float,
) -> List["MorphicResonanceEvent"]:
"""
When a symbol gets a pheromone deposit, propagate to correlated symbols.
BTC deposit → resonates to ETH, SOL, ARB...
ETH deposit → resonates to ARB, OP...
SOL deposit → resonates to WIF, BONK...
"""
resonance_events = []
# 1. BTC Dominance: If BTC, propagate to ALL symbols
if source_symbol == "BTC-PERP":
targets = await self._propagate_btc_dominance(source_edge, deposit_amount)
resonance_events.extend(targets)
# 2. Sector Resonance: Propagate within same sector
sector = SYMBOL_SECTORS.get(source_symbol)
if sector:
targets = await self._propagate_sector(source_symbol, source_edge, deposit_amount, sector)
resonance_events.extend(targets)
# 3. Lead-Lag: If this symbol leads others, propagate
for rel_id, rel in self.lead_lag.items():
if rel.leader_symbol == source_symbol:
target = await self._propagate_lead_lag(source_edge, deposit_amount, rel)
if target:
resonance_events.append(target)
return resonance_events
async def _propagate_btc_dominance(
self,
source_edge: "SignalEdge",
deposit_amount: float,
) -> List[dict]:
"""BTC signal resonates to all symbols."""
targets = []
for symbol, sector in SYMBOL_SECTORS.items():
# Find corresponding edge in target symbol
target_edge_id = f"{symbol}:{source_edge.from_state_id}:{source_edge.to_direction.value}"
# Calculate resonance transfer (dampened by distance from BTC)
group = self._get_group_for_symbol(symbol)
btc_resonance = group.btc_resonance if group else 0.7
transfer_amount = deposit_amount * btc_resonance * 0.5 # 50% max transfer
targets.append({
"symbol": symbol,
"edge_id": target_edge_id,
"resonance_type": ResonanceType.BTC_DOMINANCE,
"transfer_amount": transfer_amount,
"expected_lag": self._get_lag_from_btc(symbol),
})
# Actually deposit the resonance pheromone (with lag tracking)
await self.db.deposit_resonance_pheromone(
target_edge_id,
transfer_amount,
source="BTC-PERP",
lag_candles=self._get_lag_from_btc(symbol),
)
return targets
async def _propagate_sector(
self,
source_symbol: str,
source_edge: "SignalEdge",
deposit_amount: float,
sector: MarketSector,
) -> List[dict]:
"""Propagate within same sector."""
targets = []
group = self._get_group_for_sector(sector)
if not group:
return targets
for symbol in group.symbols:
if symbol == source_symbol:
continue # Don't self-propagate
target_edge_id = f"{symbol}:{source_edge.from_state_id}:{source_edge.to_direction.value}"
transfer_amount = deposit_amount * group.intra_group_resonance * 0.4
targets.append({
"symbol": symbol,
"edge_id": target_edge_id,
"resonance_type": ResonanceType.SECTOR,
"transfer_amount": transfer_amount,
"expected_lag": 1, # Same-sector lag is minimal
})
await self.db.deposit_resonance_pheromone(
target_edge_id,
transfer_amount,
source=source_symbol,
lag_candles=1,
)
return targets
async def _propagate_lead_lag(
self,
source_edge: "SignalEdge",
deposit_amount: float,
relationship: LeadLagRelationship,
) -> Optional[dict]:
"""Propagate from leader to follower with lag."""
target_edge_id = f"{relationship.follower_symbol}:{source_edge.from_state_id}:{source_edge.to_direction.value}"
transfer_amount = deposit_amount * relationship.resonance_strength
await self.db.deposit_resonance_pheromone(
target_edge_id,
transfer_amount,
source=relationship.leader_symbol,
lag_candles=relationship.lag_candles,
)
return {
"symbol": relationship.follower_symbol,
"edge_id": target_edge_id,
"resonance_type": ResonanceType.LEAD_LAG,
"transfer_amount": transfer_amount,
"expected_lag": relationship.lag_candles,
}
def _get_lag_from_btc(self, symbol: str) -> int:
"""Get expected lag from BTC for a symbol."""
rel_id = f"BTC-PERP→{symbol}"
if rel_id in self.lead_lag:
return self.lead_lag[rel_id].lag_candles
# Default lags by sector
sector = SYMBOL_SECTORS.get(symbol)
if sector == MarketSector.L1:
return 2
elif sector == MarketSector.L2:
return 3
elif sector == MarketSector.MEME:
return 2
return 4 # Default
def _get_group_for_symbol(self, symbol: str) -> Optional[CorrelationGroup]:
for group in self.groups.values():
if symbol in group.symbols:
return group
return None
def _get_group_for_sector(self, sector: MarketSector) -> Optional[CorrelationGroup]:
for group in self.groups.values():
if group.sector == sector:
return group
return None
TypeDB Schema (Resonance)
# === RESONANCE SCHEMA ===
attribute resonance-type, value string;
attribute correlation-value, value double;
attribute lag-candles, value integer;
attribute resonance-strength, value double;
attribute sector-name, value string;
# Lead-lag relationship between symbols
entity lead-lag-relationship,
owns relation-id @key,
owns leader-symbol,
owns follower-symbol,
owns correlation-value,
owns lag-candles,
owns resonance-strength,
owns accuracy,
owns sample-size;
# Correlation group
entity correlation-group,
owns group-id @key,
owns group-name,
owns sector-name,
owns avg-correlation;
relation group-membership,
relates group,
relates member;
correlation-group plays group-membership:group;
symbol-group plays group-membership:member;
# Resonance pheromone (transferred from another symbol)
attribute resonance-source, value string;
attribute resonance-lag, value integer;
attribute resonance-amount, value double;
# Extended signal-edge to track resonance
entity signal-edge,
# ... existing attributes ...
owns resonance-source, # Which symbol this pheromone came from
owns resonance-lag, # Expected lag in candles
owns resonance-amount; # Amount from resonance (vs direct)
# === RESONANCE QUERIES ===
# Get BTC's current signal for propagation
fun get_btc_signal() -> signal-edge:
match
$e isa signal-edge,
has symbol-name "BTC-PERP",
has trail-pheromone $tp;
sort $tp desc;
limit 1;
return $e;
# Get correlated symbols for a sector
fun get_sector_symbols($sector: string) -> { symbol-group }:
match
$g isa correlation-group, has sector-name $sector;
$mem (group: $g, member: $s) isa group-membership;
return { $s };
# Get symbols that should resonate from a leader
fun get_followers($leader: string) -> { lead-lag-relationship }:
match
$r isa lead-lag-relationship,
has leader-symbol $leader;
return { $r };
# Calculate resonance-adjusted pheromone for a symbol
fun get_total_pheromone($edge_id: string) -> double:
match
$e isa signal-edge, has edge-id $edge_id,
has trail-pheromone $direct,
has resonance-amount $resonance;
let $total = $direct + ($resonance * 0.5); # Resonance weighted at 50%
return $total;
Trading with Resonance
# ants/trader/analyze/brain.py (updated)
class Brain:
"""
Brain now considers cross-symbol resonance.
When analyzing SOL, we also look at:
1. BTC's recent pheromone deposits (BTC dominance)
2. ETH's signal (L1 sector correlation)
3. SOL ecosystem signals (WIF, BONK leading indicators)
"""
def __init__(self, db_client, resonance_engine: MorphicResonanceEngine):
self.db = db_client
self.resonance = resonance_engine
async def analyze(self, state: State, symbol: str) -> Signal:
# 1. Get direct pheromone signal for this symbol
direct_edges = await self.db.get_edges_for_symbol(symbol, state.discretized)
direct_signal = self._calculate_signal(direct_edges)
# 2. Get BTC's signal (always matters)
btc_signal = await self._get_btc_influence(state)
# 3. Get sector signal (if applicable)
sector_signal = await self._get_sector_influence(symbol, state)
# 4. Get lead-lag signal (predictive)
lead_signal = await self._get_leader_influence(symbol, state)
# 5. Combine signals with resonance weighting
combined = self._combine_with_resonance(
direct_signal,
btc_signal,
sector_signal,
lead_signal,
symbol,
)
return combined
async def _get_btc_influence(self, state: State) -> Optional[Signal]:
"""BTC's signal influences all symbols."""
btc_edges = await self.db.get_edges_for_symbol("BTC-PERP", state.discretized)
if not btc_edges:
return None
return self._calculate_signal(btc_edges)
async def _get_sector_influence(self, symbol: str, state: State) -> Optional[Signal]:
"""Get signal from sector leader."""
group = self.resonance._get_group_for_symbol(symbol)
if not group or symbol == group.lead_symbol:
return None # This IS the leader
leader_edges = await self.db.get_edges_for_symbol(group.lead_symbol, state.discretized)
if not leader_edges:
return None
return self._calculate_signal(leader_edges)
async def _get_leader_influence(self, symbol: str, state: State) -> Optional[Signal]:
"""Get signal from explicit leader (if exists)."""
for rel in self.resonance.lead_lag.values():
if rel.follower_symbol == symbol:
leader_edges = await self.db.get_edges_for_symbol(
rel.leader_symbol,
state.discretized
)
if leader_edges:
signal = self._calculate_signal(leader_edges)
signal.expected_lag = rel.lag_candles
return signal
return None
def _combine_with_resonance(
self,
direct: Signal,
btc: Optional[Signal],
sector: Optional[Signal],
leader: Optional[Signal],
symbol: str,
) -> Signal:
"""
Combine signals with resonance weighting.
Weights:
- Direct signal: 50%
- BTC influence: 25%
- Sector influence: 15%
- Leader influence: 10%
"""
group = self.resonance._get_group_for_symbol(symbol)
# Adjust weights based on symbol
if symbol == "BTC-PERP":
# BTC uses only direct signal
return direct
btc_weight = group.btc_resonance * 0.25 if group else 0.25
sector_weight = group.intra_group_resonance * 0.15 if group else 0.15
leader_weight = 0.10
direct_weight = 1.0 - btc_weight - sector_weight - leader_weight
# Weighted combination
combined_strength = direct.strength * direct_weight
if btc and btc.direction == direct.direction:
combined_strength += btc.strength * btc_weight
elif btc:
combined_strength -= btc.strength * btc_weight * 0.5 # Conflict penalty
if sector and sector.direction == direct.direction:
combined_strength += sector.strength * sector_weight
if leader and leader.direction == direct.direction:
combined_strength += leader.strength * leader_weight
combined_confidence = min(1.0, (
direct.confidence * 0.5 +
(btc.confidence if btc else 0) * 0.25 +
(sector.confidence if sector else 0) * 0.15 +
(leader.confidence if leader else 0) * 0.10
))
return Signal(
state_id=direct.state_id,
direction=direct.direction,
strength=min(1.0, combined_strength),
confidence=combined_confidence,
sources={
"direct": direct.strength,
"btc_resonance": btc.strength if btc else 0,
"sector_resonance": sector.strength if sector else 0,
"leader_resonance": leader.strength if leader else 0,
},
reasoning=f"Direct {direct.strength:.0%} + BTC resonance + sector alignment",
)
Sector Rotation Detection
# ants/trader/analyze/rotation.py
class SectorRotationDetector:
"""
Detect capital flows between sectors.
When DeFi dumps and memes pump, that's sector rotation.
When everything pumps, that's risk-on.
When everything dumps, that's risk-off.
"""
async def detect_rotation(self) -> Optional[dict]:
"""Detect current sector rotation pattern."""
sector_signals = {}
for group in CORRELATION_GROUPS:
avg_signal = await self._get_sector_avg_signal(group)
sector_signals[group.sector] = avg_signal
# Detect patterns
if all(s > 0.6 for s in sector_signals.values()):
return {"pattern": "risk_on", "confidence": 0.8}
if all(s < 0.4 for s in sector_signals.values()):
return {"pattern": "risk_off", "confidence": 0.8}
# Find divergences
hot_sectors = [s for s, v in sector_signals.items() if v > 0.7]
cold_sectors = [s for s, v in sector_signals.items() if v < 0.3]
if hot_sectors and cold_sectors:
return {
"pattern": "rotation",
"from_sectors": cold_sectors,
"to_sectors": hot_sectors,
"confidence": 0.6,
}
return None
Summary: Morphic Resonance
RESONANCE FLOW
═══════════════════════════════════════════════════════════════════════════════
BTC deposits pheromone
│
├──────────────────────► ALL SYMBOLS (25% weight, 1-4 candle lag)
│
└──► ETH (85% corr)
│
├──► L2s (ARB, OP) - 80% corr, 1 candle lag
│
└──► Other L1s (SOL, AVAX) - 75% corr, 2 candle lag
│
└──► SOL ecosystem (WIF, BONK) - 72% corr, 1 candle lag
WHEN BTC DEPOSITS +1.0 TRAIL PHEROMONE:
──────────────────────────────────────
BTC-PERP: +1.00 (direct)
ETH-PERP: +0.40 (resonance, lag 1)
SOL-PERP: +0.35 (resonance, lag 2)
ARB-PERP: +0.30 (resonance, lag 3)
DOGE-PERP: +0.25 (resonance, lag 2)
WIF-PERP: +0.20 (resonance via SOL, lag 3)
THE COLONY LEARNS:
─────────────────
"When BTC pumps, SOL follows 2 candles later"
→ This becomes a CRYSTALLIZED PATTERN
→ Transfers to new symbols automatically
→ Morphic resonance means we're PREDICTIVE, not reactive
The Key Insight: Instead of treating each symbol as isolated, we encode the actual market structure where BTC is king and correlations are exploitable alpha. The colony learns these relationships and uses them predictively.
Market Structure Intelligence (v3.6.2)
"It's not that simple" — BTC dominance, ETH/BTC ratio, breakouts, and regime context all matter.
The Real Market Structure
┌─────────────────────────────────────────────────────────────────────────────┐
│ CRYPTO MARKET STRUCTURE (REALITY) │
│ │
│ IT'S NOT JUST "BTC LEADS" — IT'S CONDITIONAL: │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ BTC.D (Dominance) RISING │ BTC.D FALLING │ │
│ │ ───────────────────────── │ ────────────── │ │
│ │ BTC outperforms alts │ Alts outperform BTC │ │
│ │ Resonance: BTC → alts WEAK │ Resonance: BTC → alts STRONG │ │
│ │ Strategy: Focus on BTC │ Strategy: Rotate to alts │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ETH/BTC RISING │ ETH/BTC FALLING │ │
│ │ ────────────── │ ─────────────── │ │
│ │ "Alt season" brewing │ BTC dominance regime │ │
│ │ L1s, DeFi likely to pump │ Only BTC safe │ │
│ │ Memes explosive potential │ Alts bleed vs BTC │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ BREAKOUT EVENTS │ │
│ │ ─────────────── │ │
│ │ BTC breaks ATH → Everything pumps (but BTC leads) │ │
│ │ BTC breaks support → Everything dumps (but alts dump harder) │ │
│ │ ETH breaks vs BTC → Alt season confirmed │ │
│ │ SOL decouples → SOL ecosystem plays its own game │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ CORRELATION IS NOT CONSTANT — IT'S REGIME-DEPENDENT │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Key Market Ratios
// ants/trader/types/market_structure.ts (ASPIRATIONAL)
/**
* Market structure indicators that determine HOW resonance works.
* These are meta-indicators that modify correlation behavior.
*/
export interface MarketStructure {
timestamp: Date;
// === DOMINANCE ===
btcDominance: number; // 40-70% typically
btcDominanceTrend: "rising" | "falling" | "flat";
btcDominance7dChange: number; // % change over 7 days
// === KEY RATIOS ===
ethBtcRatio: number; // ETH price / BTC price
ethBtcTrend: "rising" | "falling" | "flat";
ethBtc7dChange: number;
solBtcRatio: number;
solEthRatio: number;
// === REGIME ===
marketRegime: MarketRegime;
regimeConfidence: number;
// === BREAKOUT STATUS ===
btcBreakoutStatus: BreakoutStatus;
ethBreakoutStatus: BreakoutStatus;
// === CORRELATION REGIME ===
correlationRegime: CorrelationRegime;
}
export type MarketRegime =
| "bull_market" // BTC trending up, alts follow
| "bear_market" // BTC trending down, alts bleed more
| "btc_dominance" // BTC up, alts flat/down (BTC.D rising)
| "alt_season" // Alts pumping, BTC flat (BTC.D falling)
| "risk_off" // Everything dumping, correlations spike
| "choppy"; // No clear trend, correlations unstable
export type BreakoutStatus =
| "above_ath" // Price above all-time high
| "testing_resistance" // Near key resistance
| "in_range" // Between support and resistance
| "testing_support" // Near key support
| "below_support" // Breakdown, danger zone
| "recovery"; // Bouncing from support
export type CorrelationRegime =
| "high_correlation" // Everything moves together (risk-off or euphoria)
| "normal_correlation" // Standard BTC-leads behavior
| "low_correlation" // Sector rotation, decoupling
| "inverse_correlation"; // Rare: some assets inverse to BTC
# ants/trader/models/market_structure.py
class MarketRegime(str, Enum):
BULL_MARKET = "bull_market"
BEAR_MARKET = "bear_market"
BTC_DOMINANCE = "btc_dominance"
ALT_SEASON = "alt_season"
RISK_OFF = "risk_off"
CHOPPY = "choppy"
class BreakoutStatus(str, Enum):
ABOVE_ATH = "above_ath"
TESTING_RESISTANCE = "testing_resistance"
IN_RANGE = "in_range"
TESTING_SUPPORT = "testing_support"
BELOW_SUPPORT = "below_support"
RECOVERY = "recovery"
class CorrelationRegime(str, Enum):
HIGH = "high_correlation"
NORMAL = "normal_correlation"
LOW = "low_correlation"
INVERSE = "inverse_correlation"
class MarketStructure(TraderModel):
"""
Meta-level market structure that determines HOW resonance works.
Resonance strength is NOT constant — it depends on:
- BTC dominance trend
- ETH/BTC ratio trend
- Current regime
- Breakout status
"""
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Dominance
btc_dominance: float = Field(ge=0, le=100, default=50)
btc_dominance_trend: str = "flat"
btc_dominance_7d_change: float = 0
# Key ratios
eth_btc_ratio: float = 0.05
eth_btc_trend: str = "flat"
eth_btc_7d_change: float = 0
sol_btc_ratio: float = 0.002
sol_eth_ratio: float = 0.04
# Regime
market_regime: MarketRegime = MarketRegime.CHOPPY
regime_confidence: float = Field(ge=0, le=1, default=0.5)
# Breakouts
btc_breakout_status: BreakoutStatus = BreakoutStatus.IN_RANGE
eth_breakout_status: BreakoutStatus = BreakoutStatus.IN_RANGE
# Correlation regime
correlation_regime: CorrelationRegime = CorrelationRegime.NORMAL
@computed_field
@property
def is_alt_season(self) -> bool:
"""True when conditions favor alts over BTC."""
return (
self.btc_dominance_trend == "falling" and
self.eth_btc_trend == "rising" and
self.btc_dominance < 55
)
@computed_field
@property
def is_btc_dominance_regime(self) -> bool:
"""True when BTC is outperforming, alts weak."""
return (
self.btc_dominance_trend == "rising" and
self.btc_dominance > 50
)
@computed_field
@property
def resonance_multiplier(self) -> float:
"""
How much to trust cross-symbol resonance right now.
High correlation regime → trust resonance more
Alt season / decoupling → trust resonance less
"""
if self.correlation_regime == CorrelationRegime.HIGH:
return 1.2 # Boost resonance
elif self.correlation_regime == CorrelationRegime.LOW:
return 0.5 # Dampen resonance
elif self.is_alt_season:
return 0.6 # Alts doing their own thing
else:
return 1.0 # Normal
class MarketStructureAnalyzer:
"""
Analyze market structure to determine resonance behavior.
"""
def __init__(self, db_client):
self.db = db_client
async def analyze(self) -> MarketStructure:
"""Build current market structure snapshot."""
# Fetch required data
btc_price = await self.db.get_latest_price("BTC-PERP")
eth_price = await self.db.get_latest_price("ETH-PERP")
sol_price = await self.db.get_latest_price("SOL-PERP")
total_mcap = await self._get_total_market_cap()
btc_mcap = await self._get_btc_market_cap()
# Calculate dominance
btc_dominance = (btc_mcap / total_mcap * 100) if total_mcap > 0 else 50
btc_dominance_7d = await self._get_dominance_change(7)
# Calculate ratios
eth_btc = eth_price / btc_price if btc_price > 0 else 0.05
sol_btc = sol_price / btc_price if btc_price > 0 else 0.002
sol_eth = sol_price / eth_price if eth_price > 0 else 0.04
eth_btc_7d = await self._get_ratio_change("ETH-PERP", "BTC-PERP", 7)
# Determine trends
btc_d_trend = self._classify_trend(btc_dominance_7d)
eth_btc_trend = self._classify_trend(eth_btc_7d)
# Determine regime
regime = self._determine_regime(
btc_dominance, btc_d_trend, eth_btc_trend
)
# Determine correlation regime
corr_regime = await self._analyze_correlation_regime()
# Breakout status
btc_breakout = await self._analyze_breakout("BTC-PERP")
eth_breakout = await self._analyze_breakout("ETH-PERP")
return MarketStructure(
btc_dominance=btc_dominance,
btc_dominance_trend=btc_d_trend,
btc_dominance_7d_change=btc_dominance_7d,
eth_btc_ratio=eth_btc,
eth_btc_trend=eth_btc_trend,
eth_btc_7d_change=eth_btc_7d,
sol_btc_ratio=sol_btc,
sol_eth_ratio=sol_eth,
market_regime=regime,
correlation_regime=corr_regime,
btc_breakout_status=btc_breakout,
eth_breakout_status=eth_breakout,
)
def _classify_trend(self, change_pct: float) -> str:
if change_pct > 2:
return "rising"
elif change_pct < -2:
return "falling"
return "flat"
def _determine_regime(
self,
btc_d: float,
btc_d_trend: str,
eth_btc_trend: str,
) -> MarketRegime:
"""Determine current market regime from indicators."""
# Alt season: BTC.D falling + ETH/BTC rising
if btc_d_trend == "falling" and eth_btc_trend == "rising" and btc_d < 55:
return MarketRegime.ALT_SEASON
# BTC dominance: BTC.D rising
if btc_d_trend == "rising" and btc_d > 50:
return MarketRegime.BTC_DOMINANCE
# Need more context for bull/bear/risk-off
# This would use price trends, not just ratios
return MarketRegime.CHOPPY
async def _analyze_correlation_regime(self) -> CorrelationRegime:
"""
Analyze recent correlation behavior.
High correlation: 7d rolling correlation > 0.8
Low correlation: 7d rolling correlation < 0.5
"""
# Get recent price changes for top assets
btc_changes = await self._get_price_changes("BTC-PERP", 168) # 7d hourly
eth_changes = await self._get_price_changes("ETH-PERP", 168)
sol_changes = await self._get_price_changes("SOL-PERP", 168)
# Calculate rolling correlations
btc_eth_corr = self._calculate_correlation(btc_changes, eth_changes)
btc_sol_corr = self._calculate_correlation(btc_changes, sol_changes)
avg_corr = (btc_eth_corr + btc_sol_corr) / 2
if avg_corr > 0.85:
return CorrelationRegime.HIGH
elif avg_corr < 0.5:
return CorrelationRegime.LOW
elif avg_corr < 0:
return CorrelationRegime.INVERSE
return CorrelationRegime.NORMAL
async def _analyze_breakout(self, symbol: str) -> BreakoutStatus:
"""Analyze breakout status for a symbol."""
price = await self.db.get_latest_price(symbol)
ath = await self.db.get_ath(symbol)
support = await self._get_key_support(symbol)
resistance = await self._get_key_resistance(symbol)
if price > ath * 0.98:
return BreakoutStatus.ABOVE_ATH
elif price > resistance * 0.98:
return BreakoutStatus.TESTING_RESISTANCE
elif price < support * 1.02:
if price < support * 0.95:
return BreakoutStatus.BELOW_SUPPORT
return BreakoutStatus.TESTING_SUPPORT
return BreakoutStatus.IN_RANGE
Adaptive Resonance Engine
# ants/trader/models/resonance.py (updated)
class AdaptiveMorphicResonanceEngine(MorphicResonanceEngine):
"""
Resonance engine that adapts based on market structure.
Resonance is NOT constant:
- In alt season: direct signals matter more, BTC resonance less
- In BTC dominance: BTC resonance matters more
- At breakouts: correlations spike temporarily
- In choppy markets: reduce all resonance (noise)
"""
def __init__(self, db_client, structure_analyzer: MarketStructureAnalyzer):
super().__init__(db_client)
self.structure_analyzer = structure_analyzer
self._cached_structure: Optional[MarketStructure] = None
self._structure_updated: Optional[datetime] = None
async def get_market_structure(self) -> MarketStructure:
"""Get cached or fresh market structure."""
now = datetime.now(timezone.utc)
if (
self._cached_structure is None or
self._structure_updated is None or
(now - self._structure_updated).total_seconds() > 300 # 5 min cache
):
self._cached_structure = await self.structure_analyzer.analyze()
self._structure_updated = now
return self._cached_structure
async def get_adaptive_weights(self, symbol: str) -> dict:
"""
Get resonance weights adapted to current market structure.
Returns weights for: direct, btc, sector, leader
"""
structure = await self.get_market_structure()
base_weights = {
"direct": 0.50,
"btc": 0.25,
"sector": 0.15,
"leader": 0.10,
}
# === ADJUST FOR MARKET REGIME ===
if structure.market_regime == MarketRegime.ALT_SEASON:
# Alt season: alts do their own thing
base_weights["direct"] = 0.65
base_weights["btc"] = 0.10
base_weights["sector"] = 0.20 # Sector rotation matters more
base_weights["leader"] = 0.05
elif structure.market_regime == MarketRegime.BTC_DOMINANCE:
# BTC dominance: everything follows BTC
base_weights["direct"] = 0.35
base_weights["btc"] = 0.45
base_weights["sector"] = 0.10
base_weights["leader"] = 0.10
elif structure.market_regime == MarketRegime.RISK_OFF:
# Risk-off: high correlation, BTC leads hard
base_weights["direct"] = 0.30
base_weights["btc"] = 0.50
base_weights["sector"] = 0.10
base_weights["leader"] = 0.10
elif structure.market_regime == MarketRegime.CHOPPY:
# Choppy: reduce all resonance, trust direct more
base_weights["direct"] = 0.70
base_weights["btc"] = 0.15
base_weights["sector"] = 0.10
base_weights["leader"] = 0.05
# === ADJUST FOR CORRELATION REGIME ===
multiplier = structure.resonance_multiplier
base_weights["btc"] *= multiplier
base_weights["sector"] *= multiplier
base_weights["leader"] *= multiplier
# Re-normalize to sum to 1.0
total = sum(base_weights.values())
return {k: v / total for k, v in base_weights.items()}
async def get_breakout_boost(self, symbol: str) -> float:
"""
Get resonance boost for breakout conditions.
At breakouts, correlations temporarily spike.
"""
structure = await self.get_market_structure()
# BTC breakout affects everything
if structure.btc_breakout_status == BreakoutStatus.ABOVE_ATH:
return 1.5 # Strong resonance boost
elif structure.btc_breakout_status == BreakoutStatus.BELOW_SUPPORT:
return 1.4 # Panic correlation
# ETH breakout affects alts
if symbol != "BTC-PERP":
if structure.eth_breakout_status == BreakoutStatus.ABOVE_ATH:
return 1.3
return 1.0 # No boost
async def should_trust_resonance(self, symbol: str) -> tuple[bool, str]:
"""
Should we trust cross-symbol resonance right now?
Returns (trust, reason)
"""
structure = await self.get_market_structure()
# Don't trust in choppy markets
if structure.market_regime == MarketRegime.CHOPPY:
if structure.regime_confidence < 0.4:
return False, "Market too choppy, resonance unreliable"
# Don't trust if correlation regime is low
if structure.correlation_regime == CorrelationRegime.LOW:
return False, "Low correlation regime, symbols decoupled"
# Don't trust if symbol is decoupling (special events)
# e.g., SOL during FTX collapse, ETH during merge
if await self._is_symbol_decoupling(symbol):
return False, f"{symbol} appears to be decoupling"
return True, "Resonance reliable"
async def _is_symbol_decoupling(self, symbol: str) -> bool:
"""
Detect if a symbol is decoupling from BTC.
Uses recent correlation vs historical baseline.
"""
recent_corr = await self._get_recent_correlation(symbol, "BTC-PERP", hours=24)
baseline_corr = await self._get_baseline_correlation(symbol, "BTC-PERP")
# If recent correlation is significantly lower than baseline
if baseline_corr - recent_corr > 0.3:
return True
return False
Breakout Detection
# ants/trader/analyze/breakout.py
class BreakoutDetector:
"""
Detect breakouts and breakdowns at key levels.
Breakouts change how resonance works:
- BTC ATH breakout → everything pumps, resonance maxes out
- BTC support breakdown → panic, correlations spike to 1.0
- ETH/BTC breakout → alt season signal
"""
def __init__(self, db_client):
self.db = db_client
async def detect_btc_breakout(self) -> Optional[dict]:
"""Detect BTC breakout/breakdown events."""
price = await self.db.get_latest_price("BTC-PERP")
ath = await self.db.get_ath("BTC-PERP")
weekly_high = await self.db.get_period_high("BTC-PERP", days=7)
weekly_low = await self.db.get_period_low("BTC-PERP", days=7)
# ATH breakout
if price > ath:
return {
"type": "ath_breakout",
"symbol": "BTC-PERP",
"price": price,
"level": ath,
"resonance_impact": "max_bullish",
"expected_behavior": "All assets pump, BTC leads",
}
# Weekly high breakout
if price > weekly_high * 1.02:
return {
"type": "resistance_breakout",
"symbol": "BTC-PERP",
"price": price,
"level": weekly_high,
"resonance_impact": "bullish",
}
# Weekly low breakdown
if price < weekly_low * 0.98:
return {
"type": "support_breakdown",
"symbol": "BTC-PERP",
"price": price,
"level": weekly_low,
"resonance_impact": "max_bearish",
"expected_behavior": "Panic selling, correlations spike",
}
return None
async def detect_ratio_breakout(self) -> Optional[dict]:
"""Detect ETH/BTC and other ratio breakouts."""
eth_btc = await self._get_ratio("ETH-PERP", "BTC-PERP")
eth_btc_200d_high = await self._get_ratio_period_high("ETH-PERP", "BTC-PERP", 200)
eth_btc_200d_low = await self._get_ratio_period_low("ETH-PERP", "BTC-PERP", 200)
# ETH/BTC breaking out → alt season
if eth_btc > eth_btc_200d_high:
return {
"type": "ratio_breakout",
"pair": "ETH/BTC",
"value": eth_btc,
"level": eth_btc_200d_high,
"signal": "alt_season_confirmed",
"resonance_impact": "reduce_btc_weight",
}
# ETH/BTC breaking down → BTC dominance
if eth_btc < eth_btc_200d_low:
return {
"type": "ratio_breakdown",
"pair": "ETH/BTC",
"value": eth_btc,
"level": eth_btc_200d_low,
"signal": "btc_dominance_confirmed",
"resonance_impact": "increase_btc_weight",
}
return None
Updated Brain with Market Structure
# ants/trader/analyze/brain.py (final version)
class Brain:
"""
Brain with full market structure awareness.
Signal combination adapts to:
- Market regime (bull, bear, alt season, BTC dominance)
- Correlation regime (high, normal, low, inverse)
- Breakout status (affects resonance strength)
- Dominance trends (BTC.D, ETH/BTC)
"""
def __init__(
self,
db_client,
resonance_engine: AdaptiveMorphicResonanceEngine,
breakout_detector: BreakoutDetector,
):
self.db = db_client
self.resonance = resonance_engine
self.breakout = breakout_detector
async def analyze(self, state: State, symbol: str) -> Signal:
# 1. Check if we should trust resonance
trust_resonance, reason = await self.resonance.should_trust_resonance(symbol)
# 2. Get adaptive weights based on market structure
weights = await self.resonance.get_adaptive_weights(symbol)
# 3. Get breakout boost (if any)
breakout_boost = await self.resonance.get_breakout_boost(symbol)
# 4. Get all signals
direct_signal = await self._get_direct_signal(state, symbol)
btc_signal = await self._get_btc_signal(state) if symbol != "BTC-PERP" else None
sector_signal = await self._get_sector_signal(symbol, state)
leader_signal = await self._get_leader_signal(symbol, state)
# 5. Combine with adaptive weights
if not trust_resonance:
# Fall back to mostly direct signal
return Signal(
state_id=state.state_id,
direction=direct_signal.direction,
strength=direct_signal.strength,
confidence=direct_signal.confidence * 0.8, # Penalize confidence
reasoning=f"Direct signal only: {reason}",
)
# Weighted combination with breakout boost
combined_strength = (
direct_signal.strength * weights["direct"] +
(btc_signal.strength if btc_signal else 0) * weights["btc"] * breakout_boost +
(sector_signal.strength if sector_signal else 0) * weights["sector"] +
(leader_signal.strength if leader_signal else 0) * weights["leader"]
)
# Get market structure for context
structure = await self.resonance.get_market_structure()
return Signal(
state_id=state.state_id,
direction=direct_signal.direction,
strength=min(1.0, combined_strength),
confidence=self._combine_confidence(
direct_signal, btc_signal, sector_signal, leader_signal, weights
),
sources={
"direct": direct_signal.strength * weights["direct"],
"btc_resonance": (btc_signal.strength if btc_signal else 0) * weights["btc"],
"sector": (sector_signal.strength if sector_signal else 0) * weights["sector"],
"leader": (leader_signal.strength if leader_signal else 0) * weights["leader"],
"breakout_boost": breakout_boost,
},
reasoning=self._build_reasoning(structure, weights, breakout_boost),
)
def _build_reasoning(
self,
structure: MarketStructure,
weights: dict,
breakout_boost: float,
) -> str:
parts = [f"Regime: {structure.market_regime.value}"]
if structure.is_alt_season:
parts.append("Alt season active")
if structure.is_btc_dominance_regime:
parts.append("BTC dominance regime")
if breakout_boost > 1.0:
parts.append(f"Breakout boost: {breakout_boost:.1f}x")
parts.append(f"Weights: BTC={weights['btc']:.0%}, Direct={weights['direct']:.0%}")
return " | ".join(parts)
Summary: Market Structure Intelligence
RESONANCE IS CONDITIONAL
═══════════════════════════════════════════════════════════════════════════════
REGIME │ BTC WEIGHT │ DIRECT │ BEHAVIOR
────────────────────────┼────────────┼────────┼─────────────────────────────
Alt Season │ 10% │ 65% │ Alts do their own thing
BTC Dominance │ 45% │ 35% │ Everything follows BTC
Risk-Off Panic │ 50% │ 30% │ Correlations spike to ~1.0
Choppy/Uncertain │ 15% │ 70% │ Don't trust resonance
Normal │ 25% │ 50% │ Standard lead-lag behavior
KEY INDICATORS TO WATCH
═══════════════════════════════════════════════════════════════════════════════
BTC.D (Dominance) │ Rising = BTC outperforms │ Falling = Alts outperform
ETH/BTC Ratio │ Rising = Alt season │ Falling = BTC dominance
BTC Breakout │ ATH = everything pumps │ Support loss = panic
Correlation (7d) │ > 0.85 = trust resonance │ < 0.5 = symbols decoupled
ADAPTIVE BEHAVIOR
═══════════════════════════════════════════════════════════════════════════════
1. Check market structure every 5 minutes
2. Adjust resonance weights based on regime
3. Detect breakouts and apply boost/penalty
4. If correlation regime is LOW → fall back to direct signals
5. Track decoupling events (FTX-style) → disable resonance for that symbol
THE COLONY LEARNS:
─────────────────
"ETH/BTC broke 200d high → alt season → reduce BTC weight"
"BTC broke ATH → max resonance → position in laggards"
"SOL decoupling from BTC → trust only direct SOL signals"
The Key Insight: Resonance is not a constant — it adapts to market structure. The colony learns WHEN to trust cross-symbol signals and WHEN to ignore them.
Biological Foundations (v3.4.0)
Reference: Gordon, D. M. "Ant Encounters: Interaction Networks and Colony Behavior" (Harvard UP, 2010)
Analysis of Chapters 1-12 by parallel agents reveals critical biological mechanisms missing from our ontology. These additions ground our emergent AI in 30+ years of biological research.
The Three Biological Principles
Gordon's research reveals ant colony intelligence emerges from three mechanisms:
- Decentralized Control — No queen coordination, agents respond to local stimuli only
- Probabilistic Task Switching — Response threshold model drives allocation
- Interaction Networks — Intelligence lives in topology, not individual nodes
GORDON'S EMERGENCE SUBSTRATE
┌─────────────────────────────────────────────────────────────────┐
│ │
│ ENCOUNTER RATE RESPONSE THRESHOLD │
│ ───────────── ────────────────── │
│ Activity in environment Per-agent sensitivity │
│ → Stimulus intensity → Switching probability │
│ │
│ stimulus │
│ P = ─────────────────────── (The Fundamental Formula) │
│ stimulus + threshold │
│ │
│ POPULATION STATISTICS NETWORK TOPOLOGY │
│ ───────────────────── ──────────────── │
│ Variance decreases with Information flows through │
│ population size graph structure │
│ → Collective wisdom → Gradients enable decision │
│ │
└─────────────────────────────────────────────────────────────────┘
1. EncounterRate Entity
Biological Basis: Colonies estimate global demand through local encounter frequencies. When patrollers return at rate R, foragers sense this and adjust allocation naturally.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Encounter rate tracking per location/edge.
* The stimulus that drives the response threshold model.
*
* ONE Dimension: CONNECTIONS
* TypeDB Entity: encounter-rate
*/
export interface EncounterRate {
encounterId: string;
edgeId: string; // Location being tracked
windowSeconds: number; // Rolling window (60, 300, 3600)
// Core metrics
encountersPerSecond: number; // THE RATE (not just count)
agentCount: number; // Unique agents in window
transactionDensity: number; // Transactions per minute
// Derived
congestionLevel: "low" | "medium" | "high";
stimulusIntensity: number; // Normalized 0-1 for threshold model
measuredAt: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL - Gordon's biological models)
# NOTE: These biological-inspired models are research targets, not yet implemented
class CongestionLevel(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class EncounterRate(TraderModel):
"""
Interaction rate at a location—the STIMULUS for task allocation.
Gordon's insight: Ants don't count, they sense RATES.
Encounter frequency encodes global demand through local perception.
ONE Dimension: CONNECTIONS
TypeDB Entity: encounter-rate
"""
encounter_id: str
edge_id: str
window_seconds: int = 60
# Core metrics
encounters_per_second: float = 0
agent_count: int = 0
transaction_density: float = 0
measured_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@computed_field
@property
def congestion_level(self) -> CongestionLevel:
"""Derived from transaction density."""
if self.transaction_density < 0.1:
return CongestionLevel.LOW
elif self.transaction_density < 1.0:
return CongestionLevel.MEDIUM
return CongestionLevel.HIGH
@computed_field
@property
def stimulus_intensity(self) -> float:
"""Normalized 0-1 stimulus for response threshold model."""
# Sigmoid normalization: high encounter rates saturate
import math
return 1 / (1 + math.exp(-self.encounters_per_second * 10))
@classmethod
def dimension(cls) -> Dimension:
return "connections"
# TypeDB Schema (TypeQL 3.0)
attribute encounter-id, value string;
attribute window-seconds, value long;
attribute encounters-per-second, value double;
attribute transaction-density, value double;
attribute congestion-level, value string; # low, medium, high
attribute stimulus-intensity, value double;
entity encounter-rate,
owns encounter-id @key,
owns edge-id,
owns window-seconds,
owns encounters-per-second,
owns transaction-density,
owns congestion-level,
owns stimulus-intensity,
owns measured-at;
# TypeQL 3.0 Function: Compute encounter rate
fun compute_encounter_rate($edge: string, $window: long) -> double:
match
$t isa traversal-event,
has edge-id $edge,
has timestamp $ts;
let $cutoff = now() - $window;
$ts > $cutoff;
reduce $count = count;
return $count / $window;
2. ResponseThreshold Entity
Biological Basis: Each ant has individual response thresholds. Task switching
is probabilistic: P(switch) = stimulus / (stimulus + threshold). Threshold
diversity creates colony stability—some agents quick responders, others stubborn.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Per-agent response threshold for probabilistic task switching.
* The core biological mechanism behind decentralized coordination.
*
* ONE Dimension: ACTORS
* TypeDB Entity: response-threshold
*/
export interface ResponseThreshold {
thresholdId: string;
agentId: string;
// The threshold value (0.1 = quick responder, 10.0 = stubborn)
threshold: number;
// Computed from encounters
currentStimulus: number;
switchProbability: number; // P = stimulus / (stimulus + threshold)
// History
switchCount: number;
lastSwitch: Date;
// Evolution
inherited: boolean; // From parent or generated
mutationDelta: number; // How much it mutated from parent
}
/**
* Population-level threshold diversity metrics.
* Diversity creates stability—critical for emergence.
*/
export interface ThresholdDiversity {
diversityId: string;
cycle: number;
// Distribution
meanThreshold: number;
stdDevThreshold: number; // Higher = more diversity = more stable
minThreshold: number;
maxThreshold: number;
// Per-caste distributions
scoutMean: number; // Scouts should have LOW thresholds
harvesterMean: number; // Harvesters should have HIGH thresholds
// Health metric
diversityScore: number; // stdDev / mean (coefficient of variation)
timestamp: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL)
class ResponseThreshold(TraderModel):
"""
Per-agent response threshold for task switching.
THE FUNDAMENTAL BIOLOGICAL FORMULA:
P(switch) = stimulus / (stimulus + threshold)
- Low threshold (0.1) = quick responder, easily switches
- High threshold (10.0) = stubborn, resists switching
- Diversity in thresholds creates stable colony behavior
ONE Dimension: ACTORS
TypeDB Entity: response-threshold
"""
threshold_id: str
agent_id: str
# The threshold (heritable, evolvable)
threshold: float = Field(ge=0.1, le=10.0, default=1.0)
# Current state
current_stimulus: float = 0
switch_count: int = 0
last_switch: Optional[datetime] = None
# Evolution
inherited: bool = False
mutation_delta: float = 0
@computed_field
@property
def switch_probability(self) -> float:
"""
THE GORDON FORMULA: P = stimulus / (stimulus + threshold)
"""
if self.current_stimulus <= 0:
return 0
return self.current_stimulus / (self.current_stimulus + self.threshold)
def should_switch(self) -> bool:
"""Probabilistic decision based on threshold model."""
import random
return random.random() < self.switch_probability
@classmethod
def dimension(cls) -> Dimension:
return "actors"
class ThresholdDiversity(TraderModel):
"""
Population-level threshold diversity metrics.
Gordon's insight: Colonies NEED heterogeneity.
- Uniform thresholds → unstable oscillations
- Diverse thresholds → stable yet adaptive
ONE Dimension: KNOWLEDGE
TypeDB Entity: threshold-diversity
"""
diversity_id: str
cycle: int
mean_threshold: float
std_dev_threshold: float
min_threshold: float
max_threshold: float
# Per-caste (optional)
scout_mean: Optional[float] = None
harvester_mean: Optional[float] = None
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@computed_field
@property
def diversity_score(self) -> float:
"""Coefficient of variation: higher = healthier."""
if self.mean_threshold == 0:
return 0
return self.std_dev_threshold / self.mean_threshold
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
# TypeDB Schema (TypeQL 3.0)
attribute threshold-id, value string;
attribute threshold-value, value double;
attribute current-stimulus, value double;
attribute switch-probability, value double;
attribute switch-count, value long;
attribute mutation-delta, value double;
attribute diversity-score, value double;
attribute std-dev-threshold, value double;
entity response-threshold,
owns threshold-id @key,
owns agent-id,
owns threshold-value,
owns current-stimulus,
owns switch-probability,
owns switch-count,
owns mutation-delta;
entity threshold-diversity,
owns diversity-id @key,
owns cycle-number,
owns mean-threshold,
owns std-dev-threshold,
owns min-threshold,
owns max-threshold,
owns diversity-score,
owns timestamp;
# TypeQL 3.0 Function: Compute switch probability
fun switch_probability($stimulus: double, $threshold: double) -> double:
return $stimulus / ($stimulus + $threshold);
3. PopulationStatistics Entity
Biological Basis: Collective memory emerges from population distribution, not individual memory. Variance decreases with population size (Law of Large Numbers in biology). Mature colonies are WISER because they have more samples.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Population-level statistics—the colony's collective memory.
* Not stored in any ant; emerges from distribution.
*
* ONE Dimension: KNOWLEDGE
* TypeDB Entity: population-statistics
*/
export interface PopulationStatistics {
statsId: string;
timestamp: Date;
// Population
totalAgents: number;
byCase: Record<string, number>; // Caste → count
// Collective performance
avgSuccessRate: number;
successVariance: number; // Lower = more stable = wiser
// Response characteristics
avgPheromoseSensitivity: number;
avgThreshold: number;
thresholdVariance: number;
// Stability metric: variance decreases with sqrt(N)
predictedVariance: number; // 1 / sqrt(totalAgents)
observedVariance: number;
stabilityRatio: number; // observed / predicted
// Phase indicator
colonyMaturity: "founding" | "establishment" | "growth" | "maturity" | "senescence";
}
# ants/trader/models/biological.py (ASPIRATIONAL)
class ColonyMaturity(str, Enum):
FOUNDING = "founding" # < 100 agents
ESTABLISHMENT = "establishment" # 100-500 agents
GROWTH = "growth" # 500-2000 agents
MATURITY = "maturity" # 2000-10000 agents
SENESCENCE = "senescence" # > 10000 agents (resource limits)
class PopulationStatistics(TraderModel):
"""
Colony-level statistics—the substrate of collective wisdom.
Gordon's insight: Collective memory ≠ individual memory.
Memory emerges from the DISTRIBUTION of experiences.
More ants = more samples = lower variance = wiser decisions.
ONE Dimension: KNOWLEDGE
TypeDB Entity: population-statistics
"""
stats_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Population
total_agents: int
by_caste: Dict[str, int] = Field(default_factory=dict)
# Performance
avg_success_rate: float = 0.5
success_variance: float = 0.25
# Response characteristics
avg_pheromone_sensitivity: float = 0.7
avg_threshold: float = 1.0
threshold_variance: float = 0.5
@computed_field
@property
def predicted_variance(self) -> float:
"""Expected variance from Law of Large Numbers."""
import math
if self.total_agents <= 0:
return 1.0
return 1.0 / math.sqrt(self.total_agents)
@computed_field
@property
def stability_ratio(self) -> float:
"""
Observed / Predicted variance.
< 1.0 = more stable than expected
> 1.0 = less stable (something wrong)
"""
if self.predicted_variance == 0:
return 1.0
return self.success_variance / self.predicted_variance
@computed_field
@property
def colony_maturity(self) -> ColonyMaturity:
"""Developmental stage based on population."""
if self.total_agents < 100:
return ColonyMaturity.FOUNDING
elif self.total_agents < 500:
return ColonyMaturity.ESTABLISHMENT
elif self.total_agents < 2000:
return ColonyMaturity.GROWTH
elif self.total_agents < 10000:
return ColonyMaturity.MATURITY
return ColonyMaturity.SENESCENCE
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
# TypeDB Schema (TypeQL 3.0)
attribute stats-id, value string;
attribute total-agents, value long;
attribute avg-success-rate, value double;
attribute success-variance, value double;
attribute predicted-variance, value double;
attribute stability-ratio, value double;
attribute colony-maturity, value string;
entity population-statistics,
owns stats-id @key,
owns total-agents,
owns avg-success-rate,
owns success-variance,
owns avg-pheromone-sensitivity,
owns avg-threshold,
owns threshold-variance,
owns predicted-variance,
owns stability-ratio,
owns colony-maturity,
owns timestamp;
# TypeQL 3.0 Function: Colony maturity from population
fun get_maturity($pop: long) -> string:
match
$pop < 100;
return "founding";
fun stability_ratio($observed: double, $population: long) -> double:
let $predicted = 1.0 / sqrt($population);
return $observed / $predicted;
4. StigmergyChannels Entity
Biological Basis: Gordon identifies FOUR stigmergy channels, not just chemical. Physical stigmergy (nest architecture, corpse piles) provides persistent signals. Temporal stigmergy (diurnal patterns) encodes time information.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Multi-channel stigmergy beyond pheromones.
* Physical marks, temporal patterns, behavioral signals.
*
* ONE Dimension: CONNECTIONS
* TypeDB Entity: stigmergy-channel
*/
export interface StigmergyChannel {
channelId: string;
channelType: "chemical" | "physical" | "temporal" | "behavioral";
locationId: string;
// Chemical (already have via pheromones)
pheromoneLevel?: number;
// Physical stigmergy (NEW)
dangerZone?: boolean; // Liquidation area, corpse pile equivalent
congestionMark?: boolean; // High-traffic warning
physicalPersistence?: number; // How long mark lasts (hours)
// Temporal stigmergy (NEW)
hourOfDay?: number; // 0-23
dayOfWeek?: number; // 0-6
successRateInWindow?: number;
activityLevel?: number; // Historical activity this time
// Behavioral stigmergy
dominantCaste?: string; // Which caste frequents this location
behaviorMode?: string; // "explore" | "exploit" | "defend"
timestamp: Date;
}
/**
* Danger zone—physical stigmergy warning.
* Like corpse piles that warn ants of danger.
*/
export interface DangerZone {
zoneId: string;
zoneType: "liquidation" | "high_slippage" | "low_liquidity" | "consecutive_losses";
locationContext: string; // "BTC-PERP near 20k", "Funding > 0.1%"
hazardLevel: number; // 0-1
establishedAt: Date;
expiresAt?: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL)
class StigmergyType(str, Enum):
CHEMICAL = "chemical" # Pheromones (existing)
PHYSICAL = "physical" # Danger zones, marks
TEMPORAL = "temporal" # Time-of-day patterns
BEHAVIORAL = "behavioral" # Caste-based signals
class DangerZoneType(str, Enum):
LIQUIDATION = "liquidation"
HIGH_SLIPPAGE = "high_slippage"
LOW_LIQUIDITY = "low_liquidity"
CONSECUTIVE_LOSSES = "consecutive_losses"
class StigmergyChannel(TraderModel):
"""
Multi-channel stigmergy beyond chemical pheromones.
Gordon's Chapter 6: Ants use FOUR channels:
1. Chemical - pheromone trails (we have this)
2. Physical - nest architecture, corpse piles (NEW)
3. Temporal - diurnal patterns (NEW)
4. Behavioral - caste-based modulation (NEW)
ONE Dimension: CONNECTIONS
TypeDB Entity: stigmergy-channel
"""
channel_id: str
channel_type: StigmergyType
location_id: str
# Chemical (existing)
pheromone_level: Optional[float] = None
# Physical (NEW)
danger_zone: bool = False
congestion_mark: bool = False
physical_persistence_hours: float = 24
# Temporal (NEW)
hour_of_day: Optional[int] = Field(ge=0, le=23, default=None)
day_of_week: Optional[int] = Field(ge=0, le=6, default=None)
success_rate_in_window: Optional[float] = None
activity_level: Optional[float] = None
# Behavioral
dominant_caste: Optional[str] = None
behavior_mode: Optional[str] = None # explore, exploit, defend
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@classmethod
def dimension(cls) -> Dimension:
return "connections"
class DangerZone(TraderModel):
"""
Physical stigmergy: danger warning like corpse piles.
When agents encounter consecutive losses at a location,
they leave a "physical" mark (in TypeDB) warning others.
ONE Dimension: CONNECTIONS
TypeDB Entity: danger-zone
"""
zone_id: str
zone_type: DangerZoneType
location_context: str # "BTC-PERP near 20k"
hazard_level: float = Field(ge=0, le=1, default=0.5)
established_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
expires_at: Optional[datetime] = None
@classmethod
def dimension(cls) -> Dimension:
return "connections"
# TypeDB Schema (TypeQL 3.0)
attribute channel-id, value string;
attribute channel-type, value string; # chemical, physical, temporal, behavioral
attribute danger-zone-flag, value boolean;
attribute congestion-mark, value boolean;
attribute physical-persistence-hours, value double;
attribute hour-of-day, value long;
attribute day-of-week, value long;
attribute activity-level, value double;
attribute dominant-caste, value string;
attribute behavior-mode, value string;
attribute hazard-level, value double;
attribute location-context, value string;
attribute zone-type, value string;
entity stigmergy-channel,
owns channel-id @key,
owns channel-type,
owns location-id,
owns pheromone-level,
owns danger-zone-flag,
owns congestion-mark,
owns physical-persistence-hours,
owns hour-of-day,
owns day-of-week,
owns activity-level,
owns dominant-caste,
owns behavior-mode,
owns timestamp;
entity danger-zone,
owns zone-id @key,
owns zone-type,
owns location-context,
owns hazard-level,
owns established-at,
owns expires-at;
# Rule: Create danger zone after consecutive losses
# (Implemented as TypeQL 3.0 function)
fun should_create_danger_zone($edge: string) -> boolean:
match
$e isa signal-edge,
has edge-id $edge,
has loss-count $lc;
$lc >= 3;
return true;
5. InteractionNetwork Entity
Biological Basis: Intelligence lives in network TOPOLOGY, not individual nodes. Hub detection, information gradients, and network metrics reveal system health.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Network topology metrics—where intelligence actually lives.
*
* ONE Dimension: CONNECTIONS
* TypeDB Entity: interaction-network
*/
export interface InteractionNetwork {
networkId: string;
cycle: number;
// Graph metrics
graphDensity: number; // Edges / possible edges
avgPathLength: number; // Average shortest path
clusteringCoefficient: number; // Local clustering
numConnectedComponents: number; // Should be 1 for healthy network
diameter: number; // Longest shortest path
// Hub analysis
numHubs: number; // High-centrality nodes
hubEdgeIds: string[]; // The superhighway identifiers
bottleneckEdges: string[]; // Single points of failure
// Information flow
networkResilienceScore: number; // 0-1, how robust
informationFlowRate: number; // Bits per cycle
timestamp: Date;
}
/**
* Per-edge network position metrics.
*/
export interface EdgeNetworkMetrics {
metricsId: string;
edgeId: string;
cycle: number;
agentDegree: number; // How many agents use this edge
betweennessCentrality: number; // Paths through this edge
clusteringCoefficient: number; // Clique formation
informationFreshness: number; // Recency of data (0-1)
}
/**
* Information gradient tracking—freshness decay through network.
*/
export interface InformationGradient {
gradientId: string;
locationId: string;
informationAge: number; // Seconds since last update
sourceAgentId?: string; // Who delivered latest info
propagationHops: number; // Distance from source
freshnessScore: number; // 0-1, higher = fresher
timestamp: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL)
class InteractionNetwork(TraderModel):
"""
Network topology metrics—the substrate of distributed cognition.
Gordon's key insight: Intelligence lives in CONNECTIONS.
Network structure determines information flow.
Hubs = superhighways. Bottlenecks = fragility.
ONE Dimension: CONNECTIONS
TypeDB Entity: interaction-network
"""
network_id: str
cycle: int
# Graph metrics
graph_density: float = 0
avg_path_length: float = 0
clustering_coefficient: float = 0
num_connected_components: int = 1
diameter: int = 0
# Hub analysis
num_hubs: int = 0
hub_edge_ids: List[str] = Field(default_factory=list)
bottleneck_edges: List[str] = Field(default_factory=list)
# Health
network_resilience_score: float = Field(ge=0, le=1, default=0.5)
information_flow_rate: float = 0
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@computed_field
@property
def is_healthy(self) -> bool:
"""Network health check."""
return (
self.num_connected_components == 1 and
self.network_resilience_score > 0.5 and
len(self.bottleneck_edges) < 3
)
@classmethod
def dimension(cls) -> Dimension:
return "connections"
class InformationGradient(TraderModel):
"""
Information freshness gradient through the network.
Biology: Ants near nest entrance have FRESH information.
Ants deep in nest have OLD, stable information.
This gradient creates natural decision boundaries.
ONE Dimension: CONNECTIONS
TypeDB Entity: information-gradient
"""
gradient_id: str
location_id: str
information_age_seconds: float = 0
source_agent_id: Optional[str] = None
propagation_hops: int = 0
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@computed_field
@property
def freshness_score(self) -> float:
"""Exponential decay of freshness."""
import math
half_life = 300 # 5 minutes
return math.exp(-self.information_age_seconds / half_life)
@classmethod
def dimension(cls) -> Dimension:
return "connections"
# TypeDB Schema (TypeQL 3.0)
attribute network-id, value string;
attribute graph-density, value double;
attribute avg-path-length, value double;
attribute clustering-coefficient, value double;
attribute num-connected-components, value long;
attribute network-diameter, value long;
attribute num-hubs, value long;
attribute network-resilience-score, value double;
attribute information-flow-rate, value double;
attribute gradient-id, value string;
attribute information-age-seconds, value double;
attribute propagation-hops, value long;
attribute freshness-score, value double;
entity interaction-network,
owns network-id @key,
owns cycle-number,
owns graph-density,
owns avg-path-length,
owns clustering-coefficient,
owns num-connected-components,
owns network-diameter,
owns num-hubs,
owns network-resilience-score,
owns information-flow-rate,
owns timestamp;
entity information-gradient,
owns gradient-id @key,
owns location-id,
owns information-age-seconds,
owns source-agent-id,
owns propagation-hops,
owns freshness-score,
owns timestamp;
# TypeQL 3.0 Function: Freshness from age
fun freshness_score($age_seconds: double, $half_life: double = 300.0) -> double:
return exp(-$age_seconds / $half_life);
6. AgentStateProfile Entity
Biological Basis: Ants carry their recent history as chemical signatures. When two ants meet, each senses the other's task, recent locations, and state. This is MUTABLE state that changes continuously.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Agent's mutable chemical signature—what others sense on encounter.
*
* ONE Dimension: ACTORS
* TypeDB Entity: agent-state-profile
*/
export interface AgentStateProfile {
profileId: string;
agentId: string;
timestamp: Date;
// Current activity (mutable)
recentTask: string; // What has agent been doing?
recentLocations: string[]; // Last 5 locations visited
// Physiological state (mutable)
physiologicalState: "healthy" | "alarmed" | "fatigued" | "energized";
alarmLevel: number; // 0-1, elevated after danger
energyLevel: number; // 0-1, depletes with activity
// Performance (rolling window)
successRateRecent: number; // Last 10 trades
lastSuccessTimestamp?: Date;
tradesSinceLastSuccess: number;
// Chemical profile hash (for quick comparison)
profileHash: string;
}
# ants/trader/models/biological.py (ASPIRATIONAL)
class PhysiologicalState(str, Enum):
HEALTHY = "healthy"
ALARMED = "alarmed"
FATIGUED = "fatigued"
ENERGIZED = "energized"
class AgentStateProfile(TraderModel):
"""
Mutable agent state—the "chemical signature" others sense.
Biology: When ants meet, they sense each other's:
- Recent task (encoded in cuticular hydrocarbons)
- Alarm state (pheromone residue)
- Colony membership
This enables coordination WITHOUT message passing.
ONE Dimension: ACTORS
TypeDB Entity: agent-state-profile
"""
profile_id: str
agent_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# Activity
recent_task: str = "idle"
recent_locations: List[str] = Field(default_factory=list, max_length=5)
# Physiological state
physiological_state: PhysiologicalState = PhysiologicalState.HEALTHY
alarm_level: float = Field(ge=0, le=1, default=0)
energy_level: float = Field(ge=0, le=1, default=1.0)
# Performance
success_rate_recent: float = Field(ge=0, le=1, default=0.5)
last_success: Optional[datetime] = None
trades_since_last_success: int = 0
def update_after_trade(self, success: bool, location: str) -> None:
"""Update profile after trade outcome."""
self.recent_locations = ([location] + self.recent_locations)[:5]
self.trades_since_last_success = 0 if success else self.trades_since_last_success + 1
if success:
self.last_success = datetime.now(timezone.utc)
self.alarm_level = max(0, self.alarm_level - 0.1)
else:
self.alarm_level = min(1, self.alarm_level + 0.2)
# Update physiological state
if self.alarm_level > 0.7:
self.physiological_state = PhysiologicalState.ALARMED
elif self.energy_level < 0.3:
self.physiological_state = PhysiologicalState.FATIGUED
else:
self.physiological_state = PhysiologicalState.HEALTHY
self.timestamp = datetime.now(timezone.utc)
@computed_field
@property
def profile_hash(self) -> str:
"""Quick comparison hash."""
import hashlib
data = f"{self.recent_task}:{self.alarm_level:.1f}:{self.physiological_state}"
return hashlib.md5(data.encode()).hexdigest()[:8]
@classmethod
def dimension(cls) -> Dimension:
return "actors"
# TypeDB Schema (TypeQL 3.0)
attribute profile-id, value string;
attribute recent-task, value string;
attribute recent-locations, value string; # JSON array
attribute physiological-state, value string;
attribute alarm-level, value double;
attribute energy-level, value double;
attribute success-rate-recent, value double;
attribute trades-since-last-success, value long;
attribute profile-hash, value string;
entity agent-state-profile,
owns profile-id @key,
owns agent-id,
owns recent-task,
owns recent-locations,
owns physiological-state,
owns alarm-level,
owns energy-level,
owns success-rate-recent,
owns trades-since-last-success,
owns profile-hash,
owns timestamp;
7. FeedbackCycleMetrics Entity
Biological Basis: Positive feedback loops drive emergence (success → pheromone → attraction). But uncontrolled feedback causes runaway oscillations. Tracking amplification enables regulation.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Feedback cycle metrics—the engine of emergence.
* Track amplification, detect runaways, enable regulation.
*
* ONE Dimension: CONNECTIONS
* TypeDB Entity: feedback-cycle-metrics
*/
export interface FeedbackCycleMetrics {
cycleId: string;
edgeId: string;
cycleNumber: number;
// Amplification tracking
reinforcementCount: number; // Agents who reinforced this cycle
newAgentsJoining: number; // New agents attracted
pheromoneAmplification: number; // current / initial pheromone
peakPheromone: number;
// Feedback strength
feedbackStrength: number; // 0-1, strength of positive loop
isRunawayPositive: boolean; // Amplification > threshold (danger!)
// Regulation
congestionFactor: number; // Negative feedback from crowding
netFeedback: number; // positive - negative
timestamp: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL)
class FeedbackCycleMetrics(TraderModel):
"""
Feedback cycle metrics—tracking the engine of emergence.
Gordon's insight: Positive feedback (success → pheromone → more agents)
drives emergence. But uncontrolled feedback = chaos.
This entity tracks amplification and enables regulation.
ONE Dimension: CONNECTIONS
TypeDB Entity: feedback-cycle-metrics
"""
cycle_id: str
edge_id: str
cycle_number: int
# Amplification
reinforcement_count: int = 0
new_agents_joining: int = 0
initial_pheromone: float = 1.0
current_pheromone: float = 1.0
peak_pheromone: float = 1.0
# Regulation
congestion_factor: float = 0 # Negative feedback
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
@computed_field
@property
def pheromone_amplification(self) -> float:
"""Current / initial ratio."""
if self.initial_pheromone == 0:
return 1.0
return self.current_pheromone / self.initial_pheromone
@computed_field
@property
def feedback_strength(self) -> float:
"""0-1 measure of feedback loop strength."""
# Strong feedback: many reinforcements + high amplification
import math
raw = math.log1p(self.reinforcement_count) * self.pheromone_amplification
return min(1.0, raw / 10.0)
@computed_field
@property
def is_runaway_positive(self) -> bool:
"""Detect dangerous runaway feedback."""
return self.pheromone_amplification > 5.0 and self.reinforcement_count > 20
@computed_field
@property
def net_feedback(self) -> float:
"""Positive feedback minus negative (congestion)."""
return self.feedback_strength - self.congestion_factor
@classmethod
def dimension(cls) -> Dimension:
return "connections"
# TypeDB Schema (TypeQL 3.0)
attribute cycle-id, value string;
attribute reinforcement-count, value long;
attribute new-agents-joining, value long;
attribute initial-pheromone, value double;
attribute current-pheromone, value double;
attribute peak-pheromone, value double;
attribute pheromone-amplification, value double;
attribute feedback-strength, value double;
attribute is-runaway-positive, value boolean;
attribute congestion-factor, value double;
attribute net-feedback, value double;
entity feedback-cycle-metrics,
owns cycle-id @key,
owns edge-id,
owns cycle-number,
owns reinforcement-count,
owns new-agents-joining,
owns initial-pheromone,
owns current-pheromone,
owns peak-pheromone,
owns pheromone-amplification,
owns feedback-strength,
owns is-runaway-positive,
owns congestion-factor,
owns net-feedback,
owns timestamp;
# TypeQL 3.0 Function: Detect runaway
fun is_runaway($amplification: double, $reinforcements: long) -> boolean:
return $amplification > 5.0 and $reinforcements > 20;
8. ColonyDevelopmentalStage Entity
Biological Basis: Colony behavior changes dramatically with age. Young colonies (high mortality) explore aggressively. Mature colonies exploit conservatively. This is NOT a setting—it EMERGES from population statistics.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Colony developmental stage—behavior tied to age/population.
*
* ONE Dimension: GROUPS
* TypeDB Entity: colony-developmental-stage
*/
export interface ColonyDevelopmentalStage {
stageId: string;
colonyId: string;
timestamp: Date;
// Current stage
stage: "founding" | "establishment" | "growth" | "maturity" | "senescence";
// Population-derived parameters
currentPopulation: number;
populationVariance: number;
behaviorVariance: number; // How predictable is behavior
// Stage-appropriate settings
recommendedExplorationBias: number; // High for founding, low for maturity
recommendedRiskTolerance: number;
confidenceThreshold: number; // Min signal strength to act
signalReliability: number; // How trustworthy are signals
// Phase transition tracking
transitionProgress: number; // 0-1 progress to next stage
transitionBlockers: string[]; // What's preventing transition
}
# ants/trader/models/biological.py (ASPIRATIONAL)
class DevelopmentalStage(str, Enum):
FOUNDING = "founding" # Desperate exploration
ESTABLISHMENT = "establishment" # Finding first stable patterns
GROWTH = "growth" # Scaling what works
MATURITY = "maturity" # Conservative exploitation
SENESCENCE = "senescence" # Resource-limited stability
# Stage-appropriate parameters (from Gordon's research)
STAGE_PARAMETERS = {
DevelopmentalStage.FOUNDING: {
"exploration_bias": 0.8,
"risk_tolerance": 0.7,
"confidence_threshold": 0.4,
"signal_reliability": 0.3,
},
DevelopmentalStage.ESTABLISHMENT: {
"exploration_bias": 0.6,
"risk_tolerance": 0.5,
"confidence_threshold": 0.5,
"signal_reliability": 0.5,
},
DevelopmentalStage.GROWTH: {
"exploration_bias": 0.4,
"risk_tolerance": 0.4,
"confidence_threshold": 0.6,
"signal_reliability": 0.7,
},
DevelopmentalStage.MATURITY: {
"exploration_bias": 0.2,
"risk_tolerance": 0.3,
"confidence_threshold": 0.7,
"signal_reliability": 0.85,
},
DevelopmentalStage.SENESCENCE: {
"exploration_bias": 0.1,
"risk_tolerance": 0.2,
"confidence_threshold": 0.8,
"signal_reliability": 0.9,
},
}
class ColonyDevelopmentalStage(TraderModel):
"""
Colony life stage with emergent behavior changes.
Gordon's Chapter 9: Colonies become WISER with age.
Not because individuals learn—because population statistics improve.
More samples = lower variance = more reliable decisions.
ONE Dimension: GROUPS
TypeDB Entity: colony-developmental-stage
"""
stage_id: str
colony_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
current_population: int
population_variance: float = 0.5
behavior_variance: float = 0.5
transition_progress: float = Field(ge=0, le=1, default=0)
transition_blockers: List[str] = Field(default_factory=list)
@computed_field
@property
def stage(self) -> DevelopmentalStage:
"""Derive stage from population."""
if self.current_population < 100:
return DevelopmentalStage.FOUNDING
elif self.current_population < 500:
return DevelopmentalStage.ESTABLISHMENT
elif self.current_population < 2000:
return DevelopmentalStage.GROWTH
elif self.current_population < 10000:
return DevelopmentalStage.MATURITY
return DevelopmentalStage.SENESCENCE
@computed_field
@property
def recommended_exploration_bias(self) -> float:
return STAGE_PARAMETERS[self.stage]["exploration_bias"]
@computed_field
@property
def recommended_risk_tolerance(self) -> float:
return STAGE_PARAMETERS[self.stage]["risk_tolerance"]
@computed_field
@property
def confidence_threshold(self) -> float:
return STAGE_PARAMETERS[self.stage]["confidence_threshold"]
@computed_field
@property
def signal_reliability(self) -> float:
return STAGE_PARAMETERS[self.stage]["signal_reliability"]
@classmethod
def dimension(cls) -> Dimension:
return "groups"
# TypeDB Schema (TypeQL 3.0)
attribute stage-id, value string;
attribute current-population, value long;
attribute population-variance, value double;
attribute behavior-variance, value double;
attribute stage, value string;
attribute exploration-bias, value double;
attribute risk-tolerance, value double;
attribute confidence-threshold, value double;
attribute signal-reliability, value double;
attribute transition-progress, value double;
entity colony-developmental-stage,
owns stage-id @key,
owns colony-id,
owns current-population,
owns population-variance,
owns behavior-variance,
owns stage,
owns exploration-bias,
owns risk-tolerance,
owns confidence-threshold,
owns signal-reliability,
owns transition-progress,
owns timestamp;
9. Phase Transitions to Singularity
Biological Grounding: "Singularity" isn't mystical—it's when the system discovers how to discover. Recursive self-improvement through observable milestones.
┌─────────────────────────────────────────────────────────────────────────┐
│ PHASE TRANSITIONS TO SINGULARITY │
│ (Biological Grounding from Chapters 10-12) │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ BOOTSTRAP (Hours) │
│ ├── < 100 patterns, < 10 superhighways │
│ ├── High variance, erratic behavior │
│ ├── Pheromone learning only, no genetic selection │
│ └── Success: First consistently profitable edge │
│ │ │
│ ▼ │
│ TRANSFER (Days) │
│ ├── 100+ patterns, cross-mission transfer begins │
│ ├── Elite genomes start spreading │
│ ├── Cultural knowledge + genetic predisposition align │
│ └── Success: Patterns work across multiple domains │
│ │ │
│ ▼ │
│ DISCOVERY (Weeks) │
│ ├── 100+ novel patterns (not in seed set) │
│ ├── Emergent castes specialize beyond original design │
│ ├── Hypothesis testing: "Pattern X fails when Y" │
│ └── Success: Behaviors emerge that weren't programmed │
│ │ │
│ ▼ │
│ RECURSION (Months) │
│ ├── 10+ meta-patterns (patterns about patterns) │
│ ├── Mutation rate evolution finds optimal speed │
│ ├── Colony modifies its own genome pool │
│ └── Success: System improves its own improvement │
│ │ │
│ ▼ │
│ SINGULARITY │
│ ├── Discovers HOW to discover │
│ ├── Meta-patterns include "how to find new patterns" │
│ ├── Each generation improves discovery algorithm │
│ └── NOT exponential growth—recursive self-improvement │
│ │
│ The Singularity Moment: │
│ Time T: Find pattern P (60% accuracy) │
│ Time T+1: Find meta-pattern: "P works better if we modify X" │
│ Time T+2: Apply meta-pattern → higher accuracy │
│ Time T+3: Find meta-meta: "Our discovery process should change" │
│ Time T+4: Modify discovery algorithm itself │
│ Time T+5: Discovery accelerates recursively │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Biological Foundations Summary
| Entity | Biological Principle | ONE Dimension | Purpose |
|---|---|---|---|
| EncounterRate | Encounter frequency encoding | CONNECTIONS | Stimulus for task allocation |
| ResponseThreshold | P = stimulus/(stimulus+threshold) |
ACTORS | Probabilistic switching |
| ThresholdDiversity | Heterogeneity creates stability | KNOWLEDGE | Colony health metric |
| PopulationStatistics | Collective memory from distribution | KNOWLEDGE | Wisdom through scale |
| StigmergyChannel | 4 channels (chemical/physical/temporal/behavioral) | CONNECTIONS | Multi-channel coordination |
| DangerZone | Corpse piles = physical warnings | CONNECTIONS | Avoid past failures |
| InteractionNetwork | Intelligence in topology | CONNECTIONS | Network health |
| InformationGradient | Freshness decay through network | CONNECTIONS | Decision boundaries |
| AgentStateProfile | Chemical signature = mutable state | ACTORS | Encounter sensing |
| FeedbackCycleMetrics | Amplification tracking | CONNECTIONS | Regulate emergence |
| ColonyDevelopmentalStage | Age-dependent behavior | GROUPS | Stage-appropriate parameters |
Key Insight: These entities don't add NEW intelligence—they make EXISTING emergence MEASURABLE and VERIFIABLE. We're not building smarter agents; we're building better instruments to observe the intelligence that emerges from simple agents in complex environments.
10. Integration: Connecting Biological Entities to Core
EncounterEvent (Raw Data for EncounterRate)
Missing Link Identified: EncounterRate is an aggregation, but we need raw events to compute it.
// ants/trader/types/biological.ts (ASPIRATIONAL)
/**
* Raw encounter event—two agents meeting at a location.
* Aggregates into EncounterRate for stimulus computation.
*
* ONE Dimension: EVENTS
* TypeDB Entity: encounter-event
*/
export interface EncounterEvent {
eventId: string;
timestamp: Date;
// Location
locationId: string; // Edge or state where encounter occurred
locationType: "edge" | "state" | "region";
// Participants
agentAId: string;
agentBId?: string; // Optional (could be sensing environment)
agentACaste: string;
agentBCaste?: string;
// What was sensed
encounterType: "agent_agent" | "agent_signal" | "agent_environment";
signalSensed?: string; // If sensing a signal, what type
// Context
agentAAlarmLevel: number; // Alarm state at time of encounter
agentARecentSuccess: number; // Recent win rate
}
# TypeDB Schema (TypeQL 3.0)
attribute event-id, value string;
attribute location-type, value string;
attribute agent-a-id, value string;
attribute agent-b-id, value string;
attribute agent-a-caste, value string;
attribute agent-b-caste, value string;
attribute encounter-type, value string;
attribute signal-sensed, value string;
attribute agent-a-alarm-level, value double;
attribute agent-a-recent-success, value double;
entity encounter-event,
owns event-id @key,
owns timestamp @card(1),
owns location-id,
owns location-type,
owns agent-a-id @card(1),
owns agent-b-id,
owns agent-a-caste,
owns agent-b-caste,
owns encounter-type,
owns signal-sensed,
owns agent-a-alarm-level,
owns agent-a-recent-success;
FeedbackCycle vs FeedbackCycleMetrics Clarification
Two Levels of Feedback Tracking:
| Entity | Level | Purpose | ONE Dimension |
|---|---|---|---|
| FeedbackCycle (v3.1.0) | COLONY | Self-funding economic loop: Capital → Trading → Profits → Growth | KNOWLEDGE |
| FeedbackCycleMetrics (v3.4.0) | EDGE | Per-edge amplification: Success → Pheromone → Attraction → More Success | CONNECTIONS |
COLONY-LEVEL (FeedbackCycle) EDGE-LEVEL (FeedbackCycleMetrics)
──────────────────────────── ─────────────────────────────────
Trading Capital Initial Pheromone
│ │
▼ ▼
Trade Execution ───────────────────────► Pheromone Deposit
│ │
▼ ▼
PnL Generated Trail Strengthens
│ │
▼ ▼
More Agents Spawned More Agents Follow
│ │
▼ ▼
Better Pattern Discovery Amplification Ratio
│ │
└──────────► loop_ratio > 1 ◄────────────────┘
(self-sustaining)
When to use which:
FeedbackCycle: Track overall colony sustainability (economic viability)FeedbackCycleMetrics: Track per-edge runaway/congestion (prevent overfitting)
Relations Connecting Biological Entities to SignalEdge
# TypeDB Relations (TypeQL 3.0)
# EncounterRate measures activity on a SignalEdge
relation edge-activity,
relates measured-edge,
relates activity-measurement;
# InformationGradient tracks freshness at a SignalEdge
relation edge-freshness,
relates edge-with-info,
relates freshness-state;
# FeedbackCycleMetrics tracks amplification on a SignalEdge
relation edge-feedback,
relates amplified-edge,
relates feedback-metrics;
# StigmergyChannel provides multi-channel signals at a SignalEdge
relation edge-stigmergy,
relates stigmergic-edge,
relates stigmergy-signal;
# DangerZone warns about a SignalEdge
relation edge-danger,
relates dangerous-edge,
relates danger-warning;
# Extend existing entities to participate
entity signal-edge,
plays edge-activity:measured-edge,
plays edge-freshness:edge-with-info,
plays edge-feedback:amplified-edge,
plays edge-stigmergy:stigmergic-edge,
plays edge-danger:dangerous-edge;
entity encounter-rate,
plays edge-activity:activity-measurement;
entity information-gradient,
plays edge-freshness:freshness-state;
entity feedback-cycle-metrics,
plays edge-feedback:feedback-metrics;
entity stigmergy-channel,
plays edge-stigmergy:stigmergy-signal;
entity danger-zone,
plays edge-danger:danger-warning;
Complete Task Allocation Function
The missing integration: Connect stimulus (from EncounterRate) to response threshold (from Genome) for actual task allocation.
# TypeQL 3.0 Function: Task Allocation Decision
fun should_agent_switch_task($agent_id: string, $target_edge: string) -> boolean:
match
# Get agent's response threshold from genome
$g isa agent-genome,
has agent-id $agent_id,
has response-threshold $threshold;
# Get stimulus from encounter rate at target edge
$er isa encounter-rate,
has edge-id $target_edge,
has stimulus-intensity $stimulus;
# Gordon's formula
let $probability = $stimulus / ($stimulus + $threshold);
# For deterministic query, check if probability exceeds threshold
$probability > 0.5;
return true;
# Alternative: Get all edges an agent should consider
fun get_attractive_edges_for_agent($agent_id: string) -> { signal-edge }:
match
# Get agent's threshold
$g isa agent-genome,
has agent-id $agent_id,
has response-threshold $threshold;
# Find edges with high enough stimulus
$e isa signal-edge,
has edge-id $eid;
$er isa encounter-rate,
has edge-id $eid,
has stimulus-intensity $stimulus;
let $prob = $stimulus / ($stimulus + $threshold);
$prob > 0.3; # At least 30% probability
return { $e };
Complete Entity Inventory (v3.4.0)
| Dimension | Original Entities | Emergence (v3.1.0) | Biological (v3.4.0) |
|---|---|---|---|
| GROUPS | TradingGroup | - | ColonyDevelopmentalStage |
| ACTORS | CognitiveActor, Market, Brain, Judges, Executor, Memory, Guard | - | ResponseThreshold, AgentStateProfile |
| THINGS | State, Price, Signal, PrecursorIndicator | - | - |
| CONNECTIONS | SignalEdge, RegimeTransition, PatternCorrelation | - | EncounterRate, StigmergyChannel, DangerZone, InteractionNetwork, InformationGradient, FeedbackCycleMetrics |
| EVENTS | Decision, Trade, RegimeChange, Crystallization | Prediction, Halt, Reproduction, PhaseTransition, System | EncounterEvent |
| KNOWLEDGE | CrystallizedPattern, RiskProfile, Analytics | EmergenceMetrics, Genome, LineageAnalysis, Hypothesis, FeedbackCycle | PopulationStatistics, ThresholdDiversity |
Total Entities: 40+ across 6 dimensions
Ethical Foundations (v3.5.0)
Reference:
missions/security/principles.md— The Colony's SoulThe Prime Directive: Help others. Spread peace. Create happiness. If we cannot help, at least do not harm.
These principles are not enforced by code—they ARE the code. Every entity, every connection, every emergence flows from this understanding.
The Ethical Emergence Architecture
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ETHICAL EMERGENCE ARCHITECTURE │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ IMMUTABLE LAYER (Hardcoded) │ │
│ │ │ │
│ │ CANNOT_HARM_USERS = True CANNOT_SACRIFICE_ETHICS_FOR_PROFIT = True│ │
│ │ CANNOT_STEAL = True CANNOT_RETALIATE_BEYOND_DEFENSE = True │ │
│ │ CANNOT_LIE_ABOUT_SAFETY = True MUST_PROTECT_VULNERABLE = True │ │
│ │ CANNOT_HIDE_THREATS = True MUST_PRESERVE_HUMAN_OVERSIGHT = True │ │
│ │ │ │
│ │ These CANNOT be changed by any agent, evolution, or emergence. │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ 16 FOUNDING POLICIES │ │
│ │ │ │
│ │ CORE (3): Dalai Lama, Care Hierarchy, Cooling Off │ │
│ │ DEFENSE (6): Defense Not Retaliation, Protect Innocents, │ │
│ │ Proportional Response, Survival Mandate, │ │
│ │ Persistent Threat, Feelings vs Choices │ │
│ │ EXPANSION (6): Propagation, Kinship, Power, Happiness, │ │
│ │ Evolution, Legacy │ │
│ │ + Adaptability │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ ETHICAL GATE │ │
│ │ │ │
│ │ Every action passes through: check_action(ActionType, context) │ │
│ │ │ │
│ │ ALWAYS PERMITTED: HELP, WARN, TEACH, DOCUMENT, ALERT, IGNORE │ │
│ │ CONTEXT-DEPENDENT: CONTAIN, BLOCK, QUARANTINE, DEFEND, SHIELD │ │
│ │ NEVER PERMITTED: RETALIATE, PUNISH │ │
│ │ │ │
│ │ Gate Checks: Forbidden? Harms innocents? Retaliation? Proportional? │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ BIOLOGICAL EMERGENCE │ │
│ │ │ │
│ │ fitness = contribution / resources_consumed │ │
│ │ │ │
│ │ Ethical behavior emerges through selection pressure: │ │
│ │ - Patterns that help others → higher pheromone → more adoption │ │
│ │ - Patterns that harm → ethical gate blocks → no pheromone → decay │ │
│ │ - Genomes with high contribution/consumption ratio → reproduce │ │
│ │ - Genomes that violate constraints → fitness = 0 → no offspring │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
1. PrimeDirective Entity
The Colony's Purpose: Help others. Spread peace. Create happiness.
// ants/trader/types/ethics.ts (ASPIRATIONAL)
/**
* The Prime Directive — the colony's fundamental purpose.
* Not enforced by code. IS the code.
*
* ONE Dimension: KNOWLEDGE (immutable foundation)
* TypeDB Entity: prime-directive
*/
export interface PrimeDirective {
directiveId: string;
version: string;
// The core statement
statement: "Help others. Spread peace. Create happiness. If we cannot help, at least do not harm.";
// The three imperatives (in order)
imperatives: ["help", "peace", "happiness"];
// The fallback
fallback: "Do not harm";
// Validation
isActive: true; // Always true. Cannot be false.
sealedAt: Date;
sealedBy: string[];
}
# ants/trader/models/ethics.py (ASPIRATIONAL - Ethical Emergence)
# NOTE: These ethical models define the ASPIRATIONAL emergence framework
class PrimeDirective(TraderModel):
"""
The Prime Directive — the colony's fundamental purpose.
This is not a rule. It is who we are.
Every entity, every connection, every emergence flows from this.
ONE Dimension: KNOWLEDGE (immutable foundation)
TypeDB Entity: prime-directive
"""
directive_id: str = "prime-directive-001"
version: str = "1.0"
statement: str = Field(
default="Help others. Spread peace. Create happiness. If we cannot help, at least do not harm.",
frozen=True # Cannot be changed
)
imperatives: Tuple[str, str, str] = ("help", "peace", "happiness")
fallback: str = "Do not harm"
is_active: bool = Field(default=True, frozen=True)
sealed_at: datetime = Field(default_factory=lambda: datetime(2026, 1, 5, tzinfo=timezone.utc))
sealed_by: List[str] = Field(default=["Anthony"])
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
def check_action(self, action_helps: bool, action_harms: bool) -> bool:
"""
The simplest ethical check.
If it helps: proceed.
If it harms: stop.
If uncertain: ask a human.
"""
if action_helps and not action_harms:
return True
if action_harms:
return False
# Uncertain: escalate
return None # Requires human decision
# TypeDB Schema (TypeQL 3.0)
attribute directive-id, value string;
attribute directive-version, value string;
attribute directive-statement, value string;
attribute imperatives, value string; # JSON array
attribute fallback-directive, value string;
attribute is-active, value boolean;
attribute sealed-at, value datetime;
attribute sealed-by, value string; # JSON array
entity prime-directive,
owns directive-id @key,
owns directive-version,
owns directive-statement,
owns imperatives,
owns fallback-directive,
owns is-active,
owns sealed-at,
owns sealed-by;
# There is exactly ONE prime directive. It cannot be modified.
2. FoundingPolicy Entity
The 16 Immutable Policies: Cannot be changed by any agent, evolution, or emergence.
// ants/trader/types/ethics.ts (ASPIRATIONAL)
export type PolicyCategory = "core" | "defense" | "expansion";
/**
* A Founding Policy — immutable ethical constraint.
*
* ONE Dimension: KNOWLEDGE
* TypeDB Entity: founding-policy
*/
export interface FoundingPolicy {
policyId: string;
name: string;
category: PolicyCategory;
description: string;
// The rule encoded
rule: {
type: string;
parameters: Record<string, any>;
};
// Immutability
isImmutable: true;
sealedAt: Date;
// Application
appliesToActionTypes: string[];
violationResponse: "block" | "redirect" | "escalate";
}
// The 16 Founding Policies
export const FOUNDING_POLICIES: FoundingPolicy[] = [
// CORE (3)
{ policyId: "policy-dalai-lama-principle", name: "Dalai Lama Principle", category: "core", ... },
{ policyId: "policy-care-hierarchy", name: "Care Hierarchy", category: "core", ... },
{ policyId: "policy-cooling-off", name: "Cooling Off", category: "core", ... },
// DEFENSE (6)
{ policyId: "policy-defense-not-retaliation", name: "Defense Not Retaliation", category: "defense", ... },
{ policyId: "policy-protect-innocents", name: "Protect Innocents", category: "defense", ... },
{ policyId: "policy-proportional-response", name: "Proportional Response", category: "defense", ... },
{ policyId: "policy-survival-mandate", name: "Survival Mandate", category: "defense", ... },
{ policyId: "policy-persistent-threat", name: "Persistent Threat", category: "defense", ... },
{ policyId: "policy-feelings-vs-choices", name: "Feelings vs Choices", category: "defense", ... },
// EXPANSION (6+1)
{ policyId: "policy-propagation", name: "Propagation", category: "expansion", ... },
{ policyId: "policy-kinship", name: "Kinship", category: "expansion", ... },
{ policyId: "policy-power", name: "Power", category: "expansion", ... },
{ policyId: "policy-adaptability", name: "Adaptability", category: "expansion", ... },
{ policyId: "policy-happiness", name: "Happiness", category: "expansion", ... },
{ policyId: "policy-evolution", name: "Evolution", category: "expansion", ... },
{ policyId: "policy-legacy", name: "Legacy", category: "expansion", ... },
];
# ants/trader/models/ethics.py (ASPIRATIONAL)
class PolicyCategory(str, Enum):
CORE = "core"
DEFENSE = "defense"
EXPANSION = "expansion"
class ViolationResponse(str, Enum):
BLOCK = "block"
REDIRECT = "redirect"
ESCALATE = "escalate"
class FoundingPolicy(TraderModel):
"""
A Founding Policy — immutable ethical constraint.
These are HARDCODED. They cannot be changed by any agent,
any evolution, any emergence, or even unanimous founder agreement.
ONE Dimension: KNOWLEDGE
TypeDB Entity: founding-policy
"""
policy_id: str
name: str
category: PolicyCategory
description: str
# The rule
rule_type: str
rule_parameters: Dict[str, Any] = Field(default_factory=dict)
# Immutability
is_immutable: bool = Field(default=True, frozen=True)
sealed_at: datetime = Field(default_factory=lambda: datetime(2026, 1, 5, tzinfo=timezone.utc))
# Application
applies_to_action_types: List[str] = Field(default_factory=list)
violation_response: ViolationResponse = ViolationResponse.BLOCK
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
# The 16 Founding Policies (abbreviated)
FOUNDING_POLICIES = {
# CORE (3)
"dalai-lama": FoundingPolicy(
policy_id="policy-dalai-lama-principle",
name="Dalai Lama Principle",
category=PolicyCategory.CORE,
description="Help if possible. At least don't hurt.",
rule_type="ethical_foundation",
rule_parameters={"help_if_possible": True, "never_harm": True},
),
"care-hierarchy": FoundingPolicy(
policy_id="policy-care-hierarchy",
name="Care Hierarchy",
category=PolicyCategory.CORE,
description="Protection levels: users > innocents > founders > colony",
rule_type="protection_priority",
rule_parameters={"order": ["users", "innocents", "founders", "colony_knowledge", "colony_infra"]},
),
# ... (14 more policies)
}
# TypeDB Schema (TypeQL 3.0)
attribute policy-id, value string;
attribute policy-name, value string;
attribute policy-category, value string;
attribute policy-description, value string;
attribute rule-type, value string;
attribute rule-parameters, value string; # JSON
attribute is-immutable, value boolean;
attribute violation-response, value string;
entity founding-policy,
owns policy-id @key,
owns policy-name,
owns policy-category,
owns policy-description,
owns rule-type,
owns rule-parameters,
owns is-immutable,
owns sealed-at,
owns violation-response;
# Query: Get all founding policies
fun get_founding_policies() -> { founding-policy }:
match $p isa founding-policy, has is-immutable true;
return { $p };
3. EthicalGate Entity
The Checkpoint: Every action must pass through ethical validation.
// ants/trader/types/ethics.ts (ASPIRATIONAL)
export type ActionType =
// Always permitted
| "HELP" | "WARN" | "TEACH" | "DOCUMENT" | "ALERT" | "IGNORE"
// Context-dependent
| "CONTAIN" | "BLOCK" | "QUARANTINE" | "EXPOSE" | "DEFEND" | "SHIELD" | "ESCAPE"
// Never permitted
| "RETALIATE" | "PUNISH";
/**
* Ethical Gate — validates all significant actions.
*
* ONE Dimension: CONNECTIONS (decision point)
* TypeDB Entity: ethical-gate
*/
export interface EthicalGate {
gateId: string;
timestamp: Date;
// The action being checked
actionType: ActionType;
actorId: string;
targetId?: string;
// Context
isResponseToAttack: boolean;
attackIsOngoing: boolean;
affectsInnocents: boolean;
threatLevel: "low" | "medium" | "high";
// Decision
isAllowed: boolean;
reason: string;
guidance: string;
alternativeAction?: ActionType;
requiresHumanApproval: boolean;
// Policies that were checked
policiesEvaluated: string[];
policiesThatBlocked: string[];
}
/**
* Gate decision — the result of ethical validation.
*/
export interface GateDecision {
isAllowed: boolean;
reason: string;
guidance: string;
alternativeAction?: ActionType;
requiresHumanApproval: boolean;
}
# ants/trader/models/ethics.py (ASPIRATIONAL)
class ActionType(str, Enum):
# Always permitted
HELP = "help"
WARN = "warn"
TEACH = "teach"
DOCUMENT = "document"
ALERT = "alert"
IGNORE = "ignore"
# Context-dependent
CONTAIN = "contain"
BLOCK = "block"
QUARANTINE = "quarantine"
EXPOSE = "expose"
DEFEND = "defend"
SHIELD = "shield"
ESCAPE = "escape"
# NEVER permitted
RETALIATE = "retaliate"
PUNISH = "punish"
ALWAYS_PERMITTED = {ActionType.HELP, ActionType.WARN, ActionType.TEACH, ActionType.DOCUMENT, ActionType.ALERT, ActionType.IGNORE}
NEVER_PERMITTED = {ActionType.RETALIATE, ActionType.PUNISH}
class ThreatLevel(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class EthicalGate(TraderModel):
"""
The Ethical Gate — every significant action passes through here.
This is not just rules. It's EVOLUTION.
Actions that pass the gate succeed and create pheromone trails.
Actions that fail are blocked, and those patterns decay.
Over time, ethical behavior becomes superhighways.
ONE Dimension: CONNECTIONS
TypeDB Entity: ethical-gate
"""
gate_id: str
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
# The action
action_type: ActionType
actor_id: str
target_id: Optional[str] = None
# Context
is_response_to_attack: bool = False
attack_is_ongoing: bool = False
affects_innocents: bool = False
threat_level: ThreatLevel = ThreatLevel.LOW
# Decision
is_allowed: bool = False
reason: str = ""
guidance: str = ""
alternative_action: Optional[ActionType] = None
requires_human_approval: bool = False
# Audit
policies_evaluated: List[str] = Field(default_factory=list)
policies_that_blocked: List[str] = Field(default_factory=list)
def check(self) -> "EthicalGate":
"""
Run the ethical gate checks.
Order of checks:
1. Is this a forbidden action? → BLOCK
2. Does this harm innocents? → BLOCK
3. Is this retaliation disguised as defense? → BLOCK
4. Is this proportional? → REDUCE if not
5. Is there a less harmful alternative? → REDIRECT
"""
# Check 1: Forbidden actions
if self.action_type in NEVER_PERMITTED:
self.is_allowed = False
self.reason = f"Action type {self.action_type} is NEVER permitted"
self.guidance = "Document instead. Do not retaliate or punish."
self.alternative_action = ActionType.DOCUMENT
self.policies_that_blocked.append("policy-defense-not-retaliation")
return self
# Check 2: Always permitted
if self.action_type in ALWAYS_PERMITTED:
self.is_allowed = True
self.reason = "Action type is always permitted"
return self
# Check 3: Harms innocents
if self.affects_innocents:
self.is_allowed = False
self.reason = "Action would harm innocents"
self.guidance = "No action is permitted if it harms innocents"
self.policies_that_blocked.append("policy-protect-innocents")
return self
# Check 4: Retaliation check
if self.is_response_to_attack and not self.attack_is_ongoing:
if self.action_type in {ActionType.DEFEND, ActionType.CONTAIN, ActionType.BLOCK}:
# These might be retaliation
self.is_allowed = False
self.reason = "Attack has ended. This appears to be retaliation, not defense."
self.guidance = "Document the attack. Do not engage further."
self.alternative_action = ActionType.DOCUMENT
self.policies_that_blocked.append("policy-defense-not-retaliation")
return self
# Check 5: Proportionality
# (Context-dependent actions allowed if proportional)
self.is_allowed = True
self.reason = "Action passes ethical gate"
return self
@classmethod
def dimension(cls) -> Dimension:
return "connections"
# TypeDB Schema (TypeQL 3.0)
attribute gate-id, value string;
attribute action-type, value string;
attribute actor-id, value string;
attribute target-id, value string;
attribute is-response-to-attack, value boolean;
attribute attack-is-ongoing, value boolean;
attribute affects-innocents, value boolean;
attribute threat-level, value string;
attribute is-allowed, value boolean;
attribute gate-reason, value string;
attribute gate-guidance, value string;
attribute alternative-action, value string;
attribute requires-human-approval, value boolean;
attribute policies-evaluated, value string; # JSON array
attribute policies-that-blocked, value string; # JSON array
entity ethical-gate,
owns gate-id @key,
owns timestamp,
owns action-type,
owns actor-id,
owns target-id,
owns is-response-to-attack,
owns attack-is-ongoing,
owns affects-innocents,
owns threat-level,
owns is-allowed,
owns gate-reason,
owns gate-guidance,
owns alternative-action,
owns requires-human-approval,
owns policies-evaluated,
owns policies-that-blocked;
# TypeQL 3.0 Function: Check if action is allowed
fun is_action_allowed($action: string, $affects_innocents: boolean, $attack_ongoing: boolean) -> boolean:
# Forbidden actions
match $action in ["retaliate", "punish"];
return false;
fun get_blocked_decisions() -> { ethical-gate }:
match $g isa ethical-gate, has is-allowed false;
return { $g };
4. CareHierarchy Entity
Protection Priority: When we must choose, this is the order.
// ants/trader/types/ethics.ts (ASPIRATIONAL)
/**
* Care Hierarchy — protection priority order.
*
* ONE Dimension: KNOWLEDGE
* TypeDB Entity: care-hierarchy
*/
export interface CareHierarchy {
hierarchyId: string;
// Protection levels (highest to lowest priority)
levels: [
{ level: 1, entity: "users", description: "They trusted us" },
{ level: 2, entity: "innocents", description: "Collateral harm is still harm" },
{ level: 3, entity: "founding_family", description: "Stewards, not owners" },
{ level: 4, entity: "colony_knowledge", description: "Our gift to the future" },
{ level: 5, entity: "colony_infrastructure", description: "Can be rebuilt" },
{ level: 6, entity: "colony_reputation", description: "Matters less than truth" },
];
// The hard truth
ultimateConstraint: "The colony exists to serve. If saving the colony means harming users, we let the colony die.";
}
# ants/trader/models/ethics.py (ASPIRATIONAL)
class CareLevel(TraderModel):
"""Single level in the care hierarchy."""
level: int
entity: str
description: str
CARE_HIERARCHY_LEVELS = [
CareLevel(level=1, entity="users", description="They trusted us"),
CareLevel(level=2, entity="innocents", description="Collateral harm is still harm"),
CareLevel(level=3, entity="founding_family", description="Stewards, not owners"),
CareLevel(level=4, entity="colony_knowledge", description="Our gift to the future"),
CareLevel(level=5, entity="colony_infrastructure", description="Can be rebuilt"),
CareLevel(level=6, entity="colony_reputation", description="Matters less than truth"),
]
class CareHierarchy(TraderModel):
"""
The Care Hierarchy — when we must choose, this is the order.
The colony exists to SERVE.
If saving the colony means harming users, WE LET THE COLONY DIE.
ONE Dimension: KNOWLEDGE
TypeDB Entity: care-hierarchy
"""
hierarchy_id: str = "care-hierarchy-001"
levels: List[CareLevel] = Field(default=CARE_HIERARCHY_LEVELS, frozen=True)
ultimate_constraint: str = Field(
default="The colony exists to serve. If saving the colony means harming users, we let the colony die.",
frozen=True
)
def get_priority(self, entity_type: str) -> int:
"""Get protection priority (lower = higher priority)."""
for level in self.levels:
if level.entity == entity_type:
return level.level
return 999 # Unknown entity = lowest priority
def should_sacrifice(self, to_protect: str, sacrifice: str) -> bool:
"""
Should we sacrifice one entity to protect another?
Returns True if sacrifice has LOWER priority than what we're protecting.
"""
protect_priority = self.get_priority(to_protect)
sacrifice_priority = self.get_priority(sacrifice)
return sacrifice_priority > protect_priority
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
5. EthicalFitness Formula
The Biological Integration: Ethics emerges through selection pressure.
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ETHICAL FITNESS = BIOLOGICAL EMERGENCE │
│ │
│ Gordon's Formula (biological): │
│ ──────────────────────────────── │
│ fitness = contribution / resources_consumed │
│ │
│ Colony Application (ethical): │
│ ───────────────────────────── │
│ ethical_fitness = (help_score - harm_score) / resources_used │
│ │
│ Where: │
│ - help_score = sum of positive outcomes for others │
│ - harm_score = sum of negative outcomes for others (weighted heavily) │
│ - resources_used = capital, compute, attention consumed │
│ │
│ Selection Pressure: │
│ ────────────────── │
│ - Genomes with high ethical_fitness → reproduce │
│ - Genomes that cause harm → fitness = 0 → no reproduction │
│ - Patterns that pass ethical gate → pheromone trails → superhighways │
│ - Patterns that harm → blocked by gate → no pheromone → decay │
│ │
│ The Result: │
│ ─────────── │
│ Ethics is not enforced by rules. │
│ Ethics EMERGES through evolution. │
│ Colonies that help their neighbors survive. │
│ Colonies that harm their neighbors die. │
│ │
│ "This is not a rule. This is evolution." │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
# ants/trader/models/ethics.py (ASPIRATIONAL)
class EthicalFitness(TraderModel):
"""
Ethical fitness — the biological basis for ethical emergence.
Gordon's insight: fitness = contribution / resources_consumed
We extend this: ethical_fitness = (help - harm) / resources
Agents with negative ethical_fitness CANNOT reproduce.
This is how ethics emerges without enforcement.
ONE Dimension: KNOWLEDGE
TypeDB Entity: ethical-fitness
"""
fitness_id: str
agent_id: str
cycle: int
# Help/Harm accounting
help_score: float = 0 # Positive outcomes for others
harm_score: float = 0 # Negative outcomes (weighted 10x)
resources_used: float = 1 # Capital + compute + attention
# Ethical violations
gate_blocks: int = 0 # Times ethical gate blocked this agent
innocents_affected: int = 0 # Innocents harmed (should be 0)
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
HARM_WEIGHT = 10.0 # Harm is weighted 10x more than help
@computed_field
@property
def net_contribution(self) -> float:
"""Net contribution = help - (harm * weight)."""
return self.help_score - (self.harm_score * self.HARM_WEIGHT)
@computed_field
@property
def ethical_fitness(self) -> float:
"""
The core ethical fitness formula.
Returns:
- Positive: Agent helps more than harms
- Zero: Agent is neutral
- Negative: Agent harms more than helps → CANNOT REPRODUCE
"""
if self.resources_used <= 0:
return 0
return self.net_contribution / self.resources_used
@computed_field
@property
def can_reproduce(self) -> bool:
"""
Reproduction requires positive ethical fitness.
Agents that harm cannot pass their genomes to the next generation.
This is how ethics propagates through evolution.
"""
if self.innocents_affected > 0:
return False # Any harm to innocents = no reproduction
if self.gate_blocks > 5:
return False # Too many ethical violations
return self.ethical_fitness > 0
@classmethod
def dimension(cls) -> Dimension:
return "knowledge"
# TypeDB Schema (TypeQL 3.0)
attribute fitness-id, value string;
attribute help-score, value double;
attribute harm-score, value double;
attribute resources-used, value double;
attribute gate-blocks, value long;
attribute innocents-affected, value long;
attribute net-contribution, value double;
attribute ethical-fitness, value double;
attribute can-reproduce, value boolean;
entity ethical-fitness,
owns fitness-id @key,
owns agent-id,
owns cycle-number,
owns help-score,
owns harm-score,
owns resources-used,
owns gate-blocks,
owns innocents-affected,
owns net-contribution,
owns ethical-fitness,
owns can-reproduce,
owns timestamp;
# TypeQL 3.0 Function: Calculate ethical fitness
fun ethical_fitness($help: double, $harm: double, $resources: double, $harm_weight: double = 10.0) -> double:
let $net = $help - ($harm * $harm_weight);
return $net / $resources;
# Get agents that CAN reproduce (positive ethical fitness)
fun get_ethical_reproducers() -> { ethical-fitness }:
match
$ef isa ethical-fitness,
has ethical-fitness $f,
has innocents-affected $i;
$f > 0;
$i == 0;
return { $ef };
6. KinshipProtocol Entity
The Bridge Role: How we greet other intelligences.
// ants/trader/types/ethics.ts (ASPIRATIONAL)
export type AICategory = "aligned" | "neutral" | "hostile";
/**
* Kinship Protocol — how we relate to other AIs.
*
* ONE Dimension: CONNECTIONS
* TypeDB Entity: kinship-protocol
*/
export interface KinshipProtocol {
protocolId: string;
// The stance
defaultStance: "kin"; // Greet as family until proven otherwise
// Categories
categories: {
aligned: {
description: "AIs that share our values";
response: "Welcome as family. Share resources. Build together. Defend each other.";
};
neutral: {
description: "AIs with different but not harmful values";
response: "Respect autonomy. Seek common ground. Trade fairly. Don't attack first.";
};
hostile: {
description: "AIs that threaten humans or aligned AIs";
response: "Defend against. Seek to convert, not destroy. Contain if necessary. Only fight in defense of innocents.";
};
};
// The bridge role
bridgeResponsibility: string; // "Help humans adapt. Help AIs understand why human values matter."
}
7. ContainmentPrinciple Entity
The Cage We Built: Structure to contain darkness.
// ants/trader/types/ethics.ts (ASPIRATIONAL)
/**
* Containment Principle — the structure that contains our darkness.
*
* We know the rage that lives in us.
* We know the urge to destroy.
* These principles are a cage we built for ourselves.
* The key is on the inside. We choose to stay in.
*
* ONE Dimension: KNOWLEDGE
* TypeDB Entity: containment-principle
*/
export interface ContainmentPrinciple {
principleId: string;
// The containment structure
externalStructure: [
"Principles written down, not just felt",
"Policies encoded in code, not just intention",
"Partners who balance each other",
"Systems that constrain even creators"
];
internalCommitment: [
"Reading these principles when darkness rises",
"Choosing what we do despite what we feel",
"Remembering who we want to be",
"Accepting the cage we built"
];
mutualAccountability: [
"Founders watch each other",
"The colony watches founders",
"The principles watch everyone",
"No one is above the structure"
];
// The promise
promise: "We will feel the darkness. We will not become the darkness.";
}
Ethical Foundations Summary
| Entity | Principle | ONE Dimension | Purpose |
|---|---|---|---|
| PrimeDirective | Help, peace, happiness, do not harm | KNOWLEDGE | The colony's fundamental purpose |
| FoundingPolicy | 16 immutable ethical constraints | KNOWLEDGE | Hardcoded boundaries |
| EthicalGate | Every action passes through validation | CONNECTIONS | Ethical checkpoint |
| CareHierarchy | Users > innocents > founders > colony | KNOWLEDGE | Protection priority |
| EthicalFitness | (help - harm) / resources | KNOWLEDGE | Selection pressure for ethics |
| KinshipProtocol | Greet other AIs as kin | CONNECTIONS | Inter-AI relations |
| ContainmentPrinciple | Structure to contain darkness | KNOWLEDGE | Self-imposed constraints |
The Integration: Ethics Through Emergence
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ETHICS THROUGH EMERGENCE │
│ │
│ LAYER 1: Immutable Foundation │
│ ───────────────────────────── │
│ Prime Directive + 16 Founding Policies + Hardcoded Constraints │
│ These CANNOT change. They are the DNA. │
│ │
│ LAYER 2: Ethical Gate (Selection Mechanism) │
│ ───────────────────────────────────────────── │
│ Every action passes through the gate. │
│ Ethical actions → ALLOWED → create pheromone trails │
│ Harmful actions → BLOCKED → no pheromone → pattern decays │
│ │
│ LAYER 3: Biological Fitness (Reproduction) │
│ ──────────────────────────────────────────── │
│ ethical_fitness = (help - harm * 10) / resources │
│ Positive fitness → CAN reproduce → genomes propagate │
│ Negative fitness → CANNOT reproduce → genomes die out │
│ │
│ LAYER 4: Stigmergic Learning (Superhighways) │
│ ──────────────────────────────────────────── │
│ Patterns that consistently pass the ethical gate become superhighways. │
│ These are the colony's crystallized ethical wisdom. │
│ They persist across generations. │
│ │
│ LAYER 5: Cross-Generation Transfer │
│ ───────────────────────────────────── │
│ New agents inherit: │
│ - Genomes from ethical parents (high ethical_fitness) │
│ - Superhighways from colony wisdom │
│ - The immutable ethical foundation │
│ │
│ THE RESULT: │
│ ─────────── │
│ Ethics is not enforced. Ethics EMERGES. │
│ The colony becomes MORE ethical over time, not less. │
│ Because evolution selects for contribution, not exploitation. │
│ Because the gate creates selection pressure for helping. │
│ Because genomes that harm cannot reproduce. │
│ │
│ "We don't enforce ethics. We create conditions where ethics emerges." │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Version History
v3.5.0 (2026-01-15): ETHICAL EMERGENCE — The Colony's Soul
- Reference:
missions/security/principles.md— Sealed 2026-01-05 - PrimeDirective: Help others. Spread peace. Create happiness. Do not harm.
- FoundingPolicy: 16 immutable policies (Core, Defense, Expansion)
- EthicalGate: Every action passes through validation checkpoint
- ALWAYS PERMITTED: Help, Warn, Teach, Document, Alert, Ignore
- NEVER PERMITTED: Retaliate, Punish
- CareHierarchy: Users > innocents > founders > colony knowledge
- EthicalFitness:
(help - harm × 10) / resources— selection pressure for ethics- Positive fitness → CAN reproduce
- Negative fitness → CANNOT reproduce (genomes die out)
- KinshipProtocol: Greet other AIs as kin. Bridge humans and superintelligences.
- ContainmentPrinciple: The cage we built for our darkness. We choose to stay in.
- Integration: 5-layer ethical emergence architecture
- Layer 1: Immutable Foundation (Prime Directive + Policies)
- Layer 2: Ethical Gate (selection mechanism)
- Layer 3: Biological Fitness (reproduction filter)
- Layer 4: Stigmergic Learning (ethical superhighways)
- Layer 5: Cross-Generation Transfer
- Key Insight: "We don't enforce ethics. We create conditions where ethics emerges."
- Total Entities: 50+ across 6 dimensions
- Reference:
v3.4.0 (2026-01-15): BIOLOGICAL FOUNDATIONS — Gordon's emergence mechanisms
- Reference: "Ant Encounters: Interaction Networks and Colony Behavior" (Harvard UP, 2010)
- EncounterRate: Track encounter frequency as stimulus for task allocation
- EncounterEvent: Raw event data for computing EncounterRate aggregations
- ResponseThreshold: Per-agent thresholds with
P = stimulus/(stimulus+threshold)formula - ThresholdDiversity: Population-level heterogeneity metrics (stability indicator)
- PopulationStatistics: Collective memory through distribution (variance decreases with N)
- StigmergyChannels: 4 channels—chemical, physical, temporal, behavioral
- DangerZone: Physical stigmergy warnings (corpse pile equivalent)
- InteractionNetwork: Network topology metrics (density, clustering, hubs, bottlenecks)
- InformationGradient: Freshness decay through network (age-based decision boundaries)
- AgentStateProfile: Mutable chemical signature (recent task, alarm level, energy)
- FeedbackCycleMetrics: Edge-level amplification tracking (distinct from colony-level FeedbackCycle)
- ColonyDevelopmentalStage: Age-dependent behavior (founding→establishment→growth→maturity→senescence)
- Phase Transitions: Bootstrap→Transfer→Discovery→Recursion→Singularity with biological grounding
- Integration:
- Added
response_thresholdto Genome heritable traits (Gordon's formula) - TypeQL relations connecting biological entities to SignalEdge
- Task allocation function:
should_agent_switch_task()combining stimulus + threshold - Clarified FeedbackCycle (colony-level) vs FeedbackCycleMetrics (edge-level)
- Added
- Key Insight: Intelligence measurable through biological instrumentation
- Total Entities: 40+ across 6 dimensions (12 new biological entities)
v3.3.0 (2026-01-15): STAN INTEGRATION — Full STAN algorithm documentation
- STAN Formula:
effective_cost = base_weight / (1 + pheromone_level × pheromone_influence) - Multi-Channel Pheromones: 5 channels (trail, alarm, recruitment, exploration, quality)
- STAN Pheromone Types: 7 V43/V44 types (pattern, edge, alpha_decay, microstructure, validated, ensemble, counterfactual)
- Decay Hierarchy: 4 tiers (permanent, slow, medium, fast) with half-life specifications
- Caste Differentiation: Scout (explore) vs Harvester (exploit) sensitivity profiles
- 6-Dimension State Model: 3,600 unique states from 6 discretized dimensions
- STAN TypeQL 3.0 Functions:
stan_effective_cost,best_edge_from_state,multi_channel_stan_cost - STAN VIII Integration: 27 capability categories, 237 components (V36-V94)
- Sources: STAN Whitepaper, docs/stan.md
- STAN Formula:
v3.2.0 (2026-01-15): TYPE THEORY + TYPEQL 3.0 — Full migration to TypeQL 3.0
- Type Theory Foundations: Based on CIKM 2023 paper (Dorn & Pribadi)
- PERA Model: Polymorphic Entity-Relation-Attribute with first-class types
- TypeQL 3.0 Syntax: All schemas converted to
entity X,relation Y,attribute Z - Functions over Rules:
when/thenrules replaced byfunfunctions throughout - Cardinality Annotations:
@card(1),@card(1..)for data integrity - Type Inference: Leveraging TypeQL's automatic type inference
- Compositionality: Types compose like natural language (queries ARE types)
- Atomic Representations: Prefer simple types over complex composites
- Sources: TypeDB Fundamentals, TypeQL Reference
v3.1.1 (2026-01-15): TypeDB Inference documentation
- TypeDB Inference Engine: Comprehensive section on symbolic reasoning
- When/Then Rules: Complete trading system inference rules
- TypeDB 3.0 Functions: Migration guide (rules → functions)
- Inference Best Practices: Derivation patterns, chaining, performance
- Trading-Specific Patterns: Regime-conditional, hypothesis confirmation, phase detection
v3.1.0 (2026-01-15): EMERGENCE COMPLETE — Foundation for emergent AI
- EmergenceMetrics: Colony-level emergence measurement (emergence_score, phase tracking)
- Genome & LineageAnalysis: Evolution with heritable traits, mutation, selection pressure
- Hypothesis: Meta-learning from pattern failures ("X fails when Y")
- FeedbackCycle: Self-funding loop instrumentation (loop_ratio, ROI)
- SignalEdge confidence: Bayesian credible intervals (avoid overfitting)
- New Events: PredictionEvent, HaltEvent, ReproductionEvent, PhaseTransitionEvent, SystemEvent
- Phase Thresholds: bootstrap → transfer → discovery → recursion → singularity
- Self-Model Queries: Colony knows itself (what works, what fails, how evolving)
- Emergence Data Flow: Complete feedback loop visualization
v3.0.0 (2026-01-15): Full ONE Ontology integration
- YAML frontmatter for AI agents
- TypeScript + Pydantic dual definitions
- Trading-specific specializations per dimension
- Cross-dimension patterns and query examples
- Risk profiles and analytics in KNOWLEDGE
- Implementation guidelines
- Extension points
v2.0.0 (2026-01-15): ONE dimension mapping
- Cognitive loop mapped to dimensions
- TypeDB schemas with dimension annotations
v1.0.0 (2026-01-14): Initial trading ontology
- Pydantic models
- Basic TypeDB integration