找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 9|回复: 1

[A股] 涨停板后缩量回调不破位,再次站上5日线

[复制链接]

1894

主题

523

回帖

7443

积分

管理员

积分
7443
发表于 7 天前 | 显示全部楼层 |阅读模式
  • 第一条件(启动点): 找到近期出现的一次涨停。
  • 第二条件(回调期): 涨停之后,股价开始回调,并跌破5日均线。
  • 第三条件(计数与约束): 从跌破5日线那天开始算起,连续观察1,2,3,4,5个交易日(或更多)。在这段回调期间,必须同时满足两个“不”:(1.不能跌破涨停那天的最低价(这是重要的支撑位,如果跌破说明形态走坏)。2.不能重新站上5日均线(始终被MA5压制)。)
  • 第四条件(买点): 在满足上述回调条件后,某一天股价重新站上5日均线,此时即为买入点。

这是一个典型的“上升三法”或“空头陷阱”后的反转形态。

通达信指标:
一、选股公式(用于自动选股)
这个公式用于在收盘后运行,选出当天正好满足“站上5日线”这一买点条件的股票。
  1. {通达信选股公式:涨停回调再启动}

  2. ZT:= (C-REF(C,1))/REF(C,1)*100 > 9.5 AND C=H; {定义涨停:涨幅大于9.5%且收盘价等于最高价}
  3. {注:科创板和创业板可能需要调整幅度,可将9.5改为19.5}

  4. {找到涨停那天的位置}
  5. 涨停日:= BARSLAST(ZT); {距离今天有多少天前出现过涨停}

  6. {条件1:必须是在最近10个交易日内出现过涨停(可调整参数),且涨停那天的最低价有效}
  7. 条件涨停存在:= 涨停日<=10 AND 涨停日>0;

  8. {获取涨停那天的数据}
  9. 涨停最低价:= REF(L, 涨停日); {涨停那天的最低价}
  10. 涨停收盘价:= REF(C, 涨停日); {涨停那天的收盘价}

  11. {计算5日均线}
  12. MA5:= MA(C,5);

  13. {定义回调条件:当前处于涨停日之后的某一天,且股价在MA5下方}
  14. {我们需要确保从跌破MA5开始到现在,一直没有站上过MA5,且没跌破涨停最低价}

  15. {1. 当前是否站上MA5?——这是今天的买入信号}
  16. 站上MA5:= CROSS(C, MA5);

  17. {2. 回调期间的约束条件}
  18. {我们定义“回调期”为:从第一次跌破MA5那天开始,到昨天为止}
  19. 第一次跌破MA5日:= REF(BARSLASTCOUNT(C<MA5), 1); {昨天为止,连续在MA5之下的天数}

  20. {3. 在整个回调期内,是否始终没跌破涨停最低价?}
  21. 安全回调:= LLV(L, 第一次跌破MA5日+1) > 涨停最低价; {回调期间的最低价,大于涨停当日最低价}

  22. {最终选股条件}
  23. 买入信号: 条件涨停存在 AND 站上MA5 AND 第一次跌破MA5日>=1 AND 安全回调;
复制代码
二、主图/副图指标(用于图形显示)
把这个指标放在主图上,可以在K线旁边显示信号,方便您复盘验证。
  1. {通达信主图指标:涨停回调买点}
  2. MA5:= MA(C,5); {5日均线}

  3. {绘制均线}
  4. MA5:MA(C,5), COLORWHITE;

  5. {定义涨停}
  6. ZT:= (C-REF(C,1))/REF(C,1)*100 > 9.5 AND C=H;
  7. STICKLINE(ZT, C, O, 2, 0), COLORYELLOW; {把涨停K线涂成黄色}

  8. {找到涨停日位置}
  9. 涨停日:= BARSLAST(ZT);

  10. {涨停最低价}
  11. 涨停最低价:= IF(涨停日<=20, REF(L, 涨停日), DRAWNULL); {只显示最近20日内的涨停支撑}

  12. {绘制涨停最低价水平线}
  13. 涨停支撑: DRAWLINE(涨停日=0, L, 涨停日=0, REF(L, 涨停日), 1), COLORMAGENTA, LINETHICK2, DOTLINE;

  14. {判断当前是否处于回调期(连续在MA5下方)}
  15. 连续低于MA5天数:= BARSLASTCOUNT(C<MA5);
  16. 低于MA5且未破涨停:= C<MA5 AND L>涨停最低价 AND 涨停日<=20 AND 涨停日>0;

  17. {绘制回调期的背景色,让视觉更直观}
  18. STICKLINE(低于MA5且未破涨停, C, O, 2, 0), COLORBLUE; {回调K线涂成蓝色}

  19. {买入信号:站上5日线,且之前有满足条件的回调}
  20. 买入条件:= CROSS(C, MA5) AND REF(低于MA5且未破涨停, 1) AND 涨停日<=20;

  21. {绘制买入信号}
  22. DRAWICON(买入条件, L*0.98, 1); {在K线下方画笑脸}
复制代码


使用说明
  • 参数调整:

    • 涨停定义:A股主板通常是10%,但实际中9.8%以上往往也算涨停,所以公式里用了>9.5。如果是创业板或科创板,需要手动将9.5改为19.5。
    • 回调天数:您的策略是数1-5天,公式中我用连续低于MA5天数来动态计算,无论几天只要满足条件就行。如果你想限定最多不超过8天或10天,可以在选股条件里加上AND 连续低于MA5天数 <= 8。

  • 选股时机:
    • 建议在下午14:45以后运行选股。因为“站上MA5”这个条件需要收盘价确认,尾盘信号相对稳定,不容易在最后几分钟变盘。

  • 配合量能:
    • 这个技术形态如果配合成交量缩量(回调期间成交量明显小于涨停前后)效果会更好。您可以在指标中再加入一条成交量的条件,比如 AND REF(V, 1) < MA(V,5) * 0.8(昨日成交量小于5日均量的一半),来进一步过滤。

  • 止损纪律:
    • 这个买点的防守位置非常明确,就是涨停K线的最低价。一旦买入后股价跌破这个价位,说明形态失败,建议止损离场。


您可以直接将上述代码复制到通达信的“条件选股公式”和“技术指标公式”中即可使用。

1894

主题

523

回帖

7443

积分

管理员

积分
7443
 楼主| 发表于 7 天前 | 显示全部楼层
青龙面板定时:
以下是您需要的Python脚本,它可以在青龙面板中运行,每天收盘后筛选符合条件的股票,并通过企业微信推送结果。脚本逻辑严格按照您描述的通达信指标转换而来。
脚本功能
  • 获取全市场A股列表(剔除北交所股票可选)。
  • 对每只股票获取最近60个交易日的日线数据。
  • 计算5日均线,识别涨停板(涨幅>9.5%且收盘价=最高价)。
  • 检查是否满足:涨停→回调(连续在5日线下且不破涨停最低价)→今日重新站上5日线。
  • 将符合条件的股票汇总,通过企业微信机器人发送。

使用前准备
  • 在青龙面板新建Python脚本,将以下代码复制进去。
  • 配置企业微信机器人:将代码中的YOUR_WECHAT_ROBOT_KEY替换为您的机器人Webhook地址。
  • 设置定时任务(例如每天15:30执行)。


  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 通达信涨停回调再启动策略 - 青龙面板版
  5. 每天收盘后运行,筛选符合条件的股票并通过企业微信推送
  6. """

  7. import pandas as pd
  8. import numpy as np
  9. import akshare as ak
  10. import requests
  11. import time
  12. from datetime import datetime, timedelta

  13. # ==================== 配置参数 ====================
  14. WECHAT_ROBOT_KEY = "YOUR_WECHAT_ROBOT_KEY"  # 替换为你的企业微信机器人key
  15. LOOKBACK_DAYS = 60          # 获取多少天历史数据
  16. MAX_ZT_DAYS_AGO = 20        # 涨停日距离今天不超过20天
  17. MIN_CONTINUOUS_DAYS = 1     # 最少连续在MA5下方天数
  18. PLATE_LIMIT = {             # 不同板块涨停阈值(可根据需要调整)
  19.     '主板': 9.5,
  20.     '创业板': 19.5,
  21.     '科创板': 19.5,
  22.     '北交所': 29.5
  23. }
  24. # =================================================

  25. def get_stock_list():
  26.     """获取A股列表,返回DataFrame包含代码和名称"""
  27.     stock_info = ak.stock_info_a_code_name()
  28.     # 可选:过滤北交所(股票代码以8开头或4开头?这里简单过滤8和4)
  29.     # stock_info = stock_info[~stock_info['code'].str.startswith(('8', '4'))]
  30.     return stock_info

  31. def get_stock_data(code, end_date=None):
  32.     """
  33.     获取个股历史行情
  34.     :param code: 股票代码(如 '000001')
  35.     :param end_date: 截止日期,默认今天
  36.     :return: DataFrame包含日期、开盘、收盘、最高、最低、成交量
  37.     """
  38.     if end_date is None:
  39.         end_date = datetime.now().strftime('%Y%m%d')
  40.     start_date = (datetime.now() - timedelta(days=LOOKBACK_DAYS*2)).strftime('%Y%m%d')  # 多取一些以确保均线计算
  41.     try:
  42.         df = ak.stock_zh_a_hist(symbol=code, period='daily', start_date=start_date, end_date=end_date, adjust='')
  43.         if df.empty:
  44.             return None
  45.         # 重命名列
  46.         df.rename(columns={
  47.             '日期': 'date',
  48.             '开盘': 'open',
  49.             '收盘': 'close',
  50.             '最高': 'high',
  51.             '最低': 'low',
  52.             '成交量': 'volume'
  53.         }, inplace=True)
  54.         df['date'] = pd.to_datetime(df['date'])
  55.         df.sort_values('date', inplace=True)
  56.         df.reset_index(drop=True, inplace=True)
  57.         return df
  58.     except Exception as e:
  59.         print(f"获取{code}数据失败: {e}")
  60.         return None

  61. def is_limit_up(row, threshold=9.5):
  62.     """判断是否为涨停(涨幅>threshold且收盘价=最高价)"""
  63.     return row['pct_change'] > threshold and row['close'] == row['high']

  64. def check_stock(df):
  65.     """
  66.     核心条件检查
  67.     :param df: 包含足够历史数据的DataFrame,按日期升序
  68.     :return: (是否满足, 涨停日, 涨停最低价, 今日收盘价, 连续下方天数)
  69.     """
  70.     if df is None or len(df) < 20:  # 数据太少无法判断
  71.         return False, None, None, None, None

  72.     # 计算涨跌幅和5日均线
  73.     df['pct_change'] = (df['close'] - df['close'].shift(1)) / df['close'].shift(1) * 100
  74.     df['ma5'] = df['close'].rolling(window=5).mean()

  75.     # 识别涨停日(最近MAX_ZT_DAYS_AGO天内)
  76.     recent = df.iloc[-MAX_ZT_DAYS_AGO-5:]  # 扩大一点范围
  77.     zt_days = recent[recent.apply(lambda row: is_limit_up(row), axis=1)]

  78.     if zt_days.empty:
  79.         return False, None, None, None, None

  80.     # 取最近的涨停日
  81.     zt_day = zt_days.iloc[-1]
  82.     zt_idx = zt_day.name
  83.     zt_low = zt_day['low']          # 涨停当日最低价
  84.     zt_date = zt_day['date']

  85.     # 涨停日之后的数据
  86.     after_zt = df.loc[zt_idx+1:].copy()
  87.     if after_zt.empty:
  88.         return False, None, None, None, None

  89.     # 查找涨停后首次跌破MA5的日期
  90.     below_ma5_start = after_zt[after_zt['close'] < after_zt['ma5']]
  91.     if below_ma5_start.empty:
  92.         return False, None, None, None, None

  93.     first_below_idx = below_ma5_start.index[0]  # 首次跌破MA5的索引

  94.     # 从首次跌破到昨天为止,是否一直未站上MA5且未跌破涨停最低价
  95.     check_period = df.loc[first_below_idx:-2]  # 截止到昨天
  96.     if len(check_period) == 0:
  97.         return False, None, None, None, None

  98.     # 条件1: 这段期间所有收盘价都低于MA5(即从未站上)
  99.     all_below_ma5 = (check_period['close'] < check_period['ma5']).all()

  100.     # 条件2: 这段期间的最低价从未跌破涨停最低价
  101.     low_not_break = (check_period['low'].min() > zt_low)

  102.     if not (all_below_ma5 and low_not_break):
  103.         return False, None, None, None, None

  104.     # 连续天数
  105.     continuous_days = len(check_period)

  106.     # 检查今天是否站上MA5(收盘价上穿)
  107.     today = df.iloc[-1]
  108.     yesterday = df.iloc[-2]
  109.     cross_up = (today['close'] > today['ma5']) and (yesterday['close'] <= yesterday['ma5'])

  110.     if cross_up and continuous_days >= MIN_CONTINUOUS_DAYS:
  111.         return True, zt_date.strftime('%Y-%m-%d'), zt_low, today['close'], continuous_days
  112.     else:
  113.         return False, None, None, None, None

  114. def send_wechat_msg(content):
  115.     """通过企业微信机器人发送消息"""
  116.     url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={WECHAT_ROBOT_KEY}"
  117.     headers = {"Content-Type": "application/json"}
  118.     data = {
  119.         "msgtype": "text",
  120.         "text": {
  121.             "content": content
  122.         }
  123.     }
  124.     try:
  125.         response = requests.post(url, json=data, headers=headers)
  126.         if response.status_code == 200:
  127.             print("企业微信推送成功")
  128.         else:
  129.             print(f"企业微信推送失败: {response.text}")
  130.     except Exception as e:
  131.         print(f"企业微信推送异常: {e}")

  132. def main():
  133.     print(f"开始执行策略筛选,时间:{datetime.now()}")
  134.     stock_list = get_stock_list()
  135.     total = len(stock_list)
  136.     print(f"获取到 {total} 只股票")

  137.     matched_stocks = []

  138.     for idx, row in stock_list.iterrows():
  139.         code = row['code']
  140.         name = row['name']
  141.         # 补齐6位代码(akshare可能返回不带前导零的代码?)
  142.         code = code.zfill(6)
  143.         print(f"正在处理 [{idx+1}/{total}] {code} - {name}")

  144.         df = get_stock_data(code)
  145.         if df is None:
  146.             continue

  147.         # 检查条件
  148.         passed, zt_date, zt_low, today_close, days = check_stock(df)
  149.         if passed:
  150.             matched_stocks.append({
  151.                 '代码': code,
  152.                 '名称': name,
  153.                 '涨停日': zt_date,
  154.                 '涨停最低价': zt_low,
  155.                 '今日收盘': today_close,
  156.                 '连续下方天数': days
  157.             })

  158.         # 礼貌停顿,避免请求过快
  159.         time.sleep(0.2)

  160.     # 推送结果
  161.     if matched_stocks:
  162.         msg = f"【涨停回调再启动】符合条件的股票 ({len(matched_stocks)}只)\n"
  163.         for s in matched_stocks:
  164.             msg += f"\n{s['代码']} {s['名称']} 涨停日:{s['涨停日']} 回调{days}天 现价:{s['今日收盘']:.2f}"
  165.     else:
  166.         msg = "【涨停回调再启动】今日无符合条件的股票"

  167.     send_wechat_msg(msg)
  168.     print(msg)

  169. if __name__ == "__main__":
  170.     main()
复制代码
注意事项
  • 数据源:使用akshare库,首次运行前需在青龙面板安装:pip3 install akshare pandas requests。
  • 涨停阈值:脚本默认使用9.5%作为主板涨停阈值。如果您想区分板块,可以在get_stock_data后根据代码前缀动态设置阈值(如创业板30****使用19.5)。代码中预留了PLATE_LIMIT字典,您可以自行扩展。
  • 运行时间:建议在每天15:30以后执行,此时当日数据已更新完毕。
  • 企业微信机器人:需要先在企微群中添加机器人,获取webhook地址。
  • 性能优化:若股票数量多导致运行时间过长,可考虑使用多线程,但需注意akshare的访问限制。当前单线程加0.2秒延时,约需15-20分钟,青龙面板通常允许。

如果遇到任何问题(如数据获取失败),请检查网络或更换数据源(如tushare)。您也可以根据实际需求调整参数(如回调天数、涨停范围等)。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表