【python量化】基于ChatGPT的多因子框架实现

史上最强,建议收藏!

尝试用ChatGPT完成量化测试中的常用功能,包括因子构建、因子改进、测试框架,毕竟如果ChatGPT都会算会改进的因子,如果还不会,就只能去搬砖了,就问你慌不慌

除了这里展示的这些,还尝试了一些其他的,包括询问特定基金、股票的信息、求导、积分,甚至解偏微分方程,都能实现。测下来的整体感觉是,除了不能保证准确度,其他都挺好的,但毕竟只是3.5,4已经有了相当程度的提升,以后可能还会有5、6...,相信这会是一个新时代的起点

因子定义及改进

动量因子,代码太长截不下,完整代码放后面了

c76b25b5be422b58c6f21f3554245914.png

完整代码如下,有点问题,但问题不大

import datetime
import pandas as pd
from WindPy import w

# 初始化Wind API
w.start()

# 设置起始日期和结束日期
start_date = datetime.date(2022, 3, 1)
end_date = datetime.date(2023, 3, 21)

# 获取股票数据
code = "000001.SZ"
data = w.wsd(code, "close", start_date, end_date, "Fill=Previous")

# 将数据转换为DataFrame
df = pd.DataFrame(data.Data[0], index=data.Times, columns=["close"])

# 计算Momentum指标
df["Mom12_1"] = df["close"].pct_change(periods=12)

# 输出结果
print(df.tail())

b2b1420341812fb8ecff7688a2872cb8.png

反转因子

a2ef2b1b1b77b1b812967c5ea9b82078.png

完整代码附在下面,可以测试一下,甚至会帮忙把因子调整成正向

import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from WindPy import w

# 连接Wind API
w.start()

# 设置计算参数
start_date = datetime.now() - timedelta(days=30) # 计算过去一个月的数据
end_date = datetime.now()
stock_code = '600000.SH'
freq = 'M'
field = 'close'

# 获取股票收盘价数据
raw_data = w.wsd(stock_code, field, start_date, end_date, "")

# 将数据转换为DataFrame格式
df = pd.DataFrame(raw_data.Data[0], index=raw_data.Times, columns=[stock_code])
df = df.resample(freq).last().ffill()

# 计算收益率并标准化
returns = df.pct_change().dropna()
z_scores = (returns - returns.mean()) / returns.std()

# 计算反转因子并排序
rev_factor = -z_scores
rev_factor = rev_factor.dropna().sort_values()

# 输出结果
print(rev_factor)

1b7b8c93f0ca6623c6a9dd2ce37480be.png

超预期因子

c46c3ba5bd23b3a08c86eb8e67eef86b.png

完整代码如下,不能说完全错误,至少也是毫不相干吧

import datetime
import pandas as pd
from WindPy import w

# 初始化Wind API
w.start()

# 设置起始日期和结束日期
start_date = datetime.date(2022, 3, 1)
end_date = datetime.date(2023, 3, 21)

# 获取股票数据
code = "000001.SZ"
fields = ["eps_basic", "eps_diluted", "oper_rev", "net_profit"]
data = w.wsd(code, fields, start_date, end_date, "Fill=Previous")

# 将数据转换为DataFrame
df = pd.DataFrame(data.Data, index=fields, columns=data.Times).T

# 计算预期收益
df["expected_eps"] = df["oper_rev"] * df["eps_basic"] / df["net_profit"]

# 计算非预期收益
df["unexpected_eps"] = df["eps_basic"] - df["expected_eps"]

# 计算标准化非预期收益(SUE)
df["SUE"] = df["unexpected_eps"].rolling(window=4).std() / df["eps_basic"].rolling(window=4).std()

# 输出结果
print(df.tail())

07623f47f91a152295f911fb55db649b.png

242f7ecc984ceab95baca56387e30e6a.png

7bff85e17d2da8d820dfb4fc4f7180ff.png

测试框架

计算IC的函数

757e3a97a83239f9edcedec03024e0c7.png

分层测试的函数

376516f417552e7894e26555eb65011a.png

完整代码如下

import pandas as pd
import numpy as np
import statsmodels.api as sm


def factor_test(factor_data, ret_data, num_groups=5):
    """
    进行因子分层测试
    
    参数:
    factor_data : pandas.DataFrame
        包含因子值的数据框
    ret_data : pandas.DataFrame
        包含股票收益率的数据框
    num_groups : int, 可选(默认值为5)
        分层的组数
    
    返回:
    dict
        包含每个组的平均收益率和t值的字典
    """
    # 确保因子和收益率数据的列名一致
    factor_data.columns = ret_data.columns
    
    # 将因子值标准化为z-score
    factor_data = (factor_data - factor_data.mean()) / factor_data.std()
    
    # 按因子值大小将股票分为不同的组
    groupings = pd.qcut(factor_data, num_groups, labels=False)
    
    # 计算每个组的平均收益率和t值
    group_ret = ret_data.groupby(groupings)
    means = group_ret.mean()
    stds = group_ret.std()
    t_values = means / (stds / np.sqrt(group_ret.count()))
    
    # 返回结果
    return {"mean_returns": means, "t_values": t_values}

事件测试的函数

3c14fa1f34bb2f1d4bf642cecfe010df.png

组合优化的函数

742cfb942453d5e179065e17229d4070.png

代码如下

import numpy as np
import pandas as pd
from scipy.optimize import minimize

def optimize_portfolio(stocks, start_date, end_date):
    # 获取股票数据
    data = get_stock_data(stocks, start_date, end_date)

    # 计算日收益率和协方差矩阵
    returns = data.pct_change().mean()
    cov_matrix = data.pct_change().cov()

    # 定义优化函数
    def portfolio_variance(weights):
        return np.dot(weights.T, np.dot(cov_matrix, weights))

    # 定义约束条件
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})

    # 设置初始权重
    num_stocks = len(stocks)
    init_weights = np.array([1.0 / num_stocks] * num_stocks)

    # 最小化方差
    result = minimize(portfolio_variance, init_weights, method='SLSQP',
                      constraints=constraints)

    # 返回最优权重
    return result.x
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值