问财量化选股策略逻辑
振幅大于1,PE>0,换手率3%-12%
选股逻辑分析
该选股逻辑通过考虑股票的波动性、估值以及市场流动性等因素来综合筛选具备一定投资价值的股票。其中,振幅大于1可以较为准确地过滤出波动性较大的标的;PE>0则体现了公司的盈利能力和估值水平;换手率3%-12%则从市场流动性的角度考虑,选出具备较好流动性的股票。虽然综合考虑不同因素,但也面临一些风险和不足。
有何风险?
该选股逻辑未考虑公司的基本面表现、行业比较等因素,偏向于中短期市场流动性和短期市场波动性。同时,对于波动性较小的标的,则会被该策略忽略,导致股票池较为局限。此外,换手率变化幅度大且难以预测,在实际使用中需要谨慎。
如何优化?
为了更好地使用该逻辑筛选出具备更大投资价值的标的,可以添加一些公司基本面表现、行业比较等长期因素的考虑,从而提高选择的精确度。在振幅的选择上,可以较为准确地算出不同股票的波动率,结合历史波动性进行筛选。此外,可以考虑选取多个不同时间段内的市场流动性进行筛选,从而更全面地判断股票的流动性。
最终的选股逻辑
- 振幅大于平均值
- PE>0
- 换手率3%-12%
- 公司基本面好
- 行业相对估值合理
同花顺指标公式代码参考
振幅大于平均值:(REF(MAX(CLOSE,REF(CLOSE,1)),1)-REF(MIN(CLOSE,REF(CLOSE,1)),1))/MA(C,30)>1
PE>0:PE>0
换手率3%-12%:((VOL/100)/CAPITALANDLARGESTVALUE)<=0.12 AND ((VOL/100)/CAPITALANDLARGESTVALUE)>=0.03
python代码参考
import baostock as bs
# 获取指定股票的数据
def get_stock_data(stock_code, start_date, end_date):
bs.login()
rs = bs.query_history_k_data_plus(stock_code,
"date,code,open,high,low,close,volume",
start_date=start_date,
end_date=end_date,
frequency="d")
data_list = []
while (rs.error_code == '0') & rs.next():
data_list.append(rs.get_row_data())
bs.logout()
data_df = pd.DataFrame(data_list, columns=rs.fields)
return data_df
# 振幅大于平均值
def filter_amplitude(data_df):
avg_amplitude = ((data_df["close"].rolling(window=30).max() - data_df["close"].rolling(window=30).min())
/ data_df["close"].rolling(window=30).mean())
data_df = data_df[avg_amplitude > 1]
return data_df
# PE > 0
def filter_pe(data_df):
# 使用baostock获取PE数据
# 前提是有bs.db库的登录信息
data_df = data_df.dropna()
pe_list = []
for date in data_df["date"].tolist():
rs = bs.query_history_k_data_plus(data_df[data_df["date"] == date]["code"].tolist()[0],
"peTTM",
start_date=date,
end_date=date,
frequency="d")
while (rs.error_code == '0') & rs.next():
pe_list.append(float(rs.get_row_data()[-1]))
pe_df = pd.DataFrame(pe_list, columns=["PE"])
data_df = pd.concat([data_df.reset_index(drop=True), pe_df.reset_index(drop=True)], axis=1)
data_df = data_df[data_df["PE"] > 0]
return data_df
# 换手率
def filter_turnover(data_df):
capital_list = []
for date in data_df["date"].tolist():
rs = bs.query_history_k_data_plus(data_df[data_df["date"] == date]["code"].tolist()[0],
"capitalandlargestshareholdertradingrate",
start_date=date,
end_date=date,
frequency="d")
while (rs.error_code == '0') & rs.next():
capital_list.append(float(rs.get_row_data()[-1]))
capital_df = pd.DataFrame(capital_list, columns=["CAPITALANDLARGESTVALUE"])
data_df = pd.concat([data_df.reset_index(drop=True), capital_df.reset_index(drop=True)], axis=1)
data_df["VOL"] = data_df["volume"].astype(float)
data_df = data_df[((data_df["VOL"] / 100) / data_df["CAPITALANDLARGESTVALUE"]) <= 0.12]
data_df = data_df[((data_df["VOL"] / 100) / data_df["CAPITALANDLARGESTVALUE"]) >= 0.03]
return data_df
# 公司基本面好
def filter_fundamental(data_df):
# TO DO
return data_df
# 行业相对估值合理
def filter_industry(data_df):
# TO DO
return data_df
# 筛选出符合条件的股票
def select_stocks(stock_list, start_date, end_date):
selected_stocks = []
for stock_code in stock_list:
data_df = get_stock_data(stock_code, start_date, end_date)
data_df = filter_amplitude(data_df)
data_df = filter_pe(data_df)
data_df = filter_turnover(data_df)
data_df = filter_fundamental(data_df)
data_df = filter_industry(data_df)
if not data_df.empty:
selected_stocks.append(stock_code)
return selected_stocks
```
## 如何进行量化策略实盘?
请把您优化好的选股语句放入文章最下面模板的选股语句中即可。
select_sentence = '市值小于100亿' #选股语句。
模板如何使用?
点击图标右上方的复制按钮,复制到自己的账户即可使用模板进行回测。
## 如果有任何问题请添加 下方的二维码进群提问。
