richmanbtcさんのForce Entry Priceがよく分からなかったので、自分なりにまとめてみた
botter必読書
- 日給300万円のSS級トレーダーが明かすbotterのリアル
ぼんやりと仮想通貨のトレードで儲けたいと考えていた僕を、
botterの道へ明確に導くキッカケになった本。
botterになろうと考えている人は、botterのメリット、
狙い目などの概略的な部分が知れて良いと思います。
- Kaggleで勝つ技術
僕はデータの前処理や学習モデルを作っているとき、「???」となることがあった。
そのとき読んでクリアできた。
文系で機械学習未経験の僕が、richmanBTCさんのチュートリアルをやってbotterになるまでの流れ
最初に
書いてあることが間違っている可能性があるので、注意して読んでいただけると助かります。
Force Entry Priceについて
Force Entry Priceは買うと決めてから約定するまで指値で追いかけた場合に、実際に約定する価格です。独自用語です。指値の出し方は任意です。entryと名前がついていますがexitも同じ計算なので区別はないです
つまりどういうことか
指値注文をして、エントリーの約定ができる価格を調べている。
ちなみに約定できた場合、約定するまでかかった時間を調べるためにForce Entry Timeも算出している。
約定 と 決済 の違いを知っておかないと理解が難しい気がする
約定を決済と同じ意味合いで使っている人が多く、勘違いしやすい気がする。
-
約定 注文が成立すること。つまりエントリー時の注文も約定、利確損切りといった決済(エグジット)も約定。
-
決済(エグジット) 利確や損切りの際の約定のこと。
算出する目的
機械学習の正解データを作るためのパーツ
約定できなかったら、そもそもエントリーできないので勝敗を求めることが出来ない。
正解データの作り方 (この記事では②まで扱う)
- 毎時刻、あるルールで計算された指値距離(limit_price_dist)に基づいて、買い指値を出す
- 買い指値が約定しなかった場合のyはゼロとする
- 買い指値が約定した場合、一定時間(horizon)だけ待ってから、Force Entry Priceの執行方法でエグジットする
- エグジット価格 / エントリー価格 - 1 - 2 * feeをyとする
約定(エントリー)できたら、次の工程
使い方
各足ごとにエントリーできるか探っていくイメージ
エントリーできた場合、
def calc_force_entry_price(entry_price=None, lo=None, pips=None):
y = entry_price.copy()
y[:] = np.nan
force_entry_time = entry_price.copy()
force_entry_time[:] = np.nan
for i in range(entry_price.size):
for j in range(i + 1, entry_price.size):
if round(lo[j] / pips) < round(entry_price[j - 1] / pips):
y[i] = entry_price[j - 1]
force_entry_time[i] = j - i
break
return y, force_entry_time
この関数の引数にentry_priceを入れていく。
entry_priceに入れる値を一貫するために、ATRという指標を使って、
買い指値なら['buy_price'] 、売り指値なら['sell_price']を作る。
ATRは、ボラティリティ(値幅)を測定するために使うインジケーター。
算出方法は以下三つの式で計算して、一番大きいものをトゥルーレンジ(本当の値幅)として扱う。
①時間足の高値 - 時間足の安値 =(例 10pips)
②時間足の安値 - 時間足の終値 =(例 15pips)
③時間足の高値 - 時間足の安値 =(例 8pips)
こうすることによって、一番値幅が大きいものはなにか調べることができる。
ちなみに、上の場合、②がトゥルーレンジとして利用される。
ちなみに、ATRをインジケーターとして使う場合は、これを各足で計算して、移動平均を求める。
一般的に、日足で使われる場合は14日間の移動平均値が使われる。
なお、今回はエントリーの算出に使うだけなので、移動平均は求めない。
もし一貫していないと、データの整合性がなくなる。
これはサンプルなので、独自の指標を作ってエントリー判定しても良いとある。
pips = 1
limit_price_dist = df['ATR'] * 0.5 #ATRはTa-libを使って定義済み
limit_price_dist = np.maximum(1, (limit_price_dist / pips).round().fillna(1)) * pips
# 終値から両側にlimit_price_distだけ離れたところに、買い指値と売り指値を出します
# これがエントリーの一貫した価格として使われる。
df['buy_price'] = df['cl'] - limit_price_dist
df['sell_price'] = df['cl'] + limit_price_dist
買い指値 : 終値 - ATR
売り指値 : 終値 + ATR を一貫したエントリー価格として使う。
# 指値が約定したかどうか (0, 1)
df['buy_executed'] = ((df['buy_price'] / pips).round() > (df['lo'].shift(-1) / pips).round()).astype('float64')
エントリーできたかどうかを0,1の形にする。
ここでは指値が一本後に約定したかどうかを判定している。
約定したらTrueなので1,できなかったらFalseなので0になる。
※実際のコードではこのコードは以下のコードの下にあります。
# Force Entry Priceの計算
df['buy_fep'], df['buy_fet'] = calc_force_entry_price(
entry_price=df['buy_price'].values,
lo=df['lo'].values,
pips=pips,
)
df['buy_fep'] にエントリーできた価格
df['buy_fet']にエントリーまでにかかった時間 が返ってくる。
sellの方もあるが、マイナスにしたらできるので割愛
出典
約定シミュレーション「https://note.com/btcml/n/n9f730e59848c」
約定と決済「https://rinofx.xbiz.jp/fx-yakujou-kessai/
richmanbtcさんのgithub「https://github.com/richmanbtc/mlbot_tutorial」
Discussion