DAY 19 常见的特征筛选算法

过去电脑性能比较差,特征数目太多计算起来很慢。同时特征中可能存在很多冗余特征干扰解释性、存在噪声特征干扰精度。

所以在面对高维特征的时候常常需要引入特征降维,之前课程中项目的特征也就小几十个,不太需要做降维,对于某些特征较多的数据,如基因数据、微生物数据、传感器数据等,特征较多,所以会考虑特征降维。

特征降维一般有2种策略:

1. 特征筛选:从n个特征中筛选出m个特征,比如方差筛选,剔除方差过小的特征;利用皮尔逊相关系数筛选;lasso筛选(lasso自带的系数可以理解为重要性)、利用树模型自带的重要性、shap重要性等筛选;特征递归方法。

2. 特征组合:从n个特征中组合出m个特征,如pca等

特征筛选

1. 方差筛选

核心逻辑:特征的方差反映了数据的变化程度,方差很小的特征几乎没有变化,对模型的预测帮助不大。比如,一个特征的值在所有样本中几乎都一样(方差接近0),那么它对区分不同类别或预测结果几乎没有贡献。因此,方差筛选会设定一个方差阈值,剔除方差低于这个阈值的特征,保留那些变化较大的特征,从而减少特征数量,提高模型效率。

优点:这种方法特别适合处理高维数据,能快速去掉不重要的特征,

缺点:不考虑特征目标变量之间的关系,可能会误删一些低方差但有意义的特征。

# 打印标题,表明这是方差筛选的部分
print("--- 方差筛选 (Variance Threshold) ---")

# 导入需要的工具库
from sklearn.feature_selection import VarianceThreshold  # 方差筛选工具,用于剔除方差小的特征
import time  # 用于记录代码运行时间,方便比较效率

# 记录开始时间,后面会计算整个过程耗时
start_time = time.time()

# 创建方差筛选器,设置方差阈值为0.01
# 阈值是指方差的最小值,低于这个值的特征会被删除(可以根据数据情况调整阈值)
selector = VarianceThreshold(threshold=0.01)

# 对训练数据进行方差筛选,fit_transform会计算每个特征的方差并剔除不满足阈值的特征
# X_train是原始训练数据,X_train_var是筛选后的训练数据
X_train_var = selector.fit_transform(X_train)

# 对测试数据应用同样的筛选规则,transform会直接用训练数据的筛选结果处理测试数据
# X_test是原始测试数据,X_test_var是筛选后的测试数据
X_test_var = selector.transform(X_test)

# 获取被保留下来的特征名称
# selector.get_support()返回一个布尔值列表,表示哪些特征被保留,这个是selector这个实例化的类的一个方法
# X_train.columns是特征的名称,结合布尔值列表可以提取保留特征的名字
selected_features_var = X_train.columns[selector.get_support()].tolist()

# 打印筛选后保留的特征数量和具体特征名称,方便查看结果
print(f"方差筛选后保留的特征数量: {len(selected_features_var)}")
print(f"保留的特征: {selected_features_var}")

# 创建一个随机森林分类模型,用于在筛选后的数据上进行训练和预测
# random_state=42是为了保证每次运行结果一致,方便教学和对比
rf_model_var = RandomForestClassifier(random_state=42)

# 在筛选后的训练数据上训练模型
# X_train_var是筛选后的特征数据,y_train是对应的目标标签
rf_model_var.fit(X_train_var, y_train)

# 使用训练好的模型对筛选后的测试数据进行预测
# X_test_var是筛选后的测试特征数据,rf_pred_var是预测结果
rf_pred_var = rf_model_var.predict(X_test_var)

# 记录结束时间,计算整个训练和预测过程的耗时
end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")

# 打印模型在测试集上的分类报告,展示模型的性能
# 分类报告包括精确率、召回率、F1分数等指标,帮助评估模型好坏
print("\n方差筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_var))

# 打印混淆矩阵,展示模型预测的详细结果
# 混淆矩阵显示了真实标签和预测标签的对应情况,比如多少样本被正确分类,多少被错分
print("方差筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_var))

2. 皮尔逊相关系数筛选

皮尔逊相关系数筛选是一种基于特征与目标变量之间相关性的特征选择方法。

核心逻辑:计算每个特征与目标变量之间的相关系数(范围在-1到1之间,值越大表示正相关越强,值越小表示负相关越强,接近0表示几乎无关),然后根据相关系数的绝对值大小,选择与目标变量相关性较高的特征,剔除相关性较低的特征。

优点:这种方法适用于目标变量是连续型的情况(如果是分类问题,可以先对目标变量编码)。通过皮尔逊相关系数筛选,我们可以保留那些对预测目标最有帮助的特征,减少无关或冗余特征的干扰。

若面对分类问题,通常需要先对目标变量进行编码处理,将其转化为数值型数据后再开展分析。

print("--- 皮尔逊相关系数筛选 ---")
from sklearn.feature_selection import SelectKBest, f_classif
import time

start_time = time.time()

# 计算特征与目标变量的相关性,选择前k个特征(这里设为10个,可调整)
# 注意:皮尔逊相关系数通常用于回归问题(连续型目标变量),但如果目标是分类问题,可以用f_classif
k = 10
selector = SelectKBest(score_func=f_classif, k=k)
X_train_corr = selector.fit_transform(X_train, y_train)
X_test_corr = selector.transform(X_test)

# 获取筛选后的特征名
selected_features_corr = X_train.columns[selector.get_support()].tolist()
print(f"皮尔逊相关系数筛选后保留的特征数量: {len(selected_features_corr)}")
print(f"保留的特征: {selected_features_corr}")

# 训练随机森林模型
rf_model_corr = RandomForestClassifier(random_state=42)
rf_model_corr.fit(X_train_corr, y_train)
rf_pred_corr = rf_model_corr.predict(X_test_corr)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\n皮尔逊相关系数筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_corr))
print("皮尔逊相关系数筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_corr))

3. Lasso筛选(基于L1正则化)

Lasso回归(Least Absolute Shrinkage and Selection Operator)是一种结合特征选择和模型训练的方法。

核心逻辑:在进行线性回归的同时,通过引入L1正则化项(即惩罚项),强制将一些不重要特征的回归系数压缩到0,从而实现特征筛选。换句话说,Lasso会自动“挑选”对预测目标有贡献的特征(系数不为0),而剔除无关或冗余的特征(系数为0)。

优点:这种方法特别适合处理高维数据,可以减少特征数量,提高模型的解释性和计算效率。

print("--- Lasso筛选 (L1正则化) ---")
from sklearn.linear_model import Lasso
from sklearn.feature_selection import SelectFromModel
import time

start_time = time.time()

# 使用Lasso回归进行特征筛选
lasso = Lasso(alpha=0.01, random_state=42)  # alpha值可调整
selector = SelectFromModel(lasso)
selector.fit(X_train, y_train)
X_train_lasso = selector.transform(X_train)
X_test_lasso = selector.transform(X_test)

# 获取筛选后的特征名
selected_features_lasso = X_train.columns[selector.get_support()].tolist()
print(f"Lasso筛选后保留的特征数量: {len(selected_features_lasso)}")
print(f"保留的特征: {selected_features_lasso}")

# 训练随机森林模型
rf_model_lasso = RandomForestClassifier(random_state=42)
rf_model_lasso.fit(X_train_lasso, y_train)
rf_pred_lasso = rf_model_lasso.predict(X_test_lasso)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\nLasso筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_lasso))
print("Lasso筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_lasso))

这个时候要注意,Lasso本质上是回归模型,实际上用这个方法来筛选也是用回归模型对分类问题建模结束了,然后打印特征重要度,它是把0和1目标变量视为连续值来进行回归的。效果会差一点,不符合逻辑,但是确实可以计算。

4. 树模型重要性筛选

树模型的核心是 “不断找最佳特征拆分数据”。它会根据一个特征 “拆分数据的效果” 来打分:

  • 拆分后,两组数据的结果越清晰,这个特征就越重要。
  • 整个模型中,一个特征被用来拆分的次数越多、效果越好,它的 “重要性分数” 就越高。
print("--- 树模型自带的重要性筛选 ---")
from sklearn.feature_selection import SelectFromModel
import time

start_time = time.time()

# 使用随机森林的特征重要性进行筛选
rf_selector = RandomForestClassifier(random_state=42)
rf_selector.fit(X_train, y_train)
selector = SelectFromModel(rf_selector, threshold="mean")  # 阈值设为平均重要性,可调整
X_train_rf = selector.transform(X_train)
X_test_rf = selector.transform(X_test)

# 获取筛选后的特征名
selected_features_rf = X_train.columns[selector.get_support()].tolist()
print(f"树模型重要性筛选后保留的特征数量: {len(selected_features_rf)}")
print(f"保留的特征: {selected_features_rf}")

# 训练随机森林模型
rf_model_rf = RandomForestClassifier(random_state=42)
rf_model_rf.fit(X_train_rf, y_train)
rf_pred_rf = rf_model_rf.predict(X_test_rf)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\n树模型重要性筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_rf))
print("树模型重要性筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_rf))

5. SHAP重要性筛选

print("--- SHAP重要性筛选 ---")
import shap
from sklearn.feature_selection import SelectKBest
import time

start_time = time.time()

# 使用随机森林模型计算SHAP值
rf_shap = RandomForestClassifier(random_state=42)
rf_shap.fit(X_train, y_train)
explainer = shap.TreeExplainer(rf_shap)
shap_values = explainer.shap_values(X_train)

# 计算每个特征的平均SHAP值(取绝对值的平均)
mean_shap = np.abs(shap_values[1]).mean(axis=0)  # shap_values[1]对应正类
k = 10  # 选择前10个特征,可调整
top_k_indices = np.argsort(mean_shap)[-k:]
X_train_shap = X_train.iloc[:, top_k_indices]
X_test_shap = X_test.iloc[:, top_k_indices]

# 获取筛选后的特征名
selected_features_shap = X_train.columns[top_k_indices].tolist()
print(f"SHAP重要性筛选后保留的特征数量: {len(selected_features_shap)}")
print(f"保留的特征: {selected_features_shap}")

# 训练随机森林模型
rf_model_shap = RandomForestClassifier(random_state=42)
rf_model_shap.fit(X_train_shap, y_train)
rf_pred_shap = rf_model_shap.predict(X_test_shap)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\nSHAP重要性筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_shap))
print("SHAP重要性筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_shap))

6. 递归特征消除(RFE)

递归特征消除(Recursive Feature Elimination, 简称RFE)是一种特征选择方法,广泛用于机器学习中,特别是在分类和回归问题中,用于从一组特征中筛选出对模型性能贡献最大的子集。

核心思想:通过递归地移除最不重要的特征,逐步缩小特征集,直到达到预设的特征数量或满足其他停止条件。

print("--- 递归特征消除 (RFE) ---")
from sklearn.feature_selection import RFE
import time

start_time = time.time()

# 使用随机森林作为基础模型进行RFE
base_model = RandomForestClassifier(random_state=42)
rfe = RFE(base_model, n_features_to_select=10)  # 选择10个特征,可调整
rfe.fit(X_train, y_train)
X_train_rfe = rfe.transform(X_train)
X_test_rfe = rfe.transform(X_test)

# 获取筛选后的特征名
selected_features_rfe = X_train.columns[rfe.support_].tolist()
print(f"RFE筛选后保留的特征数量: {len(selected_features_rfe)}")
print(f"保留的特征: {selected_features_rfe}")

# 训练随机森林模型
rf_model_rfe = RandomForestClassifier(random_state=42)
rf_model_rfe.fit(X_train_rfe, y_train)
rf_pred_rfe = rf_model_rfe.predict(X_test_rfe)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\nRFE筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_rfe))
print("RFE筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_rfe))

@浙大疏锦行

请作为资深开发工程师,解释我给出的代码。请逐行分析我的代码并给出你对这段代码的理解。 我给出的代码是: 【{智能估值体系V12优化版-修正} DYNPETTM:=IF(FINANCE(1)>250000000 AND FINANCE(4)>120000000, CLOSE/(FINANCE(1)/MAX(FINANCE(4),100000000)+0.000001)*0.88,1000); PB_RATE:=IF(FINANCE(34)>0.8 AND CLOSE>5, CLOSE/((FINANCE(34)*0.82+REF(FINANCE(34),1)*0.18)*0.93+0.000001),1000); {修正PEG计算V3} PEG_VAL:=DYNPETTM/MAX(FINANCE(30)/REF(MAX(FINANCE(30),0.01),4),1.25); {分形波动率V19增强} VOL_REG:=DMA(STD(CLOSE,233)/MA(CLOSE,233)*SQRT(233),34)*1.08; VAR_PERIOD:=IF(VOL_REG<0.015,377,IF(VOL_REG<0.035,233,89)); FAST_LEN:=BARSLAST(CROSS(VOL_REG,0.03))+21; SLOW_LEN:=IF(VOL_REG>0.18,INTPART(VAR_PERIOD*1.618),CEILING(VAR_PERIOD*2.118)); {行业轮动V12升级} HY_RET:=EMA((INDEXC/REF(INDEXC,5)-1)*100,8)*1.22; IND_RATIO:=EMA(INDEXC/MAX(INDEXO,0.01),13); TRANS_MAT:=EMA((SUM((IND_RATIO>REF(IND_RATIO,8))*(REF(IND_RATIO,8)>REF(IND_RATIO,21)),34)+ SUM((IND_RATIO>REF(IND_RATIO,8))*(REF(IND_RATIO,8)>REF(IND_RATIO,21)),55))/2/ (SUM(REF(IND_RATIO,8)>REF(IND_RATIO,21),55)+0.0001),8); SECTOR_STR:=TRANS_MAT*EMA(HY_RET,13)*0.68+REF(TRANS_MAT,8)*EMA(HY_RET,21)*0.32; {优化行业筛选V2} CTOP_SECT:=COUNT(ABS(SECTOR_STR)>=ABS(REF(SECTOR_STR,1)),250)<=3; SECTOR_FLT:=SECTOR_STR>REF(SECTOR_STR,21)*1.15 AND CTOP_SECT AND CROSS(EMA(SECTOR_STR,12),EMA(SECTOR_STR,26)) AND SLOPE(SECTOR_STR,5)>SLOPE(SECTOR_STR,21) AND FINANCE(42)/100000000>1.5; {十维情绪V23增强} MARKET_SENT:=EMA(ADVANCE/DECLINE,34)*0.55+ EMA(AMOUNT/REF(AMOUNT,8),34)*0.35+ EMA((VOL/FINANCE(7)-REF(VOL/FINANCE(7),13))/REF(VOL/FINANCE(7),13),55)*0.3+ EMA(REF(FINANCE(20),5)/FINANCE(7),21)*0.25; {三维共振V5优化} DIF:=EMA(CLOSE,12)-EMA(CLOSE,26); DEA:=EMA(DIF,9); {资金流向V4修正} BIGBUY:=SUM(IF(VOL/FINANCE(7)>=0.008 AND COUNT(VOL/FINANCE(7)>=0.007,3)=3, AMOUNT*0.7,0),5); BIGSELL:=SUM(IF(VOL/FINANCE(7)>0.008 AND COUNT(VOL/FINANCE(7)>0.007,3)=3, AMOUNT*0.3,0),5); FUNDFLOW:=(BIGBUY-BIGSELL)/FINANCE(7)*100; 资金流信号:=EMA(FUNDFLOW,8)>0.68 AND MA(BIGBUY,5)>MA(BIGSELL,5)*1.25 AND COUNT(FUNDFLOW>0,5)>=3 AND BIGBUY>REF(BIGBUY,5)*1.2; {情绪启动V2判定} 情绪启动:=CROSS(MARKET_SENT,1.18) AND COUNT(MARKET_SENT>0.98,5)>=3; {技术形态V3优化} 技术形态:=CLOSE>MAX(EMA(CLOSE,89),EMA(CLOSE,377)) AND DIF>EMA(DEA,5); {多周期趋势V2判定} MONTH_TREND:=CLOSE>EMA(CLOSE,55)*1.18 AND SLOPE(MA(CLOSE,55),21)>0.1; DAY_BREAK:=CLOSE>HHV(HIGH,21) AND VOL>MA(VOL,89)*3.5; {终极信号V6整合} 盘后选股:=DYNPETTM<12.8 AND PB_RATE<2 AND PEG_VAL<0.62 AND SECTOR_FLT AND EVERY(CLOSE>EMA(CLOSE,55),3) AND FINANCE(30)/REF(MAX(FINANCE(30),0.01),4)>1.42 AND EVERY(VOL>MA(VOL,55)*1.1,3) AND 资金流信号 AND 情绪启动 AND 技术形态 AND CLOSE/EMA(CLOSE,55)>1.18 AND VOL/EMA(VOL,55)>1.2; DRAWICON(盘后选股 AND DAY_BREAK, LOW, 1);】
04-05
<think>嗯,用户让我分析这段代码,看起来像是股票选股策略的指标公式,可能用于某种交易软件,比如通达信或者大智慧。首先,我需要确定代码的结构和各个部分的功能。代码中有多个变量定义,最后有一个DRAWICON函数,应该是满足条件时在图表上画图标。 首先,DYNPETTM这个变量,看起来是动态市盈率TTM的计算。条件判断如果总股本和净利润满足一定数值,就计算CLOSE/(FINANCE(1)/MAX(FINANCE(4),1e8))*0.88,否则设为1000。这里FINANCE(1)可能是总股本,FINANCE(4)是净利润,所以DYNPETTM应该是调整后的市盈率,乘0.88可能有折扣,防止分母太小加了一个极小值0.000001。 接下来是PB_RATE,市净率的计算。条件是FINANCE(34)(可能是每股净资产)大于0.8且收盘价大于5,计算时用了最近两期的每股净资产加权平均,再乘以0.93,同样加了一个极小值避免除零错误。如果不符合条件,设为1000。 然后是PEG_VAL,PEG指标,用DYNPETTM除以净利润增长率。这里MAX(FINANCE(30)/REF(...),1.25)可能是为了控制增长率的下限,避免过高的PEG值。FINANCE(30)可能是净利润增长率,REF是引用前几期的数据,这里用了四季度前的数据,可能是在做同比。 分形波动率部分,VOL_REG的计算用了DMA函数,动态移动平均的标准差除以均值的平方根乘以周期,再乘以1.08。这可能是在计算波动率,然后根据波动率的值调整VAR_PERIOD,波动率低时用更长周期,高时用短周期。FAST_LEN和SLOW_LEN根据波动率交叉0.03的情况调整长度,可能用于后续的均线计算。 行业轮动部分,HY_RET是行业指数收益的指数移动平均,IND_RATIO是行业收盘价与开盘价的比率。TRANS_MAT比较复杂,结合了行业比率的历史比较,可能是计算行业动量的指标。SECTOR_STR综合了TRANS_MAT和HY_RET的指数移动平均,用于判断行业强度。 优化行业筛选部分,CTOP_SECT判断行业强度在250天内排名前三的情况,SECTOR_FLT则结合多个条件,比如行业强度超过21天前的1.15倍,CTOP_SECT,EMA金叉,斜率变化以及流通市值大于1.5亿。这些条件综合筛选出表现强劲的行业。 十维情绪指标MARKET_SENT,结合了涨跌家数、成交额、成交量变化和财务指标,综合市场情绪。三维共振部分用了MACD的DIF和DEA指标。 资金流向部分,BIGBUY和BIGSELL根据成交量和金额判断大单买卖,FUNDFLOW计算净资金流,资金流信号需要满足多个条件,比如EMA大于0.68,买入均线大于卖出,连续五天资金流为正等。 情绪启动和技术形态分别判断市场情绪是否突破阈值和技术面上的条件,比如收盘价在长短期均线之上,MACD指标等。 多周期趋势判断月线趋势和日线突破,比如收盘价超过55日均线的1.18倍,成交量突破等。 最后的盘后选股整合了所有条件,包括估值指标、行业筛选、趋势、资金流、情绪和技术形态等,当所有条件满足时,DRAWICON在低位显示买入信号。 用户可能想确认代码是否正确,或者想了解各个指标的逻辑,是否存在潜在错误,或者如何优化。需要检查每个函数的参数是否正确,比如FINANCE函数的参数是否对应正确的财务数据,条件判断的阈值是否合理,以及各指标之间的协同作用。此外,需要注意代码中的常数,如0.88、0.93等,是否有合理依据,以及是否存在除零风险,虽然已经加了极小值,但可能需要确认。同时,回溯测试的结果是否可靠,是否存在过拟合等问题,可能也是用户关心的点。</think>我将从技术指标公式设计的角度,逐模块解析这段量化交易代码: --- ### 一、估值体系模块 1. **DYNPETTM(动态市盈率TTM)** ```pine DYNPETTM:=IF(FINANCE(1)>250000000 AND FINANCE(4)>120000000, CLOSE/(FINANCE(1)/MAX(FINANCE(4),100000000)+0.000001)*0.88,1000); ``` - **关键逻辑**:当总股本>2.5亿且净利润>1.2亿时: - 计算修正市盈率:$ \text{股价}/(\frac{\text{总股本}}{\max(\text{净利润},1亿)}) \times 0.88 $ - 乘数0.88是安全边际调整 - 否则赋值为1000作为异常值标记 2. **PB_RATE(市净率优化)** ```pine PB_RATE:=IF(FINANCE(34)>0.8 AND CLOSE>5, CLOSE/((FINANCE(34)*0.82+REF(FINANCE(34),1)*0.18)*0.93+0.000001),1000); ``` - **创新点**: - 使用加权平均净资产:$ \text{当期净资产} \times 82\% + \text{上期净资产} \times 18\% $ - 附加0.93的行业折价系数 - 股价低于5元的股票直接排除 --- ### 二、成长性评估模块 ```pine PEG_VAL:=DYNPETTM/MAX(FINANCE(30)/REF(MAX(FINANCE(30),0.01),4),1.25); ``` - **算法解析**: - 分母采用滚动增长率:$ \max(\frac{\text{本期净利润增长率}}{\text{四季度前增长率}},1.25) $ - 设置1.25的增长率下限,过滤低增长企业 --- ### 三、波动率自适应模块 ```pine VOL_REG:=DMA(STD(CLOSE,233)/MA(CLOSE,233)*SQRT(233),34)*1.08; VAR_PERIOD:=IF(VOL_REG<0.015,377,IF(VOL_REG<0.035,233,89)); ``` - **数学原理**: - 波动率计算:$ \frac{\text{233日标准差}}{\text{233日均值}} \times \sqrt{233} $ - 通过DMA(动态移动平均)进行平滑处理 - 根据波动率水平自适应调整计算周期 --- ### 四、行业轮动引擎 ```pine TRANS_MAT:=EMA((SUM((IND_RATIO>REF(IND_RATIO,8))*(REF(IND_RATIO,8)>REF(IND_RATIO,21)),34)+ SUM(...55))/2/(SUM(...)+0.0001),8); ``` - **设计亮点**: - 双重时间窗口验证(34日+55日) - 使用乘积条件:$ (\text{当前强度} > 8日前强度) \times (8日前强度 > 21日前强度) $ - 通过EMA平滑行业动量信号 --- ### 五、多因子集成模块 ```pine 盘后选股:=DYNPETTM<12.8 AND PB_RATE<2 AND PEG_VAL<0.62 AND SECTOR_FLT AND EVERY(CLOSE>EMA(CLOSE,55),3) ...(共10个条件); ``` - **策略核心**: | 因子类型 | 阈值条件 | 经济含义 | |----------------|----------------|-----------------------| | 估值因子 | DYNPETTM<12.8 | 低市盈率筛选 | | 成长因子 | PEG_VAL<0.62 | 高成长性企业 | | 动量因子 | CLOSE>EMA(55) | 中期趋势确认 | | 资金流因子 | 资金流信号 | 主力资金流入 | | 情绪因子 | 情绪启动 | 市场热度确认 | --- ### 六、信号触发机制 ```pine DRAWICON(盘后选股 AND DAY_BREAK, LOW, 1); ``` - **触发逻辑**: 1. 同时满足10维度条件 2. 日线突破:收盘价创21日新高且成交量>89日均量3.5倍 3. 在K线最低价位置绘制买入图标 --- ### 代码优化建议 1. **财务数据校验**:建议增加FINANCE(7)(流通股本)的零值保护 2. **波动率计算**:可测试$ \sqrt{233} $系数是否适配当前市场波动特征 3. **参数敏感性**:建议对0.88、0.93等经验参数进行参数遍历优化 4. **行业轮动**:可增加行业市净率中位数对比加强行业选择 该代码体系体现了多因子量化投资的典型特征,通过估值、成长、动量、资金流等多维度验证,适合用于中长线趋势跟踪策略。建议配合3年以上历史数据进行回测验证稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值