指标千千万,专业评测就一家!
声明:素材来源于网络或付费,仅供学习交流之用,无商业目的,若有侵权,请联系小编删帖,打赏费用为分析整理及运营费用;大数据模型工具及指标不属于投资资讯产品,旨在辅助大家提高投资胜率,仅不构成投资建议或未来保证,依此操作买卖,盈亏自负。
点击上方“指标评测”→点击右上角“ ... ”→选“设为星标 ★”
全自动量化工具,大数据选股,智能风控,AI盯盘,无需人工干预,散户投资也能用量化,上班族再也不愁看不了盘了! 关注仓鼠哥量化研究,围观量化实盘:
在股市里混,有句话叫“会买的是徒弟,会卖的是师傅”。 但很多时候,我们不想当什么师傅,遇上电闪雷鸣、风云突变,我们只想跑得比谁都快。 尤其对于那些用QMT搞量化策略的朋友,策略突然失灵、黑天鹅降临,或者就是单纯的想下班躺平,一个能快速离开牌桌的功能,就显得尤为重要。 所以,我写了这么个小工具,分享给有需要的朋友。 它叫 QMT 一键清仓工具,顾名思义,功能简单粗暴,就一个作用:帮你把账户里所有能卖的股票,全部清掉。 这玩意儿怎么用?用起来不难,整体分三步:准备 -> 预演 -> 动手。 第一步:准备工作(填好家庭住址)- 1. 启动它:
- • 如果你是技术宅,直接在命令行跑 python qingcang.py。
- • 如果嫌麻烦,就用我打包好的,直接双击 文件夹里的 exe。
- 2. 填好信息:
打开程序后,上方有几个空档,得填上:
- • QMT路径:找到你QMT安装目录下的 userdata_mini 文件夹,这是它的“家”。
- • 资金账号:填上你的账号“身份证号”。
- • 执行前二次确认:【墙裂建议,特别是实盘用户】 勾上这个选项!真金白银的,多一道确认,就多一分安全。
- 3. 保存设置:
如果你的电脑和账号都比较固定,点一下右下角的「保存设置」。这样下次就不用再填了,省事。 - 4、打开miniQMT,记得勾选极简模式/独立交易
第二步:预演(先看不摸)在按下“核按钮”之前,强烈建议先做两个动作测试一下: - • 点击「测试连接」:这是“握个手”,看看你的小工具能不能跟QMT的交易服务器说上话。它不下单,纯粹搞关系,放心按。成功的话会弹个窗告诉你兄弟挺你。
- • 点击「预览持仓」:这是“报个到”,看看你账上都压着哪些货,各有多少。也只看不摸,安全得很,让你心里有数。
第三步:动手(按下按钮)当你确认环境无误,仓位也看清楚,下定决心要“走为上”的时候,就可以按下那个最终的按钮—— 「一键清仓」 点击后,程序会立刻开始工作,对你所有可用的持仓发出卖出委托: - • 集合竞价时段,它会挂一个跌停价(或你设定的保守价),确保能成交。
- • 连续竞价时段,它会挂一个比买一价稍低的对手价,尽快甩卖。
整个过程都会在日志窗口里实时显示,哪只票、多少股、什么价、下单成功与否,一清二楚。最后还会给你一个总结:一共成功清掉了多少只。 一个稳妥的实盘流程如果你要在真金白银的账户上用,推荐你走完这个“标准流程”: - 1. 填好信息 -> 点一下 「保存设置」(一劳永逸)。
- 2. 点一下 「测试连接」 -> 确认网络和软件环境OK。
- 3. 点一下 「预览持仓」 -> 最后再看一眼你的 soldiers。
- 4. 当所有准备就绪,终于,深吸一口气,按下那个 「一键清仓」。
搞定。 工具虽好,可不要乱用。建议先在模拟环境里玩熟了,再上实盘。 祝你买啥啥涨,永远也用不上这个清仓功能。
示例
源码
- <div style="text-align: left;">from xtquant import xtdata</div><div style="text-align: left;">from xtquant.xttrader import XtQuantTrader</div><div style="text-align: left;">from xtquant.xttype import StockAccount</div><div style="text-align: left;">from xtquant import xtconstant</div><div style="text-align: left;">import datetime</div><div style="text-align: left;">import time</div><div style="text-align: left;">import random</div><div style="text-align: left;">import os</div><div style="text-align: left;">import json</div><div style="text-align: left;">import tkinter as tk</div><div style="text-align: left;">from tkinter import filedialog, messagebox</div><div style="text-align: left;">
- </div><div style="text-align: left;">
- </div><div style="text-align: left;">class MiniQMTClearAll:</div><div style="text-align: left;">def __init__(self, qmt_path, account_id):</div><div style="text-align: left;">"""</div><div style="text-align: left;">初始化一键清仓类</div><div style="text-align: left;">:param qmt_path: QMT安装路径下的userdata_mini文件夹路径</div><div style="text-align: left;">:param account_id: 资金账号</div><div style="text-align: left;">"""</div><div style="text-align: left;">self.qmt_path = qmt_path</div><div style="text-align: left;">self.account_id = account_id</div><div style="text-align: left;">self.session_id = random.randint(100000, 999999)</div><div style="text-align: left;">self.trader = None</div><div style="text-align: left;">self.account = None</div><div style="text-align: left;">
- </div><div style="text-align: left;">def connect_trader(self):</div><div style="text-align: left;">"""连接交易服务器"""</div><div style="text-align: left;">try:</div><div style="text-align: left;">self.trader = XtQuantTrader(self.qmt_path, self.session_id)</div><div style="text-align: left;">self.trader.start()</div><div style="text-align: left;">
- </div><div style="text-align: left;">connect_result = self.trader.connect()</div><div style="text-align: left;">if connect_result != 0:</div><div style="text-align: left;">print("交易服务器连接失败")</div><div style="text-align: left;">return False</div><div style="text-align: left;">
- </div><div style="text-align: left;">self.account = StockAccount(self.account_id)</div><div style="text-align: left;">subscribe_result = self.trader.subscribe(self.account)</div><div style="text-align: left;">if subscribe_result != 0:</div><div style="text-align: left;">print("账户订阅失败")</div><div style="text-align: left;">return False</div><div style="text-align: left;">
- </div><div style="text-align: left;">print("交易服务器连接成功")</div><div style="text-align: left;">return True</div><div style="text-align: left;">
- </div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">print(f"连接交易服务器时发生异常: {e}")</div><div style="text-align: left;">return False</div><div style="text-align: left;">
- </div><div style="text-align: left;">def get_current_time_period(self):</div><div style="text-align: left;">"""</div><div style="text-align: left;">判断当前所处的交易时段</div><div style="text-align: left;">返回: period_type - 'auction_am'(早盘竞价), 'continuous_am'(早盘连续),</div><div style="text-align: left;">'auction_pm'(午盘竞价), 'continuous_pm'(午盘连续), 'non_trading'(非交易时间)</div><div style="text-align: left;">"""</div><div style="text-align: left;">now = datetime.datetime.now()</div><div style="text-align: left;">current_time = now.time()</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 定义交易时段</div><div style="text-align: left;">morning_auction_start = datetime.time(9, 15) # 早盘集合竞价开始</div><div style="text-align: left;">morning_auction_end = datetime.time(9, 25) # 早盘集合竞价结束</div><div style="text-align: left;">morning_continuous_start = datetime.time(9, 30) # 早盘连续交易开始</div><div style="text-align: left;">noon_end = datetime.time(11, 30) # 午间休市</div><div style="text-align: left;">afternoon_start = datetime.time(13, 0) # 下午开盘</div><div style="text-align: left;">afternoon_auction_start = datetime.time(14, 57) # 收盘集合竞价开始</div><div style="text-align: left;">market_close = datetime.time(15, 0) # 收盘</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 判断当前时段</div><div style="text-align: left;">if morning_auction_start <= current_time <= morning_auction_end:</div><div style="text-align: left;">return 'auction_am'</div><div style="text-align: left;">elif morning_continuous_start <= current_time <= noon_end:</div><div style="text-align: left;">return 'continuous_am'</div><div style="text-align: left;">elif afternoon_start <= current_time < afternoon_auction_start:</div><div style="text-align: left;">return 'continuous_pm'</div><div style="text-align: left;">elif afternoon_auction_start <= current_time <= market_close:</div><div style="text-align: left;">return 'auction_pm'</div><div style="text-align: left;">else:</div><div style="text-align: left;">return 'non_trading'</div><div style="text-align: left;">
- </div><div style="text-align: left;">def get_stock_detail(self, stock_code):</div><div style="text-align: left;">"""</div><div style="text-align: left;">获取股票的详细信息,包括跌停价等</div><div style="text-align: left;">"""</div><div style="text-align: left;">try:</div><div style="text-align: left;">detail = xtdata.get_instrument_detail(stock_code)</div><div style="text-align: left;">if detail:</div><div style="text-align: left;">lower_limit = detail.get('DownStopPrice', 0)</div><div style="text-align: left;">upper_limit = detail.get('UpStopPrice', 0)</div><div style="text-align: left;">return lower_limit, upper_limit</div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">print(f"获取股票{stock_code}详情失败: {e}")</div><div style="text-align: left;">return 0, 0</div><div style="text-align: left;">
- </div><div style="text-align: left;">def get_market_price(self, stock_code):</div><div style="text-align: left;">"""</div><div style="text-align: left;">获取股票的最新市场价格</div><div style="text-align: left;">"""</div><div style="text-align: left;">try:</div><div style="text-align: left;">tick_data = xtdata.get_full_tick([stock_code])</div><div style="text-align: left;">if stock_code in tick_data:</div><div style="text-align: left;">last_price = tick_data[stock_code].get('lastPrice', 0)</div><div style="text-align: left;">bid_prices = tick_data[stock_code].get('bidPrice', [0])</div><div style="text-align: left;">ask_prices = tick_data[stock_code].get('askPrice', [0])</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 返回最新价、买一价、卖一价</div><div style="text-align: left;">return last_price, bid_prices[0] if bid_prices else last_price, ask_prices[</div><div style="text-align: left;">0] if ask_prices else last_price</div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">print(f"获取股票{stock_code}行情失败: {e}")</div><div style="text-align: left;">return 0, 0, 0</div><div style="text-align: left;">
- </div><div style="text-align: left;">def check_stock_status(self, stock_code):</div><div style="text-align: left;">"""</div><div style="text-align: left;">检查股票交易状态</div><div style="text-align: left;">"""</div><div style="text-align: left;">try:</div><div style="text-align: left;">detail = xtdata.get_instrument_detail(stock_code)</div><div style="text-align: left;">if detail:</div><div style="text-align: left;"># 假设InstrumentStatus <= 0表示正常交易状态</div><div style="text-align: left;">status = detail.get('InstrumentStatus', 1)</div><div style="text-align: left;">return status <= 0</div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">print(f"检查股票{stock_code}状态失败: {e}")</div><div style="text-align: left;">return False</div><div style="text-align: left;">
- </div><div style="text-align: left;">def get_positions(self):</div><div style="text-align: left;">"""获取当前持仓"""</div><div style="text-align: left;">try:</div><div style="text-align: left;">positions = self.trader.query_stock_positions(self.account)</div><div style="text-align: left;">if positions is None:</div><div style="text-align: left;">return []</div><div style="text-align: left;"># 过滤掉持仓数量为0的股票</div><div style="text-align: left;">return [pos for pos in positions if pos.volume > 0]</div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">print(f"查询持仓失败: {e}")</div><div style="text-align: left;">return []</div><div style="text-align: left;">
- </div><div style="text-align: left;">def calculate_sell_price(self, stock_code, period_type):</div><div style="text-align: left;">"""</div><div style="text-align: left;">根据交易时段计算卖出价格</div><div style="text-align: left;">"""</div><div style="text-align: left;">if period_type in ['auction_am', 'auction_pm']:</div><div style="text-align: left;"># 集合竞价时段:使用跌停价[1](@ref)</div><div style="text-align: left;">lower_limit, _ = self.get_stock_detail(stock_code)</div><div style="text-align: left;">if lower_limit > 0:</div><div style="text-align: left;">return lower_limit, '跌停价'</div><div style="text-align: left;">else:</div><div style="text-align: left;"># 如果获取跌停价失败,使用最新价</div><div style="text-align: left;">last_price, _, _ = self.get_market_price(stock_code)</div><div style="text-align: left;">return last_price * 0.9, '最新价90%' # 保守估计</div><div style="text-align: left;">else:</div><div style="text-align: left;"># 连续竞价时段:使用买一价或略低于买一价</div><div style="text-align: left;">_, bid_price, _ = self.get_market_price(stock_code)</div><div style="text-align: left;">if bid_price > 0:</div><div style="text-align: left;"># 略低于买一价,确保快速成交</div><div style="text-align: left;">sell_price = max(bid_price - 0.01, 0.01) # 最小变动单位</div><div style="text-align: left;">return sell_price, '对手价'</div><div style="text-align: left;">else:</div><div style="text-align: left;">last_price, _, _ = self.get_market_price(stock_code)</div><div style="text-align: left;">return last_price, '最新价'</div><div style="text-align: left;">
- </div><div style="text-align: left;">def clear_all_positions(self):</div><div style="text-align: left;">"""执行一键清仓操作"""</div><div style="text-align: left;">if not self.connect_trader():</div><div style="text-align: left;">return False</div><div style="text-align: left;">
- </div><div style="text-align: left;">print("开始执行一键清仓...")</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 获取当前持仓</div><div style="text-align: left;">positions = self.get_positions()</div><div style="text-align: left;">if not positions:</div><div style="text-align: left;">print("当前没有持仓可清仓")</div><div style="text-align: left;">return True</div><div style="text-align: left;">
- </div><div style="text-align: left;">print(f"发现 {len(positions)} 个持仓标的")</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 获取当前交易时段</div><div style="text-align: left;">period_type = self.get_current_time_period()</div><div style="text-align: left;">period_names = {</div><div style="text-align: left;">'auction_am': '早盘集合竞价',</div><div style="text-align: left;">'continuous_am': '早盘连续交易',</div><div style="text-align: left;">'auction_pm': '收盘集合竞价',</div><div style="text-align: left;">'continuous_pm': '午盘连续交易',</div><div style="text-align: left;">'non_trading': '非交易时间'</div><div style="text-align: left;">}</div><div style="text-align: left;">print(f"当前时段: {period_names.get(period_type, '未知时段')}")</div><div style="text-align: left;">
- </div><div style="text-align: left;">if period_type == 'non_trading':</div><div style="text-align: left;">print("当前为非交易时间,无法执行清仓操作")</div><div style="text-align: left;">return False</div><div style="text-align: left;">
- </div><div style="text-align: left;">success_count = 0</div><div style="text-align: left;">fail_count = 0</div><div style="text-align: left;">
- </div><div style="text-align: left;">for position in positions:</div><div style="text-align: left;">stock_code = position.stock_code</div><div style="text-align: left;"># 使用可用数量进行清仓,避免包含冻结或不可卖出的部分</div><div style="text-align: left;">try:</div><div style="text-align: left;">available_volume = getattr(position, 'can_use_volume', position.volume)</div><div style="text-align: left;">except Exception:</div><div style="text-align: left;">available_volume = position.volume</div><div style="text-align: left;">
- </div><div style="text-align: left;">if available_volume <= 0:</div><div style="text-align: left;">print(f"\n处理标的: {stock_code}, 可用持仓数量为0,跳过")</div><div style="text-align: left;">fail_count += 1</div><div style="text-align: left;">continue</div><div style="text-align: left;">
- </div><div style="text-align: left;">print(f"\n处理标的: {stock_code}, 可用持仓数量: {available_volume}")</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 检查股票状态</div><div style="text-align: left;">if not self.check_stock_status(stock_code):</div><div style="text-align: left;">print(f" ⚠️ {stock_code} 可能停牌或不可交易,跳过")</div><div style="text-align: left;">fail_count += 1</div><div style="text-align: left;">continue</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 计算卖出价格</div><div style="text-align: left;">sell_price, price_type = self.calculate_sell_price(stock_code, period_type)</div><div style="text-align: left;">print(f" 使用{price_type}: {sell_price}")</div><div style="text-align: left;">
- </div><div style="text-align: left;">if sell_price <= 0:</div><div style="text-align: left;">print(f" ❌ 价格无效,跳过")</div><div style="text-align: left;">fail_count += 1</div><div style="text-align: left;">continue</div><div style="text-align: left;">
- </div><div style="text-align: left;">try:</div><div style="text-align: left;"># 发送卖单(按可用数量清仓)</div><div style="text-align: left;">order_id = self.trader.order_stock(</div><div style="text-align: left;">account=self.account,</div><div style="text-align: left;">stock_code=stock_code,</div><div style="text-align: left;">order_type=xtconstant.STOCK_SELL, # 卖出</div><div style="text-align: left;">order_volume=available_volume, # 使用可用数量</div><div style="text-align: left;">price_type=xtconstant.FIX_PRICE, # 限价单</div><div style="text-align: left;">price=sell_price, # 价格</div><div style="text-align: left;">strategy_name='一键清仓',</div><div style="text-align: left;">order_remark='一键清仓'</div><div style="text-align: left;">)</div><div style="text-align: left;">
- </div><div style="text-align: left;">if order_id and int(order_id) > 0:</div><div style="text-align: left;">print(f" ✅ 清仓委托成功,订单号: {order_id}")</div><div style="text-align: left;">success_count += 1</div><div style="text-align: left;">else:</div><div style="text-align: left;">print(f" ❌ 清仓委托失败")</div><div style="text-align: left;">fail_count += 1</div><div style="text-align: left;">
- </div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">print(f" ❌ 下单异常: {e}")</div><div style="text-align: left;">fail_count += 1</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 短暂间隔,避免请求过于频繁</div><div style="text-align: left;">time.sleep(0.5)</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 输出汇总结果</div><div style="text-align: left;">print(f"\n清仓操作完成:")</div><div style="text-align: left;">print(f"成功委托: {success_count} 笔")</div><div style="text-align: left;">print(f"失败: {fail_count} 笔")</div><div style="text-align: left;">
- </div><div style="text-align: left;">return fail_count == 0</div><div style="text-align: left;">
- </div><div style="text-align: left;">def disconnect(self):</div><div style="text-align: left;">"""断开连接"""</div><div style="text-align: left;">if self.trader:</div><div style="text-align: left;">try:</div><div style="text-align: left;">self.trader.stop()</div><div style="text-align: left;">print("交易连接已断开")</div><div style="text-align: left;">except:</div><div style="text-align: left;">pass</div><div style="text-align: left;">
- </div><div style="text-align: left;">
- </div><div style="text-align: left;">def run_gui():</div><div style="text-align: left;">root = tk.Tk()</div><div style="text-align: left;">root.title("QMT 一键清仓工具1.0--仓鼠哥")</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 配置文件路径(与脚本同目录)</div><div style="text-align: left;">config_path = os.path.join(os.path.dirname(__file__), 'qingcang_config.json')</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 默认值</div><div style="text-align: left;">qmt_path_var = tk.StringVar(value='D:\\通达信\\QMT\\国金QMT交易端模拟\\userdata_mini')</div><div style="text-align: left;">account_var = tk.StringVar(value='39973887')</div><div style="text-align: left;">confirm_before_clear_var = tk.BooleanVar(value=True)</div><div style="text-align: left;">
- </div><div style="text-align: left;"># 尝试加载历史配置</div><div style="text-align: left;">try:</div><div style="text-align: left;">if os.path.exists(config_path):</div><div style="text-align: left;">with open(config_path, 'r', encoding='utf-8') as f:</div><div style="text-align: left;">cfg = json.load(f)</div><div style="text-align: left;">if isinstance(cfg, dict):</div><div style="text-align: left;">if cfg.get('qmt_path'):</div><div style="text-align: left;">qmt_path_var.set(cfg['qmt_path'])</div><div style="text-align: left;">if cfg.get('account_id'):</div><div style="text-align: left;">account_var.set(cfg['account_id'])</div><div style="text-align: left;">if 'confirm_before_clear' in cfg:</div><div style="text-align: left;">confirm_before_clear_var.set(bool(cfg['confirm_before_clear']))</div><div style="text-align: left;">except Exception:</div><div style="text-align: left;"># 配置加载异常时忽略,使用默认值</div><div style="text-align: left;">pass</div><div style="text-align: left;">
- </div><div style="text-align: left;">frame_top = tk.Frame(root)</div><div style="text-align: left;">frame_top.pack(fill=tk.X, padx=10, pady=10)</div><div style="text-align: left;">
- </div><div style="text-align: left;">tk.Label(frame_top, text="QMT 路径:").grid(row=0, column=0, sticky=tk.W, pady=5)</div><div style="text-align: left;">entry_qmt = tk.Entry(frame_top, textvariable=qmt_path_var, width=60)</div><div style="text-align: left;">entry_qmt.grid(row=0, column=1, sticky=tk.W, pady=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">def browse_qmt_path():</div><div style="text-align: left;">path = filedialog.askdirectory(title="选择 QMT userdata_mini 目录")</div><div style="text-align: left;">if path:</div><div style="text-align: left;">qmt_path_var.set(path)</div><div style="text-align: left;">
- </div><div style="text-align: left;">btn_browse = tk.Button(frame_top, text="浏览...", command=browse_qmt_path)</div><div style="text-align: left;">btn_browse.grid(row=0, column=2, padx=5, pady=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">tk.Label(frame_top, text="资金账号:").grid(row=1, column=0, sticky=tk.W, pady=5)</div><div style="text-align: left;">entry_account = tk.Entry(frame_top, textvariable=account_var, width=30)</div><div style="text-align: left;">entry_account.grid(row=1, column=1, sticky=tk.W, pady=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">frame_buttons = tk.Frame(root)</div><div style="text-align: left;">frame_buttons.pack(fill=tk.X, padx=10, pady=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">chk_confirm = tk.Checkbutton(frame_buttons, text="执行前二次确认", variable=confirm_before_clear_var)</div><div style="text-align: left;">chk_confirm.pack(side=tk.LEFT, padx=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">text_log = tk.Text(root, height=12, state=tk.DISABLED)</div><div style="text-align: left;">text_log.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)</div><div style="text-align: left;">
- </div><div style="text-align: left;">def log(message):</div><div style="text-align: left;">text_log.configure(state=tk.NORMAL)</div><div style="text-align: left;">text_log.insert(tk.END, str(message) + "\n")</div><div style="text-align: left;">text_log.see(tk.END)</div><div style="text-align: left;">text_log.configure(state=tk.DISABLED)</div><div style="text-align: left;">
- </div><div style="text-align: left;">def test_connect():</div><div style="text-align: left;">qmt_path = qmt_path_var.get().strip()</div><div style="text-align: left;">account_id = account_var.get().strip()</div><div style="text-align: left;">
- </div><div style="text-align: left;">if not qmt_path or not account_id:</div><div style="text-align: left;">messagebox.showwarning("提示", "请先填写 QMT 路径和资金账号")</div><div style="text-align: left;">return</div><div style="text-align: left;">
- </div><div style="text-align: left;">log("开始测试连接...")</div><div style="text-align: left;">clear_bot = MiniQMTClearAll(qmt_path, account_id)</div><div style="text-align: left;">try:</div><div style="text-align: left;">if clear_bot.connect_trader():</div><div style="text-align: left;">log("交易服务器连接成功")</div><div style="text-align: left;">messagebox.showinfo("测试连接", "交易服务器连接成功")</div><div style="text-align: left;">else:</div><div style="text-align: left;">log("交易服务器连接失败")</div><div style="text-align: left;">messagebox.showerror("测试连接", "交易服务器连接失败")</div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">log(f"连接测试异常: {e}")</div><div style="text-align: left;">messagebox.showerror("测试连接", f"连接测试异常: {e}")</div><div style="text-align: left;">finally:</div><div style="text-align: left;">clear_bot.disconnect()</div><div style="text-align: left;">log("连接已断开")</div><div style="text-align: left;">
- </div><div style="text-align: left;">def save_settings():</div><div style="text-align: left;">"""保存当前界面设置到本地配置文件"""</div><div style="text-align: left;">cfg = {</div><div style="text-align: left;">'qmt_path': qmt_path_var.get().strip(),</div><div style="text-align: left;">'account_id': account_var.get().strip(),</div><div style="text-align: left;">'confirm_before_clear': bool(confirm_before_clear_var.get()),</div><div style="text-align: left;">}</div><div style="text-align: left;">try:</div><div style="text-align: left;">with open(config_path, 'w', encoding='utf-8') as f:</div><div style="text-align: left;">json.dump(cfg, f, ensure_ascii=False, indent=2)</div><div style="text-align: left;">log("设置已保存")</div><div style="text-align: left;">messagebox.showinfo("保存设置", "当前设置已保存")</div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">log(f"保存设置失败: {e}")</div><div style="text-align: left;">messagebox.showerror("保存设置", f"保存设置失败: {e}")</div><div style="text-align: left;">
- </div><div style="text-align: left;">def preview_positions():</div><div style="text-align: left;">qmt_path = qmt_path_var.get().strip()</div><div style="text-align: left;">account_id = account_var.get().strip()</div><div style="text-align: left;">
- </div><div style="text-align: left;">if not qmt_path or not account_id:</div><div style="text-align: left;">messagebox.showwarning("提示", "请先填写 QMT 路径和资金账号")</div><div style="text-align: left;">return</div><div style="text-align: left;">
- </div><div style="text-align: left;">log("开始预览持仓...")</div><div style="text-align: left;">clear_bot = MiniQMTClearAll(qmt_path, account_id)</div><div style="text-align: left;">try:</div><div style="text-align: left;">if not clear_bot.connect_trader():</div><div style="text-align: left;">log("预览持仓时连接交易服务器失败")</div><div style="text-align: left;">messagebox.showerror("预览持仓", "连接交易服务器失败")</div><div style="text-align: left;">return</div><div style="text-align: left;">
- </div><div style="text-align: left;">positions = clear_bot.get_positions()</div><div style="text-align: left;">if not positions:</div><div style="text-align: left;">log("当前没有持仓")</div><div style="text-align: left;">messagebox.showinfo("预览持仓", "当前没有持仓")</div><div style="text-align: left;">return</div><div style="text-align: left;">
- </div><div style="text-align: left;">log(f"发现 {len(positions)} 个持仓标的:")</div><div style="text-align: left;">for pos in positions:</div><div style="text-align: left;">try:</div><div style="text-align: left;">stock_code = getattr(pos, 'stock_code', '')</div><div style="text-align: left;">volume = getattr(pos, 'volume', 0)</div><div style="text-align: left;">log(f"标的: {stock_code}, 持仓数量: {volume}")</div><div style="text-align: left;">except Exception:</div><div style="text-align: left;">pass</div><div style="text-align: left;">
- </div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">log(f"预览持仓异常: {e}")</div><div style="text-align: left;">messagebox.showerror("预览持仓", f"预览持仓异常: {e}")</div><div style="text-align: left;">finally:</div><div style="text-align: left;">try:</div><div style="text-align: left;">clear_bot.disconnect()</div><div style="text-align: left;">except Exception:</div><div style="text-align: left;">pass</div><div style="text-align: left;">log("预览完成,连接已断开")</div><div style="text-align: left;">
- </div><div style="text-align: left;">def clear_all_with_confirm():</div><div style="text-align: left;">qmt_path = qmt_path_var.get().strip()</div><div style="text-align: left;">account_id = account_var.get().strip()</div><div style="text-align: left;">
- </div><div style="text-align: left;">if not qmt_path or not account_id:</div><div style="text-align: left;">messagebox.showwarning("提示", "请先填写 QMT 路径和资金账号")</div><div style="text-align: left;">return</div><div style="text-align: left;">
- </div><div style="text-align: left;">if confirm_before_clear_var.get():</div><div style="text-align: left;">msg = (</div><div style="text-align: left;">"将对当前账户的全部持仓执行一键清仓操作,\n"</div><div style="text-align: left;">f"QMT 路径: {qmt_path}\n"</div><div style="text-align: left;">f"资金账号: {account_id}\n\n"</div><div style="text-align: left;">"请确认您已了解相关风险。"</div><div style="text-align: left;">)</div><div style="text-align: left;">ok = messagebox.askyesno("确认清仓", msg)</div><div style="text-align: left;">if not ok:</div><div style="text-align: left;">return</div><div style="text-align: left;">
- </div><div style="text-align: left;">no_more = messagebox.askyesno("确认提示设置", "是否下次不再弹出清仓确认对话框?")</div><div style="text-align: left;">if no_more:</div><div style="text-align: left;">confirm_before_clear_var.set(False)</div><div style="text-align: left;">
- </div><div style="text-align: left;">log("开始执行一键清仓...")</div><div style="text-align: left;">clear_bot = MiniQMTClearAll(qmt_path, account_id)</div><div style="text-align: left;">try:</div><div style="text-align: left;">success = clear_bot.clear_all_positions()</div><div style="text-align: left;">
- </div><div style="text-align: left;">if success:</div><div style="text-align: left;">log("一键清仓操作已完成")</div><div style="text-align: left;">messagebox.showinfo("一键清仓", "一键清仓操作已完成")</div><div style="text-align: left;">else:</div><div style="text-align: left;">log("一键清仓操作完成,但存在部分失败委托")</div><div style="text-align: left;">messagebox.showwarning("一键清仓", "一键清仓操作完成,但存在部分失败委托")</div><div style="text-align: left;">except Exception as e:</div><div style="text-align: left;">log(f"一键清仓异常: {e}")</div><div style="text-align: left;">messagebox.showerror("一键清仓", f"一键清仓异常: {e}")</div><div style="text-align: left;">finally:</div><div style="text-align: left;">try:</div><div style="text-align: left;">clear_bot.disconnect()</div><div style="text-align: left;">except Exception:</div><div style="text-align: left;">pass</div><div style="text-align: left;">log("清仓流程结束,连接已断开")</div><div style="text-align: left;">
- </div><div style="text-align: left;">btn_test = tk.Button(frame_buttons, text="测试连接", command=test_connect)</div><div style="text-align: left;">btn_test.pack(side=tk.LEFT, padx=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">btn_preview = tk.Button(frame_buttons, text="预览持仓", command=preview_positions)</div><div style="text-align: left;">btn_preview.pack(side=tk.LEFT, padx=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">btn_clear = tk.Button(frame_buttons, text="一键清仓", command=clear_all_with_confirm)</div><div style="text-align: left;">btn_clear.pack(side=tk.LEFT, padx=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">btn_save = tk.Button(frame_buttons, text="保存设置", command=save_settings)</div><div style="text-align: left;">btn_save.pack(side=tk.LEFT, padx=5)</div><div style="text-align: left;">
- </div><div style="text-align: left;">root.mainloop()</div><div style="text-align: left;">
- </div><div style="text-align: left;">
- </div><div style="text-align: left;">if __name__ == '__main__':</div><div style="text-align: left;">run_gui()</div>
复制代码
打包文件: 试读已结束,请付费阅读全文。   本文只能试读97%,付费后可阅读全文。  |