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.
This commit is contained in:
Codex
2026-07-14 15:18:56 +02:00
parent 455a7a5a4e
commit 401d5a70ca
2 changed files with 102 additions and 42 deletions

View File

@@ -604,7 +604,7 @@ class MinimalCryptoLOBCWM:
tail_risk = self._tail_risk_proxy(next_state)
is_maker = (action.order_type and
action.order_type.value in ("POST_ONLY", "LIMIT"))
action.order_type.value == "LIMIT") or action.post_only
is_cross = action.kind.value == "CROSS_SPREAD"
is_cancel = action.kind.value in ("CANCEL", "CANCEL_REPLACE")
@@ -636,7 +636,7 @@ class MinimalCryptoLOBCWM:
reward -= params.w_tail_loss * self._tail_risk_proxy(next_state)
reward -= params.w_time_decay * math.log1p(max(time_in_loss, 0.0))
if action.order_type and action.order_type.value in ("POST_ONLY", "LIMIT"):
if (action.order_type and action.order_type.value == "LIMIT") or action.post_only:
reward += params.w_fee_quality * max(0.0, -prev_state.venue.maker_fee_bps)
if action.kind.value == "CROSS_SPREAD":