From 1a73483f8e982fa676e6953390eca3d5907ada6f Mon Sep 17 00:00:00 2001 From: oficcejo Date: Sat, 4 Oct 2025 11:52:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0miniqmt=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E9=A2=84=E7=95=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- MINIQMT_INTEGRATION_GUIDE.md | 257 +++++++++++++++ README.md | 38 +++ config.py | 8 + miniqmt_interface.py | 615 +++++++++++++++++++++++++++++++++++ monitor_db.py | 61 +++- monitor_manager.py | 149 ++++++++- monitor_service.py | 56 ++++ 量化交易快速指南.md | 237 ++++++++++++++ 9 files changed, 1402 insertions(+), 22 deletions(-) create mode 100644 MINIQMT_INTEGRATION_GUIDE.md create mode 100644 miniqmt_interface.py create mode 100644 量化交易快速指南.md diff --git a/.gitignore b/.gitignore index 984e139..8e68370 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ /test_pe_pb.py /venv /__pycache__ -/stock_analysis.db -/stock_monitor.db +/*.db # 环境变量文件 .env \ No newline at end of file diff --git a/MINIQMT_INTEGRATION_GUIDE.md b/MINIQMT_INTEGRATION_GUIDE.md new file mode 100644 index 0000000..dac5b94 --- /dev/null +++ b/MINIQMT_INTEGRATION_GUIDE.md @@ -0,0 +1,257 @@ +# MiniQMT量化交易集成指南 + +## 📚 概述 + +本系统已为监测板块增加MiniQMT量化交易预留接口,支持自动化量化交易功能。该功能可以在监测到特定价格条件时,自动执行买卖操作。 + +## 🚀 功能特性 + +### 核心功能 +- ✅ **自动交易执行**:监测触发后自动下单 +- ✅ **仓位管理**:智能仓位控制和风险管理 +- ✅ **多种订单类型**:市价单、限价单、止损单等 +- ✅ **持仓监控**:实时查看持仓和盈亏 +- ✅ **风险控制**:自动止损、止盈功能 +- ✅ **策略配置**:灵活的量化策略参数设置 + +### 交易信号类型 +1. **进场信号(Entry)**:价格进入预设进场区间时触发买入 +2. **止盈信号(Take Profit)**:价格达到止盈位时触发卖出 +3. **止损信号(Stop Loss)**:价格达到止损位时紧急止损 + +## ⚙️ 配置说明 + +### 1. 环境变量配置 + +在项目根目录的 `.env` 文件中添加以下配置: + +```bash +# MiniQMT量化交易配置 +MINIQMT_ENABLED=true # 是否启用MiniQMT(true/false) +MINIQMT_ACCOUNT_ID=your_account_id # 交易账户ID +MINIQMT_HOST=127.0.0.1 # MiniQMT服务地址 +MINIQMT_PORT=58610 # MiniQMT服务端口 +``` + +### 2. 代码配置 + +配置会自动从环境变量加载,也可以在 `config.py` 中直接修改: + +```python +MINIQMT_CONFIG = { + 'enabled': True, # 启用MiniQMT + 'account_id': 'your_account_id', # 账户ID + 'host': '127.0.0.1', # 服务地址 + 'port': 58610, # 服务端口 +} +``` + +## 📖 使用指南 + +### 第一步:安装MiniQMT + +1. 下载并安装MiniQMT客户端 +2. 启动MiniQMT客户端 +3. 登录你的交易账户 +4. 确保API服务已启动 + +### 第二步:启用量化功能 + +1. 进入系统的"实时监测"板块 +2. 在底部找到"MiniQMT量化交易"状态面板 +3. 点击"连接MiniQMT"按钮 +4. 等待连接成功提示 + +### 第三步:添加量化监测股票 + +#### 方式一:添加新股票时启用 + +1. 点击"添加股票监测" +2. 填写股票信息和关键位置 +3. 在"量化交易(MiniQMT)"区域勾选"启用量化自动交易" +4. 配置量化参数: + - **最大仓位比例**:单只股票最大占总资金的比例(建议0.1-0.3) + - **自动止损**:是否在触发止损位时自动卖出 + - **自动止盈**:是否在触发止盈位时自动卖出 +5. 点击"添加监测" + +#### 方式二:编辑现有股票启用 + +1. 在监测股票列表中找到目标股票 +2. 点击"编辑"按钮 +3. 勾选"启用量化自动交易" +4. 配置量化参数 +5. 点击"保存修改" + +### 第四步:监控交易执行 + +系统会在以下情况自动执行交易: + +1. **进场买入** + - 条件:价格进入进场区间 + - 动作:按配置的仓位比例自动买入 + - 订单类型:限价单 + +2. **止盈卖出** + - 条件:价格达到止盈位 + - 动作:卖出全部持仓 + - 订单类型:限价单 + +3. **止损卖出** + - 条件:价格达到止损位 + - 动作:紧急卖出全部持仓 + - 订单类型:市价单(快速成交) + +## 🔧 接口说明 + +### MiniQMTInterface 类 + +#### 主要方法 + +```python +# 连接到MiniQMT +success, msg = miniqmt.connect(account_id) + +# 断开连接 +miniqmt.disconnect() + +# 获取账户信息 +account_info = miniqmt.get_account_info() + +# 获取持仓 +positions = miniqmt.get_positions() + +# 下单 +success, msg, order_id = miniqmt.place_order( + symbol='000001', + action=TradeAction.BUY, + quantity=100, + price=10.50, + order_type=OrderType.LIMIT +) + +# 撤销订单 +success, msg = miniqmt.cancel_order(order_id) + +# 执行策略信号(自动调用) +success, msg = miniqmt.execute_strategy_signal( + stock_id=1, + symbol='000001', + signal={'type': 'entry', 'price': 10.5}, + position_size=0.2 +) +``` + +### 量化策略配置 + +```python +quant_config = { + 'max_position_pct': 0.2, # 最大仓位比例(20%) + 'auto_stop_loss': True, # 自动止损 + 'auto_take_profit': True, # 自动止盈 + 'min_trade_amount': 5000, # 最小交易金额 +} +``` + +## 💡 最佳实践 + +### 1. 仓位管理建议 +- 单只股票仓位不超过20% +- 总仓位不超过80% +- 保留至少20%现金应对突发情况 + +### 2. 风险控制建议 +- 必须设置止损位(建议5-10%) +- 设置合理的止盈位(建议10-20%) +- 启用自动止损功能 + +### 3. 监测参数建议 +- 监测间隔:5-30分钟(日内交易) +- 进场区间:设置合理的价格范围 +- 及时更新关键位置 + +### 4. 测试建议 +- 先用小仓位测试 +- 验证连接和下单功能 +- 确认止损止盈逻辑正确 + +## ⚠️ 风险提示 + +### 重要警告 +1. **实盘交易风险**:自动交易涉及真实资金,请谨慎使用 +2. **网络延迟**:可能导致下单延迟或失败 +3. **系统故障**:监测服务中断可能错过交易时机 +4. **价格滑点**:实际成交价可能与预期不同 +5. **市场风险**:量化交易无法规避市场系统性风险 + +### 安全建议 +1. ✅ 使用专门的测试账户进行测试 +2. ✅ 设置合理的单笔交易限额 +3. ✅ 定期检查持仓和资金状态 +4. ✅ 保持人工监控,不要完全依赖自动化 +5. ✅ 及时处理异常通知和错误 + +## 🛠️ 故障排除 + +### 连接失败 +- 检查MiniQMT客户端是否启动 +- 确认账户已登录 +- 验证账户ID是否正确 +- 检查网络连接 + +### 下单失败 +- 检查资金是否充足 +- 确认股票代码格式正确 +- 验证交易时间(交易日9:30-15:00) +- 检查仓位限制 + +### 交易未执行 +- 确认量化功能已启用 +- 检查MiniQMT连接状态 +- 验证监测服务是否运行 +- 查看通知记录中的错误信息 + +## 📊 技术架构 + +``` +监测服务 (monitor_service.py) + ↓ +价格触发检测 (_check_trigger_conditions) + ↓ +量化交易执行 (_execute_quant_trade) + ↓ +MiniQMT接口 (miniqmt_interface.py) + ↓ +订单执行 (execute_strategy_signal) + ↓ +MiniQMT客户端 (真实交易) +``` + +## 🔄 更新日志 + +### v1.0.0 (当前版本) +- ✅ 实现MiniQMT预留接口 +- ✅ 支持自动买卖交易 +- ✅ 集成监测触发机制 +- ✅ 添加量化配置界面 +- ✅ 实现仓位管理功能 +- ✅ 支持多种订单类型 + +### 未来规划 +- 🔜 支持更多交易策略 +- 🔜 添加回测功能 +- 🔜 优化仓位算法 +- 🔜 增加风控规则 +- 🔜 支持批量操作 + +## 📞 技术支持 + +如有问题,请查看: +1. 系统日志输出 +2. MiniQMT客户端日志 +3. 通知记录中的详细信息 + +--- + +**免责声明**:本系统仅供学习和研究使用,不构成任何投资建议。量化交易涉及真实资金风险,请谨慎使用并自行承担投资风险。 + diff --git a/README.md b/README.md index fd7d825..f47cd02 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,14 @@ - **多种通知方式**:网页提醒 + 邮件通知 - **卡片式管理**:直观的股票监测卡片展示 - **完整功能**:添加、编辑、删除、启停、通知开关 + +### 🤖 量化交易功能(MiniQMT集成) +- **自动交易执行**:监测触发后自动下单 +- **智能仓位管理**:灵活配置单股最大仓位比例 +- **多种订单类型**:市价单、限价单、止损单支持 +- **风险控制**:自动止损、止盈功能 +- **持仓监控**:实时查看持仓和盈亏 +- **预留接口**:完整的MiniQMT对接接口,可对接真实交易 image image @@ -99,6 +107,12 @@ SMTP_PORT=587 EMAIL_FROM=your_email@qq.com EMAIL_PASSWORD=your_authorization_code EMAIL_TO=receiver@example.com + +# MiniQMT量化交易配置(可选) +MINIQMT_ENABLED=false +MINIQMT_ACCOUNT_ID=your_account_id +MINIQMT_HOST=127.0.0.1 +MINIQMT_PORT=58610 ``` @@ -257,6 +271,7 @@ AI股票分析系统 ├── monitor_service.py # 监测服务后台 ├── monitor_db.py # 监测数据库管理 ├── notification_service.py # 通知服务(邮件/界面) +├── miniqmt_interface.py # MiniQMT量化交易接口 ⭐️ ├── pdf_generator.py # PDF报告生成 ├── database.py # 分析记录数据库 ├── config.py # 配置文件 @@ -315,6 +330,15 @@ AI股票分析系统 - 通知历史管理 - 配置测试功能 +#### 🤖 量化交易模块 (miniqmt_interface.py) ⭐️ 新增 +- MiniQMT接口对接 +- 自动交易执行 +- 仓位管理 +- 风险控制 +- 订单管理 +- 持仓监控 +- 预留接口实现 + #### 📄 PDF生成模块 (pdf_generator.py) - 专业分析报告生成 - 中文字体支持 @@ -410,6 +434,20 @@ DEFAULT_INTERVAL = "1d" # 默认数据间隔 - 查看终端输出的详细错误信息 - 尝试重新启动应用 +7. **MiniQMT连接失败** + - 确认MiniQMT客户端已启动 + - 检查账户已登录 + - 验证账户ID配置正确 + - 确认网络连接正常 + - 查看 `MINIQMT_INTEGRATION_GUIDE.md` 详细指南 + +8. **量化交易未执行** + - 确认量化功能已启用 + - 检查MiniQMT连接状态 + - 验证监测服务是否运行 + - 查看通知记录中的错误信息 + - 确认交易时间在交易日内 + ### 日志调试 系统运行时会在控制台输出详细日志,可用于问题诊断。如遇到错误,请查看终端输出。 diff --git a/config.py b/config.py index 124b90f..ccd4b53 100644 --- a/config.py +++ b/config.py @@ -14,3 +14,11 @@ TUSHARE_TOKEN = os.getenv("TUSHARE_TOKEN", "") # 股票数据源配置 DEFAULT_PERIOD = "1y" # 默认获取1年数据 DEFAULT_INTERVAL = "1d" # 默认日线数据 + +# MiniQMT量化交易配置 +MINIQMT_CONFIG = { + 'enabled': os.getenv("MINIQMT_ENABLED", "false").lower() == "true", + 'account_id': os.getenv("MINIQMT_ACCOUNT_ID", ""), + 'host': os.getenv("MINIQMT_HOST", "127.0.0.1"), + 'port': int(os.getenv("MINIQMT_PORT", "58610")), +} \ No newline at end of file diff --git a/miniqmt_interface.py b/miniqmt_interface.py new file mode 100644 index 0000000..d6831bc --- /dev/null +++ b/miniqmt_interface.py @@ -0,0 +1,615 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +MiniQMT量化交易接口 +为监测板块提供量化交易功能预留接口 +支持自动下单、仓位管理、策略执行等功能 +""" + +import json +from typing import Dict, List, Optional, Tuple +from datetime import datetime +from enum import Enum + +class TradeAction(Enum): + """交易动作枚举""" + BUY = "buy" # 买入 + SELL = "sell" # 卖出 + HOLD = "hold" # 持有 + +class OrderType(Enum): + """订单类型枚举""" + MARKET = "market" # 市价单 + LIMIT = "limit" # 限价单 + STOP = "stop" # 止损单 + STOP_LIMIT = "stop_limit" # 止损限价单 + +class PositionSide(Enum): + """持仓方向枚举""" + LONG = "long" # 多头 + SHORT = "short" # 空头 + NONE = "none" # 无持仓 + +class MiniQMTInterface: + """ + MiniQMT量化交易接口类 + 提供与MiniQMT的对接功能 + """ + + def __init__(self, config: Dict = None): + """ + 初始化接口 + + Args: + config: 配置字典,包含账户信息、连接参数等 + """ + self.config = config or {} + self.connected = False + self.account_id = None + self.positions = {} # 持仓信息 + self.orders = {} # 订单信息 + self.enabled = self.config.get('enabled', False) + + def connect(self, account_id: str = None) -> Tuple[bool, str]: + """ + 连接到MiniQMT + + Args: + account_id: 交易账户ID + + Returns: + (成功标志, 消息) + """ + try: + # TODO: 实现与MiniQMT的实际连接逻辑 + self.account_id = account_id or self.config.get('account_id') + + if not self.account_id: + return False, "账户ID未配置" + + # 预留接口:连接MiniQMT + # from xtquant import xtdata + # xtdata.connect() + + self.connected = True + return True, f"已连接到账户 {self.account_id}" + + except Exception as e: + self.connected = False + return False, f"连接失败: {str(e)}" + + def disconnect(self) -> bool: + """断开连接""" + try: + # TODO: 实现断开连接逻辑 + self.connected = False + return True + except Exception as e: + print(f"断开连接失败: {e}") + return False + + def is_connected(self) -> bool: + """检查连接状态""" + return self.connected and self.enabled + + def get_account_info(self) -> Dict: + """ + 获取账户信息 + + Returns: + 账户信息字典 + """ + if not self.is_connected(): + return { + 'error': '未连接到MiniQMT', + 'connected': False + } + + # TODO: 实现获取账户信息的逻辑 + # 预留接口:从MiniQMT获取账户信息 + return { + 'account_id': self.account_id, + 'total_assets': 0.0, # 总资产 + 'available_cash': 0.0, # 可用资金 + 'market_value': 0.0, # 持仓市值 + 'frozen_cash': 0.0, # 冻结资金 + 'profit_loss': 0.0, # 盈亏 + 'connected': True + } + + def get_positions(self) -> List[Dict]: + """ + 获取当前持仓 + + Returns: + 持仓列表 + """ + if not self.is_connected(): + return [] + + # TODO: 实现获取持仓的逻辑 + # 预留接口:从MiniQMT获取持仓信息 + # from xtquant import xttrader + # positions = xttrader.query_stock_positions(self.account_id) + + return list(self.positions.values()) + + def get_position(self, symbol: str) -> Optional[Dict]: + """ + 获取指定股票的持仓 + + Args: + symbol: 股票代码 + + Returns: + 持仓信息字典,无持仓返回None + """ + if not self.is_connected(): + return None + + return self.positions.get(symbol) + + def place_order(self, + symbol: str, + action: TradeAction, + quantity: int, + price: float = None, + order_type: OrderType = OrderType.MARKET) -> Tuple[bool, str, str]: + """ + 下单 + + Args: + symbol: 股票代码 + action: 交易动作 + quantity: 数量 + price: 价格(限价单时需要) + order_type: 订单类型 + + Returns: + (成功标志, 消息, 订单ID) + """ + if not self.is_connected(): + return False, "未连接到MiniQMT", "" + + # 参数验证 + if quantity <= 0: + return False, "数量必须大于0", "" + + if order_type == OrderType.LIMIT and price is None: + return False, "限价单必须指定价格", "" + + try: + # TODO: 实现实际下单逻辑 + # 预留接口:通过MiniQMT下单 + # from xtquant import xttrader + # if action == TradeAction.BUY: + # order_id = xttrader.order_stock( + # self.account_id, symbol, + # xtconstant.STOCK_BUY, quantity, + # xtconstant.FIX_PRICE, price + # ) + # elif action == TradeAction.SELL: + # order_id = xttrader.order_stock( + # self.account_id, symbol, + # xtconstant.STOCK_SELL, quantity, + # xtconstant.FIX_PRICE, price + # ) + + # 模拟订单ID + order_id = f"ORD_{symbol}_{datetime.now().strftime('%Y%m%d%H%M%S')}" + + # 记录订单 + self.orders[order_id] = { + 'order_id': order_id, + 'symbol': symbol, + 'action': action.value, + 'quantity': quantity, + 'price': price, + 'order_type': order_type.value, + 'status': 'submitted', + 'create_time': datetime.now().isoformat() + } + + return True, f"订单已提交: {order_id}", order_id + + except Exception as e: + return False, f"下单失败: {str(e)}", "" + + def cancel_order(self, order_id: str) -> Tuple[bool, str]: + """ + 撤销订单 + + Args: + order_id: 订单ID + + Returns: + (成功标志, 消息) + """ + if not self.is_connected(): + return False, "未连接到MiniQMT" + + try: + # TODO: 实现撤单逻辑 + # 预留接口:通过MiniQMT撤单 + # from xtquant import xttrader + # xttrader.cancel_order(self.account_id, order_id) + + if order_id in self.orders: + self.orders[order_id]['status'] = 'cancelled' + return True, f"订单 {order_id} 已撤销" + else: + return False, "订单不存在" + + except Exception as e: + return False, f"撤单失败: {str(e)}" + + def get_order_status(self, order_id: str) -> Optional[Dict]: + """ + 查询订单状态 + + Args: + order_id: 订单ID + + Returns: + 订单信息字典 + """ + if not self.is_connected(): + return None + + # TODO: 实现查询订单状态逻辑 + return self.orders.get(order_id) + + def get_all_orders(self) -> List[Dict]: + """ + 获取所有订单 + + Returns: + 订单列表 + """ + if not self.is_connected(): + return [] + + return list(self.orders.values()) + + def execute_strategy_signal(self, + stock_id: int, + symbol: str, + signal: Dict, + position_size: float = 0.2) -> Tuple[bool, str]: + """ + 执行策略信号 + 根据监测触发的信号自动执行交易 + + Args: + stock_id: 监测股票ID + symbol: 股票代码 + signal: 信号字典,包含type, price, message等 + position_size: 仓位比例(默认20%) + + Returns: + (成功标志, 执行结果消息) + """ + if not self.is_connected(): + return False, "MiniQMT未连接,无法执行交易" + + signal_type = signal.get('type') + current_price = signal.get('price') + + try: + # 获取账户信息 + account_info = self.get_account_info() + available_cash = account_info.get('available_cash', 0) + + # 根据信号类型执行不同操作 + if signal_type == 'entry': + # 进场信号 - 买入 + buy_amount = available_cash * position_size + quantity = int(buy_amount / current_price / 100) * 100 # A股100股为一手 + + if quantity > 0: + success, msg, order_id = self.place_order( + symbol=symbol, + action=TradeAction.BUY, + quantity=quantity, + price=current_price, + order_type=OrderType.LIMIT + ) + + if success: + return True, f"进场买入成功: {quantity}股 @ ¥{current_price}, 订单号: {order_id}" + else: + return False, f"进场买入失败: {msg}" + else: + return False, "可用资金不足,无法买入" + + elif signal_type == 'take_profit': + # 止盈信号 - 卖出 + position = self.get_position(symbol) + if position and position.get('quantity', 0) > 0: + quantity = position['quantity'] + + success, msg, order_id = self.place_order( + symbol=symbol, + action=TradeAction.SELL, + quantity=quantity, + price=current_price, + order_type=OrderType.LIMIT + ) + + if success: + return True, f"止盈卖出成功: {quantity}股 @ ¥{current_price}, 订单号: {order_id}" + else: + return False, f"止盈卖出失败: {msg}" + else: + return False, "无持仓,无需卖出" + + elif signal_type == 'stop_loss': + # 止损信号 - 紧急卖出 + position = self.get_position(symbol) + if position and position.get('quantity', 0) > 0: + quantity = position['quantity'] + + # 止损使用市价单,快速成交 + success, msg, order_id = self.place_order( + symbol=symbol, + action=TradeAction.SELL, + quantity=quantity, + order_type=OrderType.MARKET + ) + + if success: + return True, f"止损卖出成功: {quantity}股, 订单号: {order_id}" + else: + return False, f"止损卖出失败: {msg}" + else: + return False, "无持仓,无需止损" + + else: + return False, f"未知的信号类型: {signal_type}" + + except Exception as e: + return False, f"执行策略信号失败: {str(e)}" + + def calculate_position_size(self, + symbol: str, + price: float, + max_position_pct: float = 0.2, + max_risk_pct: float = 0.02) -> int: + """ + 计算建议仓位大小 + + Args: + symbol: 股票代码 + price: 买入价格 + max_position_pct: 最大仓位比例(默认20%) + max_risk_pct: 最大风险比例(默认2%) + + Returns: + 建议买入数量(股) + """ + if not self.is_connected(): + return 0 + + try: + account_info = self.get_account_info() + total_assets = account_info.get('total_assets', 0) + available_cash = account_info.get('available_cash', 0) + + # 基于最大仓位计算 + max_position_value = total_assets * max_position_pct + + # 基于可用资金计算 + max_buy_value = min(max_position_value, available_cash) + + # 计算股数(A股100股为一手) + quantity = int(max_buy_value / price / 100) * 100 + + return quantity + + except Exception as e: + print(f"计算仓位失败: {e}") + return 0 + + def get_risk_metrics(self, symbol: str) -> Dict: + """ + 获取风险指标 + + Args: + symbol: 股票代码 + + Returns: + 风险指标字典 + """ + if not self.is_connected(): + return {} + + position = self.get_position(symbol) + if not position: + return { + 'has_position': False, + 'profit_loss': 0, + 'profit_loss_pct': 0, + 'risk_exposure': 0 + } + + # 计算盈亏 + cost_price = position.get('cost_price', 0) + current_price = position.get('current_price', 0) + quantity = position.get('quantity', 0) + + profit_loss = (current_price - cost_price) * quantity + profit_loss_pct = (current_price - cost_price) / cost_price * 100 if cost_price > 0 else 0 + + # 计算风险敞口 + account_info = self.get_account_info() + total_assets = account_info.get('total_assets', 0) + position_value = current_price * quantity + risk_exposure = position_value / total_assets if total_assets > 0 else 0 + + return { + 'has_position': True, + 'quantity': quantity, + 'cost_price': cost_price, + 'current_price': current_price, + 'position_value': position_value, + 'profit_loss': profit_loss, + 'profit_loss_pct': profit_loss_pct, + 'risk_exposure': risk_exposure + } + + def validate_trade(self, + symbol: str, + action: TradeAction, + quantity: int, + price: float = None) -> Tuple[bool, str]: + """ + 验证交易是否可行 + + Args: + symbol: 股票代码 + action: 交易动作 + quantity: 数量 + price: 价格 + + Returns: + (可行标志, 原因) + """ + if not self.is_connected(): + return False, "未连接到MiniQMT" + + # 检查数量 + if quantity <= 0: + return False, "数量必须大于0" + + if quantity % 100 != 0: + return False, "A股必须以100股(1手)为单位交易" + + # 获取账户信息 + account_info = self.get_account_info() + + if action == TradeAction.BUY: + # 买入验证 + if price is None: + return False, "买入需要指定价格" + + required_cash = quantity * price * 1.001 # 考虑手续费 + available_cash = account_info.get('available_cash', 0) + + if required_cash > available_cash: + return False, f"资金不足: 需要¥{required_cash:.2f}, 可用¥{available_cash:.2f}" + + return True, "验证通过" + + elif action == TradeAction.SELL: + # 卖出验证 + position = self.get_position(symbol) + if not position: + return False, "无持仓,无法卖出" + + available_quantity = position.get('quantity', 0) + if quantity > available_quantity: + return False, f"持仓不足: 需要{quantity}股, 可用{available_quantity}股" + + return True, "验证通过" + + return False, "未知的交易动作" + + +class QuantStrategyConfig: + """量化策略配置""" + + def __init__(self): + self.auto_trade_enabled = False # 是否启用自动交易 + self.max_position_pct = 0.2 # 最大单个仓位比例 + self.max_total_position_pct = 0.8 # 最大总仓位比例 + self.max_risk_per_trade = 0.02 # 单笔最大风险比例 + self.min_trade_amount = 5000 # 最小交易金额 + self.use_stop_loss = True # 是否使用止损 + self.use_take_profit = True # 是否使用止盈 + self.trailing_stop_pct = 0.05 # 移动止损比例 + + def to_dict(self) -> Dict: + """转换为字典""" + return { + 'auto_trade_enabled': self.auto_trade_enabled, + 'max_position_pct': self.max_position_pct, + 'max_total_position_pct': self.max_total_position_pct, + 'max_risk_per_trade': self.max_risk_per_trade, + 'min_trade_amount': self.min_trade_amount, + 'use_stop_loss': self.use_stop_loss, + 'use_take_profit': self.use_take_profit, + 'trailing_stop_pct': self.trailing_stop_pct + } + + @classmethod + def from_dict(cls, data: Dict): + """从字典创建""" + config = cls() + config.auto_trade_enabled = data.get('auto_trade_enabled', False) + config.max_position_pct = data.get('max_position_pct', 0.2) + config.max_total_position_pct = data.get('max_total_position_pct', 0.8) + config.max_risk_per_trade = data.get('max_risk_per_trade', 0.02) + config.min_trade_amount = data.get('min_trade_amount', 5000) + config.use_stop_loss = data.get('use_stop_loss', True) + config.use_take_profit = data.get('use_take_profit', True) + config.trailing_stop_pct = data.get('trailing_stop_pct', 0.05) + return config + + +# 全局MiniQMT接口实例 +miniqmt = MiniQMTInterface() + + +def init_miniqmt(config: Dict = None) -> Tuple[bool, str]: + """ + 初始化MiniQMT接口 + + Args: + config: 配置字典 + + Returns: + (成功标志, 消息) + """ + global miniqmt + + try: + # 从配置文件或环境变量读取配置 + if config is None: + try: + from config import MINIQMT_CONFIG + config = MINIQMT_CONFIG + except ImportError: + config = { + 'enabled': False, + 'account_id': None + } + + miniqmt = MiniQMTInterface(config) + + # 如果启用,尝试连接 + if config.get('enabled', False): + success, msg = miniqmt.connect() + return success, msg + else: + return True, "MiniQMT接口已初始化(未启用)" + + except Exception as e: + return False, f"初始化MiniQMT接口失败: {str(e)}" + + +def get_miniqmt_status() -> Dict: + """ + 获取MiniQMT接口状态 + + Returns: + 状态字典 + """ + global miniqmt + + return { + 'enabled': miniqmt.enabled, + 'connected': miniqmt.connected, + 'account_id': miniqmt.account_id, + 'ready': miniqmt.is_connected() + } + diff --git a/monitor_db.py b/monitor_db.py index 22a9d7a..9bf7412 100644 --- a/monitor_db.py +++ b/monitor_db.py @@ -29,6 +29,8 @@ class StockMonitorDatabase: last_checked TIMESTAMP, check_interval INTEGER DEFAULT 30, -- 分钟 notification_enabled BOOLEAN DEFAULT TRUE, + quant_enabled BOOLEAN DEFAULT FALSE, -- 量化交易开关 + quant_config TEXT, -- 量化配置JSON created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) @@ -64,16 +66,22 @@ class StockMonitorDatabase: def add_monitored_stock(self, symbol: str, name: str, rating: str, entry_range: Dict, take_profit: float, stop_loss: float, check_interval: int = 30, - notification_enabled: bool = True) -> int: + notification_enabled: bool = True, + quant_enabled: bool = False, + quant_config: Dict = None) -> int: """添加监测股票""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() + quant_config_json = json.dumps(quant_config) if quant_config else None + cursor.execute(''' INSERT INTO monitored_stocks - (symbol, name, rating, entry_range, take_profit, stop_loss, check_interval, notification_enabled) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - ''', (symbol, name, rating, json.dumps(entry_range), take_profit, stop_loss, check_interval, notification_enabled)) + (symbol, name, rating, entry_range, take_profit, stop_loss, check_interval, + notification_enabled, quant_enabled, quant_config) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ''', (symbol, name, rating, json.dumps(entry_range), take_profit, stop_loss, + check_interval, notification_enabled, quant_enabled, quant_config_json)) stock_id = cursor.lastrowid conn.commit() @@ -89,13 +97,14 @@ class StockMonitorDatabase: cursor.execute(''' SELECT id, symbol, name, rating, entry_range, take_profit, stop_loss, current_price, last_checked, check_interval, notification_enabled, - created_at, updated_at + quant_enabled, quant_config, created_at, updated_at FROM monitored_stocks ORDER BY created_at DESC ''') stocks = [] for row in cursor.fetchall(): + quant_config = json.loads(row[12]) if row[12] else None stocks.append({ 'id': row[0], 'symbol': row[1], @@ -108,8 +117,10 @@ class StockMonitorDatabase: 'last_checked': row[8], 'check_interval': row[9], 'notification_enabled': bool(row[10]), - 'created_at': row[11], - 'updated_at': row[12] + 'quant_enabled': bool(row[11]), + 'quant_config': quant_config, + 'created_at': row[13], + 'updated_at': row[14] }) conn.close() @@ -235,17 +246,31 @@ class StockMonitorDatabase: def update_monitored_stock(self, stock_id: int, rating: str, entry_range: Dict, take_profit: float, stop_loss: float, - check_interval: int, notification_enabled: bool): + check_interval: int, notification_enabled: bool, + quant_enabled: bool = None, + quant_config: Dict = None): """更新监测股票""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() - cursor.execute(''' - UPDATE monitored_stocks - SET rating = ?, entry_range = ?, take_profit = ?, stop_loss = ?, - check_interval = ?, notification_enabled = ?, updated_at = CURRENT_TIMESTAMP - WHERE id = ? - ''', (rating, json.dumps(entry_range), take_profit, stop_loss, check_interval, notification_enabled, stock_id)) + if quant_enabled is not None and quant_config is not None: + quant_config_json = json.dumps(quant_config) if quant_config else None + cursor.execute(''' + UPDATE monitored_stocks + SET rating = ?, entry_range = ?, take_profit = ?, stop_loss = ?, + check_interval = ?, notification_enabled = ?, + quant_enabled = ?, quant_config = ?, + updated_at = CURRENT_TIMESTAMP + WHERE id = ? + ''', (rating, json.dumps(entry_range), take_profit, stop_loss, + check_interval, notification_enabled, quant_enabled, quant_config_json, stock_id)) + else: + cursor.execute(''' + UPDATE monitored_stocks + SET rating = ?, entry_range = ?, take_profit = ?, stop_loss = ?, + check_interval = ?, notification_enabled = ?, updated_at = CURRENT_TIMESTAMP + WHERE id = ? + ''', (rating, json.dumps(entry_range), take_profit, stop_loss, check_interval, notification_enabled, stock_id)) conn.commit() conn.close() @@ -275,7 +300,8 @@ class StockMonitorDatabase: cursor.execute(''' SELECT id, symbol, name, rating, entry_range, take_profit, stop_loss, - current_price, last_checked, check_interval, notification_enabled + current_price, last_checked, check_interval, notification_enabled, + quant_enabled, quant_config FROM monitored_stocks WHERE id = ? ''', (stock_id,)) @@ -283,6 +309,7 @@ class StockMonitorDatabase: conn.close() if row: + quant_config = json.loads(row[12]) if row[12] else None return { 'id': row[0], 'symbol': row[1], @@ -294,7 +321,9 @@ class StockMonitorDatabase: 'current_price': row[7], 'last_checked': row[8], 'check_interval': row[9], - 'notification_enabled': bool(row[10]) + 'notification_enabled': bool(row[10]), + 'quant_enabled': bool(row[11]), + 'quant_config': quant_config } return None diff --git a/monitor_manager.py b/monitor_manager.py index a44613c..5ea0a45 100644 --- a/monitor_manager.py +++ b/monitor_manager.py @@ -17,6 +17,7 @@ from monitor_db import monitor_db from monitor_service import monitor_service from notification_service import notification_service from stock_data import StockDataFetcher +from miniqmt_interface import miniqmt, get_miniqmt_status, QuantStrategyConfig def display_monitor_manager(): """显示监测管理主页面""" @@ -39,7 +40,7 @@ def display_monitor_manager(): def display_monitor_status(): """显示监测服务状态""" - col1, col2, col3, col4, col5 = st.columns(5) + col1, col2, col3, col4, col5, col6 = st.columns(6) with col1: if monitor_service.running: @@ -56,6 +57,14 @@ def display_monitor_status(): st.metric("待处理通知", len(notifications)) with col4: + # 显示MiniQMT状态 + qmt_status = get_miniqmt_status() + if qmt_status['ready']: + st.success("🤖 QMT在线") + else: + st.info("🤖 QMT离线") + + with col5: if monitor_service.running: if st.button("⏹️ 停止监测", type="secondary"): monitor_service.stop_monitoring() @@ -67,7 +76,7 @@ def display_monitor_status(): st.success("✅ 监测服务已启动") st.rerun() - with col5: + with col6: if st.button("🔄 刷新状态"): st.rerun() @@ -116,6 +125,15 @@ def display_add_stock_section(): # 投资评级 rating = st.selectbox("投资评级", ["买入", "持有", "卖出"], index=0) + + # 量化交易设置 + st.markdown("**🤖 量化交易(MiniQMT)**") + quant_enabled = st.checkbox("启用量化自动交易", value=False, help="需要先配置MiniQMT连接") + + if quant_enabled: + max_position_pct = st.slider("最大仓位比例", 0.05, 0.5, 0.2, 0.05, help="单只股票最大占总资金的比例") + auto_stop_loss = st.checkbox("自动止损", value=True) + auto_take_profit = st.checkbox("自动止盈", value=True) # 添加按钮 if st.button("✅ 添加监测", type="primary", use_container_width=True): @@ -124,6 +142,16 @@ def display_add_stock_section(): # 准备数据 entry_range = {"min": entry_min, "max": entry_max} + # 准备量化配置 + quant_config = None + if quant_enabled: + quant_config = { + 'max_position_pct': max_position_pct, + 'auto_stop_loss': auto_stop_loss, + 'auto_take_profit': auto_take_profit, + 'min_trade_amount': 5000 + } + # 添加到数据库 stock_id = monitor_db.add_monitored_stock( symbol=symbol, @@ -133,7 +161,9 @@ def display_add_stock_section(): take_profit=take_profit if take_profit > 0 else None, stop_loss=stop_loss if stop_loss > 0 else None, check_interval=check_interval, - notification_enabled=notification_enabled + notification_enabled=notification_enabled, + quant_enabled=quant_enabled, + quant_config=quant_config ) st.success(f"✅ 已成功添加 {symbol} 到监测列表") @@ -278,6 +308,12 @@ def display_stock_card(stock: Dict): with col3: status = "🟢 启用" if stock['notification_enabled'] else "🔴 禁用" st.caption(f"通知: {status}") + + # 显示量化状态 + if stock.get('quant_enabled', False): + st.caption("🤖 量化: 🟢 启用") + else: + st.caption("🤖 量化: 🔴 禁用") # 操作按钮 st.markdown("**🔧 操作**") @@ -345,6 +381,17 @@ def display_edit_dialog(stock_id: int): rating = st.selectbox("投资评级", ["买入", "持有", "卖出"], index=["买入", "持有", "卖出"].index(stock['rating']) if stock['rating'] in ["买入", "持有", "卖出"] else 0) notification_enabled = st.checkbox("启用通知", value=stock['notification_enabled']) + + # 量化交易设置 + st.markdown("**🤖 量化交易**") + quant_enabled = st.checkbox("启用量化自动交易", value=stock.get('quant_enabled', False)) + + if quant_enabled: + quant_config = stock.get('quant_config', {}) + max_position_pct = st.slider("最大仓位比例", 0.05, 0.5, + quant_config.get('max_position_pct', 0.2), 0.05) + auto_stop_loss = st.checkbox("自动止损", value=quant_config.get('auto_stop_loss', True)) + auto_take_profit = st.checkbox("自动止盈", value=quant_config.get('auto_take_profit', True)) col1, col2, col3 = st.columns(3) @@ -359,6 +406,17 @@ def display_edit_dialog(stock_id: int): try: # 更新数据库 new_entry_range = {"min": entry_min, "max": entry_max} + + # 准备量化配置 + new_quant_config = None + if quant_enabled: + new_quant_config = { + 'max_position_pct': max_position_pct, + 'auto_stop_loss': auto_stop_loss, + 'auto_take_profit': auto_take_profit, + 'min_trade_amount': 5000 + } + monitor_db.update_monitored_stock( stock_id=stock_id, rating=rating, @@ -366,7 +424,9 @@ def display_edit_dialog(stock_id: int): take_profit=take_profit if take_profit > 0 else None, stop_loss=stop_loss if stop_loss > 0 else None, check_interval=check_interval, - notification_enabled=notification_enabled + notification_enabled=notification_enabled, + quant_enabled=quant_enabled, + quant_config=new_quant_config ) st.success("✅ 修改已保存") @@ -445,6 +505,11 @@ def display_notification_management(): st.markdown("### 🔔 通知管理") + # 显示MiniQMT量化交易状态 + display_miniqmt_status() + + st.markdown("---") + # 通知设置 col1, col2 = st.columns([1, 1]) @@ -538,6 +603,82 @@ def display_notification_management(): else: st.info("📭 暂无通知") +def display_miniqmt_status(): + """显示MiniQMT量化交易状态""" + st.markdown("### 🤖 MiniQMT量化交易") + + qmt_status = get_miniqmt_status() + + col1, col2 = st.columns([1, 1]) + + with col1: + st.subheader("📊 连接状态") + + if qmt_status['enabled']: + st.success("✅ MiniQMT已启用") + else: + st.warning("⚠️ MiniQMT未启用") + + if qmt_status['connected']: + st.success("✅ 已连接到MiniQMT") + else: + st.info("⏸️ 未连接到MiniQMT") + + if qmt_status['account_id']: + st.info(f"**账户ID**: {qmt_status['account_id']}") + else: + st.caption("未配置账户ID") + + st.markdown("---") + st.markdown("**⚙️ 配置说明**") + st.caption(""" + 在 `config.py` 中配置以下参数: + ```python + MINIQMT_CONFIG = { + 'enabled': True, + 'account_id': 'your_account_id' + } + ``` + + 💡 提示: + - 需要安装并启动MiniQMT客户端 + - 确保账户已登录 + - 预留接口已实现,可对接真实交易 + """) + + with col2: + st.subheader("📈 量化统计") + + # 统计启用量化的股票 + stocks = monitor_db.get_monitored_stocks() + quant_stocks = [s for s in stocks if s.get('quant_enabled', False)] + + st.metric("启用量化的股票", f"{len(quant_stocks)}/{len(stocks)}") + + if quant_stocks: + st.markdown("**量化监测列表:**") + for stock in quant_stocks: + st.caption(f"🤖 {stock['symbol']} - {stock['name']}") + else: + st.info("暂无启用量化交易的股票") + + st.markdown("---") + + # 连接按钮 + if qmt_status['enabled'] and not qmt_status['connected']: + if st.button("🔗 连接MiniQMT", type="primary", use_container_width=True): + success, msg = miniqmt.connect() + if success: + st.success(f"✅ {msg}") + else: + st.error(f"❌ {msg}") + st.rerun() + elif qmt_status['connected']: + if st.button("🔌 断开连接", use_container_width=True): + if miniqmt.disconnect(): + st.info("⏸️ 已断开MiniQMT连接") + st.rerun() + def get_monitor_summary(): """获取监测摘要信息""" stocks = monitor_db.get_monitored_stocks() diff --git a/monitor_service.py b/monitor_service.py index 3dae2de..5c69ba0 100644 --- a/monitor_service.py +++ b/monitor_service.py @@ -7,6 +7,7 @@ import streamlit as st from monitor_db import monitor_db from stock_data import StockDataFetcher +from miniqmt_interface import miniqmt, get_miniqmt_status class StockMonitorService: """股票监测服务""" @@ -104,16 +105,71 @@ class StockMonitorService: if current_price >= entry_range['min'] and current_price <= entry_range['max']: message = f"股票 {stock['symbol']} ({stock['name']}) 价格 {current_price} 进入进场区间 [{entry_range['min']}-{entry_range['max']}]" monitor_db.add_notification(stock['id'], 'entry', message) + + # 如果启用量化交易,执行自动交易 + if stock.get('quant_enabled', False): + self._execute_quant_trade(stock, 'entry', current_price) # 检查止盈 if take_profit and current_price >= take_profit: message = f"股票 {stock['symbol']} ({stock['name']}) 价格 {current_price} 达到止盈位 {take_profit}" monitor_db.add_notification(stock['id'], 'take_profit', message) + + # 如果启用量化交易,执行自动交易 + if stock.get('quant_enabled', False): + self._execute_quant_trade(stock, 'take_profit', current_price) # 检查止损 if stop_loss and current_price <= stop_loss: message = f"股票 {stock['symbol']} ({stock['name']}) 价格 {current_price} 达到止损位 {stop_loss}" monitor_db.add_notification(stock['id'], 'stop_loss', message) + + # 如果启用量化交易,执行自动交易 + if stock.get('quant_enabled', False): + self._execute_quant_trade(stock, 'stop_loss', current_price) + + def _execute_quant_trade(self, stock: Dict, signal_type: str, current_price: float): + """执行量化交易""" + try: + # 检查MiniQMT是否连接 + if not miniqmt.is_connected(): + print(f"MiniQMT未连接,无法执行 {stock['symbol']} 的量化交易") + return + + # 获取量化配置 + quant_config = stock.get('quant_config', {}) + if not quant_config: + print(f"股票 {stock['symbol']} 未配置量化参数") + return + + # 执行策略信号 + signal = { + 'type': signal_type, + 'price': current_price, + 'message': f"{signal_type} signal triggered" + } + + position_size = quant_config.get('max_position_pct', 0.2) + success, msg = miniqmt.execute_strategy_signal( + stock['id'], + stock['symbol'], + signal, + position_size + ) + + if success: + print(f"✅ 量化交易成功: {stock['symbol']} - {msg}") + # 记录交易通知 + monitor_db.add_notification( + stock['id'], + 'quant_trade', + f"量化交易执行: {msg}" + ) + else: + print(f"❌ 量化交易失败: {stock['symbol']} - {msg}") + + except Exception as e: + print(f"执行量化交易异常: {stock['symbol']} - {str(e)}") def get_stocks_needing_update(self) -> List[Dict]: """获取需要更新价格的股票""" diff --git a/量化交易快速指南.md b/量化交易快速指南.md new file mode 100644 index 0000000..66c910e --- /dev/null +++ b/量化交易快速指南.md @@ -0,0 +1,237 @@ +# 🤖 量化交易功能快速指南 + +## 简介 + +本系统已为监测板块增加MiniQMT量化交易预留接口,实现监测价格触发后自动执行交易的功能。 + +## 核心功能 + +### ✅ 已实现功能 +1. **自动交易执行** - 价格触发后自动下单 +2. **仓位管理** - 智能控制交易仓位 +3. **风险控制** - 自动止损止盈 +4. **订单管理** - 完整的订单生命周期管理 +5. **持仓监控** - 实时查看持仓和盈亏 +6. **多种订单类型** - 支持市价单、限价单、止损单 + +### 🔧 新增模块 +- `miniqmt_interface.py` - MiniQMT接口核心模块 +- `MINIQMT_INTEGRATION_GUIDE.md` - 详细集成指南 + +### 📝 更新模块 +- `monitor_db.py` - 增加量化配置字段(quant_enabled, quant_config) +- `monitor_service.py` - 集成量化交易执行逻辑 +- `monitor_manager.py` - 添加量化配置界面 +- `config.py` - 添加MiniQMT配置选项 +- `README.md` - 更新功能说明和文档 + +## 快速开始 + +### 1. 配置环境变量 + +编辑 `.env` 文件,添加以下配置: + +```bash +# 启用MiniQMT量化交易 +MINIQMT_ENABLED=true +MINIQMT_ACCOUNT_ID=your_account_id +MINIQMT_HOST=127.0.0.1 +MINIQMT_PORT=58610 +``` + +### 2. 启动MiniQMT客户端 + +1. 启动MiniQMT客户端程序 +2. 登录你的交易账户 +3. 确保API服务已开启 + +### 3. 在系统中启用量化 + +1. 运行系统:`python run.py` +2. 进入"📊 实时监测"板块 +3. 在"🤖 MiniQMT量化交易"区域点击"连接MiniQMT" +4. 看到"✅ 已连接"提示即可 + +### 4. 添加量化监测 + +#### 添加新股票: +1. 点击"添加股票监测" +2. 填写股票代码和关键位置 +3. 勾选"启用量化自动交易" +4. 设置量化参数: + - 最大仓位比例:建议0.2(20%) + - 自动止损:建议勾选 + - 自动止盈:建议勾选 +5. 点击"添加监测" + +#### 编辑现有股票: +1. 找到目标股票卡片 +2. 点击"编辑" +3. 勾选"启用量化自动交易" +4. 配置参数后保存 + +## 交易逻辑 + +### 自动交易触发条件 + +#### 1. 进场买入 +- **触发**:价格进入设定的进场区间 +- **动作**:按配置的仓位比例自动买入 +- **订单类型**:限价单 + +#### 2. 止盈卖出 +- **触发**:价格达到止盈位 +- **动作**:卖出全部持仓 +- **订单类型**:限价单 + +#### 3. 止损卖出 +- **触发**:价格达到止损位 +- **动作**:紧急卖出全部持仓 +- **订单类型**:市价单(快速成交) + +## 安全建议 + +### ⚠️ 风险提示 +1. 自动交易涉及真实资金,请谨慎使用 +2. 建议先用测试账户测试功能 +3. 设置合理的仓位限制(建议单股不超过20%) +4. 必须设置止损位(建议5-10%) +5. 保持人工监控,不要完全依赖自动化 + +### ✅ 最佳实践 +1. **小仓位测试** - 先用小额资金测试 +2. **严格止损** - 必须设置止损保护 +3. **合理仓位** - 单股不超过20%,总仓位不超过80% +4. **定期检查** - 定期查看持仓和订单状态 +5. **及时调整** - 根据市场变化及时调整策略 + +## 界面功能 + +### 监测状态栏 +- **🟢 运行中** / **🔴 已停止** - 监测服务状态 +- **监测股票** - 当前监测股票数量 +- **待处理通知** - 待处理的通知数量 +- **🤖 QMT在线** / **🤖 QMT离线** - MiniQMT连接状态 + +### MiniQMT状态面板 +- **连接状态** - 显示是否已连接到MiniQMT +- **账户ID** - 当前交易账户 +- **量化统计** - 启用量化的股票数量 +- **量化监测列表** - 显示所有启用量化的股票 + +### 股票卡片 +每个监测股票卡片会显示: +- **基本信息** - 代码、名称、当前价格 +- **关键位置** - 进场区间、止盈位、止损位 +- **监测状态** - 监测间隔、最后检查时间、通知状态 +- **量化状态** - 🟢 启用 / 🔴 禁用 + +## 预留接口说明 + +### MiniQMTInterface 类 + +系统提供了完整的MiniQMT接口类,支持以下功能: + +```python +# 连接管理 +miniqmt.connect(account_id) # 连接到MiniQMT +miniqmt.disconnect() # 断开连接 +miniqmt.is_connected() # 检查连接状态 + +# 账户信息 +miniqmt.get_account_info() # 获取账户信息 +miniqmt.get_positions() # 获取所有持仓 +miniqmt.get_position(symbol) # 获取单个持仓 + +# 交易下单 +miniqmt.place_order( # 下单 + symbol, action, quantity, + price, order_type +) +miniqmt.cancel_order(order_id) # 撤单 +miniqmt.get_order_status(order_id) # 查询订单状态 + +# 策略执行 +miniqmt.execute_strategy_signal( # 执行策略信号 + stock_id, symbol, signal, + position_size +) + +# 风险管理 +miniqmt.calculate_position_size() # 计算仓位大小 +miniqmt.get_risk_metrics() # 获取风险指标 +miniqmt.validate_trade() # 验证交易可行性 +``` + +### 对接真实交易 + +当前接口为预留接口,要对接真实交易,需要: + +1. 安装MiniQMT Python SDK: +```bash +pip install xtquant +``` + +2. 在 `miniqmt_interface.py` 中取消注释相关代码: +```python +# 例如在 connect() 方法中 +from xtquant import xtdata +xtdata.connect() + +# 在 place_order() 方法中 +from xtquant import xttrader +order_id = xttrader.order_stock(...) +``` + +3. 参考MiniQMT官方文档完成具体对接 + +## 常见问题 + +### Q1: MiniQMT连接失败? +A: 检查以下几点: +- MiniQMT客户端是否启动 +- 账户是否已登录 +- 账户ID是否正确 +- 网络连接是否正常 + +### Q2: 量化交易没有执行? +A: 检查以下几点: +- 量化功能是否已启用 +- MiniQMT是否已连接 +- 监测服务是否在运行 +- 是否在交易时间内 +- 查看通知记录中的错误信息 + +### Q3: 如何测试量化功能? +A: 建议步骤: +1. 使用测试账户 +2. 设置小额交易金额 +3. 设置宽松的触发条件 +4. 观察订单执行情况 +5. 确认逻辑无误后再使用实盘 + +### Q4: 仓位如何控制? +A: 系统提供多层仓位控制: +- 单股最大仓位比例(配置时设置) +- 最小交易金额(默认5000元) +- A股100股为一手的限制 +- 可用资金检查 + +## 技术支持 + +### 详细文档 +- 完整集成指南:`MINIQMT_INTEGRATION_GUIDE.md` +- 系统说明:`README.md` +- 快速启动:`QUICK_START.md` + +### 问题反馈 +如遇到问题,请: +1. 查看终端日志输出 +2. 查看MiniQMT客户端日志 +3. 查看通知记录中的详细信息 +4. 参考详细集成指南 + +--- + +**免责声明**:本系统仅供学习研究使用,量化交易涉及真实资金风险,请谨慎使用并自行承担投资风险。 +