19.7%年化的大小盘轮动——策略如何调优 | Deap因子挖掘系统重构(附python代码)

 原创文章第619篇,专注“AI量化投资、世界运行的规律、个人成长与财富自由"。

咱们有了策略向导,写策略就特别快了。

今天来复现的策略是一个经典的——大小盘趋势轮动策略

沪深300代表的大盘与创业板代表的小盘之间,按动量来轮动。

直接信号轮动的效果:

图片

过滤掉负的动量:

动量小于零的时候,平仓,收益率和最大回撤均得到改善。

图片

再优化进场信号——在动量大于0.02的时候才进场,为负的时候离场:

年化进一步提升至19.7%,这样一个策略就完成了。

图片

我们发布到服务器:

图片

图片

这些代表在本周五都会在星球更新:


AI量化实验室——2024量化投资的星辰大海

本周一个任务主线是——重构Deap因子挖掘系统。

商品期货池:我们从国内期货市场筛选出历史流动性较好的41个品种具体如下表所示。

图片

41个商品期货主连合约,我整理到咱们平台上了:

图片

然后直接做单因子分析,用动量先看看:

单调性很好——但是是动量越大,收益越小

图片

看下分层收益:

图片

IC上也得到印证——期货截面20日动量与收益率呈现负相关,因此我们只需要设计一个策略,买入动量最小的,卖空动量最大的即可:

图片

回测区间:我们使用2016/1/1-2022/1/1作为样本内训练集,2022/1/2-2023/3/10作为样本外测试集,总回测区间为2016/1/1-2023/3/10。

算子函数集——也就是咱们的因子表达式引擎里提供的,这里才是因子挖掘的核心——因为无论是deap还是gplearn,框架本身你会使用就可以了。

图片

这些函数的实现在这里:

图片

代码都不复杂:

import numpy as np
import pandas as pd
from .expr_utils import calc_by_symbol, calc_by_date


@calc_by_symbol
def ts_delay(se: pd.Series, periods=5):  # 滞后N天的序列
    return se.shift(periods=periods)


@calc_by_symbol
def ts_delta(se: pd.Series, periods=20):  # 当前序列与滞后N天之差
    se_result = se - se.shift(periods=periods)
    return se_result


@calc_by_symbol
def ts_mean(se: pd.Series, d):
    return se.rolling(window=d).mean()


@calc_by_symbol
def ts_median(se: pd.Series, d):
    return se.rolling(window=d).median()


@calc_by_symbol
def ts_min(se: pd.Series, periods=5):
    return se.rolling(window=periods).min()


@calc_by_symbol
def ts_max(se: pd.Series, periods=5):
    return se.rolling(window=periods).max()


@calc_by_symbol
def ts_sum(se: pd.Series, N):
    ret = se.rolling(N).sum()
    return ret


@calc_by_symbol
def ts_argmin(se: pd.Series, periods=5):
    return se.rolling(periods, min_periods=2).apply(lambda x: x.argmin())


@calc_by_symbol
def ts_argmax(se: pd.Series, periods=5):
    return se.rolling(periods, min_periods=2).apply(lambda x: x.argmax())


@calc_by_symbol
def stddev(se, periods=5):
    return se.rolling(window=periods).std()


@calc_by_symbol
def ts_rank(se: pd.Series, periods=9):
    ret = se.rolling(window=periods).rank(pct=True)
    return ret


@calc_by_symbol
def shift(se: pd.Series, N):
    return se.shift(N)


@calc_by_symbol
def roc(se: pd.Series, N):
    return se / shift(se, N) - 1


@calc_by_symbol
def ts_product(se: pd.Series, d):
    return se.rolling(window=d).apply(np.product)


@calc_by_symbol
def zscore(se: pd.Series, N):
    def _zscore(x):

        try:
            x.dropna(inplace=True)
            # print('sub', x)
            value = (x[-1] - x.mean()) / x.std()
            if value:
                return value
        except:
            return -1

    # print(se)
    ret = se.rolling(window=N).apply(lambda x: _zscore(x))
    return ret


def decay_linear(series, window):
    """
    对输入的时间序列进行线性衰减。

    :param series: 输入的时间序列。
    :param window: 衰减的窗口大小。
    :return: 衰减后的序列。
    """
    weights = np.arange(1, window + 1)
    decay = np.convolve(series, weights, 'valid') / np.sum(weights)
    return decay

绝大多数算子,无论是时序,还是截面,都可以通过封装numpy来完成,不过技术分析类的,还是只能通过Talib这样的技术指标库。

pandas_ta实现一个指标——不过pandas_ta似乎有bug,numpy版本不兼容:

import pandas_ta as ta


@calc_by_symbol
def ts_dema(X, d):
    ret = ta.dema(X, d)
    if ret is None:
        return pd.Series(None, index=X.index)

这些都准备好之后,因子挖掘就是使用框架的问题了,只是框架目前没有现成的、适用于因子挖掘的。

因此,我会为大家提供重写后的版本,本周是deap,下周也许会重写gplearn。

AI量化实验室——2024量化投资的星辰大海

吾日三省吾身

“懂那么多道理,却过不好这一生“。

知道到做到,还有千山万水。

财富自由快车道,从需求出发,用户在抱怨什么。

比如大家急需要策略,要因子,想知道如何挖掘因子,这就是刚需。

有些用户想要实盘,自动化交易等等。

一个反馈系统非常关键。

把事情做精,把点打透,才能产生价值。

点子不重要,点子的执行才重要,直接解决问题。

历史文章:

红利低波与创成长,加上动量过滤,年化12.6%(python代码)

年化26.4%,quantlab5.5发布——多任务机器学习组合优化,可视化策略生成向导(代码+数据)

AI量化实验室——2024量化投资的星辰大海

DEAP (Distributed Evolutionary Algorithms in Python) 是一个用于构建和实验遗传算法(GA)和其他进化计算方法的Python库。它专注于提供灵活且易于使用的接口,让你能够快速构建和原型化进化计算应用。 在DEAP中,微分熵(differential entropy)通常用于评估个体(如解或种群成员)的多样性或信息内容。微分熵是一个统计量,它衡量了随机变量的概率分布接近均匀分布的程度。在特征提取中,这可能用于评估适应度函数中的个体适应性。 下面是一个简单的DEAP示例,展示了如何使用微分熵作为特征的一部分,这里我们假设你有一个名为`individual`的列表,其中包含代表解决方案的向量: ```python from deap import base, creator, tools import numpy as np import math # 假设creator.Individual是你的解决方案类型 creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) creator.create("Individual", list, fitness=creator.FitnessMin) def compute_entropy(vector): probabilities = np.array(vector) / sum(vector) return -np.sum(probabilities * np.log(probabilities)) def feature_extractor(individual): # 计算每个特征的熵 feature_values = np.array(individual) feature_entropies = [compute_entropy(feature_values[i]) for i in range(len(feature_values))] # 将熵组合成一个元组作为特征 return tuple(feature_entropies), individual.fitness.values toolbox = base.Toolbox() toolbox.register("attr_float", np.random.uniform, 0, 1) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=len(individuals)) toolbox.register("population", tools.initRepeat, list, toolbox.individual) # 初始化一个种群 population = toolbox.population(n=pop_size) # 使用自定义的特征提取器 feature_toolbox = base.Toolbox() feature_toolbox.register("evaluate", feature_extractor) # 进行微分熵特征评估并更新适应度 for ind in population: feature_toolbox.evaluate(ind) ind.fitness.values = ind # 假设特征熵是第一个元素 # 此后的遗传操作如选择、交叉、变异会基于这些特征熵 # ... # 提取特征的部分只执行一次,因为适应度已经包含特征信息 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI量化投资实验室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值