股票量化分析工具QTYX使用攻略——添加自定义形态选股策略


aacaa86ea11a655aff6ee15e7f56ba76.png

搭建自己的量化系统

a9d1e0a0bee7e2889c4300d57c7ac624.png

股票量化交易系统QTYX是一个即可以用于学习,也可以用于实战炒股分析的系统。

分享QTYX系统目的是提供给大家一个搭建量化系统的模版,最终帮助大家搭建属于自己的系统。因此我们提供源码,可以根据自己的风格二次开发。

关于QTYX的使用攻略可以查看链接:QTYX使用攻略

QTYX一直迭代更新,当前版本V2.7.2。后续升级版本会同步更新文档内容。

0c50a998781caa68b67c060959b7f4fb.png

DIY系列说明

fd7c8fd62499c899703d9989af13b8dd.png

本篇属于使用攻略的DIY系列,即教大家如何在QTYX源码基础上二次开发自己的策略和用法。

QTYX系统内置了一些形态选股策略,比如双底形态突破、主升浪拉升等。我们不但可以对这些策略进行优化修改,也可以单独在这个系统中植入自己的策略。


e5d81505388dc8abfa32153f170dfbf0.png

形态选股设计框架‍‍‍‍‍

20ee6f99b1b3b4a2f3dc0da7799068c4.png

整体的设计框架如下图所示。

操作上,要在主界面上更新股票数据和选择选股策略。操作方法可参照使用攻略中对应专题。

执行选股时采用多任务方案,每个任务中注册了相应的策略,股票数据会分发给这些任务,每个任务独立选股,最后合并为一份选股结果。

选股结果出来后,还可以叠加一些特殊数据进行多方位条件选股,比如财务数据、基金持仓数据、基本面数据等等。

1f766ec38c9d93acae20ee0994e519b4.png


3ba9cc6d4f21d2f234441fb24fd8e67e.png

如何添加代码

a5bd35fcbfddfde6a99cd856dcaf15f2.png

接下来介绍下如何添加策略代码。

首先找到文件“QTYX/StrategyGath/PattenGath.py”,根据统一格式添加一个自己的策略函数,比如名称“user_define_strategy”,然后在函数中用Python添加自己的策略逻辑,如下代码所示:(编写策略代码时,请注意传入参数的格式和内容,以及返回数据的格式,以兼容这个系统框架)

@staticmethod
    def user_define_strategy(name, code, stock_data, patlog_obj, **kwargs):


        """
        # 输入参数
        :param name:  股票名称, 平安银行
        :param code:  股票代码, 000001.SZ
        :param stock_data:  股票数据, DataFrame格式
        :param patlog_obj: 打印日志接口
        :param kwargs: dict: 配置参数, 可以直接在函数中修改
        :return:
        """


        try:
            df_search = pd.DataFrame()  # 构建一个空的dataframe用来装数据


            MA1 = stock_data["收盘价"].rolling(window=5).mean()  # 计算M日的移动平均线
            MA2 = stock_data["收盘价"].rolling(window=10).mean()  # 计算M日的移动平均线
            MA3 = stock_data["收盘价"].rolling(window=20).mean()  # 计算M日的移动平均线
            MA4 = stock_data["收盘价"].rolling(window=30).mean()  # 计算M日的移动平均线
            CLOSE = stock_data["收盘价"]
            MA1.fillna(0, inplace=True)
            MA2.fillna(0, inplace=True)
            MA3.fillna(0, inplace=True)
            MA4.fillna(0, inplace=True)


            # 循环判断是否连续N日都符合均线多头排列的特征
            for id in range(0, 4):
                T = (CLOSE[-1 - id] > MA1[-1 - id] > MA2[-1 - id] > MA3[-1 - id] > MA4[-1 - id])
                if T != True: break  # 只要有一天不满足则退出


            if id >= 3:
                # 输出满足要求的股票
                patlog_obj.re_print("符合特征: 股票 {},代码 {}".format(name, code))
                df_search = pd.DataFrame([[name, code]], index=[0], columns=["股票名称", "股票代码"])


            return df_search


        except Exception as e:
            print(e)
            return pd.DataFrame()

编写完策略后,需要把策略注册到选股框架中。先是在界面中注册。找到文件“QTYX/MainlyGui/ElementGui/DefDialogs/ParaDialog.py”, SelectModeDialog类的“self.patten_type_cmbo”变量中添加一个策略名称,比如“自定义策略-DIY学习”。如以下代码所示:

class SelectModeDialog(wx.Dialog): # 形态选股参数/更新行情数据参数/RPS选股参数


    def __init__(self, parent,  title=u"形态选股参数配置", size=(750, 200)):
        pass


    def patten_dialog(self, sizer_object):
        # 中间代码已省略
        # 形态选股参数——形态类型选取
        self.patten_type_box = wx.StaticBox(self, -1, u'选股模型')
        self.patten_type_sizer = wx.StaticBoxSizer(self.patten_type_box, wx.HORIZONTAL)


        self.patten_type_cmbo = wx.ComboBox(self, -1, choices=["主升浪(均线多头&突破前高)", "双底形态突破", "箱体形态突破", "单针探底回升",
                                                               "自定义策略-DIY学习", "线性回归-预留"],
                                            style=wx.CB_READONLY | wx.CB_DROPDOWN)  # 选股项

添加完成后,在界面中会看到对应得选项,如下图所示:

1910f2bc8ed5f44ee70eb42d2b812d43.png

然后在选股框架中注册。找到文件“QTYX/MainlyGui/UserFrame.py”,在“patten_analy_execute”函数的“register_info”变量中添加刚才创建的策略名称,记得要界面中的名称和函数名称一一对应。如以下代码所示:

def patten_analy_execute(self, stock_code):


        register_info = {"双底形态突破": Base_Patten_Group.double_bottom_search,
                         "箱体形态突破": Base_Patten_Group.bottom_average_break,
                         "单针探底回升": Base_Patten_Group.needle_bottom_raise,
                         "主升浪(均线多头&突破前高)": Base_Patten_Group.main_rise_wave,
                         "自定义策略-DIY学习": Base_Patten_Group.user_define_strategy,
                         }
        # 中间代码已省略 
        return df_return # 有效则添加至分析结果文件中

另外,每个策略都有它的算法参数,需要创建一个填写参数的对话框。找到文件“QTYX/MainlyGui/ElementGui/DefDialogs/SpecDialog.py”,添加一个对话框类,比如名称“UserDefStrategyDialog”。如果是自己使用,并且参数已经确定了,可以直接在策略代码中固定参数值,界面只需要留一个空壳即可,这样更简单点。如下代码所示:

class UserDefStrategyDialog(wx.Dialog):  # 用户自定义参数界面


    def __init__(self, parent, title=u"自定义提示信息", size=(500, 360)):
        wx.Dialog.__init__(self, parent, -1, title, size=size, style=wx.DEFAULT_FRAME_STYLE)
        # 中间代码已省略
        # 创建FlexGridSizer布局网格
        # rows 定义GridSizer行数
        # cols 定义GridSizer列数
        # vgap 定义垂直方向上行间距
        # hgap 定义水平方向上列间距
        self.FlexGridSizer = wx.FlexGridSizer(rows=1, cols=2, vgap=0, hgap=0)


        self.ok_btn = wx.Button(self, wx.ID_OK, u"确认")
        self.ok_btn.SetDefault()
        self.cancel_btn = wx.Button(self, wx.ID_CANCEL, u"取消")


        self.FlexGridSizer.Add(self.ok_btn, proportion=1, border=1, flag=wx.ALL | wx.EXPAND)
        self.FlexGridSizer.Add(self.cancel_btn, proportion=1, border=1, flag=wx.ALL | wx.EXPAND)


        self.FlexGridSizer.SetFlexibleDirection(wx.BOTH)
        self.SetSizerAndFit(self.FlexGridSizer)
        self.Centre()


    def feedback_paras(self):


        self.user_para = dict()


        return self.user_para

接下来在文件“QTYX/MainlyGui/UserFrame.py”中,把对话框函数“UserDefStrategyDialog”导入进去。如下代码所示:

from MainlyGui.ElementGui.DefDialogs.SpecDialog import UserDefStrategyDialog

接下来在文件“QTYX/MainlyGui/UserFrame.py”中,找到事件函数“_ev_patten_select_func”,把对话框函数“UserDefStrategyDialog”注册进去,记得要界面中的名称和函数名称一一对应。

def _ev_patten_select_func(self, event):


        pass
        register_info = {"主升浪(均线多头&突破前高)":{"对话框函数": MainRiseWaveDialog,
                                        "日志信息":"主升浪形态选股正在执行..."},
                        "双底形态突破": {"对话框函数": DouBottomDialog,
                                        "日志信息":"双底形态选股正在执行..."},
                         "箱体形态突破":{"对话框函数": BreakBottomDialog,
                                        "日志信息":"底部形态选股正在执行..."},
                         "单针探底回升": {"对话框函数": NeedleBottomDialog,
                                    "日志信息": "单针探底回升选股正在执行..."},
                         "自定义策略-DIY学习":{"对话框函数": UserDefStrategyDialog,
                                    "日志信息": "单针探底回升选股正在执行..."}


                         }


        pass

最后生成选股结果时,如果想要叠加特色数据,就在文件“QTYX/MainlyGui/UserFrame.py”中,找到函数“patten_analy_result”,把特色数据叠加到形态选股文件中即可。

def patten_analy_result(self):


        pass


        if self.patten_paras[u"北向资金持股"] == True:
           pass


        if self.patten_paras[u"每日基本面指标"] == True:
           pass


        if self.patten_paras[u"叠加利润报表"] == True:
           pass


        Base_File_Oper.save_csv_file(df_search, f"全市场选股结果/{self.patten_paras['选股模型']}分析结果_{select_date.strftime('%Y-%m-%d')}_高速版.csv")
        self.patlog.re_print("\n形态分析完成!明细查看路径ConfigFiles/全市场选股结果/")

想要叠加的特色数据类别是在选股配置界面上勾选的,也是在“QTYX/MainlyGui/ElementGui/DefDialogs/ParaDialog.py”的“SelectModeDialog”类中修改。

f4dd4eb7fe8f426c24a0684d18c0a5a7.png

673a9bf1f07af3316399ce7885498ac8.png

总结‍‍

b6a95c0a441e80862bd25d6fe15af77d.png

以上就是在QTYX系统中添加自己的选股策略的方法,例程代码会体现在2.7.2版本中,以供大家参考和学习。在调试过程中难免不会一帆风顺,大家记得多使用print打印日志,排查问题,祝愿各位早日搭建出属于自己的量化系统!

说明

想要加入知识星球《玩转股票量化交易》的小伙伴记得先微信call我获取福利!

知识星球介绍点击:知识星球《玩转股票量化交易》精华内容概览

f17a772473aefbdac5105bf0c430cced.jpeg

<think>好的,用户的问题是关于QMT平台中集合竞价选股的方法或策略。首先,我需要回顾一下QMT平台的相关知识,并结合提供的引用内容来整理答案。 用户提到的引用中有关于QMT平台的介绍,比如引用[2]提到在QMT中使用通达信公式转换,处理日线回测时需要注意下单价格为当天收盘价。这可能和集合竞价阶段的数据获取有关。此外,引用[1]提到在分钟回测中可用当天开盘价,但集合竞价下单时无法使用,这可能影响策略的设计。 接下来,我需要确定集合竞价选股的关键点。通常,集合竞价阶段的数据包括开盘价、成交量、委托量等。策略可能基于这些指标,比如高开幅度、成交量突增等。需要确保在QMT中能够获取这些数据,比如使用get_current_data函数,但要注意在回测中的限制,如引用[1]所说,集合竞价时无法知道开盘价,可能需要调整回测逻辑。 然后,考虑策略构建方法。可能需要结合技术指标,如引用[2]中的通达信公式转换,将选股条件转换为Python代码。例如,使用量价关系或市场情绪指标。此外,引用[3]提到QTYX系统支持自定义选股,可能可以参考其选股框架,利用问财等工具获取数据。 还需要考虑回测机制,如引用[2]提到的日线周期回测使用handlebar机制,下单价格为收盘价。这可能与实际集合竞价的成交价不同,需要特别注意回测结果的准确性,可能需要使用分钟级别的回测数据。 最后,整理步骤:数据获取、策略逻辑、编码实现、回测优化。确保每个步骤都符合QMT平台的功能和限制,并引用相关的参考资料来支持建议。</think>关于QMT平台集合竞价选股策略的构建方法,可参考以下步骤: ### 一、数据获取要点 1. 使用$get\_current\_data()$获取实时数据,需注意**集合竞价阶段**的特殊性: - 可获取$pre\_close$(前收盘价)、$limit\_up\_price$(涨停价)等静态数据 - 动态数据如$bid\_volumes$(委买量)、$ask\_volumes$(委卖量)需通过Level2接口获取[^1] 2. 关键指标计算公式: - 开盘强度比:$$强度比 = \frac{open\_price}{pre\_close} \times 100\%$$ - 委托不平衡度:$$委差比 = \frac{bid\_volume - ask\_volume}{bid\_volume + ask\_volume}$$ ### 二、策略逻辑设计 1. **量价突破型策略**(参考引用[2]的指标转换方法): - 条件1:前日涨停且当日竞价涨幅>3% - 条件2:竞价量能>5日均量的2倍 - 实现示例: ```python def is_breakout(stock): data = get_history_data(stock, '1d', 'close,volume', 5) current = get_current_data(stock) cond1 = (data['close'][-2] == data['close'][-2] * 1.1) # 前日涨停判断 cond2 = (current['open'] / data['close'][-1] > 1.03) cond3 = current['volume'] > data['volume'].mean() * 2 return cond1 & cond2 & cond3 ``` 2. **市场情绪联动策略**(基于引用[3]的选股框架): - 步骤1:筛选所属行业竞价强度Top3的板块 - 步骤2:在板块内选择委买比率前5的个股 - 使用$get\_industry\_stocks()$获取行业成分股[^3] ### 三、回测注意事项 1. 时间设定: - 回测周期应包含**09:15-09:25**的集合竞价时段 - 使用分钟级回测模式而非日线模式[^2] 2. 成交机制模拟: - 价格匹配:按**最大成交量原则** - 委托方式示例: ```python order(stock, 'limit', price=涨停价, amount=委托量, time='09:25:00') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值