Codex
6990ff3bee
malkhut: asset-faithful book generation with composable toggles
...
Three independently toggleable features:
1. Asset-faithful depth/spread: levels sized by OB study power-law per asset
2. Intraday volume clock: depth scales by time-of-day (peak/trough)
3. Realistic spread: per-asset spread from OB study + Flight7
Composable via BookGenerationConfig toggles:
use_asset_faithful_depth, use_asset_faithful_spread, use_intraday_clock,
use_weekend_mode, use_stress_mode, use_fragility, worst_case_mode
worst_case_mode overrides everything for max adversarial learning:
spread * stress_mult, depth * fragility, no intraday/weekend.
DuckDB registry for online updates:
AssetRegistry: upsert/get/list/delete/query
RuntimeProfileCache: hot-reload during CWM runs
upsert_from_csv/export_csv: pipeline support
upsert_all_from_asset_behaviors(): seed from OB study
Results (8 assets):
BTC: spread 0.031 bps, depth $350M (normal) / $4.9M (worst)
DOGE: spread 2.86 bps, depth $2M (normal) / $132K (worst)
ADA: spread 11.8 bps, depth $10M (normal) / $511K (worst)
Intraday: BTC peak/trough = 2.8x depth ratio
All 99 tests green (31 new + 68 existing).
2026-07-20 19:06:24 +02:00
Codex
97a770da65
malkhut: online EWMA self-calibrating slippage model
...
Flight7 model underestimates by 80% in CWM dynamic book:
raw predicted: 0.034 bps, actual: 0.180 bps
Constant error across 22K episodes — no feedback loop.
Root cause: Flight7 calibrated on real BingX taker fills, but CWM's
synthetic dynamic book has different fill characteristics.
Fix: SlippageSelfCalibrator with EWMA feedback loop.
After each fill: error = actual - predicted (clipped to +/-20 bps)
EWMA smooths per-symbol errors (alpha=0.2)
Next prediction = raw_model + EWMA_correction
Bounded output: 0-50 bps absolute
Convergence (300 eps across 8 assets):
ETH: 9% error (from 80%)
SOL: 3.5%
DOGE: 6.7%
LINK: 5.7%
ADA: 9.7%
BTC: 48.6% (low fill count, converging)
AVAX: 28.6% (low fill count)
UNI: 52.5% (low fill count, early outlier)
Truthfulness guarantees:
- Correction is observable (CALIBRATOR.correction(symbol))
- Resets between runs (no hidden state)
- Only uses observed fills, no assumptions
- Error clipping prevents outlier domination
- Absolute bounds prevent runaway
2026-07-20 15:17:16 +02:00
Codex
70f33f6911
malkhut: friction settings configurable per scenario
...
Scenario gains 3 new fields:
maker_fee_bps: Optional[float] = None (override per-scenario)
taker_fee_bps: Optional[float] = None (override per-scenario)
adverse_cost_bps: Optional[float] = None (per-fill adverse selection)
ScenarioFactory gains friction constructor params:
ScenarioFactory(exchange_id='bingx', maker_fee_bps=2.0, taker_fee_bps=5.0)
_make_state() accepts friction overrides → applies to VenueRules
_behavior_state() passes friction overrides through
All 34 scenario builder calls updated with friction overrides.
System can now learn in ALL conditions:
Scenario A: maker=0, taker=5 (free maker fills)
Scenario B: maker=2, taker=5 (BingX real)
Scenario C: maker=1, taker=3 (Binance-like)
CMA-ES optimizes strategy for EACH friction profile independently.
2026-07-19 00:25:26 +02:00
Codex
ebf7f17132
malkhut: fee+slippage execution threshold
2026-07-18 17:44:20 +02:00
Codex
5503aafa28
malkhut: P0 guard + P1 BingX protective strings + tests fixed
...
P0 (safety): adapter.py rejects unmapped types (OCO, TP_SL) via
is_type_available() guard. Returns None instead of silent LIMIT fallback.
P1 (BingX strings): STOP_MARKET → STOP_MARKET (protective, reduce-only)
STOP_LIMIT → STOP (protective)
TRIGGER_MARKET stays generic MIT
TRAILING_STOP → TRAILING_STOP_MARKET
Tests updated to match corrected mappings.
2026-07-18 15:08:57 +02:00
Codex
041c879e82
malkhut: all exchange order types in DSL + action_menu
...
ActionType → OrderType mapping (common-sensical):
QUOTE/REQUOTE/CHASE: LIMIT (passive, post_only)
CROSS_SPREAD (high urgency): MARKET (immediate fill)
CROSS_SPREAD (medium urgency): LIMIT + IOC (partial fill)
STOP_LOSS: STOP_MARKET (trigger → market exit)
TAKE_PROFIT: TRIGGER_MARKET (trigger → market exit)
TRAILING_STOP: TRAILING_STOP (trailing stop exit)
EXIT/FLAT_ALL: STOP_MARKET
EMERGENCY_EXIT: MARKET (immediate)
All order types exercised: LIMIT, MARKET, STOP_MARKET, TRIGGER_MARKET, TRAILING_STOP
2026-07-18 12:25:41 +02:00
Codex
8322550fbc
malkhut: REQUOTE as proper CANCEL_REPLACE primitive + action_menu metadata
...
REQUOTE is now distinct from QUOTE:
QUOTE: PLACE new order (no existing to cancel)
REQUOTE: CANCEL_REPLACE existing + place new (immediate)
CHASE: PLACE with short TTL (auto-cancel retry)
CANCEL: Remove existing order
action_menu generates REQUOTE with metadata={'requote': True} for existing orders.
DSL REQUOTE produces CANCEL_REPLACE when existing order, falls back to PLACE.
All 800+ tests pass.
2026-07-17 23:17:22 +02:00
Codex
4926ef6788
malkhut: CHASE mechanics FIXED + Flight9 learnings + TTL enforcement
...
1. CHASE mechanics (NOW WORKING):
- CWM enforces TTL on open orders (auto-cancel when expired)
- DSL CHASE produces PLACE with metadata={chase: True}
- Action menu generates chase actions with wait_to_retry_ms TTL
- OpenOrderState.gains ttl_ms field (0=no expiry, >0=auto-cancel)
2. TTL enforcement (CWM):
- HftBacktestCWM: auto-cancels orders where age >= ttl_ms
- MinimalCryptoLOBCWM: same TTL enforcement
- This is how CHASE works: place→wait→auto-cancel→next step re-places
3. Flight9 learnings:
- Slippage model gains trade_flow_intensity parameter
- Book imbalance as proxy for trade arrival rate
- Markout = quality concept documented
4. CHASE tests: 10 new tests covering TTL enforcement, cancel-retry cycle,
max retries, DSL CHASE action, CMA codec integration
5. All 800+ tests pass
2026-07-17 19:30:17 +02:00
Codex
bb229833d3
malkhut: Flight9 learnings — markout=quality, queue×flow, depth-for-size
...
Fable's Flight9/BLUE generalizable features incorporated:
1. Slippage model gains trade_flow_intensity parameter:
- Estimated from book imbalance (proxy for trade arrivals)
- More flow → better fills (lower slippage)
- Fable: 'fill = queue position × trade-flow intensity'
2. Markout = quality concept documented:
- Score fills by post-fill markout, not just fill/no-fill
- Maker fills are adversely selected
3. Depth-for-size documented:
- Spread lies; key on depth-within-K-bps vs order notional
4. Measured fees:
- BingX maker=2.00bp, taker=5.016bp (over 1,455 fills)
- BingX commission = NEGATIVE (debit)
5. OB study updated with Flight9 learnings
2026-07-17 16:18:43 +02:00
Codex
8857daedfa
malkhut: urgency-driven maker/taker + calibrated slippage + chase + docs
2026-07-17 10:16:55 +02:00
Codex
5c4ccdb1de
malkhut: 3.5H instrumented E2E + calibrated slippage + conditional slippage
2026-07-15 19:32:46 +02:00
Codex
618ad723e3
malkhut(wire): fill quality as PRIMARY optimization target
...
Fill quality is MALKHUT's core aim. Wired end-to-end:
1. FillQuality state (state.py):
- slippage_bps, price_improvement_bps, levels_consumed
- is_maker_fill, rolling_fill_rate, post_fill_adverse_bps
- fill_value_score: composite metric for optimization
- Added to MarketWorldState.fill_quality field
2. HftBacktestCWM.transition() (hft_cwm.py):
- _compute_fill_quality() computes all metrics per transition
- Fill quality now tracked for every CWM step
- Empty book guards added for safety
3. MinimalCryptoLOBCWM.transition() (core.py):
- Same fill quality computation for deterministic fallback
- Empty book guards added
4. Reward function (hft_cwm.py):
- fill_quality_reward = w_fill_probability * fill_value_score (PRIMARY)
- Bonus for maker fills that improve price
- Penalty for adverse selection after fill
- Base reward (PnL, adverse selection, fees) preserved
5. PerformanceMatrix (selector.py):
- RegimeStrategyScore: 4 new fill quality fields
- record(): accepts fill_rate, slippage, price_improvement, fill_value_score
- EMA updates for all fill quality metrics
6. EpisodeResult (cma_trainer.py):
- avg_fill_value_score, avg_price_improvement_bps, avg_post_fill_adverse_bps
- Accumulated per-step during _run_episode
- Recorded to PerformanceMatrix in evaluate_candidate
All 1379+ tests green.
2026-07-15 15:22:25 +02:00
Codex
f6d8d13146
malkhut(wire): 5 risk gate stubs implemented + 3 scenarios behavior-driven
...
Risk gate (risk/gate.py) — 5 stubs implemented:
1. _kill_switch_active(): operator-controlled emergency stop via set_kill_switch()
2. _cancel_rate_would_exceed(): tracks cancel timestamps per symbol in 60s
sliding window, blocks if >= MAX_CANCELS_PER_SYMBOL_PER_MINUTE
3. _would_self_trade(): checks open orders for same symbol+side at same price
(within tick_size), skipping the cancel_order_id for CANCEL_REPLACE
4. _would_exceed_symbol_notional(): sums current open order notional + new
order notional, blocks if > equity * MAX_SYMBOL_NOTIONAL_FRACTION
5. _violates_venue_minima(): checks tick alignment, lot rounding, min_qty,
and min_notional — all float-robust comparisons
ScenarioFactory — 3 remaining hardcoded scenarios converted:
1. _spread_tightening: spread_mult=0.3, depth_fraction=1.0 (was hardcoded BTC)
2. _cross_venue_arb: spread_mult=0.5, depth_fraction=0.5 (was hardcoded BTC)
3. _cross_exchange_arb_stress: spread_mult=0.8, depth_fraction=0.3 (was hardcoded BTC)
All 30 scenarios now use _behavior_state() — zero hardcoded prices remain.
675 tests pass. Zero regressions.
2026-07-14 17:01:38 +02:00
Codex
b70a6f0ad8
malkhut(wire): PerformanceMatrix keyed by (regime, strategy, venue)
...
Three-dimensional key enables:
- Per-venue best: get_best(regime, venue='bingx')
- Cross-venue comparison: get_venue_comparison(regime, strategy_id)
- Venue-agnostic: get_best(regime) scans all venues (backward compat)
New API:
- record(..., venue='bingx'): venue parameter (default 'bingx')
- get_best(regime, venue=None): optional venue filter
- get_scores_for_regime(regime, venue=None): optional venue filter
- get_venue_comparison(regime, strategy_id) -> {venue: score}
119 tests pass. All existing callers backward compatible.
2026-07-14 15:37:36 +02:00
Codex
2cba60a154
malkhut(wire): venue passed through matrix recording for cross-exchange comparison
...
- evaluator: passes scenario.venue to matrix.record(venue=...)
- PerformanceMatrix.record(): accepts venue parameter (default='bingx')
- Enables cross-exchange learnings: same strategy tested on BingX vs Binance
gets separate performance entries per venue
Adversary ecology analysis:
Counterparties operate at ActionKind level (CROSS_SPREAD/PLACE/CANCEL),
not at order-type level. The CWM infers order type from ActionKind:
CROSS_SPREAD → fills aggressively → equivalent to MARKET
PLACE → passive quote → equivalent to LIMIT
This is correct and venue-independent. Fee calculation already uses
VenueRules (per-exchange fees). No adversary changes needed.
2026-07-14 15:26:30 +02:00
Codex
401d5a70ca
malkhut(wire): venue tagging + cross-exchange transfer + CWM order type fix
...
ScenarioFactory + CWM + Engine changes:
1. Scenario.venue field (default='bingx') — each scenario tagged with venue
2. ScenarioFactory.exchange_id parameter — controls which exchange scenarios simulate
3. _make_state + _behavior_state: venue propagated to VenueRules.exchange
4. All 34 scenario builders: venue=self.exchange_id
5. cross_exchange_transfer(): re-tag scenarios for different exchange
(strategy evolved on BingX can be re-evaluated on Binance)
6. CWM core.py: is_maker check updated for three-dimensional order model
(POST_ONLY no longer in OrderType; uses post_only flag instead)
Cross-exchange learning flow:
factory_bingx = ScenarioFactory(exchange_id='bingx')
scenarios_bingx = factory_bingx.build_suite(symbols=[...])
strategy = train(scenarios_bingx) # evolve on BingX
factory_binance = ScenarioFactory(exchange_id='binance')
scenarios_binance = factory_bingx.cross_exchange_transfer(
scenarios_bingx, target_exchange='binance')
score = evaluate(strategy, scenarios_binance) # test on Binance
All tests pass. Strategy PARAMETERS transfer; only venue tag + fees + order mapping change.
2026-07-14 15:18:56 +02:00
Codex
d24d9bc6bd
malkhut(wire): OrderType as three orthogonal dimensions — Fable's corrections
...
CRITICAL REFACTOR based on Fable's review (S9 roadmap item):
Before: flat enum conflating order types with TIF/instructions
OrderType had MARKET, LIMIT, IOC, FOK, POST_ONLY, REDUCE_ONLY, etc.
After: three orthogonal dimensions (FIX-aligned):
1. OrderType (Tag 40): what the order IS
LIMIT, MARKET, STOP_MARKET, STOP_LIMIT, TRIGGER_MARKET, TRIGGER_LIMIT,
TRAILING_STOP, OCO, TP_SL
2. TimeInForce (Tag 59): how long it LIVES
GTC, IOC, FOK, GTD
3. Instructions (Tag 18): behavioral modifiers
POST_ONLY, REDUCE_ONLY, HIDDEN, ICEBERG
Key corrections:
- POST_ONLY is an instruction on a LIMIT order, not a standalone type
- IOC/FOK are TimeInForce values, not order types
- BingX trailing_stop -> native TRAILING_STOP_MARKET (not TRIGGER_MARKET)
- FulfilmentAction.time_in_force: new field, default GTC
Exchange mappings restructured:
EXCHANGE_ORDER_TYPE_MAP: OrderType -> exchange native 'type' param
EXCHANGE_TIF_MAP: TimeInForce -> exchange native 'timeInForce' param
EXCHANGE_INSTRUCTION_MAP: Instruction -> exchange encoding
21 files changed. 380+ tests pass. Backward compatible.
2026-07-14 14:46:44 +02:00
Codex
369d9b41ad
malkhut: ExchangeProfile gains available_order_types per venue
...
Each exchange now declares which normalized order types it supports:
- binance: limit, market, stop_market, stop_limit, post_only, ioc, fok, trailing_stop, reduce_only
- bingx: limit, market, stop_market, stop_limit, post_only, ioc, fok, trailing_stop, reduce_only
- bybit: limit, market, stop_market, stop_limit, post_only, ioc, fok, trailing_stop, reduce_only
Backward compatible: new field has default=('limit', 'market').
Enables: agents/adversaries check is_type_available() before placing orders.
2026-07-14 12:14:54 +02:00
Codex
53e02c84ec
malkhut: standardized order types — FIX/CCXT-aligned, multi-exchange mapping
...
order_types.py: Five-layer taxonomy normalized to industry standards:
Layer 1: Base types (FIX Tag 40) — MARKET, LIMIT
Layer 2: Time-in-force (FIX Tag 59) — GTC, IOC, FOK, GTD
Layer 3: Conditional/Trigger (FIX Tag 3/4+MIT) — STOP_MARKET, STOP_LIMIT,
TRIGGER_MARKET, TRIGGER_LIMIT, TRAILING_STOP
Layer 4: Instructions (FIX Tag 18) — POST_ONLY, REDUCE_ONLY, HIDDEN, ICEBERG
Layer 5: Compound (exchange-specific) — OCO, TP_SL
Cross-exchange mapping: BingX ↔ Binance ↔ Bybit (from CCXT source code).
Standards: FIX 4.4 Tag 40/59/18, CCXT unified API, ISO 10383 (MIC).
Transferability: strategy PARAMETERS transfer. ORDER TYPE NAMES are
venue-specific but semantics identical (LIMIT = LIMIT everywhere).
14 tests. README updated with full mapping table and standards references.
2026-07-14 12:02:01 +02:00
Codex
7ad123c4c1
malkhut(spec): items 5-10 — manifold, actuals, OOD, query, book fidelity
...
Item 5 — PerformanceMatrix manifold:
RegimeStrategyScore: added confidence, support_count, distance_to_nearest
record() populates confidence from episode count (more evidence = more confidence)
Item 6 — ActualsLoader:
ActualsSnapshot: 12-field frozen dataclass for live market data
ActualsLoader: reads CH tables (obf_universe, exf_data, maras_fingerprint, etc.)
Synthetic fallback when CH unavailable
Item 7 — OOD verdict in RiskGate:
validate() now accepts daat_verdict parameter
OUT_OF_DISTRIBUTION → veto action, fall back to doctrinal simple policy
Backward compatible: default daat_verdict='KNOWN'
Item 8 — Manifold query (three-phase recommendation):
1. DAAT classify live state (KNOWN/MARGINAL/OOD)
2. If KNOWN: find nearest regime in PerformanceMatrix → best strategy
3. If OOD: return doctrinal_simple fallback
ManifoldRecommendation: strategy_id, confidence, regime, verdict, reason
Item 10 — Book fidelity gap:
BookFidelityConfig: n_levels, aggregation_window, min_depth
synthesize_book_from_params: power-law D(d)=amplitude*d^(1-alpha) → OrderBookState
Bridges OBF 15B rows → MALKHUT finite Tuple[PriceLevel]
5 files, 282 insertions.
2026-07-14 06:11:37 +02:00
Codex
1f41be845b
malkhut(spec): item 4 — ScenarioLibrary sweep for Mode 1 coverage
...
ScenarioLibrary sweeps the state space (not samples) across:
- spread_mult: [0.1, 0.5, 1.0, 2.0, 5.0, 10.0]
- depth_fraction: [0.01, 0.05, 0.1, 0.3, 0.5, 1.0]
- toxicity: [0.0, 0.3, 0.7, 1.0]
- regime: [normal, crisis, recovery, transition]
Default: 13 assets × 576 grid points = 7,488 scenarios.
Customizable: specify symbols, dimensions, ranges.
7 tests covering: grid size, sweep output, point fields,
regime coverage, custom dimensions, summary, factory function.
2026-07-14 05:34:05 +02:00
Codex
eef890a5cc
malkhut(spec): item 1 mutation-litmus + item 3 maker-fee UNVERIFIED comment
...
Item 1 — Mutation-litmus test (spec §1 item 3):
- test_taker_fee_10x_changes_score: fee change MUST affect score
- test_zero_fees_vs_correct_fees: zero vs 5bps must differ
- BOTH PASS — confirms fees ARE wired into reward function
- If fees were ignored, these tests would go RED
Item 3 — Maker fee verification (spec §1 item 5):
- Added '# UNVERIFIED — no maker fills on record as of 2026-07-13'
to Binance and Bybit exchange profiles
- Maker fee sign (positive on BingX, negative rebate on others)
is correct after fee fix but unverified from actual fills.
Items 2,4-10 remain for implementation.
2026-07-13 23:24:05 +02:00
Codex
5523be1d44
malkhut(fix): CORRECT FEE BUG — taker 0.5→5.0, maker -0.2→+2.0
...
Fable's spec (SPEC_MALKHUT_ACTUALS_INTAKE.md) confirmed 10x fee error
from our own fills (dolphin.trade_execution_quality).
Fixed:
- BingX taker: 0.5 → 5.0 bps
- BingX maker: -0.2 → +2.0 bps (POSITIVE on BingX, not a rebate)
- Binance taker: 0.4 → 4.5 bps
- Bybit taker: 0.06 → 5.5 bps
- All 13 per-asset profiles: maker=-0.2 taker=0.5 → maker=2.0 taker=5.0
Source of truth: dolphin.trade_execution_quality (8006 rows, avg taker=5.016 bps).
Every policy trained before this fix was at 10x too-cheap fees.
Re-measurement at correct fees is required.
2026-07-13 20:26:53 +02:00
Codex
d9b7e05531
malkhut(perf): optimize _run_episode — reduced Python overhead
...
Optimizations in _run_episode:
- Pre-allocated ActionKind constants (avoid repeated attribute lookups)
- Removed unnecessary max_pos_qty tracking (unused in scoring)
- Simplified action kind checks (single comparison chain)
- Reduced frozen dataclass allocations per step
Result: same behavioral output, cleaner code path.
Episode time: ~19ms/step sequential, ~13ms/step parallel (unchanged —
bottleneck is MCTS planner + CWM, not Python orchestration).
2026-07-13 15:11:19 +02:00
Codex
db8e6d11f2
malkhut(scoring): fast scalar + advantage mode, reward execution quality
...
Fast scalar mode (default, for CMA loop):
- Rewards: fill quality (PnL when fills happen), moderate fill rate (5-15% sweet spot)
- Tolerates: no-fills (valid advisory recommendation)
- Penalizes: extreme fill rates (<3% lazy, >30% picked off), adverse selection, drawdown
- Light noop penalty (-0.5) vs old heavy (-50) — no-fills are valid signals
Advantage mode (for offline analysis):
- advantage = raw_performance - baseline_performance
- baseline = exponential moving average (decay=0.995)
- Clipped to [-10, +10]
- Reduces score variance 5.5x vs raw scoring
Scoring mode selection:
PolicyEvaluator(scoring_mode='fast') — default for CMA loop
PolicyEvaluator(scoring_mode='advantage') — for offline analysis
8 new tests for scoring modes. Total: 1186 tests, 50 files, all green.
2026-07-13 13:38:32 +02:00
Codex
459215b7d8
malkhut(fix): wire workers into CMA training loop
...
CMAESTrainer.train() now accepts workers parameter and passes it to
evaluate_candidate(), enabling parallel episode evaluation during
actual training (not just in tests/benchmarks).
Benchmark result: ProcessPoolExecutor is optimal (4.76x speedup).
Ray is slower (0.36x) due to head init + plasma overhead for 90 scenarios.
2026-07-13 03:25:55 +02:00
Codex
c6b7a41bb4
malkhut(optim): vectorized reward + Ray parallel eval + VBT post-analysis
...
1. Vectorized reward path (cwm/core.py):
- Wired up existing compute_reward_vectorized from numba_core (was unused!)
- Eliminates FeatureVector dict allocation + Python dict lookups on hot path
- Numba path used when _HAS_NUMBA=True, Python fallback otherwise
- Bit-identical: same math operations, just via numba JIT
2. Ray-based parallel eval (training/ray_eval.py):
- Industrial multi-core execution via Ray (used by OpenAI/Anyscale)
- ray.put() stores params/scenarios in shared object store (no pickle per worker)
- Each worker: own CWM + planner, zero shared state, no races
- Bit-identical: same seed + same params = same results regardless of worker count
- PolicyEvaluator.evaluate_candidate: new use_ray=True parameter
3. VBT post-analysis (training/vbt_analysis.py):
- episodes_to_pnl_array, episodes_to_metrics (Sharpe, Sortino, VaR, win_rate, etc.)
- cross_asset_comparison, parameter_sensitivity
- format_metrics for human-readable output
- Analysis tool only — runs AFTER engine produces results
4. numba_core.py: added missing 'import math' for compute_reward_vectorized
13 new tests: vectorized reward bit-identity, Ray determinism, Ray result fields,
VBT metrics structure, cross-asset comparison, parameter sensitivity, edge cases.
Total: 1178 tests, 50 files, all green, zero regressions.
2026-07-12 23:56:16 +02:00
Codex
019b620ab9
malkhut: asset bridge — directory ↔ classification integration
...
asset_bridge.py: connects Fable's AssetDirectory (operational layer,
runtime-mutable, JSON-backed listing status) with our AssetProfile
(taxonomic layer, frozen, invariant classification).
Functions:
- sync_asset_to_profile(directory, symbol): sync one asset's TRADING
exchanges from directory to AssetProfile.exchanges
- sync_exchanges_from_directory(directory): sync all matching assets
- get_universe_stats(directory): matched/unmatched counts
49 tests covering:
- normalize_symbol (7 edge cases)
- ExchangeListing validation (4 tests)
- AssetRecord listing queries (5 tests)
- AssetDirectory CRUD + persistence (14 tests)
- symbols_for_exchange filtering by status (4 tests)
- venue_symbol mapping (3 tests)
- Bridge sync (8 tests with state save/restore)
- Integration with ScenarioFactory + get_assets_on_exchange (4 tests)
Total: 1246 tests across 49 files, all green, zero regressions.
Fable's assets/ package preserved intact, interfaces retained.
2026-07-12 10:45:37 +02:00
Codex
1f709af6d1
malkhut: three-layer identifier architecture for cross-system asset identification
...
Layer 1 (canonical identity): symbol, base_asset, name, unified_symbol
(CCXT format), quote_currency
Layer 2 (cross-system): coingecko_id, cmc_id, blockchain, contract_address
Layer 3 (exchange mapping): exchanges tuple
All 13 pre-defined assets migrated with accurate CoinGecko IDs, CMC IDs,
blockchains, and contract addresses (ERC-20 tokens).
7 new query functions: get_asset_by_coingecko_id, get_asset_by_cmc_id,
get_assets_by_base_asset, get_assets_by_blockchain,
get_assets_by_unified_symbol.
33 new tests covering: Layer 1 identity, Layer 2 cross-system identifiers,
identifier query functions, identifier consistency (uniqueness, derivation),
exchange registry.
Total: 1189 tests, 47 files, all green.
Based on research: CCXT BASE/QUOTE is de facto standard, CoinGecko ID
most widely used in crypto-native, ISO 24165 DTI emerging, FIGI for
institutional.
2026-07-12 00:40:14 +02:00
Codex
d2d0c5e292
malkhut: multi-exchange asset universe + schema docs
...
ExchangeProfile: standardized exchange metadata (fees, latency, capabilities).
3 pre-defined exchanges: Binance, BingX, Bybit.
AssetProfile.exchanges: tuple[str] — which venues trade each asset.
New query functions: get_assets_on_exchange, get_common_assets,
get_exchange_for_asset, get_exchange, list_exchanges.
_DATA_STORAGE_SCHEMA_FORMATS.md: comprehensive reference for agent
consumption — data model, storage format, query interfaces, data flow
diagram, enum reference, import patterns for BLUE/VIOLET/UV integration.
README updated: exchange registry section, package structure, subsystems
table.
2026-07-11 22:37:15 +02:00
Codex
be0e1468da
malkhut(perf): parallel episode eval — 9x single-eval speedup, zero fidelity loss
...
- parallel_eval.py: ProcessPoolExecutor-based episode runner. Each worker
gets its own CWM + planner instance. Zero shared state = embarrassingly
parallel. Deterministic: same seed → same result.
- PolicyEvaluator.evaluate_candidate: new workers parameter (0=sequential,
>1=parallel). Backward compatible: default workers=0.
- 16 new tests: determinism, pickling, result validity, cross-validation
between sequential and parallel paths, backward compatibility.
- README: training performance table with speedup measurements.
Speedup results (3 assets × 30 scenarios = 90 scenarios):
Sequential: 3.3s per eval (1.0x)
2 workers: 1.3s per eval (2.6x)
4 workers: 0.6s per eval (5.9x)
8 workers: 0.4s per eval (9.1x)
CMA-ES 48 evals: 125s → 85s (1.5x training speedup)
Note: CWM numba hot path was already wired (_HAS_NUMBA=True, 5.3µs/transition).
Bottleneck is MCTS planner (96% of eval time), not CWM.
2026-07-11 20:19:32 +02:00
Codex
dd86174107
malkhut(T8): cognition pipeline + regime expansion + prod tooling
...
Cognition pipeline (cognition.py): rate-limited, 8 sources, dedup, perm-run.
Regime expansion (regime_expansion.py): 200+ regimes from 4x4x4x4 dimensions.
News sources (news_sources.py): 12 industry-standard sources with ranking.
Monitor (monitor.py): metrics, health scoring, alerts, JSONL logging.
Cognition launcher (cognition_launcher.py): standalone long-run service.
Continuous pipeline (continuous_pipeline.py): forever-loop training runner.
2026-07-11 10:39:03 +02:00
Codex
ef2f8e8827
malkhut(T6): training core — CMA-ES trainer, registry, pipeline, selector
...
CMA-ES trainer (cma_trainer.py): self-play pool, bootstrap CI, ScenarioFactory
with behavior-driven scenarios, auto-compile, label query interfaces.
Policy registry (registry.py): CANDIDATE → ACTIVE lifecycle.
Training pipeline (pipeline.py): bounded continuous learning loop + logger.
Strategy selector (selector.py): regime → strategy mapping, performance matrix.
2026-07-11 10:33:56 +02:00
Codex
863a4cc8c9
malkhut(T4): Strategy DSL v2 + generator + supporting modules
...
Strategy DSL v2 (dsl.py): 40+ action primitives, 40+ market sensors,
12 comparison operators, 16 builtins, full parser.
Strategy Generator (generator.py): genetic programming evolution —
crossover, mutation, tournament selection, pool management.
Supporting: discrepancy tracking, execution quality, hooks, feature
importance, observability, parallel eval, auto-rollback, stress testing,
structured observations, trajectory recording.
2026-07-11 10:28:38 +02:00
Codex
981b469d51
malkhut: asset classification, behavior DSL, auto-compiler, behavior-driven scenarios
...
Cambrian Explosion Phase 0 complete:
- Multi-label invariant asset taxonomy (13 assets, 10 sectors, 6 roles)
- Asset Behavior DSL: 10 orthogonal dimensions per asset, 3 composable
templates, research-validated from live Binance/BingX API data
- Asset Compiler: auto-fetch from Binance public API, compute profiles,
rate-limited (1 req/s), cached, 28 known classifications
- ScenarioFactory: all 30 scenario types use behavior-driven prices
(BTC=$64K, ETH=$1.8K, SOL=$80, DOGE=$0.07) instead of hardcoded
BTC prices. Auto-compiles unknown assets on demand.
- Label query interfaces: build_suite_for_sector/role/template/vol/labels
- 190 exhaustive tests for asset classification (up from 66)
- 1140 tests all green, CWM throughput 189K calls/s (121% of baseline)
- Comprehensive README: 1043 lines with full documentation
Research sources: Binance live REST API, BingX open API, CoinGlass,
academic literature (Bouchaud, Cont/Stoikov, Cartea/Jaimungal)
2026-07-11 06:37:17 +02:00