4S选股指标自定义修改工具,可视化调整营收,ROE筛选阀值。
2026/6/21 21:52:10 网站建设 项目流程

实际应用场景描述

在量化投资研究中,策略的有效性高度依赖于参数的选取。以“4S选股法”(或任何基于基本面的选股策略)为例,研究员或投资者通常需要通过历史数据回测,来找到最优的筛选阈值(如“营业收入同比增长率 > 15%”或“ROE > 10%”)。

传统的做法是硬编码阈值,每次调整都需要修改代码并重新运行,效率低下且缺乏直观性。本工具旨在解决这一问题,提供一个可视化的、交互式的参数调优界面,让用户可以通过拖动滑块实时调整筛选条件,并立即查看符合条件的股票数量变化,从而快速锁定合理的参数区间。

引入痛点

1. 代码门槛高:非专业程序员(如金融分析师)难以通过修改代码行来调整复杂的SQL或Pandas筛选条件。

2. 调试效率低:修改一个阈值(如将ROE从10%调到12%),需要修改代码、保存、重新运行脚本、等待结果,循环往复,耗时耗力。

3. 缺乏直观反馈:无法实时感知参数微调对“幸存者数量”的影响,难以判断筛选条件是过严还是过宽。

核心逻辑讲解

本工具的核心逻辑基于 Streamlit 的交互式组件 与 Pandas 的数据过滤 能力:

1. 数据层:使用

"pandas" 加载包含股票基本面数据的 CSV 文件(如营业收入、ROE、市盈率等)。

2. 交互层:利用

"streamlit" 的

"slider"(滑块)组件,将原本硬编码的阈值(如

"roe_threshold = 0.1")暴露给用户。

3. 响应层:一旦用户拖动滑块,Streamlit 会重新运行脚本,此时筛选逻辑会使用最新的滑块数值,通过

"df.query()" 或布尔索引过滤数据。

4. 可视化:利用

"matplotlib" 或

"streamlit" 自带的图表功能,展示筛选后的结果分布(如直方图)或直接在表格中展示明细。

代码模块化实现

1. 环境准备 (

"requirements.txt")

streamlit>=1.20.0

pandas>=1.5.0

matplotlib>=3.7.0

numpy>=1.24.0

2. 核心应用代码 (

"app.py")

import streamlit as st

import pandas as pd

import matplotlib.pyplot as plt

import numpy as np

# ==========================================

# 模块 1:数据加载与预处理

# ==========================================

@st.cache_data # 缓存数据,避免每次交互都重新读取大文件

def load_data(file_path='stock_data.csv'):

"""

加载股票基本面数据。

模拟数据包含:代码、名称、营收同比增长率(rev_growth)、ROE、市盈率(PE)、行业。

"""

try:

df = pd.read_csv(file_path)

# 数据清洗:确保关键列为数值类型

numeric_cols = ['rev_growth', 'roe', 'pe']

for col in numeric_cols:

df[col] = pd.to_numeric(df[col], errors='coerce')

return df.dropna(subset=numeric_cols)

except FileNotFoundError:

st.error(f"错误:未找到数据文件 {file_path}")

return None

def generate_mock_data():

"""生成模拟数据以供演示"""

np.random.seed(42)

codes = [f"SH60{str(i).zfill(4)}" for i in range(100, 200)]

names = [f"公司_{i}" for i in range(100)]

data = {

'code': codes,

'name': names,

'rev_growth': np.random.uniform(-0.5, 1.0, len(codes)), # -50% 到 100%

'roe': np.random.uniform(-0.2, 0.4, len(codes)), # -20% 到 40%

'pe': np.random.uniform(5, 100, len(codes)),

'industry': np.random.choice(['科技', '金融', '消费', '医药', '制造'], len(codes))

}

return pd.DataFrame(data)

# ==========================================

# 模块 2:侧边栏 - 参数控制面板

# ==========================================

def render_sidebar(df):

"""渲染侧边栏,包含所有的筛选阈值滑块"""

st.sidebar.header("📊 4S 选股指标调整")

# 营收增长阈值

rev_min = float(df['rev_growth'].min())

rev_max = float(df['rev_growth'].max())

rev_threshold = st.sidebar.slider(

"营收同比增长率下限 (%)",

min_value=rev_min * 100,

max_value=rev_max * 100,

value=10.0, # 默认值 10%

step=1.0,

help="仅保留营收增长高于此值的股票"

)

# ROE 阈值

roe_min = float(df['roe'].min())

roe_max = float(df['roe'].max())

roe_threshold = st.sidebar.slider(

"ROE (净资产收益率) 下限 (%)",

min_value=roe_min * 100,

max_value=roe_max * 100,

value=8.0, # 默认值 8%

step=0.5,

help="仅保留ROE高于此值的股票"

)

# 市盈率范围

pe_threshold = st.sidebar.slider(

"市盈率 (PE) 上限",

min_value=float(df['pe'].min()),

max_value=float(df['pe'].max()),

value=50.0,

step=1.0,

help="排除估值过高的股票"

)

return rev_threshold, roe_threshold, pe_threshold

# ==========================================

# 模块 3:核心筛选逻辑

# ==========================================

def filter_stocks(df, rev_thresh, roe_thresh, pe_thresh):

"""

根据阈值筛选股票。

业务逻辑:营收增长 > X% AND ROE > Y% AND PE < Z

"""

# 注意:滑块返回的是百分比数值,需转为小数进行比较

query_str = (

f"rev_growth > {rev_thresh / 100} and "

f"roe > {roe_thresh / 100} and "

f"pe < {pe_thresh}"

)

filtered_df = df.query(query_str)

return filtered_df

# ==========================================

# 模块 4:可视化展示

# ==========================================

def display_results(filtered_df, total_count):

"""展示筛选结果及统计图表"""

count = len(filtered_df)

# 关键指标展示

col1, col2, col3 = st.columns(3)

col1.metric("符合条件的股票数", f"{count} 只", f"{count/total_count*100:.1f}%")

if count > 0:

col2.metric("平均 ROE", f"{filtered_df['roe'].mean()*100:.2f}%")

col3.metric("平均营收增长", f"{filtered_df['rev_growth'].mean()*100:.2f}%")

st.divider()

# 行业分布图

if count > 0:

st.subheader("行业分布")

fig, ax = plt.subplots(figsize=(10, 4))

# 为了中文显示正常

plt.rcParams['font.family'] = 'WenQuanYi Micro Hei'

industry_counts = filtered_df['industry'].value_counts()

ax.barh(industry_counts.index, industry_counts.values, color='#4C72B0')

ax.set_xlabel("数量")

ax.invert_yaxis() # 让数量最多的在上面

st.pyplot(fig)

# 数据明细表

st.subheader("筛选明细")

# 格式化显示

display_df = filtered_df.copy()

display_df[['rev_growth', 'roe']] = display_df[['rev_growth', 'roe']].applymap(lambda x: f"{x*100:.2f}%")

display_df['pe'] = display_df['pe'].map(lambda x: f"{x:.2f}")

st.dataframe(display_df[['code', 'name', 'industry', 'rev_growth', 'roe', 'pe']])

else:

st.warning("当前参数组合下无符合条件的股票,请放宽筛选条件。")

# ==========================================

# 模块 5:主程序入口

# ==========================================

def main():

st.set_page_config(page_title="4S 选股指标可视化工具", layout="wide")

st.title("📈 4S 选股指标自定义修改工具")

st.caption("拖动滑块实时调整筛选阈值,观察选股池变化")

# 加载数据

df = load_data()

if df is None:

# 如果文件不存在,使用模拟数据

df = generate_mock_data()

st.info("💡 当前使用模拟数据进行演示。如需使用实盘数据,请将 `stock_data.csv` 放入同目录。")

total_count = len(df)

# 渲染控制面板

rev_thresh, roe_thresh, pe_thresh = render_sidebar(df)

# 执行筛选

filtered_df = filter_stocks(df, rev_thresh, roe_thresh, pe_thresh)

# 展示结果

display_results(filtered_df, total_count)

if __name__ == "__main__":

main()

README 文件 (

"README.md")

# 4S 选股指标可视化调整工具

[![Python Version](https://img.shields.io/badge/Python-3.9+-blue.svg)](https://www.python.org/)

[![Streamlit](https://img.shields.io/badge/Streamlit-1.20+-red.svg)](https://streamlit.io/)

## 📖 项目简介

一个基于 Python 和 Streamlit 构建的交互式股票筛选工具。用户可以通过可视化滑块实时调整“4S选股法”中的核心指标阈值(营收增长率、ROE、PE),并即时查看筛选结果的变化。

## ✨ 功能特性

- **营收增长率筛选**:剔除增长停滞或衰退的企业。

- **ROE 筛选**:锁定盈利能力强的公司。

- **PE 估值筛选**:排除估值泡沫过大的标的。

- **实时统计**:显示符合条件的股票数量、占比及行业分布。

## 🚀 快速开始

### 1. 环境安装

bash

pip install -r requirements.txt

### 2. 准备数据

在项目根目录创建 `stock_data.csv`,需包含以下列:

- `code` (代码), `name` (名称), `industry` (行业)

- `rev_growth` (营收同比增长率, 小数形式, 如 0.15 代表 15%)

- `roe` (净资产收益率, 小数形式)

- `pe` (市盈率)

若无数据文件,应用将自动加载内置的模拟数据进行演示。

### 3. 运行应用

bash

streamlit run app.py

## ⚙️ 技术架构

- **UI 框架**: Streamlit

- **数据处理**: Pandas

- **可视化**: Matplotlib

## ⚠️ 免责声明

本工具仅供技术研究与学习使用,不构成任何投资建议。股市有风险,投资需谨慎。

核心知识点卡片

1. 交互式数据应用架构

* 概念:将数据分析逻辑与前端展示分离,通过 UI 组件(如滑块、输入框)接收用户输入,实时更新后端计算结果。

* 实现:Streamlit 的

"st.slider" 绑定变量,一旦变量变化,脚本重新执行,驱动数据刷新。

2. 基本面选股逻辑 (4S 简化版)

* 营收增长 (Sales Growth):反映企业市场份额的扩张能力。

"rev_growth > 10%" 通常被视为成长型公司的门槛。

* ROE (Return on Equity):反映股东投入资本的回报率。长期来看,股价表现与 ROE 高度相关。

* PE (Price-to-Earnings):反映市场对公司未来增长的预期。低 PE 可能意味着低估,但也可能是价值陷阱。

3. 数据可视化反馈

* 原理:人类大脑处理图像的速度远快于数字。通过柱状图展示行业分布,比看表格更能快速发现“哪个行业在当前策略下更占优势”。

免责声明与风险提示

免责声明:

本工具为开源技术演示项目,旨在展示 Python 在数据科学领域的应用能力。

1. 工具中涉及的选股指标(如营收、ROE)仅为常见基本面分析维度,不代表任何投资价值判断。

2. 若使用真实市场数据,数据来源的准确性、完整性由数据提供方负责,本工具不承担任何数据相关责任。

3. 模拟数据仅为展示算法逻辑,不代表真实市场情况。

风险提示:

1. 回测不代表未来:基于历史财务数据的筛选无法预测未来股价走势。

2. 幸存者偏差:筛选出的“好公司”不代表就是“好股票”,还需考虑买入时机、市场情绪等因素。

3. 参数过拟合:过度优化参数以适应历史数据,可能导致策略在未来失效。

总结

本文介绍了如何利用 Python + Streamlit 构建一个“4S选股指标可视化调整工具”。

通过 模块化 的设计(数据层、控制层、逻辑层、展示层),我们将枯燥的代码逻辑转化为直观的 滑块交互。这不仅降低了量化策略调试的门槛,也极大地提升了研究效率。

核心收获:

1. Streamlit 是将 Python 脚本转化为 Web 应用的利器,特别适合数据科学类 Demo。

2. Pandas 的

"query" 方法结合字符串格式化,可以优雅地实现动态筛选逻辑。

3. 在量化研究中,工具化思维(将重复劳动自动化、可视化)是提升生产力的关键。

本文代码仅供学习与技术交流,不构成任何投资建议,股市有风险,入市需谨慎!

利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询