alphax/app/cli.py
2026-05-16 23:54:43 +08:00

114 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Unified CLI entrypoint for AlphaX Agent Crypto jobs."""
import argparse
import sys
from app.services import altcoin_confirm, altcoin_screener, event_driven_screener, onchain_monitor, paper_trader, price_streamer, price_tracker, review_engine, sentiment_monitor
def build_parser():
parser = argparse.ArgumentParser(description="AlphaX Agent Crypto 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 实时价格流")
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 == "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