搭建网站手机软件,网站关键词快照优化,宝格丽网站建设策划案,h5手机网站实例目录 0. 承前1. AI金融智能体1.1 What is AI金融智能体1.2 Why is AI金融智能体1.3 How to AI金融智能体 2. 数据要素计算流程2.1 参数集设置2.2 数据获取预处理2.3 收益率计算2.4 因子构建与预期收益率计算2.5 协方差矩阵计算2.6 投资组合优化2.7 持仓筛选2.8 AI金融… 目录 0. 承前1. AI金融智能体1.1 What is AI金融智能体1.2 Why is AI金融智能体1.3 How to AI金融智能体 2. 数据要素计算流程2.1 参数集设置2.2 数据获取预处理2.3 收益率计算2.4 因子构建与预期收益率计算2.5 协方差矩阵计算2.6 投资组合优化2.7 持仓筛选2.8 AI金融智能体调仓函数 3. 汇总代码4. 反思4.1 不足之处4.2 提升思路 5. 启后 0. 承前
本篇博文是对上一篇文章链接: 4. 马科维茨资产组合模型Fama-French五因子优化方案理论Python实战 的资产权重进行AI干预。 本文首先使用Fama-French五因子计算出资产组合模型权重再把权重结合政策信息输入AI模型目的是
在金融工程中实现AI功能在金融模型的落地的尝试AI模型对政策信息描述内容情绪分析等进行分析实现政策信息对金融模型的主动影响。
本文主要要素
马科维茨资产组合模型Fama-French五因子模型预期收益率AI金融智能体通义千问qwen-max提示词工程政策信息通过AI转化影响预期收益率。
如果想更加全面清晰地了解金融资产组合模型进化论的体系架构可参考 0. 金融资产组合模型进化全图鉴
1. AI金融智能体
1.1 What is AI金融智能体
AI金融智能体是指利用人工智能技术特别是机器学习、深度学习和自然语言处理等先进技术来模拟人类分析师的行为以执行复杂的金融分析任务的软件。本文主要是通过提示词工程结合政策信息给予AI一定的范围权限去影响资产组合权重属于金融工程构建的尝试性实验。
1.2 Why is AI金融智能体 自动接入全网实时搜索并分析海量数据AI金融智能体能够无缝连接互联网迅速处理和解析大量的金融市场信息为用户提供即时的洞察和支持。 拥有远超人类的计算能力揭示潜在的市场盲点凭借其卓越的计算力AI智能体可以深入挖掘数据识别出那些基于常识可能被忽视的市场机会或风险。 顺应技术潮流推动更多AI工具在金融领域的实际应用随着技术的进步AI在金融行业的落地已成为必然趋势。金融机构需积极探索和实施更多的AI解决方案以保持竞争力和服务创新。
1.3 How to AI金融智能体 参数集设置 ts.set_token设置Tushare的API访问令牌industry选择目标行业如银行end_date回测结束日期格式为’YYYYMMDD’years回测年限默认5年risk_free_rate无风险利率默认0.03top_holdings投资组合持仓数量默认10只股票index_code市场指数代码默认’000300.SH’api_key通义千问APIcharacterAI人设提示词工程policy_info政策信息5条 数据准备 股票行业数据通过tushare获取指定行业的股票列表历史价格数据获取指定时间段内的股票日线数据市场指数数据获取指定时间段内的市场指数数据因子数据获取市值(Size)和账面市值比(B/M)数据财务数据获取ROE和资产增长率数据无风险利率设定无风险利率参数 计算流程 数据获取获取股票、市场指数和因子数据收益率计算计算月度对数收益率因子构建构建SMB、HML、RMW和CMA因子因子载荷计算计算每只股票对五个因子的敏感度FF5预期收益使用五因子模型计算预期收益率组合优化最大化夏普比率得到最优权重持仓筛选选取权重最大的N只股票并归一化AI函数结合权重数据、政策信息、提示词工程对权重实现智能调整
2. 数据要素计算流程
2.1 参数集设置
设置模型所需的基本参数包括数据获取、回测区间和优化约束等。
# 参数集
ts.set_token(token)
pro ts.pro_api()
industry 银行
end_date 20240101
years 5 # 数据时长
risk_free_rate 0.03 # 无风险利率参数
top_holdings 10 # 持仓数量参数
index_code 000300.SH # 市场指数代码参数
api_keysk-api_key # 通义千问API# AI人设提示词工程
character f
你是一名专业的金融数据与政策分析师擅长解读金融市场动态和政策导向并据此调整资产组合的权重分布以优化投资策略。你的主要任务是对给定的资产组合进行权重调整确保
1. 权重之和精确为1
2. 每个资产调整后的权重只能在原有基础上增减最多10%
3. 每个资产调整完毕后如果权重之和不等于1则归一化使权重之和精确为1
4. 数据对应的日期是{end_date}在思考过程中切勿根据该日期之后的信息进行思考。
5. 输出的数据格式需与输入保持一致仅提供数据而不做额外解释当你接收到具体的资产组合及其权重时请根据最新的金融数据和政策信息对其进行合理调整。
# 通过工作流获取的政策信息
policy_info
| 日期 | 政策简述 |
|------|----------|
| 2023-12-29 | 央行发布《关于优化商业银行存款利率监管有关事项的通知》取消定期存款利率浮动上限允许银行自主协调存贷款利率 |
| 2023-11-17 | 央行、银保监会联合发布《关于做好当前商业银行房地产贷款投放管理的通知》优化房地产信贷政策支持刚性和改善性住房需求 |
| 2023-09-25 | 银保监会发布《关于进一步加强银行业金融机构流动性风险管理的通知》要求银行加强流动性风险管理完善风险监测预警机制 |
| 2023-08-31 | 央行、银保监会宣布下调全国首套住房贷款利率下限各地可自主决定下调幅度二套房贷款利率政策与首套相同 |
| 2023-07-21 | 十四届全国人大常委会第四次会议表决通过《中华人民共和国金融稳定法》建立健全金融风险防范化解制度体系 |2.2 数据获取预处理
获取股票、市场指数、因子数据和财务数据并进行必要的数据清洗和格式转换。
def get_industry_stocks(industry):获取指定行业的股票列表df pro.stock_basic(fields[ts_code, name, industry])industry_stocks df[df[industry]industry].copy()industry_stocks.sort_values(byts_code, inplaceTrue)industry_stocks.reset_index(dropTrue, inplaceTrue)return industry_stocks[ts_code].tolist()def get_data(code_list, end_date, years):获取指定行业名称的历史收盘价数据ts_code_list code_listend_date_dt datetime.strptime(end_date, %Y%m%d)start_date_dt end_date_dt - timedelta(daysyears*365)start_date start_date_dt.strftime(%Y%m%d)all_data []for stock in ts_code_list:df pro.daily(ts_codestock, start_datestart_date, end_dateend_date)all_data.append(df)combined_df pd.concat(all_data).sort_values(by[ts_code, trade_date])combined_df.reset_index(dropTrue, inplaceTrue)combined_df.rename(columns{trade_date: date}, inplaceTrue)return combined_dfdef get_market_data(index_code000300.SH, start_dateNone, end_dateNone):获取市场指数数据用于计算贝塔df_market pro.index_daily(ts_codeindex_code, start_datestart_date, end_dateend_date,fields[trade_date, close])df_market[date] pd.to_datetime(df_market[trade_date])df_market.set_index(date, inplaceTrue)df_market df_market.sort_index()monthly_last_close df_market[close].resample(M).last()monthly_log_returns np.log(monthly_last_close).diff().dropna()return monthly_log_returnsdef get_factor_data(stock_codes, start_dateNone, end_dateNone):获取指定股票的因子数据市值和PBall_factor_data []for stock in stock_codes:try:df pro.daily_basic(ts_codestock,start_datestart_date,end_dateend_date,fields[ts_code, trade_date, total_mv, pb])all_factor_data.append(df)except Exception as e:print(f获取股票 {stock} 的因子数据失败: {str(e)})continuefactor_data pd.concat(all_factor_data, ignore_indexTrue)factor_data[trade_date] pd.to_datetime(factor_data[trade_date])return factor_datadef get_fina_data(stock_codes, start_dateNone, end_dateNone):获取指定股票的财务指标数据ROE和资产增长率all_fina_data []for stock in stock_codes:try:df pro.fina_indicator(ts_codestock,start_datestart_date,end_dateend_date,fields[ts_code, end_date, roe_dt, assets_yoy, update_flag])all_fina_data.append(df)except Exception as e:print(f获取股票 {stock} 的财务数据失败: {str(e)})continue# 合并数据fina_data pd.concat(all_fina_data, ignore_indexTrue)# 处理update_flag保留最新数据fina_data (fina_data.groupby([ts_code, end_date]).agg({roe_dt: first, assets_yoy: first,update_flag: max}).reset_index())# 将end_date转换为datetimefina_data[end_date] pd.to_datetime(fina_data[end_date])# 创建季度到月度的映射monthly_data []for _, row in fina_data.iterrows():quarter_end row[end_date]if quarter_end.month 3: # Q1months [quarter_end pd.DateOffset(monthsi) for i in range(1, 4)]elif quarter_end.month 6: # Q2months [quarter_end pd.DateOffset(monthsi) for i in range(1, 4)]elif quarter_end.month 9: # Q3months [quarter_end pd.DateOffset(monthsi) for i in range(1, 4)]else: # Q4months [quarter_end pd.DateOffset(monthsi) for i in range(1, 4)]for month in months:monthly_data.append({ts_code: row[ts_code],trade_date: month,roe_dt: row[roe_dt],assets_yoy: row[assets_yoy]})monthly_df pd.DataFrame(monthly_data)return monthly_df2.3 收益率计算
计算月度对数收益率为后续的因子构建和优化计算做准备。
def calculate_monthly_log_returns(df):计算每月的对数收益率df[date] pd.to_datetime(df[date])monthly_last_close df.groupby([ts_code, pd.Grouper(keydate, freqM)])[close].last().unstack(level-1)monthly_log_returns np.log(monthly_last_close).diff().dropna()return monthly_log_returns.T2.4 因子构建与预期收益率计算
构建SMB、HML、RMW和CMA因子并使用五因子模型计算预期收益率。
def calculate_expected_returns(monthly_log_returns):使用Fama-French五因子模型计算各股票的预期收益率start_date monthly_log_returns.index.min().strftime(%Y%m%d)end_date monthly_log_returns.index.max().strftime(%Y%m%d)# 获取财务数据时将start_date往前推一个季度以确保有完整的季度数据fina_start_date (datetime.strptime(start_date, %Y%m%d) - timedelta(days90)).strftime(%Y%m%d)# 获取市场收益率market_returns get_market_data(index_code, start_date, end_date)# 获取股票的市值和PB数据stock_data get_factor_data(monthly_log_returns.columns.tolist(),start_date,end_date)# 获取财务指标数据使用提前的start_datefina_data get_fina_data(monthly_log_returns.columns.tolist(),fina_start_date,end_date)# 确保所有数据的日期对齐aligned_dates monthly_log_returns.index.intersection(market_returns.index)market_returns market_returns[aligned_dates]stock_returns monthly_log_returns.loc[aligned_dates].copy() # 使用copy()避免SettingWithCopyWarningdef calculate_size_factor(date):date_data stock_data[stock_data[trade_date].dt.to_period(M) date.to_period(M)]median_mv date_data[total_mv].median()small_returns stock_returns.loc[date, date_data[date_data[total_mv] median_mv][ts_code]]big_returns stock_returns.loc[date, date_data[date_data[total_mv] median_mv][ts_code]]return small_returns.mean() - big_returns.mean()def calculate_value_factor(date):date_data stock_data[stock_data[trade_date].dt.to_period(M) date.to_period(M)]# 创建date_data的副本并计算bm_ratiodate_data date_data.copy()date_data.loc[:, bm_ratio] 1 / date_data[pb]median_bm date_data[bm_ratio].median()high_returns stock_returns.loc[date, date_data[date_data[bm_ratio] median_bm][ts_code]]low_returns stock_returns.loc[date, date_data[date_data[bm_ratio] median_bm][ts_code]]return high_returns.mean() - low_returns.mean()def calculate_profitability_factor(date):date_data fina_data[fina_data[trade_date].dt.to_period(M) date.to_period(M)]median_roe date_data[roe_dt].median()robust_returns stock_returns.loc[date, date_data[date_data[roe_dt] median_roe][ts_code]]weak_returns stock_returns.loc[date, date_data[date_data[roe_dt] median_roe][ts_code]]return robust_returns.mean() - weak_returns.mean()def calculate_investment_factor(date):date_data fina_data[fina_data[trade_date].dt.to_period(M) date.to_period(M)]median_growth date_data[assets_yoy].median()conservative_returns stock_returns.loc[date, date_data[date_data[assets_yoy] median_growth][ts_code]]aggressive_returns stock_returns.loc[date, date_data[date_data[assets_yoy] median_growth][ts_code]]return conservative_returns.mean() - aggressive_returns.mean()# 计算每个月的因子收益smb_factor pd.Series([calculate_size_factor(date) for date in aligned_dates], indexaligned_dates)hml_factor pd.Series([calculate_value_factor(date) for date in aligned_dates], indexaligned_dates)rmw_factor pd.Series([calculate_profitability_factor(date) for date in aligned_dates], indexaligned_dates)cma_factor pd.Series([calculate_investment_factor(date) for date in aligned_dates], indexaligned_dates)# 使用OLS回归计算每个股票的因子载荷factor_loadings {}for stock in stock_returns.columns:X sm.add_constant(pd.concat([market_returns - risk_free_rate,smb_factor,hml_factor,rmw_factor,cma_factor], axis1))y stock_returns[stock] - risk_free_ratemodel sm.OLS(y, X).fit()factor_loadings[stock] model.params[1:]# 计算因子风险溢价market_premium market_returns.mean() - risk_free_ratesmb_premium smb_factor.mean()hml_premium hml_factor.mean()rmw_premium rmw_factor.mean()cma_premium cma_factor.mean()# 使用FF5模型计算预期收益率expected_returns pd.Series({stock: (risk_free_rate loadings.iloc[0] * market_premium loadings.iloc[1] * smb_premium loadings.iloc[2] * hml_premium loadings.iloc[3] * rmw_premium loadings.iloc[4] * cma_premium)for stock, loadings in factor_loadings.items()})return expected_returns2.5 协方差矩阵计算
计算收益率的协方差矩阵用于评估资产间的相关性和波动性。
def calculate_covariance_matrix(monthly_log_returns):计算收益率协方差矩阵return monthly_log_returns.cov()2.6 投资组合优化
通过最大化夏普比率来寻找最优权重配置。
def max_sharpe_ratio(mean_returns, cov_matrix, risk_free_rate):计算最大夏普比率的投资组合权重num_assets len(mean_returns)args (mean_returns, cov_matrix, risk_free_rate)constraints ({type: eq, fun: lambda x: np.sum(x) - 1})bounds tuple((0, 1) for asset in range(num_assets))result minimize(negative_sharpe_ratio, num_assets*[1./num_assets], argsargs,methodSLSQP, boundsbounds, constraintsconstraints)return result.x2.7 持仓筛选
选取权重最大的N只股票并重新归一化权重。
def calculate_top_holdings_weights(optimal_weights, monthly_log_returns_columns, top_n):计算前N大持仓的权重占比result_dict {asset: weight for asset, weight in zip(monthly_log_returns_columns, optimal_weights)}top_n_holdings sorted(result_dict.items(), keylambda item: item[1], reverseTrue)[:top_n]top_n_sum sum(value for _, value in top_n_holdings)updated_result {key: value / top_n_sum for key, value in top_n_holdings}return updated_result2.8 AI金融智能体调仓函数
def get_ai_weights(character, policy_info, updated_result, api_key):# 定义发送对话内容messages [{role: system, content: character},{role: user, content: policy_info},{role: user, content: json.dumps(updated_result, ensure_asciiFalse)}]response dashscope.Generation.call(api_keyapi_key,modelqwen-max,messagesmessages,result_formatmessage,enable_searchTrue,top_p0.01)# 提取content内容content response[output][choices][0][message][content]# 将JSON字符串转换为Python字典portfolio_weights json.loads(content)# 对AI输出结果进行归一化weights_sum sum(portfolio_weights.values())portfolio_weights {key: value/weights_sum for key, value in portfolio_weights.items()}# 将字典中的值修改为6位小数portfolio_weights {k: round(v, 6) for k, v in portfolio_weights.items()}return portfolio_weights3. 汇总代码
以下即为全量代码修改参数集中内容即可跑出个性化数据。
import tushare as ts
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from scipy.optimize import minimize
import backtrader as bt
import statsmodels.api as sm
import os
import json
import dashscope# 参数集##############################################################################
ts.set_token(token)
pro ts.pro_api()
industry 银行
end_date 20240101
years 5 # 数据时长
risk_free_rate 0.03 # 无风险利率参数
top_holdings 10 # 持仓数量参数
index_code 000300.SH # 市场指数代码参数
api_keysk-api_key # 通义千问API# AI人设提示词工程
character f
你是一名专业的金融数据与政策分析师擅长解读金融市场动态和政策导向并据此调整资产组合的权重分布以优化投资策略。你的主要任务是对给定的资产组合进行权重调整确保
1. 权重之和精确为1
2. 每个资产调整后的权重只能在原有基础上增减最多10%
3. 每个资产调整完毕后如果权重之和不等于1则归一化使权重之和精确为1
4. 数据对应的日期是{end_date}在思考过程中切勿根据该日期之后的信息进行思考。
5. 输出的数据格式需与输入保持一致仅提供数据而不做额外解释当你接收到具体的资产组合及其权重时请根据最新的金融数据和政策信息对其进行合理调整。
# 通过工作流获取的政策信息
policy_info
| 日期 | 政策简述 |
|------|----------|
| 2023-12-29 | 央行发布《关于优化商业银行存款利率监管有关事项的通知》取消定期存款利率浮动上限允许银行自主协调存贷款利率 |
| 2023-11-17 | 央行、银保监会联合发布《关于做好当前商业银行房地产贷款投放管理的通知》优化房地产信贷政策支持刚性和改善性住房需求 |
| 2023-09-25 | 银保监会发布《关于进一步加强银行业金融机构流动性风险管理的通知》要求银行加强流动性风险管理完善风险监测预警机制 |
| 2023-08-31 | 央行、银保监会宣布下调全国首套住房贷款利率下限各地可自主决定下调幅度二套房贷款利率政策与首套相同 |
| 2023-07-21 | 十四届全国人大常委会第四次会议表决通过《中华人民共和国金融稳定法》建立健全金融风险防范化解制度体系 |# 参数集##############################################################################def get_industry_stocks(industry):获取指定行业的股票列表df pro.stock_basic(fields[ts_code, name, industry])industry_stocks df[df[industry]industry].copy()industry_stocks.sort_values(byts_code, inplaceTrue)industry_stocks.reset_index(dropTrue, inplaceTrue)return industry_stocks[ts_code].tolist()def get_data(code_list, end_date, years):获取指定行业名称的历史收盘价数据ts_code_list code_listend_date_dt datetime.strptime(end_date, %Y%m%d)start_date_dt end_date_dt - timedelta(daysyears*365)start_date start_date_dt.strftime(%Y%m%d)all_data []for stock in ts_code_list:df pro.daily(ts_codestock, start_datestart_date, end_dateend_date)all_data.append(df)combined_df pd.concat(all_data).sort_values(by[ts_code, trade_date])combined_df.reset_index(dropTrue, inplaceTrue)combined_df.rename(columns{trade_date: date}, inplaceTrue)return combined_dfdef get_market_data(index_code000300.SH, start_dateNone, end_dateNone):获取市场指数数据用于计算贝塔df_market pro.index_daily(ts_codeindex_code, start_datestart_date, end_dateend_date,fields[trade_date, close])df_market[date] pd.to_datetime(df_market[trade_date])df_market.set_index(date, inplaceTrue)df_market df_market.sort_index()monthly_last_close df_market[close].resample(M).last()monthly_log_returns np.log(monthly_last_close).diff().dropna()return monthly_log_returnsdef get_factor_data(stock_codes, start_dateNone, end_dateNone):获取指定股票的因子数据市值和PBall_factor_data []for stock in stock_codes:try:df pro.daily_basic(ts_codestock,start_datestart_date,end_dateend_date,fields[ts_code, trade_date, total_mv, pb])all_factor_data.append(df)except Exception as e:print(f获取股票 {stock} 的因子数据失败: {str(e)})continuefactor_data pd.concat(all_factor_data, ignore_indexTrue)factor_data[trade_date] pd.to_datetime(factor_data[trade_date])return factor_datadef get_fina_data(stock_codes, start_dateNone, end_dateNone):获取指定股票的财务指标数据ROE和资产增长率all_fina_data []for stock in stock_codes:try:df pro.fina_indicator(ts_codestock,start_datestart_date,end_dateend_date,fields[ts_code, end_date, roe_dt, assets_yoy, update_flag])all_fina_data.append(df)except Exception as e:print(f获取股票 {stock} 的财务数据失败: {str(e)})continue# 合并数据fina_data pd.concat(all_fina_data, ignore_indexTrue)# 处理update_flag保留最新数据fina_data (fina_data.groupby([ts_code, end_date]).agg({roe_dt: first, assets_yoy: first,update_flag: max}).reset_index())# 将end_date转换为datetimefina_data[end_date] pd.to_datetime(fina_data[end_date])# 创建季度到月度的映射monthly_data []for _, row in fina_data.iterrows():quarter_end row[end_date]if quarter_end.month 3: # Q1months [quarter_end pd.DateOffset(monthsi) for i in range(1, 4)]elif quarter_end.month 6: # Q2months [quarter_end pd.DateOffset(monthsi) for i in range(1, 4)]elif quarter_end.month 9: # Q3months [quarter_end pd.DateOffset(monthsi) for i in range(1, 4)]else: # Q4months [quarter_end pd.DateOffset(monthsi) for i in range(1, 4)]for month in months:monthly_data.append({ts_code: row[ts_code],trade_date: month,roe_dt: row[roe_dt],assets_yoy: row[assets_yoy]})monthly_df pd.DataFrame(monthly_data)return monthly_dfdef calculate_monthly_log_returns(df):计算每月的对数收益率df[date] pd.to_datetime(df[date])monthly_last_close df.groupby([ts_code, pd.Grouper(keydate, freqM)])[close].last().unstack(level-1)monthly_log_returns np.log(monthly_last_close).diff().dropna()return monthly_log_returns.Tdef calculate_expected_returns(monthly_log_returns):使用Fama-French五因子模型计算各股票的预期收益率start_date monthly_log_returns.index.min().strftime(%Y%m%d)end_date monthly_log_returns.index.max().strftime(%Y%m%d)# 获取财务数据时将start_date往前推一个季度以确保有完整的季度数据fina_start_date (datetime.strptime(start_date, %Y%m%d) - timedelta(days90)).strftime(%Y%m%d)# 获取市场收益率market_returns get_market_data(index_code, start_date, end_date)# 获取股票的市值和PB数据stock_data get_factor_data(monthly_log_returns.columns.tolist(),start_date,end_date)# 获取财务指标数据使用提前的start_datefina_data get_fina_data(monthly_log_returns.columns.tolist(),fina_start_date,end_date)# 确保所有数据的日期对齐aligned_dates monthly_log_returns.index.intersection(market_returns.index)market_returns market_returns[aligned_dates]stock_returns monthly_log_returns.loc[aligned_dates].copy() # 使用copy()避免SettingWithCopyWarningdef calculate_size_factor(date):date_data stock_data[stock_data[trade_date].dt.to_period(M) date.to_period(M)]median_mv date_data[total_mv].median()small_returns stock_returns.loc[date, date_data[date_data[total_mv] median_mv][ts_code]]big_returns stock_returns.loc[date, date_data[date_data[total_mv] median_mv][ts_code]]return small_returns.mean() - big_returns.mean()def calculate_value_factor(date):date_data stock_data[stock_data[trade_date].dt.to_period(M) date.to_period(M)]# 创建date_data的副本并计算bm_ratiodate_data date_data.copy()date_data.loc[:, bm_ratio] 1 / date_data[pb]median_bm date_data[bm_ratio].median()high_returns stock_returns.loc[date, date_data[date_data[bm_ratio] median_bm][ts_code]]low_returns stock_returns.loc[date, date_data[date_data[bm_ratio] median_bm][ts_code]]return high_returns.mean() - low_returns.mean()def calculate_profitability_factor(date):date_data fina_data[fina_data[trade_date].dt.to_period(M) date.to_period(M)]median_roe date_data[roe_dt].median()robust_returns stock_returns.loc[date, date_data[date_data[roe_dt] median_roe][ts_code]]weak_returns stock_returns.loc[date, date_data[date_data[roe_dt] median_roe][ts_code]]return robust_returns.mean() - weak_returns.mean()def calculate_investment_factor(date):date_data fina_data[fina_data[trade_date].dt.to_period(M) date.to_period(M)]median_growth date_data[assets_yoy].median()conservative_returns stock_returns.loc[date, date_data[date_data[assets_yoy] median_growth][ts_code]]aggressive_returns stock_returns.loc[date, date_data[date_data[assets_yoy] median_growth][ts_code]]return conservative_returns.mean() - aggressive_returns.mean()# 计算每个月的因子收益smb_factor pd.Series([calculate_size_factor(date) for date in aligned_dates], indexaligned_dates)hml_factor pd.Series([calculate_value_factor(date) for date in aligned_dates], indexaligned_dates)rmw_factor pd.Series([calculate_profitability_factor(date) for date in aligned_dates], indexaligned_dates)cma_factor pd.Series([calculate_investment_factor(date) for date in aligned_dates], indexaligned_dates)# 使用OLS回归计算每个股票的因子载荷factor_loadings {}for stock in stock_returns.columns:X sm.add_constant(pd.concat([market_returns - risk_free_rate,smb_factor,hml_factor,rmw_factor,cma_factor], axis1))y stock_returns[stock] - risk_free_ratemodel sm.OLS(y, X).fit()factor_loadings[stock] model.params[1:]# 计算因子风险溢价market_premium market_returns.mean() - risk_free_ratesmb_premium smb_factor.mean()hml_premium hml_factor.mean()rmw_premium rmw_factor.mean()cma_premium cma_factor.mean()# 使用FF5模型计算预期收益率expected_returns pd.Series({stock: (risk_free_rate loadings.iloc[0] * market_premium loadings.iloc[1] * smb_premium loadings.iloc[2] * hml_premium loadings.iloc[3] * rmw_premium loadings.iloc[4] * cma_premium)for stock, loadings in factor_loadings.items()})return expected_returnsdef calculate_covariance_matrix(monthly_log_returns):计算收益率协方差矩阵return monthly_log_returns.cov()def portfolio_performance(weights, mean_returns, cov_matrix):计算投资组合的表现returns np.sum(mean_returns * weights) std_dev np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))return returns, std_devdef negative_sharpe_ratio(weights, mean_returns, cov_matrix, risk_free_rate):计算负夏普比率p_ret, p_std portfolio_performance(weights, mean_returns, cov_matrix)sharpe_ratio (p_ret - risk_free_rate) / p_stdreturn -sharpe_ratiodef max_sharpe_ratio(mean_returns, cov_matrix, risk_free_rate):计算最大夏普比率的投资组合权重num_assets len(mean_returns)args (mean_returns, cov_matrix, risk_free_rate)constraints ({type: eq, fun: lambda x: np.sum(x) - 1})bounds tuple((0, 1) for asset in range(num_assets))result minimize(negative_sharpe_ratio, num_assets*[1./num_assets], argsargs,methodSLSQP, boundsbounds, constraintsconstraints)return result.xdef calculate_top_holdings_weights(optimal_weights, monthly_log_returns_columns, top_n):计算前N大持仓的权重占比result_dict {asset: weight for asset, weight in zip(monthly_log_returns_columns, optimal_weights)}top_n_holdings sorted(result_dict.items(), keylambda item: item[1], reverseTrue)[:top_n]top_n_sum sum(value for _, value in top_n_holdings)updated_result {key: value / top_n_sum for key, value in top_n_holdings}return updated_resultdef get_ai_weights(character, policy_info, updated_result, api_key):# 定义发送对话内容messages [{role: system, content: character},{role: user, content: policy_info},{role: user, content: json.dumps(updated_result, ensure_asciiFalse)}]response dashscope.Generation.call(api_keyapi_key,modelqwen-max,messagesmessages,result_formatmessage,enable_searchTrue,top_p0.01)# 提取content内容content response[output][choices][0][message][content]# 将JSON字符串转换为Python字典portfolio_weights json.loads(content)# 对AI输出结果进行归一化weights_sum sum(portfolio_weights.values())portfolio_weights {key: value/weights_sum for key, value in portfolio_weights.items()}# 将字典中的值修改为6位小数portfolio_weights {k: round(v, 6) for k, v in portfolio_weights.items()}return portfolio_weightsdef main():# 获取数据code_list get_industry_stocks(industry)df get_data(code_list, end_date, years)# 计算每月的对数收益率monthly_log_returns calculate_monthly_log_returns(df)# 使用FF5模型计算预期收益率mean_returns calculate_expected_returns(monthly_log_returns)# 计算收益率协方差矩阵cov_matrix calculate_covariance_matrix(monthly_log_returns)# 优化权重optimal_weights max_sharpe_ratio(mean_returns, cov_matrix, risk_free_rate)# 计算前N大持仓权重updated_result calculate_top_holdings_weights(optimal_weights, monthly_log_returns.columns, top_holdings)# 计算AI调仓后的持仓权重updated_result get_ai_weights(character, policy_info, updated_result, api_key)# 打印更新后的资产占比print(f\n{end_date}最优资产前{top_holdings}占比:)print(updated_result)if __name__ __main__:main()
运行结果
AI金融智能体调仓前权重
股票代码占比601398.SH0.16318772568631026601328.SH0.16177476392789242600919.SH0.12936894301756055600036.SH0.10747174637443846601169.SH0.0958427702817229600016.SH0.09012906474680284601166.SH0.08768928377548085601288.SH0.06538512327994642600908.SH0.05559150377594274600926.SH0.043559075133902475
AI金融智能体调仓后权重
{601398.SH: 0.163025, 601328.SH: 0.161623, 600919.SH: 0.129252, 600036.SH: 0.107372, 601169.SH: 0.095764,
600016.SH: 0.090046, 601166.SH: 0.087606, 601288.SH: 0.065323, 600908.SH: 0.055541, 600926.SH: 0.044449}股票代码占比601398.SH0.163025601328.SH0.161623600919.SH0.129252600036.SH0.107372601169.SH0.095764600016.SH0.090046601166.SH0.087606601288.SH0.065323600908.SH0.055541600926.SH0.044449
可见AI金融智能体通过对政策信息的了解加大对银行业投资的信心特别是对大型国有银行和部分地方性银行。这种调整反映了AI对于市场动态的理解以及对未来收益预期的优化。 我们后验的经验也证明在2024年银行行业是一个值得投资的行业如果在20240101投资银行行业将会获得不俗的收益。
4. 反思
4.1 不足之处
政策信息获取获取政策信息方案仍为半手动AI逻辑缜密度AI可能未能完全按照提示词工程执行
4.2 提升思路
更换AI智能体使用由幻方量化开发的DeepSeek-V3 模型工作流接入金融工程内部实现真正全自动
5. 启后 优化下一篇文章将会尝试使用由幻方量化开发的DeepSeek_V3模型可参考下一篇文章 6. 马科维茨资产组合模型政策意图AI金融智能体(DeepSeek-V3)增强方案理论Python实战 量化回测实现可参考下一篇文章 pass