7. 马科维茨资产组合模型+金融研报AI长文本智能体(Qwen-Long)增强方案(理论+Python实战)
目录
- 0. 承前
- 1. 深度金融研报准备
- 2. 核心AI函数代码讲解
- 2.1 函数概述
- 2.2 输入参数
- 2.3 主要流程
- 2.4 异常处理
- 2.5 清理工作
- 2.7 get_ai_weights函数汇总
- 3. 汇总代码
- 4. 反思
- 4.1 不足之处
- 4.2 提升思路
- 5. 启后
0. 承前
本篇博文是对前两篇文章,链接:
5. 马科维茨资产组合模型+政策意图AI金融智能体(Qwen-Max)增强方案(理论+Python实战)
6. 马科维茨资产组合模型+政策意图AI金融智能体(DeepSeek-V3)增强方案(理论+Python实战)
的缺点:AI金融智能体所获取信息量(政策意图)过少的改进方案,使用权重计算日期的多篇行业内深度金融研报作为输入信息,为AI金融智能体提供更多更全面的信息支持。
本文与前两篇文章的唯一区别之处在于上文中的get_ai_weights函数,如果需要整体金融工程的思路流程,可以在上文直接跳转,本文中会直接给出修改地方,与能够直接运行的汇总代码。
其中多篇行业内深度金融研报的语义分析,内容整理的实现可参考:
98.1 AI量化开发:长文本AI金融智能体(Qwen-Long)对金融研报大批量处理与智能分析的实战应用
本文与98.1的区别是:本文的行业内深度金融研报信息,会影响资产组合模型的最终权重。
本文主旨:
- 用文章向大家展示低耦合开发的优点,如本文与上一篇文章的转换只需要重写一个函数即可;
- 使用实际代码,向大家展示如何向大于语言型传输大批量研报(但单次最好还是10篇以下);
如果想更加全面清晰地了解金融资产组合模型进化论的体系架构,可参考:
0. 金融资产组合模型进化全图鉴
- 金融工程流程图:
1. 深度金融研报准备
以下研报均是使用RPA技术(Robotic Process Automation),获取到20240101日期前的,与本次研究行业(银行)相关的深度金融研报:
补充:想要找到国内外金融领域的研报,欢迎私信咨询作者。
2. 核心AI函数代码讲解
2.1 函数概述
get_ai_weights
函数通过通义千问API分析研报内容,对投资组合权重进行智能调整。
2.2 输入参数
character
: AI角色设定path
: 研报PDF文件目录路径updated_result
: 原始投资组合权重api_key
: 通义千问API密钥
2.3 主要流程
- 初始化与路径检查
# 初始化API客户端
client = OpenAI(api_key=api_key, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")# 检查并创建目录
abs_path = os.path.abspath(path)
report_dir = Path(abs_path)
- PDF文件处理
# 获取有效PDF文件
pdf_files = list(report_dir.glob("*.pdf"))
valid_pdf_files = [pdf for pdf in pdf_files if pdf.stat().st_size > 0]# 上传PDF文件获取file_ids
file_ids = []
for pdf_file in valid_pdf_files:file_object = client.files.create(file=pdf_file, purpose="file-extract")file_ids.append(file_object.id)
- AI分析调用
# 构建提示信息
prompt = f"""请分析这些研报,并基于分析结果对以下投资组合进行调整...当前投资组合:{json.dumps(updated_result)}"""# 调用API进行分析
response = client.chat.completions.create(model="qwen-long",messages=[{'role': 'system', 'content': character},{'role': 'system', 'content': file_ids_str},{'role': 'user', 'content': prompt}]
)
- 结果处理
# 解析返回结果
content = response.choices[0].message.content.strip()
portfolio_weights = json.loads(content)# 权重归一化
weights_sum = sum(portfolio_weights.values())
portfolio_weights = {key: round(value/weights_sum, 6) for key, value in portfolio_weights.items()}
2.4 异常处理
- 目录不存在时返回原始权重
- PDF文件无效时返回原始权重
- API调用失败时返回原始权重
- JSON解析错误时返回原始权重
2.5 清理工作
# 删除已上传的文件
for file_id in file_ids:client.files.delete(file_id)
2.7 get_ai_weights函数汇总
返回调整后的投资组合权重字典,格式为:
def get_ai_weights(character, path, updated_result, api_key):"""使用AI分析指定路径下的所有PDF报告内容Args:character (str): AI的角色设定path (str): 报告所在目录的路径(会被转换为绝对路径)updated_result (dict): 用户角色向AI发送的资产组合权重api_key (str): DashScope API密钥Returns:dict: AI调整后的投资组合权重"""# 初始化 OpenAI 客户端client = OpenAI(api_key=api_key,base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",)# 将路径转换为绝对路径abs_path = os.path.abspath(path)report_dir = Path(abs_path)if not report_dir.exists():try:report_dir.mkdir(parents=True, exist_ok=True)except Exception as e:raise ValueError(f"创建目录失败: {report_dir}, 错误: {str(e)}")return updated_result # 如果目录不存在,返回原始权重# 获取所有PDF文件并上传file_ids = []pdf_files = list(report_dir.glob("*.pdf"))if not pdf_files:return updated_result # 如果没有PDF文件,返回原始权重# 检查文件是否可读且非空valid_pdf_files = []for pdf_file in pdf_files:try:if pdf_file.stat().st_size > 0: # 检查文件大小valid_pdf_files.append(pdf_file)except Exception:continueif not valid_pdf_files:return updated_result # 如果没有有效文件,返回原始权重# 上传有效的PDF文件for pdf_file in valid_pdf_files:try:file_object = client.files.create(file=pdf_file,purpose="file-extract")file_ids.append(file_object.id)except Exception:continueif not file_ids:return updated_result # 如果文件上传失败,返回原始权重# 构建file_ids字符串file_ids_str = ",".join([f"fileid://{file_id}" for file_id in file_ids])try:# 构建更明确的提示信息prompt = f"""请分析这些研报,并基于分析结果对以下投资组合进行调整。请注意:1. 只需返回调整后的权重数据,格式必须与输入完全一致;2. 不要添加任何解释或说明;3. 确保返回的是有效的JSON格式。当前投资组合:{json.dumps(updated_result, ensure_ascii=False)}"""# 创建对话完成response = client.chat.completions.create(model="qwen-long",messages=[{'role': 'system', 'content': character},{'role': 'system', 'content': file_ids_str},{'role': 'user', 'content': prompt}],stream=False # 使用非流式返回)# 提取content内容content = response.choices[0].message.content.strip()# 尝试查找和提取JSON内容try:# 如果返回的不是纯JSON,尝试查找JSON部分start_idx = content.find('{')end_idx = content.rfind('}') + 1if start_idx != -1 and end_idx != 0:content = content[start_idx:end_idx]# 解析JSONportfolio_weights = json.loads(content)# 验证返回的数据包含所有原始股票if not all(stock in portfolio_weights for stock in updated_result):print("AI返回的数据不完整,使用原始权重")return updated_result# 对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_weightsexcept (json.JSONDecodeError, ValueError) as e:print(f"无法解析AI返回的内容: {str(e)}")print(f"原始返回内容: {content}")return updated_resultexcept Exception as e:error_msg = str(e)if "content blank" in error_msg:print("文件内容提取失败,使用原始权重")else:print(f"API调用错误: {error_msg}")return updated_resultfinally:# 清理已上传的文件for file_id in file_ids:try:client.files.delete(file_id)except Exception:continue
3. 汇总代码
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') # tushare接口
pro = ts.pro_api()
industry = '银行'
end_date = '20240101'
years = 5 # 数据时长
risk_free_rate = 0.03 # 无风险利率参数
top_holdings = 10 # 持仓数量参数
index_code = '000300.SH' # 市场指数代码参数
api_key='sk-api_key' # 通义千问APIcharacter = f'''
你是一名专业的金融数据与研报信息分析师,擅长解读金融市场动态和研报信息,并据此调整资产组合的权重分布,以优化投资策略。你的主要任务是对给定的资产组合进行权重调整,确保:
1. 权重之和精确为1;
2. 每个资产调整后的权重只能在原有基础上增减最多10%;
3. 每个资产调整完毕后,如果权重之和不等于1,则归一化使权重之和精确为1;
4. 数据对应的日期是{end_date},在思考过程中,切勿根据该日期之后的信息进行思考。
5. 输出的数据格式需与输入保持一致,仅提供数据而不做额外解释;当你接收到具体的资产组合及其权重时,请根据最新的研报信息对其进行合理调整。
'''# 研报路径
path = f'/portfolio_code/reports/{end_date}'# 参数集##############################################################################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(by='ts_code', inplace=True)industry_stocks.reset_index(drop=True, inplace=True)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(days=years*365)start_date = start_date_dt.strftime('%Y%m%d')all_data = []for stock in ts_code_list:df = pro.daily(ts_code=stock, start_date=start_date, end_date=end_date)all_data.append(df)combined_df = pd.concat(all_data).sort_values(by=['ts_code', 'trade_date'])combined_df.reset_index(drop=True, inplace=True)combined_df.rename(columns={'trade_date': 'date'}, inplace=True)return combined_dfdef get_market_data(index_code='000300.SH', start_date=None, end_date=None):"""获取市场指数数据用于计算贝塔"""df_market = pro.index_daily(ts_code=index_code,start_date=start_date,end_date=end_date,fields=['trade_date', 'close'])df_market['date'] = pd.to_datetime(df_market['trade_date'])df_market.set_index('date', inplace=True)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_date=None, end_date=None):"""获取指定股票的因子数据(市值和PB)"""all_factor_data = []for stock in stock_codes:try:df = pro.daily_basic(ts_code=stock,start_date=start_date,end_date=end_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_index=True)factor_data['trade_date'] = pd.to_datetime(factor_data['trade_date'])return factor_datadef get_fina_data(stock_codes, start_date=None, end_date=None):"""获取指定股票的财务指标数据(ROE和资产增长率)"""all_fina_data = []for stock in stock_codes:try:df = pro.fina_indicator(ts_code=stock,start_date=start_date,end_date=end_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_index=True)# 处理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(months=i) for i in range(1, 4)]elif quarter_end.month == 6: # Q2months = [quarter_end + pd.DateOffset(months=i) for i in range(1, 4)]elif quarter_end.month == 9: # Q3months = [quarter_end + pd.DateOffset(months=i) for i in range(1, 4)]else: # Q4months = [quarter_end + pd.DateOffset(months=i) 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(key='date', freq='M')])['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(days=90)).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], index=aligned_dates)hml_factor = pd.Series([calculate_value_factor(date) for date in aligned_dates], index=aligned_dates)rmw_factor = pd.Series([calculate_profitability_factor(date) for date in aligned_dates], index=aligned_dates)cma_factor = pd.Series([calculate_investment_factor(date) for date in aligned_dates], index=aligned_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], axis=1))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], args=args,method='SLSQP', bounds=bounds, constraints=constraints)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(), key=lambda item: item[1], reverse=True)[: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, path, updated_result, api_key):"""使用AI分析指定路径下的所有PDF报告内容Args:character (str): AI的角色设定path (str): 报告所在目录的路径(会被转换为绝对路径)updated_result (dict): 用户角色向AI发送的资产组合权重api_key (str): DashScope API密钥Returns:dict: AI调整后的投资组合权重"""# 初始化 OpenAI 客户端client = OpenAI(api_key=api_key,base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",)# 将路径转换为绝对路径abs_path = os.path.abspath(path)report_dir = Path(abs_path)if not report_dir.exists():try:report_dir.mkdir(parents=True, exist_ok=True)except Exception as e:raise ValueError(f"创建目录失败: {report_dir}, 错误: {str(e)}")return updated_result # 如果目录不存在,返回原始权重# 获取所有PDF文件并上传file_ids = []pdf_files = list(report_dir.glob("*.pdf"))if not pdf_files:return updated_result # 如果没有PDF文件,返回原始权重# 检查文件是否可读且非空valid_pdf_files = []for pdf_file in pdf_files:try:if pdf_file.stat().st_size > 0: # 检查文件大小valid_pdf_files.append(pdf_file)except Exception:continueif not valid_pdf_files:return updated_result # 如果没有有效文件,返回原始权重# 上传有效的PDF文件for pdf_file in valid_pdf_files:try:file_object = client.files.create(file=pdf_file,purpose="file-extract")file_ids.append(file_object.id)except Exception:continueif not file_ids:return updated_result # 如果文件上传失败,返回原始权重# 构建file_ids字符串file_ids_str = ",".join([f"fileid://{file_id}" for file_id in file_ids])try:# 构建更明确的提示信息prompt = f"""请分析这些研报,并基于分析结果对以下投资组合进行调整。请注意:1. 只需返回调整后的权重数据,格式必须与输入完全一致;2. 不要添加任何解释或说明;3. 确保返回的是有效的JSON格式。当前投资组合:{json.dumps(updated_result, ensure_ascii=False)}"""# 创建对话完成response = client.chat.completions.create(model="qwen-long",messages=[{'role': 'system', 'content': character},{'role': 'system', 'content': file_ids_str},{'role': 'user', 'content': prompt}],stream=False # 使用非流式返回)# 提取content内容content = response.choices[0].message.content.strip()# 尝试查找和提取JSON内容try:# 如果返回的不是纯JSON,尝试查找JSON部分start_idx = content.find('{')end_idx = content.rfind('}') + 1if start_idx != -1 and end_idx != 0:content = content[start_idx:end_idx]# 解析JSONportfolio_weights = json.loads(content)# 验证返回的数据包含所有原始股票if not all(stock in portfolio_weights for stock in updated_result):print("AI返回的数据不完整,使用原始权重")return updated_result# 对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_weightsexcept (json.JSONDecodeError, ValueError) as e:print(f"无法解析AI返回的内容: {str(e)}")print(f"原始返回内容: {content}")return updated_resultexcept Exception as e:error_msg = str(e)if "content blank" in error_msg:print("文件内容提取失败,使用原始权重")else:print(f"API调用错误: {error_msg}")return updated_resultfinally:# 清理已上传的文件for file_id in file_ids:try:client.files.delete(file_id)except Exception:continuedef 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, path, updated_result, api_key)# 打印更新后的资产占比print(f"\n{end_date}最优资产前{top_holdings}占比:")print(updated_result)if __name__ == "__main__":main()
注意:tushare接口、通义千问API需要自行申请。
运行结果:
金融研报AI长文本智能体(Qwen-Long)体调仓后权重:
{'601398.SH': 0.188942, '601328.SH': 0.166264, '600919.SH': 0.118216, '600036.SH': 0.103397, '601169.SH': 0.090905,
'600016.SH': 0.085375, '601166.SH': 0.083199, '601288.SH': 0.068825, '600908.SH': 0.049392, '600926.SH': 0.045485}
与前两篇Qwen-Max、DeepSeek-V3进行对比:
股票代码 | 股票占比(Qwen-Max) | 股票占比(DeepSeek-V3) | 股票占比(Qwen-Long) |
---|---|---|---|
601398.SH | 0.163025 | 0.166525 | 0.188942 |
601328.SH | 0.161623 | 0.165165 | 0.166264 |
600919.SH | 0.129252 | 0.134011 | 0.118216 |
600036.SH | 0.107372 | 0.112955 | 0.103397 |
601169.SH | 0.095764 | 0.092157 | 0.090905 |
600016.SH | 0.090046 | 0.086663 | 0.085375 |
601166.SH | 0.087606 | 0.084316 | 0.083199 |
601288.SH | 0.065323 | 0.062868 | 0.068825 |
600908.SH | 0.055541 | 0.053454 | 0.049392 |
600926.SH | 0.044449 | 0.041885 | 0.045485 |
Qwen-Long的股票权重配置是基于对大量研究报告(研报)的深入分析和综合考量的结果。这种策略不仅反映了模型在处理复杂信息和识别市场趋势方面的强大能力,还体现了其对宏观经济环境、行业动态以及公司特定风险因素的全面理解。
其他尝试:
- 向AI提供研报文件的同时,提供更多的因子数据
- 使用RAG技术,让AI更加全面了解研报文件内容
4. 反思
4.1 不足之处
- 研报文件获取:获取研报文件方案仍为半手动
- AI逻辑缜密度:AI可能未能完全按照提示词工程执行
4.2 提升思路
- 更换提示词工程
- 工作流接入金融工程内部,实现真正全自动
5. 启后
-
优化,:,可参考下一篇文章:
pass -
量化回测实现,可参考下一篇文章:
pass
相关文章:
7. 马科维茨资产组合模型+金融研报AI长文本智能体(Qwen-Long)增强方案(理论+Python实战)
目录 0. 承前1. 深度金融研报准备2. 核心AI函数代码讲解2.1 函数概述2.2 输入参数2.3 主要流程2.4 异常处理2.5 清理工作2.7 get_ai_weights函数汇总 3. 汇总代码4. 反思4.1 不足之处4.2 提升思路 5. 启后 0. 承前 本篇博文是对前两篇文章,链接: 5. 马科维茨资产组…...
如何在本地部署deepseek r1模型?
DeepSeek(深度求索)正式发布了其最新推理模型DeepSeek-R1,引发业界广泛关注。这款模型不仅在性能上与OpenAI的GPT-4相媲美,更以其开源策略和创新的训练方法,为AI发展带来了新的可能性。DeepSeek-R1 在后训练阶段大规模…...
HarmonyOS:状态管理最佳实践
一、概述 在声明式UI编程范式中,UI是应用程序状态的函数,应用程序状态的修改会更新相应的UI界面。ArkUI采用了MVVM模式,其中ViewModel将数据与视图绑定在一起,更新数据的时候直接更新视图。如下图所示: ArkUI的MVVM模式…...
当AI风暴来袭:中美科技商业版图的迥异走向
当AI风暴来袭:中美科技商业版图的迥异走向 美国科技巨头的 AI 豪赌:Stargate 公司的诞生 2025 年,科技界被一则重磅消息所震动:软银、NVIDIA、Oracle 与 OpenAI 共同组建了 Stargate 公司。这一合作堪称豪华阵容,软银作为全球知名的投资巨头,拥有雄厚的资金实力和广泛的…...
马尔科夫模型和隐马尔科夫模型区别
我用一个天气预报和海藻湿度观测的比喻来解释,保证你秒懂! 1. 马尔可夫模型(Markov Model, MM) 特点:状态直接可见 场景:天气预报(晴天→雨天→阴天…)核心假设: 下一个…...
面向对象设计原则 - SOLID原则 (基于C++)
SOLID 是面向对象编程中的一组五个设计原则,这些原则旨在帮助开发者创建更灵活、可维护和可扩展的软件系统。它们最初由 Robert C. Martin 提出,并在 2000 年左右被广泛接受。每个字母代表一个不同的原则: 单一职责原则 (Single Responsibil…...
ChatGPT 搜索测试整合记忆功能
据 TestingCatalog 报道,OpenAI 正在测试 ChatGPT 搜索的整合记忆功能,被命名为 “Memory in search”2。以下是关于该功能的具体情况123: 功能特点 个性化搜索:启用该功能后,ChatGPT 能利用存储的记忆数据࿰…...
PWM频率测量方法
测量PWM(脉宽调制)信号的频率是嵌入式系统中的常见需求,尤其是在电机控制、LED调光、传感器信号处理等场景中。 在这里介绍两种测量PWM频率的方法:测频法与测周法。 1、测频(率)法 原理:在闸门…...
【B站保姆级视频教程:Jetson配置YOLOv11环境(一)镜像下载与烧录】
b站同步视频教程:https://www.bilibili.com/video/BV11r6oYkEFb/ 一、引言 在人工智能与计算机视觉快速发展的当下,Jetson系列开发板凭借强大的性能,成为众多开发者进行深度学习项目的热门选择。YOLOv11作为目标检测领域的先进算法…...
使用QSqlQueryModel创建交替背景色的表格模型
class UserModel(QSqlQueryModel):def __init__(self):super().__init__()self._query "SELECT name, age FROM users"self.refresh()def refresh(self):self.setQuery(self._query)# 重新定义data()方法def data(self, index, role): if role Qt.BackgroundRole…...
计算机网络__基础知识问答
Question: 1)在计算机网络的5层结构中,每一层的功能大概是什么? 2)交换机的功能?https://www.bilibili.com/video/BV1na4y1L7Ev 3)路由器的功能?https://www.bilibili.com/video/BV1hv411k7n…...
C语言数组详解:从基础到进阶的全面解析
在C语言中,数组是一种基本的数据结构,用于存储多个相同类型的数据。数组的引入使得C语言能够高效地存储和操作大量数据。在任何一个C语言程序中,数组都发挥着极其重要的作用。无论是在算法实现、数据存储、还是在复杂程序的设计中,…...
微前端架构在前端开发中的实践与挑战
随着单页面应用(SPA)和前端框架如 React、Vue、Angular 的快速发展,现代前端应用的复杂度日益提升。尤其是当应用规模逐渐增大时,单一的代码库往往难以应对不同团队的协作和版本管理问题。为了应对这一挑战,微前端架构…...
国内flutter环境部署(记录篇)
设置系统环境变量 export PUB_HOSTED_URLhttps://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URLhttps://storage.flutter-io.cn使用以下命令下载flutter镜像 git clone -b stable https://mirror.ghproxy.com/https://github.com/<github仓库地址>#例如flutter仓…...
Julia DataFrames.jl:深入理解和使用
随着数据科学和机器学习的发展,数据框架广泛应用于数据处理与分析工作中。在 Julia 语言中,DataFrames.jl 是一个强大且灵活的数据框库,为数据操作提供了丰富的功能。本文旨在系统地介绍 DataFrames.jl 的基础概念、使用方法、常见实践和最佳…...
上位机知识篇---DDSSDK
文章目录 前言第一部分:DDS核心特性1.以数据为中心2.发布-订阅模型3.质量服务4.多语言支持 关键概念1.主题2.发布者3.订阅者4. 数据写入者5.数据读取者6.域参与者7.域 DDS的优势1.可伸缩性2.实时性3.可靠性4.容错性 DDS的应用场景1.军事通信系统2.航空航天3.工业自动…...
基于DeepSeek在藏语学习推广和藏语信息化方面可以做哪些工作?
基于DeepSeek对藏语的技术优势,您可在以下三大方向开展创新性工作,以下是20具体落地方案: 一、藏语智能教育工具开发 《三十颂》AI语法教练 开发虚拟助教自动解析藏文句子结构(标注格助词/时态变化)错误检测系统&…...
如何把obsidian的md文档导出成图片,并加上文档属性
上篇关于这个插件PKMer_Obsidian 插件:Export Image plugin 一键将笔记转换为图片分享的文章 如何把obsidian的md文档导出成图片,并加上水印-CSDN博客 如何导出图片的时候让文档属性也显示出来,啊啊,这个功能找了一晚上…...
AUTOSAR从入门到精通-车身控制系统BCM(三)
目录 前言 算法原理 什么是车身控制模块BCM 1. BCM ECU的工作原理 a. 硬件架构 b. 控制逻辑 BCM带来的好处 车身控制模块(BCM)的功用 车身控制模块(BCM)能够控制的车身功能系统 BCM的各项功能 1.1内外部灯光控制 1.2 雨刮系统 1.3 车身防盗报警系统 1.4 车锁…...
删除全表数据sql
-- 删除 employees 表中的所有数据 DELETE FROM employees;-- 清空 employees 表中的所有数据 TRUNCATE TABLE employees;TRUNCATE 操作不记录每一行的删除操作,而是直接释放数据页,所以执行速度通常比 DELETE 快。不过它不能和 WHERE 子句一起使用&…...
Winform如何取消叉号,减号和放大(两种)
方法一: 找到窗体属性 MaximizeBoxFalse; MinimizeBoxFalse; ControlBoxFALSE; 方法二: 点击Form 在From里面找到Form-Closing 这个事件 写入 if(e.CloseReasonCloseReason.UserClosing) { MessageBox.Show("对不起,你不能关闭") e.Cancel true; }...
Couchbase UI: Query
Couchbase 的 Query 页面在 UI 中是一个核心功能模块,支持 N1QL 查询的编写、调试和优化。同时,它也扩展了与查询相关的功能,比如 Workbench、Monitor 和 UDF 管理。这些功能让开发者和管理员能够更加高效地管理数据查询和性能优化。 以下是…...
Word 中实现方框内点击自动打 √ ☑
注: 本文为 “Word 中方框内点击打 √ ☑ / 打 ☒” 相关文章合辑。 对第一篇增加了打叉部分,第二篇为第一篇中方法 5 “控件” 实现的详解。 在 Word 方框内打 √ 的 6 种技巧 2020-03-09 12:38 使用 Word 制作一些调查表、检查表等,通常…...
Go优雅实现redis分布式锁
前言 系统为了保证高可用,通常会部署多实例,并且会存在同时对共享资源并发读写,这时候为了保证读写的安全,常规手段是会引入分布式锁,本文将介绍如何使用redis设计一个优雅的Go分布式锁。 设计 redis分布式锁是借助…...
A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战
服务容器化构建的环境配置构建前需要解决什么下面我们带着问题分析构建的过程:1. 如何解决jenkins执行环境与shell脚本执行环境不一致问题?2. 构建之前动态修改项目的环境变量3. 在通过容器打包时避免不了会产生比较多的不可用的镜像资源,这些资源要是不及时删除掉时会导致服…...
Controller 层优化四步曲
Controller 层优化四步曲 前言 在开发过程中,Controller 层作为系统与外界交互的桥梁,承担着接收请求、解析参数、调用业务逻辑、处理异常等职责。 然而,随着业务复杂度的增加,Controller 层的代码往往会变得臃肿且难以维护。 …...
自动化运维在云环境中的完整实践指南
随着云计算的普及,越来越多的企业将业务迁移到云上。云环境的高动态性和复杂性使得传统的手动运维方式难以应对,自动化运维成为提升效率、降低成本、保障系统稳定性的关键。本文将详细介绍如何在云环境中实施自动化运维,涵盖工具选择、实施步骤和最佳实践。 © ivwdcwso…...
electron typescript运行并设置eslint检测
目录 一、初始化package.json 二、安装依赖 三、项目结构 四、配置启动项 五、补充:ts转js别名问题 一、初始化package.json 我的:这里的"main"没太大影响,看后面的步骤。 {"name": "xloda-cloud-ui-pc"…...
DiffuEraser: 一种基于扩散模型的视频修复技术
视频修复算法结合了基于流的像素传播与基于Transformer的生成方法,利用光流信息和相邻帧的信息来恢复纹理和对象,同时通过视觉Transformer完成被遮挡区域的修复。然而,这些方法在处理大范围遮挡时常常会遇到模糊和时序不一致的问题࿰…...
《Operating System Concepts》阅读笔记:p1-p1
《Operating System Concepts》学习第 1 天,p1-p1 总结,总计 1 页。 一、技术总结 无。 二、英语总结(生词:1) 1.intermediary (1)intermediary: inter-(“between, among”) medius(“middle”) c.intermediary originally referred …...
9.8 实战:使用 GPT Builder 开发定制化 ChatGPT 应用
实战:使用 GPT Builder 开发定制化 ChatGPT 应用 引言:打造属于你的智能助手 定制化 ChatGPT 应用正在成为解决具体问题和提升生产力的关键工具。GPT Builder 提供了一个灵活、直观的平台,让开发者和非技术用户都能快速创建满足特定需求的智能助手。本文将通过一个实战案例…...
团体程序设计天梯赛-练习集——L1-024 后天
前言 首先祝大家新年快乐,然后博主今点炮让炮崩了一下,水一天 这道题5分非常简单,有不少的做法 L1-024 后天 如果今天是星期三,后天就是星期五;如果今天是星期六,后天就是星期一。我们用数字1到7对应星期…...
基于STM32的智能语音控制灯光系统设计
目录 引言系统设计 硬件设计软件设计 系统功能模块 语音识别模块灯光控制模块模式切换与场景管理模块用户交互与显示模块远程控制与数据上传模块 控制算法 语音识别与命令解析算法灯光强度与颜色调节算法数据记录与远程反馈算法 代码实现 语音识别与灯光控制代码场景模式与定时…...
Redis部署方式全解析:优缺点大对比
Redis部署方式全解析:优缺点大对比 一、引言 Redis作为一款高性能的内存数据库,在分布式系统、缓存、消息队列等众多场景中都有着广泛的应用。选择合适的Redis部署方式,对于系统的性能、可用性、可扩展性以及成本等方面都有着至关重要的影响…...
Java实现FIFO缓存策略实战
实现FIFO模型选择FIFO模型实现过程FIFO模型完整代码下面看一下先进先出的示例过程总结FIFO(First In First Out,先进先出)策略是一种基本的数据处理和存储管理方法,在Java中,这种策略通常用于管理那些需要按照顺序处理的数据项,比如任务的队列、数据的传输缓冲区等。在Ja…...
把markdown转换为pdf的方法
将 Markdown 文件转换为 PDF 有多种方法,以下是几种常见的方式: 1. 使用 VS Code 和 Markdown 插件 VS Code 是一款流行的代码编辑器,支持通过插件将 Markdown 转换为 PDF。 步骤: 安装 VS Code: 下载地址ÿ…...
Java Web 开发基础介绍
Java学习资料 Java学习资料 Java学习资料 一、引言 在当今数字化时代,Web 应用无处不在。Java 凭借其强大的功能、良好的跨平台性和丰富的开发框架,成为 Web 开发领域的热门选择之一。Java Web 开发允许开发者构建动态、交互式的 Web 应用程序&#x…...
自定义数据集,使用 PyTorch 框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测
在本文中,我们将展示如何使用 NumPy 创建自定义数据集,利用 PyTorch 实现一个简单的逻辑回归模型,并在训练完成后保存该模型,最后加载模型并用它进行预测。 1. 创建自定义数据集 首先,我们使用 NumPy 创建一个简单的…...
LangChain概述
文章目录 为什么需要LangChainLLM应用开发的最后1公里LangChain的2个关键词LangChain的3个场景LangChain的6大模块 为什么需要LangChain 首先想象一个开发者在构建一个LLM应用时的常见场景。当你开始构建一个新项目时,你可能会遇到许多API接口、数据格式和工具。对于…...
Ubuntu 16.04安装Lua
个人博客地址:Ubuntu 16.04安装Lua | 一张假钞的真实世界 在Linux系统上使用以下命令编译安装Lua: curl -R -O http://www.lua.org/ftp/lua-5.3.3.tar.gz tar zxf lua-5.3.3.tar.gz cd lua-5.3.3 make linux test 安装make 编译过程如果提示以下信息…...
独立开发者产品日刊:将 Figma 设计转化为全栈应用、对话 PDF生成思维导图、视频转 AI 笔记、AI问答引擎、Mac 应用启动器切换器
独立开发者产品日刊,每日汇集 ProductHunt 热榜产品介绍,用一个 Slogan 帮你概括产品内容,期望能够让你快速浏览get最新产品创意,激发在产品上的灵感。 Lovable Builder.io Slogan:将 Figma 设计转化为全栈应用 类别…...
【算法】经典博弈论问题——威佐夫博弈 python
目录 威佐夫博弈(Wythoff Game)【模板】 威佐夫博弈(Wythoff Game) 有两堆石子,数量任意,可以不同,游戏开始由两个人轮流取石子 游戏规定,每次有两种不同的取法 1)在任意的一堆中取走任意多的石子 2)可以在两堆中同时取走相同数量…...
Julius AI 人工智能数据分析工具介绍
Julius AI 是一款由 Casera Labs 开发的人工智能数据分析工具,旨在通过自然语言交互和强大的算法能力,帮助用户快速分析和可视化复杂数据。这款工具特别适合没有数据科学背景的用户,使数据分析变得简单高效。 核心功能 自然语言交互&#x…...
SpringBoot+Electron教务管理系统 附带详细运行指导视频
文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1.查询课程表代码2.保存学生信息代码3.用户登录代码 一、项目演示 项目演示地址: 视频地址 二、项目介绍 项目描述:这是一个基于SpringBootElectron框架开发的教务管理系统。首先ÿ…...
1.23学习记录
web XYNU2024信安杯 哎~想她了 源代码找到提示,访问页面第一层数组绕过,第二层发现ls /可以执行,接着用less代替tac和cat less /fl[a-z]g exp: URL/?fj1[]1&fj2[]2&cmdless /fl[a-z]gmisc [SWPU 2020]套娃 下载附件…...
论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(三)
Understanding Diffusion Models: A Unified Perspective(三) 文章概括 文章概括 引用: article{luo2022understanding,title{Understanding diffusion models: A unified perspective},author{Luo, Calvin},journal{arXiv preprint arXiv:…...
NeetCode刷题第17天(2025.1.27)
文章目录 086 Course Schedule II 课程安排二087 Graph Valid Tree 图有效树088 Number of Connected Components in an Undirected Graph 无向图中的连接组件数量 086 Course Schedule II 课程安排二 您将获得一个数组 prerequisites ,其中 prerequisites[i] [a,…...
Seed Edge- AGI(人工智能通用智能)长期研究计划
Seed Edge 是字节跳动豆包大模型团队推出的 AGI(人工智能通用智能)长期研究计划12。以下是对它的具体介绍1: 名称含义 “Seed” 即豆包大模型团队名称,“Edge” 代表最前沿的 AGI 探索,整体意味着该项目将在 AGI 领域…...
企业知识管理推动企业整体效能提升与创新能力发展的路径探索
内容概要 企业知识管理是指通过对组织内外部知识的识别、获取、整合与应用,提升企业整体运营效能与竞争力的一系列管理活动。其重要性在于,知识作为一种无形资产,能够显著影响企业的决策质量和创新能力。在当今快速发展的市场环境中…...
【gopher的java学习笔记】一文讲懂controller,service,mapper,entity是什么
刚开始上手Java和Spring时,就被controller,service,mapper,entity这几个词搞懵了,搞不懂这些究竟代表什么,感觉使用golang开发的时候也没太接触过这些名词啊~ 经过两三个月的开发后,逐渐搞懂了这…...