目次
概要

1980年にドナルド・M・ランバート氏が開発したオシレータ系テクニカル指標で、商品取引に特化されているため、CCIの名があります。この指標は商品価格の周期的な値動きを見極めるために考案されました。根底には商品には上昇と下落のサイクルがあるという考えがあります。価格の基準値からと基準値の平均から平均偏差を取り、そこからの変動を見て相場の方向性を判断します。図1が表示例となります。CCIはEMAよりトレンド転換のシグナルを早く表示すると言われています。
計算方法(日足の場合)
基準値を最初に計算します。この値はティピカルプライス(TP)です。次にTPのSMAを取りMAを計算します。標準的なnの値は20です。
$$ \rm{} TP = (高値+安値+終値)/3 \\ MA(TPのSMA) = SMA(TP, 20) \\ $$以上からMAからの平均偏差MD(Mean Deviation)を計算すると、
$$ \rm{} MD = \{(MA-TP_1)+(MA-TP_2)+(MA-TP_3)+…+(MA-TP_{20})\}/20 $$となります。最後にCCIを計算するためにTPとMAの差をMDで割ります。この時MDには係数0.015倍(慣用的な数字)をかけます。
$$ \rm{} CCI = (TP – MA)/(0.015 \times MD) $$それでは実際に具体的な値を入れてみましょう。
日数 | 始値 | 安値 | 高値 | 終値 | TP | SMA(TP, 5) | MD | CCI |
1日目 | 1000 | 997 | 1057 | 1050 | 1035 | |||
2日目 | 1050 | 1040 | 1074 | 1070 | 1061 | |||
3日目 | 1070 | 1057 | 1073 | 1060 | 1063 | |||
4日目 | 1060 | 1056 | 1082 | 1080 | 1072 | |||
5日目 | 1080 | 1078 | 1101 | 1100 | 1093 | 1065 | ||
6日目 | 1100 | 1095 | 1155 | 1150 | 1133 | 1085 | ||
7日目 | 1150 | 1112 | 1158 | 1120 | 1130 | 1098 | ||
8日目 | 1120 | 1113 | 1132 | 1130 | 1125 | 1110 | ||
9日目 | 1130 | 1094 | 1134 | 1100 | 1109 | 1118 | 26.23 | -22.37 |
10日目(最新) | 1100 | 1040 | 1112 | 1050 | 1064 | 1112 | 30.29 | -106.37 |
上表のように計算されるので9日目は平常値、10日目は逆張りの機会であると予想できます。
Pythonによる実装
必要なライブラリを読み込みます
!pip install mpl_finance #Collaboratoryに入っていないライブラリを読み込みます import matplotlib import matplotlib.pyplot as plt import matplotlib.dates as mdates import pandas as pd import mpl_finance import sys import numpy as np from datetime import datetime from matplotlib.offsetbox import OffsetImage, AnnotationBbox import requests import io
疑似データを読み込みます
#ファイルの読み込み URL = "https://neulab.co.jp/wp-content/uploads/pseudo_data.csv" #csvファイルのURL datafile = requests.get(URL)#ファイルの読み込み #データフレームの作成 df_temp = pd.read_csv(io.BytesIO(datafile.content), header=0, index_col=0, parse_dates=True, encoding="UTF-8") df = df_temp.loc[:,['Open','High','Low','Close']] df.head()
CCIを計算します
df['tp'] = df.loc[:,['High', 'Low', 'Close']].mean(axis='columns') ma_tp = df['tp'].rolling(20).mean() df['avd_tp'] = (df['tp'] - ma_tp).abs().rolling(20).mean() df_cci = (df['tp'] - df['tp'].rolling(20).mean())/(0.015 * df['avd_tp'])
matplotを使用した描画例です
canvas_color = '#fffafa' line_color = '#c8ced1' font_color = '#171510' colorup = '#bf0000' colordown = '#006fbf' n_data = -100 data = df[n_data:] ohlc = np.vstack((range(len(data)), data.T)).T fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [10, 6]}, sharex=True, figsize=(12,9)) fig.patch.set_facecolor(canvas_color) ax1.patch.set_facecolor(canvas_color) mpl_finance.candlestick_ohlc(ax1, ohlc, width=0.5, alpha=1, colorup=colorup, colordown=colordown) ax2.patch.set_facecolor(canvas_color) ax2.plot(range(len(data)), df_cci.values[n_data:], color='red', ls='-', label='CCI(20)') ax1.grid() ax2.grid() #ロゴ読み込み logoURL = "https://neulab.co.jp/wp-content/uploads/logo.png" #logoファイルのURL img_c = plt.imread(logoURL) imagebox = OffsetImage(img_c, zoom=0.020) #画像をimageboxにいれる。 imagebox.image.axes = ax1 im_sabo = AnnotationBbox(imagebox, (0, 9850), xybox=(0, 9950), xycoords="data", boxcoords="data", pad=0.3, frameon=False) l1,l2 = ax2.get_legend_handles_labels() ax2.legend(l1,l2, fontsize=14, edgecolor='none', facecolor=canvas_color) ax1.add_artist(im_sabo) ax1.set_ylabel("Price of Something", fontsize=22) ax1.set_ylim(9000., 10000.) ax1.yaxis.tick_right() ax1.yaxis.set_label_coords(0, 0.5) ax1.tick_params(labelsize=24, labelcolor=font_color, color=line_color) ax1.spines['left'].set_linewidth(0) ax1.spines['right'].set_linewidth(0) ax1.spines['top'].set_linewidth(0) ax1.spines['bottom'].set_linewidth(0) ax2.yaxis.tick_right() ax2.set_ylim([-200,200]) ax2.tick_params(labelsize=22, labelcolor=font_color, color=line_color) #ax2.set_yticks(np.linspace(0,100,6)) ax2.spines['left'].set_color(line_color) ax2.spines['right'].set_color(line_color) ax2.spines['top'].set_color(line_color) ax2.spines['bottom'].set_color(line_color) xtick0 = 2 plt.xticks(range(xtick0,len(data),12), [x.strftime('%m/%d') for x in df_cci.index][xtick0::12]) plt.subplots_adjust(left=0.05, right=0.89, bottom=0.1, top=0.99) plt.grid(which='major',color=line_color,linestyle='-') plt.grid(which='minor',color=line_color,linestyle='-') ax2.grid(linestyle='--', lw=1) ax1.set_axisbelow(True) fig.savefig('CCI.png', facecolor=fig.get_facecolor(), edgecolor='none')
以上のコードをGoogle社の提供しているColaboratory上で公開しており、実際に動作させることができます。
リンク先はこちら。
CCIを使った予想
一番簡単な使い方はCCIが-100から100までの間は平常値と考えて、-100と100の範囲を超えたら逆張りで入る方法です。
- 買い
- CCIが-100を下回った時に逆張りの買いでエントリー
- 売り
- CCIが100を上回った時に逆張りの売りでエントリー
図2がCCIを使った予想例となります。100や-100を超えたら反転しているのがわかりますが、超えた点で反転しているわけではなく、上下し続けることに注意が必要です。

注意点
一口に100を超えたと言っても、CCIはどこで買いが止まるかまでは教えてくれないため、エントリーポイントの見極めが難しい点に注意が必要です。他のテクニカル指標を組み合わせて使用することをお勧めします。
※このHPページで紹介しているテクニカル指標を使った取引ルールや売買シグナルの見方は一般的な考え方に基づくものであり、利益の増加や損失の減少を保証するものではありません。ご自身の判断にてお取引いただきますようお願いいたします。
現在、ニューラボでは人工知能による取引アルゴリズムを開発中です。11月にリリース予定。乞うご期待!
自動取引にご興味を持たれましたら お問い合わせページよりお気軽にお問合せください。