大数跨境
0
0

251203通达信官方量化(TDX Quant)(3)—实践<六脉神剑选股>

251203通达信官方量化(TDX Quant)(3)—实践<六脉神剑选股> 福瑞布
2025-12-03
264
导读:通达信开始支持Python增强选股回测预警功能和量化交易(TDX Quant,简写TQ),先借助这个接口,试试六脉神剑选股。

通达信开始支持Python增强选股回测预警功能和量化交易(TDX Quant,简写TQ),先借助这个接口,试试选股,以时髦的六脉神剑为例。


本例仅仅做一个TQ选股测试,六脉神剑完全可以用通达信公式选股,方便还快。但是一些复杂的形态选股,如W底选股,头肩底选股等,用通达信公式选股比较困难,现在有TQ的python选股,应该很容易实现。


TQ的选股结果如何保存到通达信板块没找到函数,用了传统办法,写文件保存到blocknew下自定义板块。


251201通达信官方Python量化(TDX Quant)(1)

251202通达信官方量化(TDX Quant)(2)—架构

我是布洗脸,关注我,第一时间获取我的研习成果。

上一节,给出来了,py跟tdwx.exe的关系架构,这是执行的总纲,明确数据流向,不迷路。

tdxw.exe运行后,接口已经暴漏给外部,执行python可以在通达信的TQ界面内部执行,也可以不管这个界面,直接在外部执行python文件,我想可以搞一些好玩的东西出来。


需要注意的是,内部执行时,工作目录是通达信根目录,所以在py文件中调用文件时,注意路径。


下面试试六脉神剑选股。


一、六脉神剑选股逻辑

该策略综合了以下6个技术指标的金叉信号:当这6个条件同时满足,并且前一天不满足时,产生买入信号。
    • MACD金叉:DIFF > DEA
    • KDJ金叉:K > D
    • RSI金叉:RSI1 > RSI2
    • LWR金叉:LWR1 > LWR2
    • BBI金叉:收盘价 > BBI
    • MTM金叉:MMS > MMM

二、量化脚本程序流程


  • 读取A股代码.txt 文件读取所有A股代码。

  • 对每只股票进行分析计算
  • 筛选出满足条件的股票
  • 保存到c:\new_tdx_test\T0002\blocknew\LMSJ.blk


三、准备工作


下载至少1年的盘后数据


创建自定义板块 六脉神剑,产生LMSJ.BLK文件。


缓存板块的勾去掉,外部写入的代码会实时刷新。


四、内部新增脚本执行


见下图,新增策略,保存,并执行。




总共选到199只。股软切换到 前面建的自定义板块查看。


也在可以在外部IDE执行,但是必须先运行tdxw.exe,下图是在灵码IDE里执行。

TQ界面也能检测到外部执行,不用理会。






TQ六脉神剑选股.py 代码如下,放入 user目录,注意py文件结束,必须有tdxdata.close(),不然TQ界面检测不到运行结束。


import numpy as npimport pandas as pdfrom tqcenter import tdxdataimport osdef ema(series, window):    """计算指数移动平均"""    return series.ewm(span=window, adjust=False).mean()def sma(series, window, k=1):    """计算简单移动平均"""    return series.rolling(window=window).mean()def llv(series, window):    """计算周期内最低值"""    return series.rolling(window=window).min()def hhv(series, window):    """计算周期内最高值"""    return series.rolling(window=window).max()def ma(series, window):    """计算简单移动平均"""    return series.rolling(window=window).mean()def ref(series, periods):    """引用若干周期前的数据"""    return series.shift(periods)def six_pulse_sword_signal(close, high, low):    """    计算六脉神剑选股信号    返回值: True表示满足买入条件,False表示不满足    """    # MACD指标    diff = ema(close, 8) - ema(close, 13)    dea = ema(diff, 5)    a1 = diff > dea        # KDJ指标    rsv1 = (close - llv(low, 8)) / (hhv(high, 8) - llv(low, 8)) * 100    k = sma(rsv1, 31)    d = sma(k, 31)    a2 = k > d        # RSI指标    lc = ref(close, 1)    rsi1 = sma(np.maximum(close - lc, 0), 51) / sma(np.abs(close - lc), 51) * 100    rsi2 = sma(np.maximum(close - lc, 0), 131) / sma(np.abs(close - lc), 131) * 100    a3 = rsi1 > rsi2        # LWR指标    rsv = -(hhv(high, 13) - close) / (hhv(high, 13) - llv(low, 13)) * 100    lwr1 = sma(rsv, 31)    lwr2 = sma(lwr1, 31)    a4 = lwr1 > lwr2        # BBI指标    bbi = (ma(close, 3) + ma(close, 6) + ma(close, 12) + ma(close, 24)) / 4    a5 = close > bbi        # MTM指标    mtm = close - ref(close, 1)    mms = 100 * ema(ema(mtm, 5), 3) / ema(ema(np.abs(mtm), 5), 3)    mmm = 100 * ema(ema(mtm, 13), 8) / ema(ema(np.abs(mtm), 13), 8)    a6 = mms > mmm        # 判断当前是否满足所有条件且前一天不满足    current_condition = a1 & a2 & a3 & a4 & a5 & a6    previous_condition = ref(current_condition, 1)        # 涨买入信号:当前满足所有条件且前一天不满足    buy_signal = current_condition & (previous_condition == False)        # 返回最新的信号    return buy_signal.iloc[-1if len(buy_signal) > 0 else Falsedef save_to_block_file(selected_stocks, block_file_path):    """    将选股结果保存到通达信板块文件    沪市: 1 + 6位代码    深市: 0 + 6位代码    北京: 2 + 6位代码    """    try:        # 确保目录存在        os.makedirs(os.path.dirname(block_file_path), exist_ok=True)                # 打开文件准备写入(会清空原有内容)        with open(block_file_path, 'w', encoding='gbk'as f:            for stock in selected_stocks:                # 解析股票代码                if stock.endswith('.SH'):                    # 沪市                    code = '1' + stock[:6]                elif stock.endswith('.SZ'):                    # 深市                    code = '0' + stock[:6]                else:                    # 默认处理(如果有北京市场或其他)                    code = stock[:7]  # 保留原始格式的前7位                                f.write(code + '\n')                print(f"选股结果已保存到 {block_file_path}")        return True    except Exception as e:        print(f"保存选股结果到文件时出错: {e}")        return Falsedef select_stocks_six_pulse_sword():    """根据六脉神剑策略选股"""    # 初始化连接    tdxdata.initialize(__file__)        try:        # 从A股代码.txt文件中读取股票列表        print("正在读取A股代码文件...")        stock_list = []        # 使用脚本所在目录的绝对路径来定位A股代码.txt文件        script_dir = os.path.dirname(os.path.abspath(__file__))        file_path = os.path.join(script_dir, 'A股代码.txt')        print(f"尝试从路径读取文件: {file_path}")                with open(file_path, 'r', encoding='utf-8'as f:            for line in f:                if '|' in line:                    code, name = line.split('|')                    name = name.strip()  # 去除换行符                                        # 剔除ST和*ST股票                    if name.startswith('ST'or name.startswith('*ST'):                        continue                                        # 转换代码格式以适配tdxdata接口                    if code.startswith('SH'):                        stock_code = code[2:] + '.SH'                    elif code.startswith('SZ'):                        stock_code = code[2:] + '.SZ'                    else:                        stock_code = code                    stock_list.append(stock_code)                print(f"共读取到{len(stock_list)}只A股股票")                # 存储符合条件的股票        selected_stocks = []                # 对所有股票进行分析        total_stocks = len(stock_list)        print(f"\n开始分析全部{total_stocks}只股票...")                for i, stock in enumerate(stock_list):            try:                # 获取最近60个交易日的日线数据(为了有足够的数据计算指标)                data = tdxdata.get_market_data(                    field_list=['Open''High''Low''Close'],                    stock_list=[stock],                    period='1d',                    count=60,                    dividend_type='none'                )                                if not data or len(data) == 0:                    continue                                # 转换为DataFrame                df = pd.DataFrame({                    'open': data['Open'][stock],                    'high': data['High'][stock],                    'low': data['Low'][stock],                    'close': data['Close'][stock]                })                                # 确保数据足够                if len(df) < 30:                    continue                                # 计算六脉神剑信号                signal = six_pulse_sword_signal(df['close'], df['high'], df['low'])                                if signal:                    selected_stocks.append(stock)                                # 显示进度(每500只股票显示一次)                if (i + 1) % 500 == 0 or i == total_stocks - 1:                    print(f"已处理{i + 1}/{total_stocks}只股票,已发现{len(selected_stocks)}只满足条件的股票...")                                except Exception as e:                # 忽略个别股票的错误                print(f"处理股票{stock}时出错: {e}")                continue                print(f"选股完成,共选出{len(selected_stocks)}只符合条件的股票")        return selected_stocks            except FileNotFoundError as e:        print(f"文件未找到: {e}")        print("请确保A股代码.txt文件存在于脚本所在目录")        return []    except Exception as e:        print(f"执行选股过程中发生错误: {e}")        import traceback        traceback.print_exc()        return []    finally:        # 关闭连接        try:            tdxdata.close()        except:            pass# 主程序入口if __name__ == "__main__":    print("开始执行六脉神剑选股策略...")    # 打印当前工作目录    import os    print(f"当前工作目录: {os.getcwd()}")    print(f"脚本所在目录: {os.path.dirname(os.path.abspath(__file__))}")        try:        selected = select_stocks_six_pulse_sword()        if selected:            print("\n符合六脉神剑买入条件的股票列表:")            for stock in selected:                print(stock)                            # 保存到通达信板块文件            # 使用基于脚本位置的绝对路径            script_dir = os.path.dirname(os.path.abspath(__file__))            block_file_path = os.path.join(script_dir, "..""..""T0002""blocknew""LMSJ.blk")            save_to_block_file(selected, block_file_path)                        # 输出选股结果供通达信使用            result = "XG," + "|".join([f"{i}#{stock}" for i, stock in enumerate(selected)])            print(f"\n选股结果代码: {result}")        else:            print("未发现符合条件的股票")            print("XG,")                        # 即使没有选股结果,也创建空的板块文件            # 使用基于脚本位置的绝对路径            script_dir = os.path.dirname(os.path.abspath(__file__))            block_file_path = os.path.join(script_dir, "..""..""T0002""blocknew""LMSJ.blk")            save_to_block_file([], block_file_path)    except Exception as e:        print(f"程序执行过程中发生错误: {e}")        import traceback        traceback.print_exc()        print("XG,")



TQ六脉神剑选股.py  和 A股代码.txt 放在网盘。 私信回复   量化   会自动推送123盘链接。  两个文件都放到user目录。



喜欢请赞,推荐,转发,收藏!这是娱乐的动力。不喜欢忽略。


本公众号所有内容旨在分享知识与信息,仅为个人观点,不构成任何专业意见或投资建议。)

#通达信公式   #通达信增强  #通达信使用  #通达信量化


本号分享的免费小工具集:

251130 本号自编小工具集

本号腾讯元器智能体

小布AI助手

【声明】内容源于网络
0
0
福瑞布
个人业余娱乐,记录自研成果。熟悉通达信软件使用、精通通达信公式设计及dll函数开发。
内容 72
粉丝 0
福瑞布 个人业余娱乐,记录自研成果。熟悉通达信软件使用、精通通达信公式设计及dll函数开发。
总阅读796
粉丝0
内容72