CCI指标,又称顺势指标,是美国股市技术分析 家唐纳德·蓝伯特(Donald Lambert)于20世纪80年代提出的。该指标专门测量股价、外汇或者贵金属交易是否已超出常态分布范围,属于超买超卖类指标中较特殊的一种。该指标波动于正无穷大和负无穷大之间。但是,它不需要以0为中轴线,这一点也和波动于正无穷大和负无穷大的指标不同。
它最早是用于期货市场的判断,后运用于股票市场的研判,并被广泛使用。与大多数单一利用股票的收盘价、开盘价、最高价或最低价而发明出的各种技术分析指标不同,CCI指标是根据统计学原理,引进价格与固定期间的股价平均区间的偏离程度的概念,强调股价平均绝对偏差在股市技术分析中的重要性,是一种比较独特的技术指标。
按照指标分析的常用思路,CCI指标的运行区间也分为三类:+100以上为超买区,—100以下为超卖区,+100到—100之间为震荡区。在+100到—100之间的震荡区,该指标基本上没有意义,不能够对大盘及个股的操作提供多少明确的建议,因此它在正常情况下是无效的。
有时候CCI指标还是比较好使的。以最近比较活跃的平潭发展为例,在股价大幅上涨的时候,CCI指标有剧烈的波动。下面给出获取股票数据以及计算CCI并且画图的python代码,希望能抛砖引玉。
本人将使用baostock的数据来进行代码展示:
import baostock as bs
import matplotlib.pyplot as plt
import matplotlib.font_manager as matfont
import numpy as np
import pandas as pd
# 设置中文字体
zhfont1 = matfont.FontProperties(fname='C:/Windows/Fonts/simkai.ttf')
def get_stock_data(stock_code='sz.000592'):
"""获取股票历史数据"""
# 登录baostock
bs.login()
# 查询历史K线数据
rs = bs.query_history_k_data_plus(
stock_code,
"date,open,high,low,close,volume",
start_date='2025-01-01', # 调整为更早的日期确保有数据
end_date='2025-10-31',
frequency="d",
adjustflag="3" # 复权类型:3-后复权
)
# 转换为DataFrame
data_list = []
while (rs.error_code == '0') and rs.next():
data_list.append(rs.get_row_data())
# 登出
bs.logout()
if data_list:
df = pd.DataFrame(data_list, columns=rs.fields)
# 转换数据类型
for col in ['open', 'high', 'low', 'close', 'volume']:
df[col] = pd.to_numeric(df[col], errors='coerce')
return df
else:
return pd.DataFrame()
def calculate_cci(high, low, close, period=14):
"""计算CCI指标"""
# 典型价格
typical_price = (high + low + close) / 3
# 典型价格的简单移动平均
sma_tp = typical_price.rolling(window=period).mean()
# 平均绝对偏差
mad = typical_price.rolling(window=period).apply(
lambda x: np.mean(np.abs(x - np.mean(x))), raw=True
)
# 计算CCI
cci = (typical_price - sma_tp) / (0.015 * mad + 1e-8)
return cci
def plot_cci_chart(stock_code='sz.000592', stock_name='平潭发展'):
"""绘制CCI指标图表"""
# 获取数据
print(f"正在获取{stock_name}({stock_code})数据...")
data = get_stock_data(stock_code)
if data.empty:
print("获取数据失败,请检查网络连接或股票代码")
return
print(f"成功获取 {len(data)} 条数据")
# 计算CCI
data['CCI'] = calculate_cci(data['high'], data['low'], data['close'])
# 取最近100个交易日数据
recent_data = data.tail(100).reset_index(drop=True)
# 创建图表
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10))
# 子图1:价格走势
ax1.plot(recent_data.index, recent_data['close'], 'b-', linewidth=2, label='收盘价')
ax1.set_ylabel('价格', fontproperties=zhfont1)
ax1.set_title(f'{stock_name}({stock_code}) - 收盘价走势', fontproperties=zhfont1, fontsize=14)
ax1.legend(prop=zhfont1)
ax1.grid(True, alpha=0.3)
# 子图2:CCI指标
ax2.plot(recent_data.index, recent_data['CCI'], 'r-', linewidth=1.5, label='CCI')
ax2.axhline(y=100, color='g', linestyle='--', alpha=0.7, label='超买线(+100)')
ax2.axhline(y=-100, color='g', linestyle='--', alpha=0.7, label='超卖线(-100)')
ax2.axhline(y=0, color='k', linestyle='-', alpha=0.5)
ax2.fill_between(recent_data.index, 100, recent_data['CCI'], where=(recent_data['CCI'] > 100),
color='red', alpha=0.3, label='超买区域')
ax2.fill_between(recent_data.index, -100, recent_data['CCI'], where=(recent_data['CCI'] < -100),
color='green', alpha=0.3, label='超卖区域')
ax2.set_ylabel('CCI指标', fontproperties=zhfont1)
ax2.set_xlabel('交易日', fontproperties=zhfont1)
ax2.set_title('CCI指标', fontproperties=zhfont1, fontsize=14)
ax2.legend(prop=zhfont1)
ax2.grid(True, alpha=0.3)
# 设置x轴刻度
date_labels = []
for i, date in enumerate(recent_data['date']):
if i % 20 == 0: # 每20个交易日显示一个日期
date_labels.append(date[5:]) # 显示月-日
else:
date_labels.append('')
ax2.set_xticks(range(len(date_labels)))
ax2.set_xticklabels(date_labels, rotation=45)
plt.tight_layout()
plt.show()
# 打印最新的CCI值
latest_cci = recent_data['CCI'].iloc[-1]
print(f"\n最新CCI值: {latest_cci:.2f}")
if latest_cci > 100:
print("状态: 超买区域")
elif latest_cci < -100:
print("状态: 超卖区域")
else:
print("状态: 正常区域")
if __name__ == '__main__':
# 绘制平潭发展的CCI指标图
plot_cci_chart('sz.000592', '平潭发展')
画出图像如下:


