自学内容网 自学内容网

Hikyuu教程 | 如何进行策略回测参数优化

不久前看到一篇文章QMT使用技巧的文章——“震惊!策略回测参数从500多秒提升到1秒,竟然这么简单?”。当时进去看了下,大概是对单股的双均线策略的快线参数和慢线参数进行寻优,从2001年起至今对50组参数进行寻优,从使用纯 python 到使用 VBA 公式,从380秒优化到 1.3 秒。便想着动手看看 hikyuu 实现同样的参数寻优需要多久。

其实曾经也有人问过如何用 hikyuu 进行参数寻优,但觉得这种参数寻优本质是一种过拟合,一直不怎么感兴趣。所以友情提醒各位看官,这种简单的参数寻优本质是对历史数据的绝对过度拟合,请不要轻易使用寻优出来的结果!!!

这里使用经典双均线趋势策略(快线 > 慢线买入、反之卖出),测试执行机器为 i9-14900K, DD5-5600。50组参数,hikyuu执行时间:92毫秒,最佳参数 7, 51。

接下来进入正题,看看如何使用 Hikyuu 来完成这种参数寻优。(完整代码见文后附图)

一、构建参数组合

在 python 中构建参数组合是非常简单的,最经典的写法就是循环:

fast_n_range = range(5, 10, 1)
slow_n_range = range(50, 60, 1)

params = []
for fast_n in fast_n_range:
    for slow_n in slow_n_range:
        if slow_n > fast_n:
            params.append((fast_n, slow_n))

更加 pythonic 的写法:

from itertools import product
params = [v for v in product(fast_n_range, slow_n_range)]  # 构建参数两两组合
params = [(fast_n, slow_n) for fast_n, slow_n in params if fast_n < slow_n] # 过滤掉 slown <= fast_n 的参数组合

二、为每一对参数组合构建系统交易实例

这里直接使用默认 hub 中的经典双均线策略,由于后面使用的是茅台进行测试,请注意创建 TM (交易账户管理实例)时,保证有充足的资金,这里直接设置账户初始资金为 100000。
为了后续观察结果方便,更改每一个系统实例的名称,在其原有名称后加上实际的参数值,如:SYS_3_5。

sys_list = []
for x, y in params:
    # 创建趋势双均线系统实例,各自测试账户初始资金为 1000000,无止损/止盈/资金控制/交易成本
    my_sys = get_part('default.sys.趋势双均线', fast_n=x,
                      slow_n=y, tm=crtTM(init_cash=1000000), mm=MM_Nothing())
    # 重新命名系统实例名称,如:SYS_3_5
    my_sys.name = f'{my_sys.name}_{x}_{y}'
    sys_list.append(my_sys)

三、执行比较每个交易系统绩效,选出最优系统

为了方便,这里创建了一个函数,函数的主要功能就是循环执行指定每一个系统,并统计其绩效,最终返回绩效最高的系统和其绩效值。

def find_optimal_param(sys_list, stk, query, key=None):
    """
    该函数用于寻找系统列表中具有最高指定性能指标的系统。

    参数:
        sys_list (list): 系统对象的列表。
        stk (object): 用于系统运行的股票数据对象。
        query (object): 查询对象,用于系统运行。
        key (str, optional): 性能指标的键,默认为'帐户平均年收益率%'。

    返回:
        tuple: 包含最高性能指标值和对应系统的元组。

    异常:
        Exception: 如果提供的性能指标键无效,则抛出异常。
    """
    if key is None:
        key = '帐户平均年收益率%'
    if not Performance.exist(key):
        raise Exception(f"Invalid key: {key}")

    max_val = -10000
    max_sys = None
    for my_sys in sys_list:
        my_sys.run(stk, query)
        per = Performance()
        per.statistics(my_sys.tm, lastdate)
        val = per[key]
        if val > max_val:
            max_val = val
            max_sys = my_sys
    return max_val, max_sys

四、执行结果

指定待测试的股票,测试时间范围,执行测试:

stk = sm[stk_code]
query = Query(Datetime(20010101))

max_val, max_sys = find_optimal_param(sys_list, stk, query, key='当前总资产')

print(max_val)
print(max_sys.name)
print(len(sys_list))

max_sys.run(stk, query)
max_sys.performance()

在这里插入图片描述
执行耗时:
在这里插入图片描述
顺便测试了 fast_n [5, 80], slow_n [50, 200] 共 10785 组参数组合,耗时 24.5 秒。

完整代码:
在这里插入图片描述


原文地址:https://blog.csdn.net/KongDong/article/details/143061204

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!