見出し画像

Pandas勉強記録 ②SWING_HIGH,LOWを計算する

今回の使用文

1. rolling
2.np.where
3. fillna

少し前ですが、某神botterが"SWING_HIGH,LOW付近でエントリーすると~"と言っていたので、SWING_HIGH,LOWをPandasで計算してみましょう。

1.SWING_HIGH,LOWの定義を考える

図1

実は考えるまでもなく定義があって、

高値が前後6本の足の高値のうち最高値であればSWING_HIGH

です。LOWは逆。
6という数字は頭のいい人が"6がいいよ~"と言ったかららしいです。

実際は好きなように数字を変えてください。

2.Pandasで計算する

図1

1.前後6本の高値を参照する
2.最高値が参照範囲の中心の足のものをSWING_HIGHとする

この手順でいきましょう。

ローソク足データは前回の記事をそのまま使います。

2-1.前後6本までの高値を参照する

図2

まずは前6本までの高値を参照してみましょう。
参照方法は、.rolling(参照する本数)で、参照先は、その行を含む前n本です。
つまり、前6本までを参照したかったら、引数を7にする必要があります。

df["swing_high"] = df.high.rolling(swing_period+1)

このままだと、参照しているだけなので、参照範囲内の最高値を探してもらいましょう。

#勉強記録1の部分
df = pd.DataFrame(ohlcv)
df.open_time = pd.to_datetime(df.open_time*10**9,)
df = df.set_index('open_time').tz_localize('UTC').tz_convert('Asia/Tokyo')
df.drop(["symbol","interval","volume","turnover"],axis = 1,inplace=True)
df = df.astype('float')

#勉強記録2の部分
swing_period = 6
df["swing_high"] = df.high.rolling(swing_period+1).max()

df.to_csv("./swing_high.csv")

これでok。

dfの中身を確認する為、最後の行でcsvファイルで出力するようにしてます。​出力先は実行ファイルがあるフォルダです。

実行すると。。。

画像11

前6本にデータが存在しない場合、結果はnanになります。
実際に必要なのは前後6本なので、少し修正します。

#勉強記録1の部分
df = pd.DataFrame(ohlcv)
df.open_time = pd.to_datetime(df.open_time*10**9,)
df = df.set_index('open_time').tz_localize('UTC').tz_convert('Asia/Tokyo')
df.drop(["symbol","interval","volume","turnover"],axis = 1,inplace=True)
df = df.astype('float')

#勉強記録2の部分
swing_period = 6
df["swing_high"] = df.high.rolling(swing_period*2,center=True).max()

df.to_csv("./swing_high.csv")

swing_periodを2倍し、引数にcenter=Trueを追加しました。
center=Trueにしている場合、最初の引数が奇数だと参照範囲が"その行を含む前後n本"となり、偶数だと"その行を含まない前後n本"となります。
これで前後6本を参照します。

画像11

2-2.最高値が参照範囲の中心の足のものをSWING_HIGHとする

図2

前後6本の最高値を持ってこれたので、"最高値が参照範囲の中央の足である足"を選定します。

ここではnp.where()を使います。
突如現れたnumpy!npもよく使います。

df["swing_high"] = np.where(df.swing_high == df.high,df.high,np.nan)

np.whereは、第一引数に条件式、第2引数に条件式がTrueのときの値、第3引数に条件式がFalseの時の値を必要とします。
上記で言うと、df.swing_high == df.highという条件式がTrueの時はdf.high,Falseの時はnp.nan(数値なし)を入れます。

#勉強記録1の部分
df = pd.DataFrame(ohlcv)
df.open_time = pd.to_datetime(df.open_time*10**9,)
df = df.set_index('open_time').tz_localize('UTC').tz_convert('Asia/Tokyo')
df.drop(["symbol","interval","volume","turnover"],axis = 1,inplace=True)
df = df.astype('float')

#勉強記録2の部分
swing_period = 6
df["swing_high"] = df.high.rolling(swing_period*2,center=True).max()
df["swing_high"] = np.where(df.swing_high == df.high,df.high,np.nan)

df.to_csv("./swing_high.csv")

実行してみましょう。

画像9

"前後6本の範囲内で最高値が中央の足"のみ数値が入ってます。

数値が入っている箇所がSWING_HIGHです。お疲れ様でした!

2-3.SWING_HIGH,LOWが更新されるまで、前のSWING_HIGH,LOWをコピーする

図2

せっかくなのでbotで使えそうな感じにするところまでやりましょう。

.fillna()を使って、nanの部分に前回の値をコピーします。
fillna(0)ならnanの部分が全て0になり、fillna()method="ffill"という引数を与えると、前の値をコピーします。
ちなみにffillではなくbfillを与えると、次の値をコピーします。

#勉強記録1の部分
df = pd.DataFrame(ohlcv)
df.open_time = pd.to_datetime(df.open_time*10**9,)
df = df.set_index('open_time').tz_localize('UTC').tz_convert('Asia/Tokyo')
df.drop(["symbol","interval","volume","turnover"],axis = 1,inplace=True)
df = df.astype('float')

#勉強記録2の部分
swing_period = 6
df["swing_high"] = df.high.rolling(swing_period*2,center=True).max()
df["swing_high"] = np.where(df.swing_high == df.high,df.high,np.nan)
df["swing_high"] = df.swing_high.fillna(method="ffill")
df.to_csv("./swing_high.csv")

画像8

ちゃんとコピーされてますね。

2-4.チャートを作成し、SWING_HIGH,LOWをチャートに表示する

図2

最後にチャートを作成しましょう。

mplfinanceというモジュールを使いました。

画像10

これ以外にもshiftで結果をずらしたり、fillnaに与える引数でコピーする回数の上限を設定したりもできます。
今回はコードを載せてこれで終わりにします。

from matplotlib import pyplot as plt
import numpy as np
import pybybit
import pandas as pd
from tqdm import tqdm
from pprint import pprint as print
from datetime import datetime
import mplfinance as mpf

apis = []
bybit = pybybit.API(*apis, testnet = True)

swing_period = 6

symbol   = "BTCUSD"
interval = 1
# ローソク足取得開始時刻
start    = '2021/06/21 09:00' # ローソク足取得開始時刻
# タイムスタンプ変換
start = int(datetime.strptime(start,"%Y/%m/%d %H:%M").timestamp()) # タイムスタンプ変換

ohlcv = bybit.rest.inverse.public_kline_list(
       symbol   = symbol,
       interval = interval,
       from_    = start
       ).json()["result"]

#勉強記録1の部分
df = pd.DataFrame(ohlcv)
df.open_time = pd.to_datetime(df.open_time*10**9,)
df = df.set_index('open_time').tz_localize('UTC').tz_convert('Asia/Tokyo')
df.drop(["symbol","interval","volume","turnover"],axis = 1,inplace=True)
df = df.astype('float')

#勉強記録2の部分
swing_period = 6
df["swing_high"] = df.high.rolling(swing_period*2,center=True).max()
df["swing_high"] = np.where(df.swing_high == df.high,df.high,np.nan)
df["swing_high"] = df.swing_high.fillna(method="ffill")

df["swing_low"] = df.low.rolling(swing_period*2,center=True).min()
df["swing_low"] = np.where(df.swing_low == df.low,df.low,np.nan)
df["swing_low"] = df.swing_low.fillna(method="ffill")

df.to_csv("./swing_high,low.csv")

#チャート表示
swing_highlow = [mpf.make_addplot(df.swing_high,scatter=True,markersize=50,marker="_",color="red"),
               mpf.make_addplot(df.swing_low,scatter=True,markersize=50,marker="_",color="blue")
               ]
mpf.plot(df,addplot=swing_highlow,type='candle',style='yahoo')

この記事が気に入ったらサポートをしてみませんか?