Pythonでサポートラインとレジスタンスラインを引く

スポンサーリンク

ある時点のサポートラインとレジスタンスラインを引くだけであれば簡単です。しかしシストレの場合は時間が進んで行きますので固定では使い物になりません。ということで私が編み出した苦肉の策をご紹介します。

スポンサーリンク

はじめに

「サポートラインとレジスタンスラインの引き方」のようなサイトを見ても、感覚的なところが多いように思います。熟練の技?的な感じがあるのかも知れません。

また、画面(チャート)のサイズ(幅)によっても、サポートラインとレジスタンスラインの見え方が変わりますよね?
サポートラインとレジスタンスラインは共に、ある一定期間の高値または安値のライン(壁)になりますが、それを越せば次のライン(壁)が出てきます。

更に、1分足と1時間足とか、いろいろ足でも見え方が異なります。

このようにサポートラインとレジスタンスラインは、きちんと定義するのが困難ですが、ある程度の目安になればいいかと、今回挑みました。

サポートラインとレジスタンスラインの方向性

私が考えた解決策としては、パーセンタイルを用いるということです。

パーセンタイルは統計学になるので説明は難しいですが、超簡単に言えば、最小値から数えてX%に位置する値ということです。なので例えば90%パーセンタイルを超える(簡単に言えば全体の90%を超える)データを異常値とみなして外しましょうということです。

上記のMEMOでは90%としていますが、今回、サポートラインとレジスタンスラインを引く際は0.1%で試しています。このあたりは、自分の好みで変更すればいいかなと思います。

そして、本数(期間)については、複数個用意して、それぞれでシストレの分析をすればいいかと思います。

プログラム

データ

なんでもいいのですが、今回は以下のようなUSD/JPYのデータを用意しました。

                  Date Time     Open     High      Low    Close  Volume
0 2019-11-03 22:00:00+00:00  108.239  108.239  108.234  108.234     2.0
1 2019-11-03 22:01:00+00:00  108.237  108.237  108.237  108.237     1.0
2 2019-11-03 22:02:00+00:00  108.242  108.242  108.240  108.240     2.0
3 2019-11-03 22:03:00+00:00  108.237  108.237  108.237  108.237     1.0
4 2019-11-03 22:04:00+00:00  108.237  108.237  108.237  108.237     1.0
・・・

サポートラインとレジスタンスラインの作成

  • line_turms:リスト形式でサポートラインとレジスタンスラインの本数(期間)を設定します。
  • lower_num:サポートラインのパーセンタイルをパーセントで指定します。1が100%になりますので、0.001で0.1%ということです。
  • upper_num:レジスタンスラインのパーセンタイルですが、サポートラインの逆になりますので自動計算しています。

本数(期間)のリストをループさせています。
rollingで本数(期間)を指定して、パーセンタイルで値を求めています。rollingは対象行を含むことになります。
対象行の足にサポートラインとレジスタンスラインの値を含めていけませんので、一つシフトさせることにより、一つ前までのデータでrollingしたパーセンタイルの値を対象行のデータとして扱うことが可能になります。

それぞれの関数は以下を参照してください。

# Support & Resistance lines
line_turms = [30,60,120]

lower_num = 0.001
upper_num = 1 - lower_num

for line_turm in line_turms:
    # Resistance lines
    df['r' + str(line_turm)] = df['Close'].rolling(line_turm).quantile(upper_num)    
    df['r' + str(line_turm)] = df['r' + str(line_turm)].shift(1)

    # Support lines
    df['s' + str(line_turm)] = df['Close'].rolling(line_turm).quantile(lower_num)
    df['s' + str(line_turm)] = df['s' + str(line_turm)].shift(1)

print(df.tail())

結果

from bokeh.plotting import figure, output_file, show
from bokeh.layouts import column
from bokeh.models import LinearAxis, Range1d
from bokeh.models import ColumnDataSource, Band

# データフレームのマスクを設定
inc = df.Close > df.Open
dec = ~inc

# ローソク足の幅は固定
w = 0.5

TOOLS = "pan,wheel_zoom,box_zoom,box_select,crosshair,reset,save"

# 日時表示用のフォーマットを設定(日足と分足に分岐
xaxis_dt_format = '%d %b %Y'
if df.iloc[0]['Date Time'].hour > 0:
    xaxis_dt_format = '%d %b %Y %H:%M:%S'

# ------------------------------------------
# 1画面目(上の画面)

# 画面の初期設定
p = figure(
    x_axis_type="linear", # datetimeでは歯抜けになる。
    tools=TOOLS, 
    plot_width=800, # チャートの幅
    title = "USD/JPY Candlestick 1 DAY bar" # タイトルは任意に
)

p.xaxis.major_label_orientation = pi/4 # 日付を斜めに表示
p.grid.grid_line_alpha=0.3 # グリッドを薄く

# ローソク足の設定
p.segment(df.index, df.High, df.index, df.Low, color="black") # 高値と安値のラインを作成
p.vbar(df.index[inc], w, df.Open[inc], df.Close[inc], fill_color="crimson", line_color="black") # 陽線を作成
p.vbar(df.index[dec], w, df.Open[dec], df.Close[dec], fill_color="royalblue", line_color="black") # 陰線を作成

# 追加するチャートの設定
p.line(df.index, df.r30, color = 'green', legend = 'R30')
p.line(df.index, df.s30, color = 'blue', legend = 'S30')

# ------------------------------------------
# indexでラベルしたものを日付に上書き
p.xaxis.major_label_overrides = {
    i: date.strftime(xaxis_dt_format) for i, date in enumerate(df["Date Time"])
}
# ラベルの位置を設定
p.legend.location = 'top_left'

# ------------------------------------------
# 出力
output_file("candlestick.html", title="candlestick.py example")

show(p)

30本(30分間*1分足のため)

サポートラインとレジスタンスラインのサンプル

30本で作成しているので、いつも見ているサポートラインとレジスタンスラインとは異なるので違和感があるように見えます。

60本(30分間*1分足のため)

サポートラインとレジスタンスラインのサンプル(60本

という感じになります。

少しギクシャクした感じがなくなりました。

見た目の問題ではなく、最終的にはシストレで利益を出すことです。
このようにすれば、ある程度のサポートラインとレジスタンスラインを実現することが可能になります。

 

コメント

タイトルとURLをコピーしました