有这么一个火遍全网的战法,据说只要在尾盘用几个指标选股,次日开盘卖出,一年就能从10万赚到100万,3年实现财富自由,这样的战法你心动吗?
这就是大名鼎鼎的尾盘选股法,相信炒股的你一定看到过这样的广告:

这种短线神话,说真的,我刷多了之后还真的心动了。但是看到要付费,我决定用Python自己来实现。
关于股票行情数据
股票行情之前一直用的是AKShare中的东方财富的行情数据,但是近期东财对爬虫打击很严,时不时就会封IP,所以花姐换了个思路,从掘金量化平台拿行情数据。为什么不用QMT或者miniQMT呢?因为好多人可能还没开通这个权限,而掘金量化你只需要下个客户端,注册下就可以了。 具体使用教程可以参考这篇文章
《AKShare被限IP、Tushare要积分?这才是最适合量化用的数据接口》
开始写策略
这个策略说起来不复杂,主要就是根据一些尾盘的特征来筛股票。比如说,涨幅在 2% 到 5% 之间,市值不能太大也不能太小,成交量要放出来,还得看到量价配合、均线走得好看一点。另外,分时图最好是全天都在均价线上方,整体走势比大盘强,才算是有希望的票。
1、拉取全部股票
先获取所有A股的列表,方便逐个遍历计算是否满足状态
python
from gm.api import *
import os
import pandas as pd
import numpy as np
set_token('你的掘金API的token')
def get_all_stock():
# 获取全A股代码(sec_type1=1)
data = get_symbols(
sec_type1=1010, #A股
sec_type2=None, #无二级类型
skip_suspended=True,#跳过停牌股
skip_st=True, #跳过ST股
df=True, #返回DataFrame
)
return data[['symbol','sec_id','sec_name']]
2、获取历史行情
python
def get_history(symbol):
#获取30根K线,不包括当前时间
df_hq = history_n(symbol=symbol,
frequency='1d',
count=30,
adjust=ADJUST_PREV,
df=True)
#获取最新的行情快照
current_data = current(symbols=symbol)
rows = []
for item in current_data:
row = {
'symbol': item['symbol'],
'frequency': '1d', #你可以改成你希望的周期
'open': item['open'],
'high': item['high'],
'low': item['low'],
'close': item['price'],
'volume': item['cum_volume'],
'amount': item['cum_amount'],
'pre_close': 0, # 数据中没有提供
'position': 0,
'bob': item['created_at'], #开始时间,用快照时间填充也行
'eob': item['created_at'], #结束时间等于快照时间
}
rows.append(row)
# 把历史和最新的拼接在一起
df_hq_current = pd.DataFrame(rows)
df = pd.concat([df_hq,df_hq_current])
return df
提示: 掘金通过 history_n 获取历史数据时,如果是在盘中,是无法获取最新的行情的,比如现在是10号,他只能获取到9号的数据,所以这里通过 current 获取最新的行情快照,然后和历史的拼接了一下。
3、判断涨幅是否在2%~5%
这个没什么好说的,直接用当前收盘价和昨天收盘价做个比就出来了
python
def is_price_rise_satisfied(df):
pre_close = df.iloc[-2]['close']
latest_close = df.iloc[-1]['close']
pct_change = (latest_close - pre_close) / pre_close * 100
if pct_change>=2 and pct_change<=5:
return True
else:
return False
4、判断流通市值50-200亿
代码看似简单,但是花姐查了好久文档才找到需要的数据的
python
def is_daily_mktvalue_satisfied(symbol):
df = stk_get_daily_mktvalue(symbol=symbol,
fields='tot_mv,tot_mv_csrc,a_mv',
start_date=None,
end_date=None,
df=True)
a_mv = df.iloc[-1]['a_mv']/100000000 #A股流通市值(含限售股)
if a_mv>=50 and a_mv<=200:
return True
else:
return False
5、判断换手率4-10%
掘金没有直接给出换手率数据,害的花姐只好手动计算了
erlang
换手率(%) = 当日成交量(股) / 总流通股本(股) × 100%
python
def is_turn_rate_satisfied(symbol):
df = stk_get_daily_basic(symbol=symbol,
fields='a_shr_unl', #无限售条件流通股本(A股)
df=True)
current_data = current(symbols=symbol)
cum_volume = current_data[0]['cum_volume']
turn_rate = cum_volume/df.iloc[-1]['a_shr_unl']*100
if turn_rate>=4 and turn_rate<=10:
return True
else:
return False
6、 判断量比大于1
量比 = 今日总成交量/昨日总成交量
python
def is_volume_ratio_satisfied(df):
volume_current = df.iloc[-1]['volume']
voluem_pre = df.iloc[-2]['volume']
if volume_current/voluem_pre>1:
return True
else:
return False
7、判断均线多头排列
这里用的是5 10 20日均线,你也可以改成你自己喜欢的
python
def is_duotou(df):
df = df.copy()
df['ma5'] = df['close'].rolling(5).mean()
df['ma10'] = df['close'].rolling(10).mean()
df['ma20'] = df['close'].rolling(20).mean()
cur_row = df.iloc[-1]
if cur_row['ma5']>cur_row['ma10'] and cur_row['ma10']>cur_row['ma20']:
return True
else:
return False
关于k线强于大盘 和分时股价全天在均价线上方第一个无需判断,个股涨幅在2%到5%就已经强于大盘了,分时股价全天在均价线上方暂时没有数据,就不做判断了,可以根据选出的股票来人工筛查。
8、写个main齐活
上面的判断都搞定了,合在一起就搞定了
python
def main():
set_token('这里是你的token,运行时记得打开掘金客户端')
df_stocks = get_all_stock()
with tqdm(total=len(df_stocks)) as bar:
for _,row in df_stocks.iterrows():
symbol = row['symbol']
try:
df_hq = get_history(symbol)
if is_price_rise_satisfied(df_hq):
if is_daily_mktvalue_satisfied(symbol):
if is_turn_rate_satisfied(symbol):
if is_volume_ratio_satisfied(df_hq):
if is_duotou(df_hq):
print(symbol,"满足尾盘选股指标")
except:
pass
finally:
bar.update(1)
小结
当前的写法比较简单,执行效率比较低,感兴趣的可以在这个基础上做优化。对于量比花姐这里偷了个懒直接用今天和昨天的成交量做了比较,其实可以改成和前N天的平均成交量做比较,同花顺软件上的量比是这样计算的。
🤔 留个开放问题给你
如果你现在有了一个"尾盘选股池",你会怎么优化它?
是加点"北向资金流入"?还是加点"龙虎榜大单"?还是搞个"次日高开选股剔除逻辑"?
欢迎在留言区分享你自己的战法灵感------真正牛的策略,永远来自实盘中碰出来的"顿悟"。