核心思想与Python源码实现指南
在量化交易领域,威廉·欧奈儿(William J. O'Neil)的CAN SLIM投资体系因其“基本面 技术面”双轮驱动的独特逻辑,成为无数投资者追寻的“圣杯”,而将这套体系转化为可量化的交易指标,则是将其从理论落地的关键一步,本文将深入解析欧奈儿核心量化指标的设计思想,并基于Python提供源码实现,帮助交易者理解、复现并应用于实际策略。
欧奈儿的CAN SLIM体系包含7个核心维度:当季每股收益增长(C)、年度每股收益增长(A)、新产品、新管理层、新 highs(N)、供给与需求(S)、市场整体走向(I),最容易被量化且直接关联交易时机的,是“新高突破”与“相对强度”两大技术指标,这也是欧奈儿“在正确的时机买入强势股”思想的集中体现。


欧奈儿认为,股价创近期新高(如52周新高)是股票进入强势阶段的信号,意味着市场对其价值的认可,量化时需结合“成交量确认”——突破新高当日成交量需显著放大(如超过过去50日均量的1.5倍),避免“无量假突破”。
相对强度衡量个股相对于大盘(如沪深300、标普500)的走势强弱,欧奈儿常用“RS评级”(1-100分,越高越强),核心是计算一段时间内个股涨幅与指数涨幅的比值,通常要求RS评级≥80,即股票表现强于80%以上的其他股票。

基于上述逻辑,我们用Python实现“新高突破”和“相对强度”两大核心指标,并给出综合信号示例。
import pandas as pd import numpy as np import akshare as ak # 用于获取股票数据(也可用tushare、yfinance等)
以A股为例,获取某股票过去一年的日线数据及对应指数数据:
def get_stock_data(stock_code, index_code="000300.SH", period="daily"):
"""获取股票及指数数据"""
# 获取股票数据(示例:贵州茅台,股票代码600519)
stock_df = ak.stock_zh_a_hist(symbol=stock_code, period="daily", start_date="20230101", end_date="20231231", adjust="qfq")
stock_df = stock_df[['日期', '开盘', '收盘', '最高', '最低', '成交量']]
stock_df.columns = ['date', 'open', 'close', 'high', 'low', 'volume']
stock_df['date'] = pd.to_datetime(stock_df['date'])
stock_df = stock_df.sort_values('date').reset_index(drop=True)
# 获取指数数据(沪深300)
index_df = ak.stock_zh_index_hist(symbol=index_code, period="daily", start_date="20230101", end_date="20231231")
index_df = index_df[['日期', '收盘']]
index_df.columns = ['date', 'index_close']
index_df['date'] = pd.to_datetime(index_df['date'])
# 合并数据
df = pd.merge(stock_df, index_df, on='date', how='left')
return df
stock_code = "600519" # 贵州茅台
df = get_stock_data(stock_code)
def new_high_breakout(df, window=252, volume_ratio=1.5):
"""
计算新高突破信号
:param df: 包含股价数据的DataFrame
:param window: 新高周期(默认252个交易日≈1年)
:param volume_ratio: 成交量放大倍数阈值
:return: 包含新高信号的DataFrame
"""
# 计算52周最高价
df['high_window_max'] = df['high'].rolling(window=window, min_periods=1).max()
# 标记新高日(当日最高价=窗口内最高价)
df['is_new_high'] = (df['high'] == df['high_window_max']).astype(int)
# 计算日均成交量
df['avg_volume'] = df['volume'].rolling(window=50, min_periods=1).mean()
# 突破条件:当日最高价创52周新高 成交量放大1.5倍
df['breakout_signal'] = (df['is_new_high'] == 1) & (df['volume'] > volume_ratio * df['avg_volume'])
return df
df = new_high_breakout(df)
def relative_strength(df, period=12):
"""
计算相对强度(RS)及RS评级
:param df: 包含股价及指数数据的DataFrame
:param period: 相对强度计算周期(默认12个月≈250个交易日,这里简化用12周≈60个交易日)
:return: 包含RS及RS评级的DataFrame
"""
# 计算个股及指数的周期涨跌幅
df['stock_return'] = df['close'].pct_change(periods=period*5) # 12周≈60个交易日
df['index_return'] = df['index_close'].pct_change(periods=period*5)
# 相对强度 = 个股涨跌幅 / 指数涨跌幅(避免除以0)
df['rs'] = np.where(df['index_return'] != 0, df['stock_return'] / df['index_return'], 1)
# 计算RS评级(将RS值映射到1-100分,取滚动分位数)
df['rs_percentile'] = df['rs'].rolling(window=252, min_periods=60).rank(pct=True) * 100
df['rs_rating'] = df['rs_percentile'].round(0).astype(int)
return df
df = relative_strength(df)
欧奈儿理想的买入信号是:新高突破 RS评级≥80 成交量确认。
def generate_oney_signals(df):
"""生成欧奈儿综合买入信号"""
df['oneil_signal'] = (df['breakout_signal'] == 1) & (df['rs_rating'] >= 80)
return df
df = generate_oney_signals(df)
# 输出信号日期
signal_dates = df[df['oneil_signal'] == 1]['date'].tolist()
print(f"欧奈儿买入信号触发日期:{signal_dates}")
window(新高周期)、volume_ratio(成交量阈值)、period(RS计算周期)需根据市场风格调整,例如牛市可缩短周期,熊市需放大成交量确认。 欧奈儿量化交易指标的精髓,是将“强者恒强”的市场哲学转化为可量化的数字信号,通过Python实现新高突破与相对强度指标,交易者不仅能理解其底层逻辑,还能根据自身需求优化参数,但需注意:没有“万能指标”,量化工具的核心是辅助决策,最终的成功仍需结合风险管理和持续的市场观察。
免责声明:本文为转载,非本网原创内容,不代表本网观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如有疑问请发送邮件至:bangqikeconnect@gmail.com