最近很多朋友问我如何用Python做量化分析,尤其是对短线交易者特别关注的涨停板数据。作为一个在量化领域摸爬滚打多年的老手,我发现同花顺问财+Python这套组合特别适合个人投资者。今天就带大家用pywencai和pandas搭建一个完整的涨停板分析系统,不仅能抓数据,还能挖掘出有价值的交易信号。
先说说为什么选择这套方案。同花顺问财的数据质量在业内是公认的靠谱,而pywencai这个开源库完美解决了网页抓取的难题。相比我之前用过的akshare,它的数据字段更丰富,特别是包含了涨停原因分类这种对短线交易至关重要的信息。pandas就不用多说了,数据分析的瑞士军刀,处理这种结构化数据再合适不过。
工欲善其事必先利其器,我们先搞定环境。打开你的终端(Windows用户用cmd或者PowerShell),按顺序执行以下命令:
bash复制# 安装Node.js(pywencai依赖JavaScript执行环境)
brew install node # Mac用户
# Windows用户去官网下载安装包
# 创建虚拟环境(推荐但不强制)
python -m venv wencai_env
source wencai_env/bin/activate # Mac/Linux
wencai_env\Scripts\activate # Windows
# 安装必要库
pip install pywencai pandas xlsxwriter
这里有个坑我踩过:Node.js版本必须≥16,否则pywencai会报错。安装完后可以用node -v检查版本。
先看一个基础版的抓取代码:
python复制import pywencai
import pandas as pd
# 设置pandas显示选项(重要!)
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.max_columns', None)
date = "20240821" # 改成你想分析的日期
query = f"{date}涨停,非ST,非科创板"
df = pywencai.get(query=query, sort_key='成交金额')
这段代码抓取了指定日期所有非ST、非科创板的涨停股。但这样太基础了,我们升级一下查询条件:
python复制advanced_query = """
20240821涨停,
非ST,
非立案调查,
a股市值<100亿,
连续涨停天数>1,
涨停原因类别包含'华为概念'
"""
df_advanced = pywencai.get(query=advanced_query)
查询语法是同花顺问财的核心能力,支持各种条件组合。几个实用技巧:
>,<,包含等运算符原始数据往往比较杂乱,我们需要先清洗:
python复制# 选择关键列
cols = ['股票代码', '股票简称', '最新价', '连续涨停天数',
'涨停原因类别', 'a股市值', '涨停类型']
clean_df = df[cols].copy()
# 处理缺失值
clean_df['连续涨停天数'] = clean_df['连续涨停天数'].fillna(1)
# 市值单位转换(原始数据是元)
clean_df['a股市值(亿)'] = clean_df['a股市值'] / 1e8
好的特征能让分析事半功倍,我常用的衍生特征:
python复制# 连板梯队标记
clean_df['梯队'] = pd.cut(clean_df['连续涨停天数'],
bins=[0, 1, 2, 3, 5, 10],
labels=['首板', '二板', '三板', '中位股', '高标'])
# 市值分组
clean_df['市值分组'] = pd.qcut(clean_df['a股市值(亿)'],
q=4,
labels=['小盘', '中盘', '大盘', '超大盘'])
# 涨停原因拆分成列表(便于后续分析)
clean_df['原因列表'] = clean_df['涨停原因类别'].str.split('+')
短线交易最关注的就是热点概念,我们可以这样分析:
python复制# 展开所有涨停原因
reason_df = clean_df.explode('原因列表')
# 统计概念热度
concept_stats = reason_df['原因列表'].value_counts().head(10)
print("当日热门概念TOP10:\n", concept_stats)
# 概念与连板天数的关系
concept_analysis = reason_df.groupby('原因列表')['连续涨停天数'].mean()
连板股是短线情绪风向标,建议重点关注:
python复制# 连板分布统计
lianban_stats = clean_df['梯队'].value_counts()
# 各梯队市值分布
lianban_market_cap = clean_df.groupby('梯队')['a股市值(亿)'].mean()
# 连板股涨停原因交叉分析
cross_tab = pd.crosstab(clean_df['梯队'], reason_df['原因列表'])
不同市值股票的涨停特征差异很大:
python复制# 各市值分组涨停数量
market_cap_count = clean_df['市值分组'].value_counts()
# 市值与连板天数的关系
market_cap_vs_lianban = clean_df.groupby('市值分组')['连续涨停天数'].mean()
基于上述分析,我们可以设计一个简单的策略:
python复制def next_day_strategy(df):
# 选择条件:二板或三板 + 小盘 + 热门概念前3
hot_concepts = df['原因列表'].explode().value_counts().index[:3]
condition = (
(df['梯队'].isin(['二板', '三板'])) &
(df['市值分组'] == '小盘') &
(df['原因列表'].apply(lambda x: any(c in x for c in hot_concepts)))
)
return df[condition]
watch_list = next_day_strategy(clean_df)
虽然没有专业回测框架,但可以用历史数据验证:
python复制# 假设我们已经有多日数据
all_days_df = pd.concat([day1_df, day2_df, day3_df])
# 计算次日开盘买入的收益率
def backtest(df):
df['次日开盘价'] = df.groupby('股票代码')['最新价'].shift(-1)
df['次日收益率'] = (df['次日开盘价'] - df['最新价']) / df['最新价']
return df.groupby('梯队')['次日收益率'].mean()
backtest_result = backtest(all_days_df)
在实际使用中,有几个关键点需要注意:
python复制# 保存数据
clean_df.to_pickle('stock_data.pkl')
# 读取数据
df = pd.read_pickle('stock_data.pkl')
python复制def get_data(date):
query = f"{date}涨停,非ST"
return pywencai.get(query=query)
这套系统我已经实盘使用了半年多,最大的感受是:数据只是工具,关键还是看你怎么用。建议新手先从简单的条件开始测试,慢慢增加复杂度。比如可以先观察"二板+小盘股"这个组合的历史表现,再逐步加入概念热度等维度。