アルティメット・オシレータ(Ultimate Oscillator)

 

概要
図1 アルティメット・オシレータの描画例

1985年にラリー・ウイリアムズ(Larry Williams)氏によって発表されたオシレータ系のテクニカル指標です。このオシレータはそれまでのオシレータ系指標が設定期間を14日とすると相場が14日周期でないと効果を発揮しないという欠点を克服するため動的に計測期間を変更するという設計が盛り込まれています。計測期間を7日、14日、28日と3つ設定し、相場の動きへの追従を試みています。オシレータを計算するために3つの計測区間それぞれに対して相場の売買圧力、変動率を計算し、足し合わせます。図1がアルティメット・オシレータの描画例です。

計算方法(日足の場合)

まず、圧力の計算をします。買い圧力は当日終値と当日安値の安い方、前日終値から計算します。売り圧力は同様に当日終値と前日終値の高い方、当日高値から計算します。

$$ \rm{} 買い圧力(BP) = 当日終値 – Min(当日安値、前日終値) \\ 売り圧力(SP) = Max(当日高値、前日終値) – 当日終値 $$

次にトゥルーレンジを計算します。これはよく使われる計算式で、当日の高値と安値、前日の終値からもっとも大きな値幅を計算します。

$$ \rm{} トゥルーレンジ(TR) = Max(当日高値-当日安値、当日高値-前日終値、前日終値-当日安値) $$

次に3つの区間の変動率を計算します。3つの区間を7日(SR)、14日(MR)、28日(LR)とし、分子をその期間のBPの合計、分子をTRの合計として変動率を計算します。つまりSRなら1日目から7日目までのBPの和を取って同じ期間のTRの和で割ります。式で書くと次の通りです。

$$ \rm{} SR = (BP_1 + BP_2 + BP_3 + BP_4 + BP_5 + BP_6 + BP_7)/(TR_1 + TR_2 + TR_3 + TR_4 + TR_5 + TR_6 + TR_7) \\ = \sum_{i=1}^7 BP_i/\sum_{i=1}^7 TR_i \\ MR = \sum_{i=1}^{14} BP_i/\sum_{i=1}^{14} TR_i \\ LR = \sum_{i=1}^{28} BP_i/\sum_{i=1}^{28} TR_i \\ $$

最後にこれらの変動率を足し合わせて、アルティメット・オシレータ(UO)を計算します。期間を28日にそろえるためにSRを4倍、MRを2倍してから足し合わせて最後に7で割ることで、UOが計算できます。

$$ \rm{} UO = (4 \times SR + 2 \times MR + LR) / 7 \times 100 $$
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()

アルティメット・オシレータを計算します

df_chart = df['Close'].rolling(25).mean()

df_low = df['Low']
df_high = df['High']
df_close = df['Close']
df_close2 = df['Close'].shift(1)
df_diff_low = df_low - df_close2
df_diff_high = df_high - df_close2

df_buy1 = df_close - df_low[df_diff_low < 0]
df_buy1 = df_buy1.fillna(0)

df_buy2 = df_close - df_close2[df_diff_low >= 0]
df_buy2 = df_buy2.fillna(0)

df_buy = df_buy1 + df_buy2

df_sell1 = df_high[df_diff_high >= 0] - df_close
df_sell1 = df_sell1.fillna(0)

df_sell2 = df_close2[df_diff_high < 0] - df_close
df_sell2 = df_sell2.fillna(0)
df_sell = df_sell1 + df_sell2

df_width = (df_buy + df_sell)

df_ratio7 = df_buy.rolling(7).sum()/df_width.rolling(7).sum() * 100
df_ratio14 = df_buy.rolling(14).sum()/df_width.rolling(14).sum() * 100
df_ratio28 = df_buy.rolling(28).sum()/df_width.rolling(28).sum() * 100

df_uo = (4*df_ratio7 + 2*df_ratio14 + df_ratio28)/7

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_uo.values[n_data:], color='red', ls='-', label='UO')
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([0,100])
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_uo.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('UlitmiateOsc.png', facecolor=fig.get_facecolor(), edgecolor='none')

以上のコードをGoogle社の提供しているColaboratory上で公開しており、実際に動作させることができます。

リンク先はこちら

アルティメット・オシレータを使った予想

アルティメット・オシレータの予想の方法は他の指標と比べて多少複雑で逆行現象が起こったことを基準として予測します。

注意点

短期の計測期間が7日のため、より短い期間では指標が有効に働かない可能性があるとされています。


※このHPページで紹介しているテクニカル指標を使った取引ルールや売買シグナルの見方は一般的な考え方に基づくものであり、利益の増加や損失の減少を保証するものではありません。ご自身の判断にてお取引いただきますようお願いいたします。


現在、ニューラボでは人工知能による取引アルゴリズムを開発中です。11月にリリース予定。乞うご期待!
自動取引にご興味を持たれましたら お問い合わせページよりお気軽にお問合せください。