最近DeepSeek发布了全新的开源推理大模型 DeepSeek-R1,在数学、编程和推理等多个特定任务上达到了与闭源模型相当的表现水平。

有朋友问能否通过这个推理模型来推荐基金

如果直接向推理模型提问“请推荐基金”,它经过思考后,大概率会先询问你的需求,比如你的风险偏好、投资目标、投资期限等,然后给出一个基金筛选策略。这个过程较为繁琐,效率不高,而且缺乏最新的基金数据,可操作性差。

如果给定一个基金筛选策略,让推理模型生成对应的Python代码,通过运行代码获取基金数据,计算和比较来筛选基金。这样不仅高效灵活,而且容易扩展。

"4433"法则

首先先选定一个基金筛选策略,这里选用“4433”法则

“4433”法则是一个简单的基金筛选法则。这个法则通过四个时间段的排名,帮助投资者根据历史数据筛选出排名靠前的基金。

4433法则是用来挑选基金的一种方式,即一只好的基金要同时满足以下条件:

1.近1年业绩排名在同类基金中位列前1/4;

2.近2/3/5年业绩排名在同类基金中位列前1/4;

3.近3个月业绩排名在同类基金中位列前1/3;

4.近6个月业绩排名在同类基金中位列前1/3。

它的理念是兼顾基金长期(法则中的“44”)和短期(法则中的“33”)的业绩表现进行筛选。

DeepSeek R1推理模型

首先访问并登录DeepSeeK官方网站。开始提问推理模型:

图片

你是一位擅长使用Python生成中国内地基金筛选策略专家。请使用Python编写"4433"法则筛选基金的策略。

1:最近 1 年收益率排名在同类型基金的前 1/4
2:最近 2 年、3 年、5 年及今年以来收益率排名均在同类型基金的前 1/4
3:最近 6 个月收益率排名在同类型基金的前 1/3
4:最近 3 个月收益率排名在同类型基金的前 1/3

推理模型生成的Python代码如下:

import pandas as pd

def filter_4433(fund_data):
    """
    使用4433法则筛选基金
    :param fund_data: DataFrame包含以下列(示例):
    ['基金代码', '基金类型', '近1月收益率', '近3月收益率', '近6月收益率',
     '近1年收益率', '近2年收益率', '近3年收益率', '近5年收益率', '今年以来收益率']
    需要包含同类型基金的排名百分比数据(0-100)
    """
    try:
        # 定义筛选条件
        condition_1 = (fund_data['近1年排名%'] <= 25)          # 近1年前1/4
        condition_2 = (fund_data['近2年排名%'] <= 25) & \
                     (fund_data['近3年排名%'] <= 25) & \
                     (fund_data['近5年排名%'] <= 25) & \
                     (fund_data['今年以来排名%'] <= 25)       # 长期表现
        condition_3 = (fund_data['近6月排名%'] <= 33.33)       # 中期表现
        condition_4 = (fund_data['近3月排名%'] <= 33.33)       # 短期表现

        # 组合条件
        selected_funds = fund_data[condition_1 & condition_2 & condition_3 & condition_4]
        
        # 按夏普比率排序(可调整)
        if '夏普比率' in selected_funds.columns:
            selected_funds = selected_funds.sort_values(by='夏普比率', ascending=False)
        
        return selected_funds[['基金代码', '基金类型', '近3月排名%', '近6月排名%', 
                              '近1年排名%', '近2年排名%', '夏普比率']].reset_index(drop=True)
    
    except KeyError as e:
        print(f"数据缺失必要字段:{e}")
        return pd.DataFrame()

# 使用示例 -------------------------------------------------
if __name__ == "__main__":
    # 模拟数据(实际使用时需替换为真实数据)
    mock_data = pd.DataFrame({
        '基金代码': ['000001', '000002', '000003'],
        '基金类型': ['股票型', '混合型', '债券型'],
        '近3月排名%': [20, 30, 40],
        '近6月排名%': [25, 30, 35],
        '近1年排名%': [20, 25, 30],
        '近2年排名%': [20, 20, 20],
        '近3年排名%': [20, 20, 20],
        '近5年排名%': [20, 20, 20],
        '今年以来排名%': [20, 20, 20],
        '夏普比率': [2.1, 1.8, 1.5]
    })
    
    result = filter_4433(mock_data)
    print("筛选结果:")
    print(result)

生成的代码看起来思路是对的,不过有一个问题,基金数据是虚构的,不是真实的基金数据。需要使用akshare获取基金数据。

使用akshare获取基金数据

akshare是AKShare开源财经数据提供的一个Python包。接口库所采集的数据皆来自公开的数据源,包括股票、期货、期权、基金、外汇、债券、指数、加密货币等金融产品的基本面数据、实时和历史行情数据。

继续向推理模型提问:

请使用akshare包获取数据

推理模型生成的Python代码如下:

import akshare as ak
import pandas as pd

def get_fund_data():
    """
    使用akshare获取基金数据
    """
    try:
        # 获取基金排名数据
        fund_rank_df = ak.fund_em_open_fund_rank()
        print("获取基金排名数据成功!")
        return fund_rank_df
    except Exception as e:
        print(f"获取基金数据失败: {e}")
        return pd.DataFrame()

def filter_4433(fund_data):
    """
    使用4433法则筛选基金
    :param fund_data: DataFrame包含基金排名数据
    """
    try:
        # 确保数据包含所需字段
        required_columns = [
            '基金代码', '基金简称', '类型', '近1周', '近1月', '近3月', 
            '近6月', '近1年', '近2年', '近3年', '今年来', '成立来'
        ]
        for col in required_columns:
            if col not in fund_data.columns:
                raise ValueError(f"数据缺失必要字段: {col}")

        # 转换百分比数据为数值
        for col in ['近1周', '近1月', '近3月', '近6月', '近1年', '近2年', '近3年', '今年来']:
            fund_data[col] = fund_data[col].str.rstrip('%').astype(float)

        # 定义筛选条件
        condition_1 = (fund_data['近1年'] >= fund_data['近1年'].quantile(0.75))  # 近1年前1/4
        condition_2 = (fund_data['近2年'] >= fund_data['近2年'].quantile(0.75)) & \
                      (fund_data['近3年'] >= fund_data['近3年'].quantile(0.75)) & \
                      (fund_data['今年来'] >= fund_data['今年来'].quantile(0.75))  # 长期表现
        condition_3 = (fund_data['近6月'] >= fund_data['近6月'].quantile(2/3))  # 近6月前1/3
        condition_4 = (fund_data['近3月'] >= fund_data['近3月'].quantile(2/3))  # 近3月前1/3

        # 组合条件
        selected_funds = fund_data[condition_1 & condition_2 & condition_3 & condition_4]
        
        # 按近1年收益率排序
        selected_funds = selected_funds.sort_values(by='近1年', ascending=False)
        
        return selected_funds[['基金代码', '基金简称', '类型', '近3月', '近6月', '近1年', '近2年', '近3年']].reset_index(drop=True)
    
    except Exception as e:
        print(f"筛选过程中发生错误: {e}")
        return pd.DataFrame()

# 使用示例
if __name__ == "__main__":
    # 获取基金数据
    fund_data = get_fund_data()
    
    if not fund_data.empty:
        # 筛选基金
        result = filter_4433(fund_data)
        print("筛选结果:")
        print(result)
    else:
        print("未获取到基金数据,请检查网络或数据源。")

注意到推理模型生成的代码中使用的是fund_em_open_fund_rank函数。

但是运行代码后发现报错

AttributeError: module 'akshare' has no attribute 'fund_em_fund_name'

因为推理模型训练时缺乏最新的akshare文档,所以无法识别最新的akshare函数。

查询akshare文档,发现获取基金排名数据应该使用fund_open_fund_rank_em函数。

于是将代码中的fund_em_open_fund_rank替换为fund_open_fund_rank_em后,同时设定获取指数型基金。

再次运行代码,出现新的错误:

筛选过程中发生错误: Can only use .str accessor with string values!

检查代码后发现,原始数据中的百分比数据已经是浮点数类型,不需要转换为数值类型。

将相关代码注释掉:

        # # 转换百分比数据为数值
        # for col in ['近1周', '近1月', '近3月', '近6月', '近1年', '近2年', '近3年', '今年来']:
        #     fund_data[col] = fund_data[col].str.rstrip('%').astype(float)

因为笔者对akshare和Python比较熟悉,所以选择直接排查错误和手工修改代码。不熟悉的朋友可以将最新akshare文档相关信息提供给DeepSeek R1推理模型,让其帮忙更新代码。

完整代码

最后完整的代码是:

import akshare as ak
import pandas as pd

def get_fund_data():
    """
    使用akshare获取基金数据
    """
    try:
        # 获取基金排名数据
        fund_rank_df = ak.fund_open_fund_rank_em(symbol="指数型")
        print("获取基金排名数据成功!")
        return fund_rank_df
    except Exception as e:
        print(f"获取基金数据失败: {e}")
        return pd.DataFrame()

def filter_4433(fund_data):
    """
    使用4433法则筛选基金
    :param fund_data: DataFrame包含基金排名数据
    """
    try:
        # 确保数据包含所需字段
        required_columns = [
            '基金代码', '基金简称', '近1周', '近1月', '近3月', 
            '近6月', '近1年', '近2年', '近3年', '今年来', '成立来'
        ]
        for col in required_columns:
            if col not in fund_data.columns:
                raise ValueError(f"数据缺失必要字段: {col}")

        # # 转换百分比数据为数值
        # for col in ['近1周', '近1月', '近3月', '近6月', '近1年', '近2年', '近3年', '今年来']:
        #     fund_data[col] = fund_data[col].str.rstrip('%').astype(float)

        # 定义筛选条件
        condition_1 = (fund_data['近1年'] >= fund_data['近1年'].quantile(0.75))  # 近1年前1/4
        condition_2 = (fund_data['近2年'] >= fund_data['近2年'].quantile(0.75)) & \
                      (fund_data['近3年'] >= fund_data['近3年'].quantile(0.75)) & \
                      (fund_data['今年来'] >= fund_data['今年来'].quantile(0.75))  # 长期表现
        condition_3 = (fund_data['近6月'] >= fund_data['近6月'].quantile(2/3))  # 近6月前1/3
        condition_4 = (fund_data['近3月'] >= fund_data['近3月'].quantile(2/3))  # 近3月前1/3

        # 组合条件
        selected_funds = fund_data[condition_1 & condition_2 & condition_3 & condition_4]
        
        # 按近1年收益率排序
        selected_funds = selected_funds.sort_values(by='近1年', ascending=False)
        
        return selected_funds[['基金代码', '基金简称', '近3月', '近6月', '近1年', '近2年', '近3年']].reset_index(drop=True)
    
    except Exception as e:
        print(f"筛选过程中发生错误: {e}")
        return pd.DataFrame()

# 使用示例
if __name__ == "__main__":
    # 获取基金数据
    fund_data = get_fund_data()
    
    if not fund_data.empty:
        # 筛选基金
        result = filter_4433(fund_data)
        print("筛选结果:")
        print(result)
    else:
        print("未获取到基金数据,请检查网络或数据源。")

运行结果

输出结果是

获取基金排名数据成功!
筛选结果:
      基金代码                基金简称    近3月    近6月    近1年    近2年    近3年
0   165524  中信保诚中证智能家居指数(LOF)A  10.30  42.98  45.05  27.35   8.78
1   008326               东财通信A   2.81  25.07  44.89  46.32  29.45
2   008327               东财通信C   2.75  24.91  44.54  45.59  28.48
3   006355             华宝香港大盘C   0.81  24.35  44.48  17.16  13.42
4   501301             华宝香港大盘A   0.91  21.84  41.88  15.52  12.29
5   006810           泰康香港银行指数C   9.13  19.94  41.22  35.07  34.18
6   006809           泰康香港银行指数A   9.25  19.46  40.94  35.35  35.01
7   009225    天弘中证中美互联网(QDII)A   6.09  23.78  39.54  69.49  48.65
8   009226    天弘中证中美互联网(QDII)C   6.03  23.71  39.24  68.68  47.57
9   010365      鹏华香港银行指数(LOF)C   8.35  18.78  38.59  32.98  33.03
10  161029      富国中证银行指数(LOF)A   6.33  19.03  33.74  33.63  27.52
11  013330      富国中证银行指数(LOF)C   6.24  18.84  33.50  33.06  26.76
12  005063    广发中证全指家用电器ETF联接A   0.82  26.09  30.85  22.57  14.05
13  005064    广发中证全指家用电器ETF联接C   0.77  25.97  30.59  22.07  13.36

输出结果包含基金代码、基金简称、近3月、近6月、近1年、近2年、近3年的业绩表现数据。

免责声明

投资有风险,决策需谨慎。基金历史业绩不代表未来表现,基金选择需根据自身风险偏好、投资目标等因素综合考虑。

本文内容仅介绍如何使用DeepSeek R1推理模型 + Python生成基金选择策略。提供的Python策略及相关代码、分析工具、数据结论等仅用于技术研究、学术探讨或示例演示,不构成任何投资建议、投资推荐或操作指导。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐