制作一个根据投资者需求提供投资组合建议的交互式界面,利用机器学习与多因子结合选股,用portfolio analytics包进行组合优化,对组合进行可视化分析,通过shiny页面进行交互。
陈酉琰-–数据获取与机器学习
芮子涵-–投资组合优化学习
林文佳-–数据可视化
张亚文-–Shiny交互页面学习
导入提前获取好的沪深300成分股的代码。
使用pedquant
包获取数据
使用者运行程序,就会自动获取最近两个月的行情数据。
# 获取当前日期
end_date <- Sys.Date()
start_date <- end_date - months(2)
# 循环获取每支股票的行情数据并添加到结果数据框中
for (code in stock_codes) {
tryCatch({
# 获取股票行情数据
stock_data <- md_stock(code, from = start_date, to = end_date, source = '163', adjust = 'dividend')
if (!is.null(stock_data)) {
print(paste("成功获取股票", code, "的行情数据"))
# 将获取到的股票数据转换为数据框格式并存储到结果数据框中
stock_data_df <- stock_data[[1]] %>% as.data.frame()
print("获取到的数据结构信息:")
str(stock_data_df)
result_df <- rbind(result_df, stock_data_df)
} else {
print(paste("未能获取股票", code, "的行情数据。"))
}
}, error = function(e) {
print(paste("获取股票", code, "的行情数据时出错:", e))
})
}
结果如下:
5日乖离率 BIAS5:(收盘价-收盘价的N日简单平均)/ 收盘价的N日简单平均*100,在此取n=5
60日变动速率 ROC60(Price Rate of Change):①AX=今天的收盘价—20天前的收盘价 ②BX=60天前的收盘价 ③ROC=AX/BX*100
单日价量趋势 single_day_VPT:(今日收盘价 - 昨日收盘价)/ 昨日收盘价 * 当日成交量
(复权方法为基于当日前复权)
Aroon指标下轨 arron_down_25:Aroon(下降)=[(计算期天数-最低价后的天数)/计算期天数]*100
Aroon指标上轨 arron_up_25:Aroon(上升)=[(计算期天数-最高价后的天数)/计算期天数]*100
BBI 为常用技术指标类因子“多空均线”
构建出的动量因子表:
今日行情作为预测集(predi),用于预测明日涨跌幅;其余数据作为训练集(train)
fluctuation
作为目标变量:。objective = "regression"
:目标任务是回归任务;
metric = "rmse"
:设定用于评估模型性能的指标为均方根误差 RMSE (预测值与真实值差值的平方的平均值的平方根)
❓WHY交叉验证
股价数据是复杂且动态变化的。简单地将数据集划分为训练集和测试集来评估模型,可能会因为数据划分的非随机性而导致评估结果不够准确。使用交叉验证的方法可以避免单次划分训练集和测试集可能带来的偏差。、
❓WHY LGBM
分布式训练支持:
LGBM 模型支持分布式训练,适合股票市场数据海量的情况。通过分布式训练,模型可以在多个计算节点上同时进行训练,加速整个训练过程。
可扩展性强:
随着新的股票数据不断产生,LGBM模型可以很容易地对新数据进行整合和重新训练。
RMES值越小表示模型的预测效果越好
[1] "训练集均方根误差(RMSE): 0.00532665709016357"
# 对预测集进行预测
predi <- as.matrix(predi[,!(names(predi) %in% c("name", "open", "high", "low", "close", "signal", "fluctuation"))])
prediction <- predict(model, newdata = predi)
# 创建一个新的数据框,包含股票代码列和预测结果列
result_df <- data.frame(symbol = predi[, 1],
prediction = prediction,
stringsAsFactors = FALSE) %>%
arrange(desc(prediction))
整理股票数据,得到有收益率及预期收益信息的数据框stock_data
symbol name date fluctuation prediction
1 000001.SZ 平安银行 2024-09-30 0.046270724 0.02275461
2 000001.SZ 平安银行 2024-10-08 -0.079205991 0.02275461
3 000001.SZ 平安银行 2024-10-09 0.039137338 0.02275461
4 000001.SZ 平安银行 2024-10-10 -0.017931872 0.02275461
5 000001.SZ 平安银行 2024-10-11 0.021068417 0.02275461
6 000001.SZ 平安银行 2024-10-14 -0.008253479 0.02275461
按预期收益率降序排序,获取前五名股票(下用top_5代称)
symbol prediction
1 002555.SZ 0.07341090
2 600276.SH 0.07165852
3 601988.SH 0.06979743
4 001965.SZ 0.06112326
5 002230.SZ 0.05904452
获取top_5的日收益率数据,并计算得到协方差矩阵
[1] "Covariance Matrix:"
002555.SZ 600276.SH 601988.SH 001965.SZ 002230.SZ
002555.SZ 0.0043901014 0.0016792468 0.0007838756 0.0021941316 0.0031113477
600276.SH 0.0016792468 0.0010736731 0.0003322849 0.0008498078 0.0012237302
601988.SH 0.0007838756 0.0003322849 0.0002432053 0.0005358282 0.0004428812
001965.SZ 0.0021941316 0.0008498078 0.0005358282 0.0015059169 0.0013340672
002230.SZ 0.0031113477 0.0012237302 0.0004428812 0.0013340672 0.0027651779
创建投资组合对象top_5_portfolio,约束条件设置为“完全投资”“非负权重”,并添加目标函数从而最大化预期收益并最小化风险。
# 添加约束条件
top_5_portfolio <- add.constraint(top_5_portfolio, type = "full_investment")
top_5_portfolio <- add.constraint(top_5_portfolio, type = "long_only")
# 添加目标函数:最大化预期收益并最小化风险
top_5_portfolio <- add.objective(top_5_portfolio, type = "return", name = "mean")
top_5_portfolio <- add.objective(top_5_portfolio, type = "risk", name = "StdDev")
利用ROI包进行优化求解。
最终得到优化后的权重如下:
002555.SZ 600276.SH 601988.SH 001965.SZ 002230.SZ
1.285425e-01 8.714575e-01 0.000000e+00 0.000000e+00 -6.110961e-17
根据优化后的权重,我们可以计算出该组合的预期收益和风险。
[1] "ROI - Expected Return: 0.0718837717473201"
[1] "ROI - Risk (Standard Deviation): 0.0355547869671811"
根据portfolio analytics包的运行结果,我们可以获得今日最适宜购买的n支股票,储存在top_5_stocks数据框中。
根据top_5的股票代码,在hs300数据框中筛选top_5的股票信息,接着根据(明日开盘价-今日收盘价)/今日收盘价,计算出他们的收益率,接着按照pa包给出的权重进行组合配比,计算出组合的标准差和收益率,计算出组合在2个月内的夏普比率变动情况。
同时对HS300数据框的数据也做同样处理,进行对比。
跟夏普相同的计算逻辑,卡尔玛比率是年化收益率与区间最大回撤的比率,代表的含义是:一个投资组合每承担一份最大回撤,获取的收益有多大。
通过对比,我们可以知道我们选取的组合与基准市场组的收益差距有多大。
通过学习《mastering shiny》,我们小组已经了解shinyApp的基础结构。
包括:
1、UI界面的布局设计
2、UI界面的函数插入
3、绘图结果展示
部分代码展示:
1、完善shinyApp各部分功能,将前一阶段已完成的核心代码改写、代入shinyApp中。
2、美化shinyApp。
md_stock_financials()
函数获取了财务数据,在下阶段我们将尝试往模型中加入估值因子、成长因子、资本结构因子……股票数据量不统一:部分股票数据有缺失,因此在提取收益率时难以创建矩阵来一一对应,最终选择使用列表来存储数据,并忽略数据量上的差异,直接计算出协方差矩阵。
精度调整:由于精度问题,即使已经设立约束条件,权重结果仍可能包含很小的负数。在尝试更换求解器未果后,决定手动调整精度,再进行归一化处理。
以上两种综合考虑风险和收益的投资组合评价,后期会引入与基准投资组合相比较的评价指标,如beta系数(衡量相关性) alpha系数(超额收益)等。也会适当引入基础指标,如收益率、波动率等。
最后由于前面的计算都是基于等权重,所以后期会加入pa包跑出来的权重计算。
symbol weight
1 002555.SZ 0.1285425
2 600276.SH 0.1285425
3 601988.SH 0.1285425
4 001965.SZ 0.1285425
5 002230.SZ 0.1285425
1、完善shinyApp各部分功能,将前一阶段已完成的核心代码改写、代入shinyApp中。
2、美化shinyApp。
获取的行情数据中,某几只股票的数据不全,导致innerjoin过后,这几只股票丢失。之后放入模型的训练集也不包含这些数据。暂时没有想好如何补全这部分数据?
000001.SZ 000002.SZ 000063.SZ 000100.SZ 000157.SZ 000166.SZ 000301.SZ 000333.SZ
39 39 39 39 39 39 39 39
000338.SZ 000408.SZ 000425.SZ 000538.SZ 000568.SZ 000596.SZ 000617.SZ 000625.SZ
39 39 39 39 39 39 39 39
000651.SZ 000661.SZ 000708.SZ 000725.SZ 000733.SZ 000768.SZ 000776.SZ 000786.SZ
39 39 39 39 39 39 39 39
000792.SZ 000800.SZ 000807.SZ 000858.SZ 000876.SZ 000895.SZ 000938.SZ 000963.SZ
39 39 39 39 39 39 39 39
000977.SZ 000983.SZ 000999.SZ 001289.SZ 001965.SZ 001979.SZ 002001.SZ 002007.SZ
39 39 39 39 39 39 39 39
002027.SZ 002049.SZ 002050.SZ 002074.SZ 002129.SZ 002142.SZ 002179.SZ 002180.SZ
39 39 39 39 39 39 39 39
002230.SZ 002236.SZ 002241.SZ 002252.SZ 002271.SZ 002304.SZ 002311.SZ 002352.SZ
39 39 39 39 39 39 39 39
002371.SZ 002410.SZ 002415.SZ 002459.SZ 002460.SZ 002466.SZ 002475.SZ 002493.SZ
39 39 39 39 39 39 39 39
002555.SZ 002594.SZ 002601.SZ 002603.SZ 002648.SZ 002709.SZ 002714.SZ 002736.SZ
39 39 39 39 39 39 39 39
002812.SZ 002821.SZ 002841.SZ 002916.SZ 002920.SZ 002938.SZ 003816.SZ 300014.SZ
39 39 39 39 39 39 39 39
300015.SZ 300033.SZ 300059.SZ 300122.SZ 300124.SZ 300142.SZ 300223.SZ 300274.SZ
39 39 39 39 39 39 39 39
300308.SZ 300316.SZ 300347.SZ 300408.SZ 300413.SZ 300418.SZ 300433.SZ 300442.SZ
39 39 39 39 39 39 39 39
300450.SZ 300454.SZ 300496.SZ 300498.SZ 300628.SZ 300661.SZ 300750.SZ 300751.SZ
39 39 39 39 39 39 39 39
300759.SZ 300760.SZ 300782.SZ 300832.SZ 300896.SZ 300919.SZ 300957.SZ 300979.SZ
39 39 39 39 39 39 39 39
300999.SZ 301269.SZ 600009.SH 600010.SH 600011.SH 600015.SH 600016.SH 600018.SH
39 27 18 39 39 39 39 39
600019.SH 600023.SH 600025.SH 600026.SH 600027.SH 600028.SH 600029.SH 600030.SH
39 39 39 39 39 39 39 39
600031.SH 600036.SH 600039.SH 600048.SH 600050.SH 600061.SH 600085.SH 600089.SH
39 39 39 39 39 39 39 39
600104.SH 600111.SH 600115.SH 600132.SH 600150.SH 600161.SH 600176.SH 600183.SH
39 39 39 39 39 39 39 39
600188.SH 600196.SH 600219.SH 600233.SH 600276.SH 600309.SH 600332.SH 600346.SH
39 39 39 39 39 39 39 39
600362.SH 600372.SH 600406.SH 600415.SH 600426.SH 600436.SH 600438.SH 600460.SH
39 39 39 39 39 39 39 39
600489.SH 600515.SH 600519.SH 600547.SH 600570.SH 600584.SH 600585.SH 600588.SH
39 39 39 39 39 39 39 39
600600.SH 600660.SH 600674.SH 600690.SH 600732.SH 600741.SH 600745.SH 600760.SH
39 39 39 39 39 39 39 39
600795.SH 600803.SH 600809.SH 600837.SH 600845.SH 600875.SH 600886.SH 600887.SH
39 39 39 36 39 39 39 39
600893.SH 600900.SH 600905.SH 600918.SH 600919.SH 600926.SH 600938.SH 600941.SH
39 39 39 39 39 39 39 39
600958.SH 600989.SH 600999.SH 601006.SH 601009.SH 601012.SH 601021.SH 601059.SH
39 39 39 39 39 39 39 39
601066.SH 601088.SH 601100.SH 601111.SH 601117.SH 601138.SH 601166.SH 601169.SH
39 39 39 39 39 39 39 39
601186.SH 601211.SH 601225.SH 601229.SH 601236.SH 601238.SH 601288.SH 601318.SH
39 36 39 39 39 39 39 39
601319.SH 601328.SH 601336.SH 601360.SH 601377.SH 601390.SH 601398.SH 601600.SH
39 39 39 39 39 39 39 39
601601.SH 601607.SH 601618.SH 601628.SH 601633.SH 601658.SH 601668.SH 601669.SH
39 39 39 39 39 39 39 39
601688.SH 601689.SH 601698.SH 601699.SH 601728.SH 601766.SH 601788.SH 601799.SH
39 39 39 39 39 39 39 39
601800.SH 601808.SH 601816.SH 601818.SH 601838.SH 601857.SH 601865.SH 601868.SH
39 39 39 39 39 39 39 39
601872.SH 601877.SH 601878.SH 601881.SH 601888.SH 601898.SH 601899.SH 601901.SH
39 39 39 39 39 39 39 39
601916.SH 601919.SH 601939.SH 601985.SH 601988.SH 601989.SH 601995.SH 601998.SH
39 39 39 39 39 39 39 39
603019.SH 603195.SH 603259.SH 603260.SH 603288.SH 603296.SH 603369.SH 603392.SH
39 39 39 39 39 39 39 39
603501.SH 603659.SH 603799.SH 603806.SH 603833.SH 603899.SH 603986.SH 603993.SH
39 39 39 39 39 39 39 39
605117.SH 605499.SH 688008.SH 688009.SH 688012.SH 688036.SH 688041.SH 688082.SH
39 39 39 39 39 39 39 39
688111.SH 688126.SH 688187.SH 688223.SH 688256.SH 688271.SH 688303.SH 688363.SH
39 39 39 39 39 39 39 39
688396.SH 688599.SH 688981.SH
39 39 39