首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >[Python技术]怎么用miniqmt筛选涨停放量下跌缩量选股

[Python技术]怎么用miniqmt筛选涨停放量下跌缩量选股

作者头像
子晓聊技术
发布2026-04-23 15:23:36
发布2026-04-23 15:23:36
1620
举报
文章被收录于专栏:子晓AI量化子晓AI量化

之前有同学问我怎么筛选 近20个交易日存在一个涨停, 最近缩量的 个股, 常规的query需求,我一般用问财搞定,毕竟我懒, 但 一些条件复杂的语句,问财可能实现就有点困难。

这些一般来说, 用Python或通达信实现更方便, 因为需要筛选A股数据量比较大,这里以miniqmt举例实现。 主要包括下载数据, 做筛选逻辑。

这只是一种策略模式。这里解释下,为啥我们要 筛选 低位上涨放量、 下跌缩量的个股, 上涨放量是有主力进攻, 而下跌缩量 说明大家都吸筹了。

在上涨趋势的回调阶段,下跌缩量(成交量萎缩至上涨段的一半以下)反映市场抛压衰竭,核心逻辑在于:惜售心理主导:持仓者(尤其是主力)因看好后市拒绝低价抛售,导致卖盘稀缺。若此时跌幅有限(如小阴线缓跌),更验证筹码锁定良好。

一些同学可能会有某些想法。比如 股价缩量回踩10日均线或20日均线附近,成交量阶梯式递减。 这些都可以用类似的方式实现, 借助talib计算均线。

这里需要注意下,并不是说这种技术形态的个股一定会涨, 还需要结合个股位置,以及热门概念, 这里只是演示下miniqmt怎么实现。

这里贴一下完整代码,参考下思路, 具体根据自己的实际情况改造。 备注:如果发现格式有多余的特殊字符,用普通浏览器打开复制应该没问题。

代码语言:javascript
复制
import time
import datetime
import pandas as pd
import numpy as np
from threading import Thread
from xtquant import xtdata
class StockSelector:
    def __init__(self):
        self.selected_stocks = {}  # 存储选股结果 {code: {'limit_up_vol': volume, 'last_vol': volume}}
        # 移除历史数据存储目录相关代码
    def get_history_data(self, code, count=20):
        """
        直接使用xtdata获取股票历史数据
        返回格式: [{'date': date, 'open', 'high', 'low', 'close', 'volume'}, ...]
        """
        # 生成xtquant标准代码格式
        xt_code = f"{code}.SZ" if code.startswith(('0', '3')) else f"{code}.SH"
        # 计算日期范围(覆盖最近count*2个交易日)
        end_date = datetime.datetime.now().strftime('%Y%m%d')
        start_date = (datetime.datetime.now() - datetime.timedelta(days=count * 2)).strftime('%Y%m%d')
        # 下载数据到miniQMT本地缓存
        xtdata.download_history_data(
            stock_code=xt_code,
            period="1d",  # 日线数据
            start_time=start_date,
            end_time=end_date
        )
        # 从本地缓存获取数据(前复权)
        data = xtdata.get_market_data_ex(
            stock_list=[xt_code],
            period="1d",
            start_time=start_date,
            end_time=end_date,
            dividend_type="front",  # 前复权
            fill_data=True
        )
        #print(data)
        if xt_code not in data:
            print(f"未获取到数据: {code}")
            return []
        # 转换为标准格式
        df = data[xt_code].reset_index()
        df = df.rename(columns={'index': 'date'})
        # 优化日期格式转换
        try:
            # 直接使用时间戳转换为日期字符串
            df['date'] = pd.to_datetime(df['date']).dt.strftime('%Y-%m-%d')
        except Exception as e:
            print(f"日期转换异常: {e}")
            df['date'] = df['date'].astype(str)
        return df.to_dict('records')
    def get_stock_list(self):
        """获取沪深A股所有股票代码(去掉后缀)"""
        all_stocks = xtdata.get_stock_list_in_sector("沪深A股")
        return [stock.split('.')[0] for stock in all_stocks]  # 去除交易所后缀
    def get_recent_limit_up_info(self, code, days=20):
        """
        获取最近20个交易日的涨停信息
        返回: [{'date': date, 'volume': volume}, ...]
        """
        try:
            # 获取历史数据
            data = self.get_history_data(code, days)
            if data is None or len(data) < 2:
                return []
            limit_up_list = []
            # 检查每天是否涨停(从最早到最新)
            for i in range(len(data) - 1):  # 不包括今天
                current = data[i]
                next_day = data[i + 1] if i + 1 < len(data) else None
                if next_day is None:
                    continue
                # 计算涨跌幅
                if current['close'] != 0:
                    change_pct = (next_day['close'] - current['close']) / current['close'] * 100
                    # 判断是否涨停(考虑不同板块的涨跌幅限制)
                    is_limit_up = False
                    if code.startswith('68'):  # 科创板
                        is_limit_up = change_pct >= 19.8
                    elif code.startswith('3') or code.startswith('0'):  # 创业板/中小板
                        is_limit_up = change_pct >= 19.8
                    else:  # 主板
                        is_limit_up = change_pct >= 9.8
                    if is_limit_up:
                        limit_up_list.append({
                            'date': next_day['date'],
                            'volume': next_day['volume']
                        })
            return limit_up_list
        except Exception as e:
            print(f"获取{code}涨停信息出错: {e}")
            return []
    def select_stocks(self):
        """
        选股逻辑:
        1. 前20个交易日有过涨停并记录下当时的成交量
        2. 上一个交易日缩量小于那个涨停成交量的4分之一
        3. 前20个交易日只有1个涨停
        """
        selected = {}
        # 获取所有股票代码
        stock_list = self.get_stock_list()
        total_stocks = len(stock_list)
        print(f"开始选股,共{total_stocks}只股票需要筛选...")
        for idx, code in enumerate(stock_list):
            if idx % 500 == 0:
                print(f"选股进度: {idx}/{total_stocks} ({idx / total_stocks * 100:.1f}%)")
            try:
                # 获取最近20个交易日的涨停信息
                limit_up_info = self.get_recent_limit_up_info(code, 20)
                # 条件1:前20个交易日只有1个涨停
                if len(limit_up_info) != 1:
                    continue
                # 获取最近2个交易日的数据
                recent_data = self.get_history_data(code, 2)
                if recent_data is None or len(recent_data) < 2:
                    continue
                last_limit_up = limit_up_info[0]
                last_day_data = recent_data[-1]  # 上一个交易日

                # 条件2:上一个交易日缩量小于涨停成交量的4分之一, 具体参数根据自己需求调整
                if last_day_data['volume'] >= last_limit_up['volume'] / 4:
                    continue
                selected[code] = {
                    'limit_up_vol': last_limit_up['volume'],
                    'last_vol': last_day_data['volume'],
                    'limit_up_date': last_limit_up['date']
                }
                print(
                    f"选中股票: {code}, 涨停日期: {last_limit_up['date']}, 涨停成交量: {last_limit_up['volume']}, 昨日成交量: {last_day_data['volume']}")
            except Exception as e:
                # 忽略异常继续下一只股票
                print(f"处理股票{code}时出错: {str(e)[:100]}...")  # 截断错误信息
                continue
        self.selected_stocks = selected
        return selected
def main():
    # 初始化选股器
    selector = StockSelector()
    print("开始选股...")
    selected = selector.select_stocks()
    print(f"选股完成,共选出 {len(selected)} 只股票")
    if len(selected) == 0:
        print("未选出符合条件的股票")
        return
    #监控
if __name__ == "__main__":
    main()

如果我的分享对你投资有所帮助,不吝啬给个点赞关注呗。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 子晓聊技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档