From 0fb327e397ab7059e458b0b3082d1bfdcb1186bd Mon Sep 17 00:00:00 2001 From: mike Date: Fri, 24 Jul 2026 12:06:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=87=E4=BB=BD=20hk=5Fintraday=5Fcl?= =?UTF-8?q?ose.py=20+=20us=5Fintraday=5Fclose.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- intraday-trading/scripts/hk_intraday_close.py | 90 +++++++++++++++++++ intraday-trading/scripts/us_intraday_close.py | 90 +++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100755 intraday-trading/scripts/hk_intraday_close.py create mode 100755 intraday-trading/scripts/us_intraday_close.py diff --git a/intraday-trading/scripts/hk_intraday_close.py b/intraday-trading/scripts/hk_intraday_close.py new file mode 100755 index 0000000..912eda8 --- /dev/null +++ b/intraday-trading/scripts/hk_intraday_close.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +"""港股日内交易强制平仓 - 北京时间15:45运行""" +import os, json, time +from datetime import datetime + +# Force SDK to use international endpoint (bypass 602315 mainland CN geo-block) +os.environ['LONGBRIDGE_REGION'] = 'ap' + +# Load LongBridge credentials +config = {} +with open(os.path.expanduser('~/.bashrc'), 'r') as f: + for line in f: + if line.startswith('export LONGPORT_'): + key, value = line.strip().split('=', 1) + config[key.replace('export ', '')] = value + +os.environ['LONGPORT_APP_KEY'] = config.get('LONGPORT_APP_KEY', '') +os.environ['LONGPORT_APP_SECRET'] = config.get('LONGPORT_APP_SECRET', '') +os.environ['LONGPORT_ACCESS_TOKEN'] = config.get('LONGPORT_ACCESS_TOKEN', '') + +from longport import openapi + +cfg = openapi.Config.from_env() +trade_ctx = openapi.TradeContext(config=cfg) + +# 读取入场记录 +entry_file = os.path.expanduser('~/.hermes/trading/hk_intraday_entries.json') +if not os.path.exists(entry_file): + print("📊 无日内持仓记录") + exit(0) + +with open(entry_file) as f: + entries = json.load(f) + +if not entries: + print("📊 无日内持仓") + exit(0) + +print(f"🔔 日内平仓开始 {datetime.now().strftime('%H:%M')}") +print("=" * 50) + +closed = [] +errors = [] + +for ticker, entry in list(entries.items()): + try: + # 只平仓日内系统自己开的仓位 + order_id = entry.get('order_id', '') + if not order_id: + print(f"⚠️ {ticker}: 无订单ID,跳过平仓") + continue + + entry_shares = entry.get('shares', 0) + + # 市价平仓(只平我们开的仓位数量) + if entry['side'] == 'buy': + resp = trade_ctx.submit_order( + symbol=ticker, + order_type=openapi.OrderType.MO, + side=openapi.OrderSide.Sell, + submitted_quantity=entry_shares, + time_in_force=openapi.TimeInForceType.Day, + ) + else: + resp = trade_ctx.submit_order( + symbol=ticker, + order_type=openapi.OrderType.MO, + side=openapi.OrderSide.Buy, + submitted_quantity=entry_shares, + time_in_force=openapi.TimeInForceType.Day, + ) + + print(f"✅ {ticker}: 平仓成功 ({entry['side']} {entry_shares}股)") + closed.append(ticker) + + except Exception as e: + print(f"❌ {ticker}: 平仓失败 - {e}") + errors.append(ticker) + +# 清理已平仓记录 +for ticker in closed: + del entries[ticker] + +with open(entry_file, 'w') as f: + json.dump(entries, f, indent=2) + +print() +print(f"📊 结果: {len(closed)}平仓, {len(errors)}失败") +if errors: + print(f"⚠️ 失败标的: {', '.join(errors)}") diff --git a/intraday-trading/scripts/us_intraday_close.py b/intraday-trading/scripts/us_intraday_close.py new file mode 100755 index 0000000..e122cd2 --- /dev/null +++ b/intraday-trading/scripts/us_intraday_close.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +"""美股日内交易强制平仓 - 北京时间3:45运行""" +import os, json, time +from datetime import datetime + +# Force SDK to use international endpoint (bypass 602315 mainland CN geo-block) +os.environ['LONGBRIDGE_REGION'] = 'ap' + +# Load LongBridge credentials +config = {} +with open(os.path.expanduser('~/.bashrc'), 'r') as f: + for line in f: + if line.startswith('export LONGPORT_'): + key, value = line.strip().split('=', 1) + config[key.replace('export ', '')] = value + +os.environ['LONGPORT_APP_KEY'] = config.get('LONGPORT_APP_KEY', '') +os.environ['LONGPORT_APP_SECRET'] = config.get('LONGPORT_APP_SECRET', '') +os.environ['LONGPORT_ACCESS_TOKEN'] = config.get('LONGPORT_ACCESS_TOKEN', '') + +from longport import openapi + +cfg = openapi.Config.from_env() +trade_ctx = openapi.TradeContext(config=cfg) + +# 读取入场记录 +entry_file = os.path.expanduser('~/.hermes/trading/us_intraday_entries.json') +if not os.path.exists(entry_file): + print("📊 无日内持仓记录") + exit(0) + +with open(entry_file) as f: + entries = json.load(f) + +if not entries: + print("📊 无日内持仓") + exit(0) + +print(f"🔔 美股日内平仓开始 {datetime.now().strftime('%H:%M')}") +print("=" * 50) + +closed = [] +errors = [] + +for ticker, entry in list(entries.items()): + try: + # 只平仓日内系统自己开的仓位 + order_id = entry.get('order_id', '') + if not order_id: + print(f"⚠️ {ticker}: 无订单ID,跳过平仓") + continue + + entry_shares = entry.get('shares', 0) + + # 市价平仓(只平我们开的仓位数量) + if entry['side'] == 'buy': + resp = trade_ctx.submit_order( + symbol=ticker, + order_type=openapi.OrderType.MO, + side=openapi.OrderSide.Sell, + submitted_quantity=entry_shares, + time_in_force=openapi.TimeInForceType.Day, + ) + else: + resp = trade_ctx.submit_order( + symbol=ticker, + order_type=openapi.OrderType.MO, + side=openapi.OrderSide.Buy, + submitted_quantity=entry_shares, + time_in_force=openapi.TimeInForceType.Day, + ) + + print(f"✅ {ticker}: 平仓成功 ({entry['side']} {entry_shares}股)") + closed.append(ticker) + + except Exception as e: + print(f"❌ {ticker}: 平仓失败 - {e}") + errors.append(ticker) + +# 清理已平仓记录 +for ticker in closed: + del entries[ticker] + +with open(entry_file, 'w') as f: + json.dump(entries, f, indent=2) + +print() +print(f"📊 结果: {len(closed)}平仓, {len(errors)}失败") +if errors: + print(f"⚠️ 失败标的: {', '.join(errors)}")