量化系统QTYX使用攻略|“选股框架”篇——添加一个选股策略,以均线发散+KDJ发散为例

图片

搭建自己的量化系统

图片

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

分享QTYX系统目的是提供给大家一个搭建量化系统的模版,最终帮助大家搭建属于自己的系统。因此我们提供源码,可以根据自己的风格二次开发。
关于QTYX的使用攻略可以查看链接:QTYX使用攻略
QTYX一直迭代更新,当前版本V2.8.3。后续升级版本会同步更新文档内容。
星球下载位置如下:
图片
图片
选股框架说明
图片
图片
QTYX的选股框架流程像是一个漏斗,把A股全市场的5000只股票的数据输入到“漏斗”中,经过逐级的过滤筛选,最终输出5只精挑细选的强势股,盘中选择1-2只买入。
目前QTYX提供“数据驱动层”、“形态驱动层”、“组合对比分析层”多层级组合过滤。
掌握了这个框架流程后大家可以把自己的思路叠加进去分析的,让QTYX变成和自己风格100%匹配的一款股票量化系统。

每个交易者都有DIY自己策略的需求,我们不但可以对QTYX系统内置的形态选股策略进行优化修改,比如双底形态突破、主升浪拉升等,也可以单独在这个系统中植入自己的策略。
本篇就来教大家如何在QTYX源码基础上二次开发自己的策略和用法

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

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

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

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

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

图片


图片
如何添加代码
图片

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

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

此处,我们编写的策略逻辑是M5M10M20三条均线呈多头排列,同时KDJ的J指标大于100,当个股持续3个交易日都满足两个叠加的条件的时候,过滤出这个股票。

   @staticmethoddef 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日的移动平均线        CLOSE = stock_data["收盘价"]        MA1.fillna(0, inplace=True)        MA2.fillna(0, inplace=True)        MA3.fillna(0, inplace=True)
        # 循环判断是否连续N日都符合均线多头排列的特征        for id_a in range(0, 4):            T = (CLOSE[-1 - id_a] > MA1[-1 - id_a] > MA2[-1 - id_a] > MA3[-1 - id_a])            if T != True: break  # 只要有一天不满足则退出
        low_list = stock_data['最低价'].rolling(9, min_periods=1).min()        high_list = stock_data['最高价'].rolling(9, min_periods=1).max()        rsv = (stock_data['收盘价'] - low_list) / (high_list - low_list) * 100        stock_data['K'] = rsv.ewm(com=2, adjust=False).mean()        stock_data['D'] = stock_data['K'].ewm(com=2, adjust=False).mean()        stock_data['J'] = 3 * stock_data['K'] - 2 * stock_data['D']
        # 循环判断是否连续N日J的值都大于100        for id_b in range(0, 4):            T = (stock_data['J'][-1 - id_b] > 100)            if T != True: break  # 只要有一天不满足则退出
        if (id_a >= 3 and id_b >= 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=(750200)):        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)  # 选股项

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

图片

然后在选股框架中注册。找到文件QTYX/MainlyGui/UserFrame.pypatten_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类中修改。

图片


图片
选股演示
图片

接下来我们看下这个自定义策略的选股结果。

图片

我们针对于近期比较热门的板块进行选股。

图片

以下就是自定义策略的选股结果。

图片

我们可以借助同花顺软件来对比下选股结果是否满足我们编写的算法。

图片

图片

用我们自己设计的策略选出来的个股,是否具有赚钱效应呢?我们还可以对结果进行回测评估,具体可以参照以下文章:

量化系统QTYX使用攻略|“回测评估”篇——选股策略赚不赚钱,上帝视角一目了然(更新2.8.1)

图片
总结‍‍
图片

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

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/105918
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 5天前
下一篇 5天前

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注