MiniQMT 量化实战:尾盘交易系统

摘要

本文基于 Python+MiniQMT 实现 A 股经典尾盘策略的全自动化,完成14:55 同花顺问财选股→CSV 存盘→14:57 自动读取并批量下单的完整流程。提供修正后可直接运行的精简代码,同时给出核心优化方向,适合上班族及量化入门者快速上手。

一、前言

尾盘选股凭借低风险、短持股、高资金效率的特点,成为 A 股主流交易策略之一。但手动盯盘选股、下单效率低且易受情绪影响。本文通过 MiniQMT 实现全流程自动化,解放人力同时提升交易执行力。

二、核心原理与系统架构

2.1 尾盘策略逻辑

  • 时间窗口:14:30-15:00,当日走势基本定型,波动风险低
  • 核心优势:仅承受隔夜风险,主力尾盘调仓行为暴露次日方向
  • 盈利逻辑:尾盘强势股次日大概率高开 / 冲高,实现 T+1 套利

2.2 系统架构

采用 "选股 + 交易" 解耦设计,通过 CSV 文件交互:

模块 执行时间 核心功能
选股模块 14:55 调用问财 API 筛选股票,生成当日选股 CSV
交易模块 14:57 MiniQMT 读取 CSV,自动计算仓位并下单

三、精简可运行代码

3.1 环境准备

  1. 登录 MiniQMT 并开启 Python API 权限
  2. 安装依赖:pip install pywencai pandas schedule

3.2 完整代码

复制代码
import pywencai
import pandas as pd
import logging
import os
import time
from datetime import datetime
from tquant import xt_trader, xtconstant

# 全局配置
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
logging.basicConfig(level=logging.INFO, format=LOG_FORMAT, handlers=[
    logging.FileHandler('tail_trade.log'), logging.StreamHandler()
])
logger = logging.getLogger(__name__)

# ---------------------- 选股模块 ----------------------
def get_stock_list():
    """自定义问财选股条件,返回股票DataFrame"""
    try:
        # 可修改为自己的选股条件
        query = "流通市值<50亿,换手率3%-10%,涨幅2%-5%,量比>1.5,非ST,非创业板,非北交所"
        df = pywencai.get(query=query, loop=True)
        logger.info(f"选股完成,共{len(df) if df is not None else 0}只")
        return df
    except Exception as e:
        logger.error(f"选股失败: {e}")
        return None

def save_csv(data):
    """保存选股结果到带日期的CSV文件"""
    if not data: return None
    os.makedirs('data', exist_ok=True)
    filename = f'data/tail_select_{datetime.now().strftime("%Y%m%d")}.csv'
    data.to_csv(filename, index=False, encoding='utf-8-sig')
    return filename

# ---------------------- 交易模块 ----------------------
class QMTTrade:
    def __init__(self):
        self.account = xt_trader.get_account_list()[0] if xt_trader.get_account_list() else None
    
    def get_price(self, code):
        """获取卖一价作为买入价,确保成交"""
        tick = xt_trader.get_full_tick([code])
        return tick[code]['askPrice1'] if (tick and code in tick) else 0
    
    def buy(self, code, quantity, price):
        """执行买入下单"""
        return xt_trader.order(self.account, code, xtconstant.STOCK_BUY, price, quantity)
    
    def run(self, csv_file):
        """执行交易主逻辑"""
        if not self.account:
            logger.error("无可用交易账户")
            return
        
        # 读取选股文件
        df = pd.read_csv(csv_file, encoding='utf-8-sig')
        if len(df) == 0: return
        
        # 获取可用资金
        balance = xt_trader.get_account_balance(self.account)
        available = balance['cash'] - balance['frozen_cash']
        logger.info(f"可用资金: {available:.2f}元")
        
        # 自动识别股票代码列
        code_col = next((c for c in ['code','股票代码','symbol'] if c in df.columns), None)
        if not code_col:
            logger.error("未找到股票代码列")
            return
        
        # 批量下单
        success = 0
        for i, row in df.iterrows():
            if i >= 5: break  # 最多买5只
            
            code = str(row[code_col]).strip()
            if '.' not in code:  # 转换为QMT标准代码
                code += '.SH' if code.startswith('6') else '.SZ'
            
            price = self.get_price(code)
            if price <= 0: continue
            
            # 每只股票用5%资金,取整100股
            qty = int(available * 0.05 / price / 100) * 100
            if qty < 100: continue
            
            if self.buy(code, qty, price):
                logger.info(f"买入成功: {code} {qty}股 @ {price:.2f}")
                success += 1
            time.sleep(0.5)
        
        logger.info(f"交易完成: 成功{success}只")

# ---------------------- 定时任务 ----------------------
def selection_task():
    data = get_stock_list()
    if data is not None:
        save_csv(data)

def trade_task():
    csv_file = f'data/tail_select_{datetime.now().strftime("%Y%m%d")}.csv'
    if os.path.exists(csv_file):
        QMTTrade().run(csv_file)
    else:
        logger.warning("今日无选股文件")

if __name__ == "__main__":
    import schedule
    schedule.every().day.at("14:55").do(selection_task)
    schedule.every().day.at("14:57").do(trade_task)
    
    logger.info("尾盘交易系统启动,等待执行...")
    while True:
        schedule.run_pending()
        time.sleep(1)

四、使用说明

  1. 修改get_stock_list函数中的query变量,替换为自己的选股条件
  2. 调整run方法中的max_stocks(默认 5 只)和position_ratio(默认 5%)
  3. 将代码复制到 MiniQMT Python 编辑器中运行,系统自动等待定时执行
  4. 查看tail_trade.log获取运行日志和交易记录

五、常见问题

  1. 问财数据为空:简化选股条件,避免过于复杂的逻辑组合
  2. 下单失败 :确认股票代码格式为xxx.SZ/SH,账户资金充足且股票未停牌
  3. 定时不执行:检查系统时间是否正确,程序是否保持后台运行

六、进阶扩展

  • 增加次日 9:30 自动止盈止损卖出
  • 加入企业微信 / 钉钉交易通知推送
  • 引入技术指标二次过滤选股结果
  • 添加单日最大亏损风控机制

七、免责声明

本文代码及策略仅供学习交流,不构成任何投资建议。量化交易存在风险,请谨慎决策并自行承担交易后果。

相关推荐
benchmark_cc11 小时前
Python量化实战:如何检测并剔除历史数据中的“闪崩/乌龙指”异常价格点?
开发语言·人工智能·python·量化·quantdash·量化数据源
2601_9669496517 小时前
实时行情中的成交量 Volume 到底是什么?包含盘中撤单量吗?从交易数据语义到 QuantDash 实战解析
开发语言·人工智能·python·量化·quantdash·量化数据源
2601_9669496521 小时前
9:25-9:30 如何获取 A 股开盘基准价?QuantDash Python SDK 实战初始化量化策略状态
开发语言·人工智能·python·量化·quantdash·量化数据源
维克兜率天21 小时前
4.1.3 策略类型全景图:六大策略,你适合哪个
笔记·python·算法·量化
维克兜率天1 天前
【维克】技术指标是什么:从均线到MACD的数学原理
人工智能·笔记·python·算法·量化
网络工程小王3 天前
【LLM开发实验】LLM推理基本介绍
人工智能·量化·推理
2601_966949653 天前
如何判断盘中最新价相对昨日收盘涨跌幅,并实时触发止盈止损条件单:QuantDash Python 实战
开发语言·python·量化策略·量化·quantdash
xier_ran3 天前
【infra之路】AWQ 详解:激活感知权重保护,让 W4A16 量化精度超越 GPTQ
线性代数·算法·机器学习·量化·infra
李可以量化4 天前
Redis Client 从了解到精通(二)下:String 类型进阶操作全解
redis·git·python·量化交易·qmt
2601_966949654 天前
如何利用 1 分钟 K 线在 14:50 精准捕捉尾盘异动?Python 量化实战:1 分钟 K 线 + 全市场扫描
开发语言·人工智能·python·量化·quantdash·量化数据源