119 lines
5.2 KiB
Python
119 lines
5.2 KiB
Python
"""Unified CLI entrypoint for AlphaX Agent jobs."""
|
|
|
|
import argparse
|
|
import sys
|
|
|
|
from app.services import altcoin_confirm, altcoin_screener, event_driven_screener, market_overview, onchain_monitor, paper_trader, price_streamer, price_tracker, review_engine, sentiment_monitor
|
|
|
|
|
|
def build_parser():
|
|
parser = argparse.ArgumentParser(description="AlphaX Agent unified CLI")
|
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
|
|
screener = subparsers.add_parser("screener", help="运行粗筛/细筛")
|
|
screener.add_argument("--compact", action="store_true", help="输出紧凑 JSON")
|
|
|
|
confirm = subparsers.add_parser("confirm", help="运行确认流程")
|
|
confirm.add_argument("--compact", action="store_true", help="输出紧凑 JSON")
|
|
|
|
tracker = subparsers.add_parser("tracker", help="运行价格跟踪")
|
|
|
|
paper = subparsers.add_parser("paper-trader", help="运行模拟交易账本同步")
|
|
paper.add_argument("--limit", type=int, default=100, help="本轮最多处理的可执行推荐数量")
|
|
|
|
subparsers.add_parser("price-streamer", help="运行 websocket 实时价格流")
|
|
subparsers.add_parser("market", help="采集全市场快照")
|
|
|
|
review = subparsers.add_parser("review", help="运行复盘")
|
|
review.add_argument("--compact", action="store_true", help="输出紧凑 JSON")
|
|
review.add_argument("--no-push", action="store_true", help="只运行复盘,不发飞书")
|
|
|
|
event = subparsers.add_parser("event", help="运行事件驱动筛选")
|
|
event.add_argument("--no-process-existing", action="store_true", help="只处理本轮新采集事件")
|
|
|
|
sentiment = subparsers.add_parser("sentiment", help="运行舆情任务")
|
|
sentiment.add_argument("--collect", action="store_true", help="采集并存储")
|
|
sentiment.add_argument("--check", action="store_true", help="输出舆情异动")
|
|
sentiment.add_argument("--scores", action="store_true", help="输出评分")
|
|
|
|
onchain = subparsers.add_parser("onchain", help="运行链上追踪任务")
|
|
onchain.add_argument("--limit", type=int, default=60, help="本轮最多处理的 token 映射数量")
|
|
|
|
llm = subparsers.add_parser("llm-insights", help="异步生成 LLM 缓存解释")
|
|
llm.add_argument("--scope", choices=["recommendations", "sentiment", "sentiment-events", "review"], default="recommendations")
|
|
llm.add_argument("--limit", type=int, default=30)
|
|
|
|
return parser
|
|
|
|
|
|
def main():
|
|
parser = build_parser()
|
|
args = parser.parse_args()
|
|
|
|
if args.command == "screener":
|
|
return altcoin_screener.main(compact=args.compact)
|
|
if args.command == "confirm":
|
|
return altcoin_confirm.main(compact=args.compact)
|
|
if args.command == "tracker":
|
|
return price_tracker.main()
|
|
if args.command == "paper-trader":
|
|
return paper_trader.main(limit=args.limit)
|
|
if args.command == "price-streamer":
|
|
return price_streamer.main()
|
|
if args.command == "market":
|
|
result = market_overview.collect_market_snapshot()
|
|
print(sentiment_monitor.json.dumps(result, ensure_ascii=False, indent=2))
|
|
return result
|
|
if args.command == "review":
|
|
return review_engine.run_review(push_enabled=not args.no_push, compact=args.compact)
|
|
if args.command == "event":
|
|
result = event_driven_screener.run_once(process_existing=not args.no_process_existing)
|
|
print(event_driven_screener.json.dumps(result, ensure_ascii=False, indent=2, default=str))
|
|
return result
|
|
if args.command == "sentiment":
|
|
if args.collect:
|
|
result = sentiment_monitor.collect_and_store()
|
|
print(sentiment_monitor.json.dumps(result, ensure_ascii=False))
|
|
return result
|
|
if args.scores:
|
|
result = sentiment_monitor.get_sentiment_scores()
|
|
print(sentiment_monitor.json.dumps(result, ensure_ascii=False, indent=2))
|
|
return result
|
|
holdings = sentiment_monitor.get_active_holdings()
|
|
alerts = sentiment_monitor.get_sentiment_alert(holdings=holdings)
|
|
if args.check:
|
|
print(sentiment_monitor.json.dumps(alerts, ensure_ascii=False, indent=2))
|
|
return alerts
|
|
result = {
|
|
"alerts": alerts,
|
|
"sentiment_scores": sentiment_monitor.get_sentiment_scores(),
|
|
"holdings_count": len(holdings),
|
|
"check_time": sentiment_monitor.datetime.now().isoformat(),
|
|
}
|
|
print(sentiment_monitor.json.dumps(result, ensure_ascii=False, indent=2))
|
|
return result
|
|
if args.command == "onchain":
|
|
return onchain_monitor.run_once(limit=args.limit)
|
|
if args.command == "llm-insights":
|
|
from app.services import llm_insights
|
|
|
|
result = llm_insights.run(scope=args.scope, limit=args.limit)
|
|
print(sentiment_monitor.json.dumps(result, ensure_ascii=False, indent=2))
|
|
return result
|
|
|
|
parser.error(f"unknown command: {args.command}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
main()
|
|
except Exception as exc:
|
|
try:
|
|
from app.db.system_logs import record_exception
|
|
|
|
command = " ".join(sys.argv[1:]) or "unknown"
|
|
record_exception(exc, source="cli", context={"argv": sys.argv, "command": command})
|
|
except Exception:
|
|
pass
|
|
raise
|