大家常说,我们只要找到符合条件底部形态的个股买入持有,找到高位卖出,就能完成 高抛低吸的操作。
那这篇文章写一写,我们怎么量化识别 股票所谓的底部形态呢?
这里先介绍下我们常见的一些底部形态。
底分型是K线理论中最基础的反转形态,由3根相邻K线组成,是构成更大级别底部(如W底、头肩底)的“基石”。其核心特征:
简单说,就是“低点更低、高点也更低”的三根K线组合,意味着短期空方力量衰竭,多方开始反攻。
底分型代表短期下跌趋势的暂停或反转。若出现在长期下跌后的低位,且伴随成交量放大,反转信号可靠性更高;若出现在下跌中继,可能是短暂反弹,需结合其他指标验证。
import akshare as ak
import pandas as pd
# 识别底分型
def find_bottom_fractal(df):
df['底分型'] = False
for i in range(1, len(df) - 1):
current_low = df['最低'].iloc[i]
current_high = df['最高'].iloc[i]
prev_low = df['最低'].iloc[i - 1]
next_low = df['最低'].iloc[i + 1]
prev_high = df['最高'].iloc[i - 1]
next_high = df['最高'].iloc[i + 1]
# 底分型条件:中间K线低点最低+高点最低
if (current_low < prev_low) and (current_low < next_low) and \
(current_high < prev_high) and (current_high < next_high):
df.at[df.index[i], '底分型'] = True
return df
# 获取股票数据(以平安银行000001为例)
def get_stock_data(symbol="000001", start_date="20250101", end_date="20250921"):
df = ak.stock_zh_a_hist(symbol=symbol, period="daily",
start_date=start_date, end_date=end_date, adjust="qfq")
df['日期'] = pd.to_datetime(df['日期'])
df.set_index('日期', inplace=True)
return df[['开盘', '收盘', '最高', '最低', '成交量']]
# 执行识别
df = get_stock_data()
df = find_bottom_fractal(df)
bottom_signals = df[df['底分型']]
print(f"共识别出{len(bottom_signals)}个底分型信号,日期:{bottom_signals.index.strftime('%Y-%m-%d').tolist()}")双重底,俗称“W底”,由两个低点和中间一个反弹高点构成,形似字母“W”。其核心特征:
W底是典型的“底部夯实”形态:第一个低点是空方第一次发力,反弹后空方再次打压,但第二个低点未创新低,说明空方力量耗尽,突破颈线则标志着多方正式接管趋势。
3、提供一个识别例子
import pandas as pd
import akshare as ak
def find_double_bottom(df, min_distance=20, price_tolerance=0.05, breakout_ratio=0.03):
# 第一步:找出所有局部低点(低点比前后5天都低)
df['局部低点'] = False
for i in range(5, len(df) - 5):
if df['最低'].iloc[i] == df['最低'].iloc[i - 5:i + 5].min():
df.at[df.index[i], '局部低点'] = True
local_lows = df[df['局部低点']]
double_bottoms = []
# 第二步:匹配两个低点,满足条件则记录
for i in range(len(local_lows) - 1):
low1 = local_lows.iloc[i]
low2 = local_lows.iloc[i + 1]
# 条件1:两个低点间隔足够
days_between = (low2.name - low1.name).days
if days_between < min_distance:
continue
# 条件2:价格相近(容忍范围内)
price_diff = abs(low2['最低'] - low1['最低']) / low1['最低']
if price_diff > price_tolerance:
continue
# 条件3:计算颈线(两个低点之间的最高点)
between_data = df[(df.index > low1.name) & (df.index < low2.name)]
neckline = between_data['最高'].max()
# 条件4:检查颈线是否被突破(low2之后的交易日)
after_low2 = df[df.index > low2.name]
if len(after_low2) == 0:
continue
breakout_close = neckline * (1 + breakout_ratio)
breakout_signals = after_low2[after_low2['收盘'] > breakout_close]
if len(breakout_signals) > 0:
double_bottoms.append({
'第一个低点日期': low1.name,
'第二个低点日期': low2.name,
'第一个低点价格': low1['最低'],
'第二个低点价格': low2['最低'],
'颈线位': neckline,
'突破日期': breakout_signals.index[0],
'突破收盘价': breakout_signals['收盘'].iloc[0]
})
return double_bottoms
# 获取股票数据(以平安银行000001为例)
def get_stock_data(symbol="000001", start_date="20250101", end_date="20250921"):
df = ak.stock_zh_a_hist(symbol=symbol, period="daily",
start_date=start_date, end_date=end_date, adjust="qfq")
df['日期'] = pd.to_datetime(df['日期'])
df.set_index('日期', inplace=True)
return df[['开盘', '收盘', '最高', '最低', '成交量']]
# 执行识别
df = get_stock_data()
# 执行识别
double_bottoms = find_double_bottom(df)
if double_bottoms:
for db in double_bottoms:
print(f"W底确认:\n第一个低点:{db['第一个低点日期']}(价格:{db['第一个低点价格']:.2f})")
print(f"第二个低点:{db['第二个低点日期']}(价格:{db['第二个低点价格']:.2f})")
print(f"颈线位:{db['颈线位']:.2f},突破日期:{db['突破日期']}\n")
else:
print("未识别出符合条件的W底形态")
篇幅有限, 其他头肩底、圆弧底、V形底、三重底 等技术底部形态后续慢慢写。 由于个人技术有限,判断不出黄金底、钻石底、婴儿底、地球顶等这些底部信号。
如果我的分享对你投资有所帮助,不吝啬给个点赞关注呗。