feat(routing): wire AI target_asset end-to-end — bot trades the right perp

Closes the loop on the asset-routing prompt change. Previously the v5
prompt emitted target_asset (e.g. SOL, TRUMP) but bot_engine still
read price_impact_asset and only ever traded BTC/ETH. Now the trade
actually fires on whatever perp the AI picked.

Schema (alembic 006):
  posts.target_asset       (str)   — HL perp ticker, any of the universe
  posts.category           (str)   — 6-class enum (direct_named, etc.)
  posts.expected_move_pct  (float) — AI's 1h move estimate

Wiring:
  truth_social.py persists the three fields when creating Post rows.
  bot_engine.py routing:  asset = target_asset || price_impact_asset || BTC
  Old rows (target_asset=NULL) fall back to legacy BTC/ETH path — no
  retroactive scoring needed; new rows route correctly from now on.

Hyperliquid trader doesn't need changes — `coin` is already a parameter,
and analysis.py validated against HL_PERPS before storing target_asset
so by the time bot_engine reads the field, it's guaranteed tradeable.

Deployment:
  alembic upgrade head    # adds the 3 columns
  Restart api container

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
k
2026-05-08 15:30:41 +08:00
parent 8fd9da3c8d
commit 9872a4cc52
4 changed files with 56 additions and 1 deletions
+5
View File
@@ -102,11 +102,16 @@ async def _process_entry(entry: dict, db: AsyncSession) -> Optional[Post]:
prefilter_reason=analysis.get("prefilter_reason"),
analysis_version=analysis.get("analysis_version"),
relevant=analysis["relevant"],
# `asset` (BTC/ETH only) feeds the existing price_impact tracker.
price_impact_asset=asset if analysis["relevant"] else None,
price_impact_m5=None, # filled by price_impact_monitor after 5 m
price_impact_m15=None, # filled by price_impact_monitor after 15 m
price_impact_m1h=None, # filled by price_impact_monitor after 1 h
price_at_post=price_at_post,
# v5 routing: AI decides the actual perp to trade. May be SOL/TRUMP/etc.
target_asset=analysis.get("target_asset"),
category=analysis.get("category"),
expected_move_pct=analysis.get("expected_move_pct"),
)
db.add(post)
await db.flush()