Files
openclaw-trading/scripts/trade_tool.py

108 lines
3.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
工具脚本手动执行交易操作
"""
import sys, os, argparse
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from engine import TradingEngine, load_config
def main():
parser = argparse.ArgumentParser(description='交易工具')
sub = parser.add_subparsers(dest='cmd')
# 状态
sub.add_parser('status', help='查看状态')
# 初始化
p_init = sub.add_parser('init', help='初始化(重置资金)')
p_init.add_argument('--cash', type=float, default=100000)
# 手动买入
p_buy = sub.add_parser('buy', help='手动买入')
p_buy.add_argument('code', help='股票代码 如 600519.SH')
p_buy.add_argument('--name', default='')
p_buy.add_argument('--price', type=float, required=True)
p_buy.add_argument('--qty', type=int, required=True)
p_buy.add_argument('--reason', default='手动买入')
# 手动卖出
p_sell = sub.add_parser('sell', help='手动卖出')
p_sell.add_argument('code', help='股票代码')
p_sell.add_argument('--price', type=float, required=True)
p_sell.add_argument('--reason', default='手动卖出')
# 运行一天
p_run = sub.add_parser('run', help='运行指定日期')
p_run.add_argument('--date', default=None)
# 交易历史
p_hist = sub.add_parser('history', help='交易历史')
p_hist.add_argument('--limit', type=int, default=20)
# 净值曲线
sub.add_parser('nav', help='净值历史')
args = parser.parse_args()
cfg = load_config()
engine = TradingEngine(cfg)
if args.cmd == 'status' or args.cmd is None:
print(engine.get_report())
elif args.cmd == 'init':
engine.state = {
'cash': args.cash, 'positions': {},
'last_scan_date': None, 'last_scan_idx': -engine.scan_interval,
'trade_count': 0, 'created': engine.state.get('created'),
'nav_history': [],
}
engine.save_state()
print(f"✅ 已重置,初始资金: ¥{args.cash:,.0f}")
elif args.cmd == 'buy':
name = args.name or args.code
engine.buy(args.code, name, args.price, args.qty,
datetime.now().strftime('%Y%m%d'), args.reason)
engine.save_state()
elif args.cmd == 'sell':
engine.sell(args.code, args.price,
datetime.now().strftime('%Y%m%d'), args.reason)
engine.save_state()
elif args.cmd == 'run':
engine.run_daily(args.date)
elif args.cmd == 'history':
import sqlite3
db = sqlite3.connect(engine._db_file())
rows = db.execute(
'SELECT date,code,name,direction,qty,price,pnl,pnl_pct,reason '
'FROM trades ORDER BY id DESC LIMIT ?', (args.limit,)
).fetchall()
db.close()
print(f"最近 {args.limit} 笔交易:")
for r in rows:
d, code, name, direction, qty, price, pnl, pnl_pct, reason = r
if direction == 'buy':
print(f" 🟢 {d} {name}({code}) {qty}股@¥{price:.2f}")
else:
print(f" {'' if (pnl or 0) > 0 else ''} {d} {name}({code}) "
f"{qty}股@¥{price:.2f} ¥{pnl or 0:+,.0f}({pnl_pct or 0:+.1f}%) [{reason}]")
elif args.cmd == 'nav':
history = engine.state.get('nav_history', [])
if not history:
print("无净值历史")
else:
print("净值历史:")
for h in history:
bar = '' * max(0, int(h['ret'] / 2)) if h['ret'] > 0 else '' * max(0, int(-h['ret'] / 2))
print(f" {h['date']}: ¥{h['nav']:>10,.2f} {h['ret']:>+6.2f}% {bar}")
if __name__ == '__main__':
main()