FXでプライスアクションをPythonを使って抽出する方法
こんばんは、新米データサイエンティスト(@algon_fx)です。無事、海外でのお仕事も終わり日本に帰国しました。
さて本ブログでも複数回に渡ってローソク足パターン分析を行ってきました。私はFX機械学習トレードを行う上で、ローソク足分析はとても強い武器の一つだと考えています。
その1 – ローソク足のパターン分析をPythonを使ってやってみる(初歩編)
その2 – ローソク足分析手法「酒田五法」をPythonで実装する方法
その2では日本でも有名な酒田五法を、Pythonを使って過去レートから検出する流れをまとめました。酒田五法と並んで、特に海外で人気の高いローソク足分析手法に「プライスアクション」という分析方法があります。
今回はPythonを使って過去為替レートからプライスアクションを検出する方法をやってみましょう!
FXのプライスアクションとは?
ローソク足には「この形」が出現したら近い将来「相場が上がる(下がる)」と言ったように、過去の為替相場の経験を体系的に分析して作られた分析手法があります。
一まとめに言うと「ローソク足パターン分析」なのですが、より細かく分類をすると個別に手法名が付いてたりします。
江戸時代の日本の有名な日本人相場師が作ったものが「酒田五法」です。酒田五法は主に5つのパターンがあり、それらを使って相場の上げ下げを予測するものです。
酒田五法に類似して欧米でもローソク足パターン分析が盛んになりました。その結果として生まれたのが「プライスアクション」です。いわば酒田五法の欧米版とでも言うべきでしょうか。
つまり酒田五法もプライスアクションもローソク足の値段(つまりプライス)の動き(アクション)を分析して、為替レートの状況判断を行う手法です。
よくプライスアクションの説明として「酒田五法は日本人がメインだけど、プライスアクションは世界的に使われているから信頼できる」的な説明があります。
どんなデータを根拠にしているのか不明なのですが、私が参加している海外のFXコミュニティなどでは酒田五法もバリバリ使われています。昔はそうだったのかもしれませんが、今やインターネットで簡単に勉強できる時代です。プライスアクションの方が世界的に使われていると言うのは大きな誤解だと私は思います。
プライスアクションの種類
さてローソク足のパターンを分析したルールが「プライスアクション」ですが、いくつか種類があります。今回は全種類は紹介しませんが、プライスアクションの主な3つを紹介します。
まずは相場の転換/停滞を教えてくれるプライスアクション「ピンバー」です。下のようなローソク足が出現したら「ピンバー」です。
ご覧の通り「実態(ローソク足の胴体部分)」が極端に短く、「ひげ(線部分)」が上下のどちらかに極端に長いローソク足をさします。ピンバーがなんども出現する相場では、相場の転換や停滞を意味します。
同じく相場の転換を示唆するプライスアクションとして「スパイク」と言う種類もあります。下の図をみてください。
スパイクには「ハイ」と「ロー」の二種類があります。上の図の左側がスパイクハイのプライスアクションです。これは相場が上昇トレンド時に出現すると相場の転換(つまり下降トレンドへ)変わるシグナルとなります。
対して右側のスパイクローは逆の考えです。相場が下降トレンド時に出現すると上昇トレンドへ転換する可能性があることを意味しています。
上の二つは相場の転換を示唆するプライスアクションでしたが、当然トレンドの出現を示唆するプライスアクションもあります。その中の一つが「スラスト」です。私はプライスアクションの中でスラストを最も信用しています。
右側がスラストアップです。ロジックは非常に単純で現在のローソク足の終値が一つ前のローソク足の高値より高い場合は上昇トレンドの勢いが強いことを示します。対して左側のスラストダウンは逆の考えです。
上昇トレンドが強い傾向にあるとスラストアップが頻繁に出現します。また正攻法の使い方ではありませんが、安値圏でスラストアップが出現し始める=上昇トレンドへ転換したと言う見方も可能です。(逆も然りで高値圏でのスラストダウンは上昇から下降への転換サイン)
今回はPythonを使ってプライスアクションのスラストを過去為替レートから検出して確認してみましょう!
STEP1 データとライブラリの読み込み
では、早速、Jupyter Notebookを立ち上げてやってみましょう。すでにPython 3の環境構築を行っている方はご自身のPCから実行してみてください。
Python(または機械学習の基本ライブラリ)の環境構築がされていな方はGoogle Colaを使いましょう。ブラウザから実行可能です。5分程度で環境構築が整います。詳しくは「Google Colabの隠し技と基本操作」をご覧ください。
Jupyter Notebookが立ち上がったら、まずは必要なライブラリをインポートしましょう。特別なライブラリなどは必要ありません。機械学習の基本ライブラリ「numpy」「pandas」「matplotlib」で実装可能です。(google colabには全てデフォルトでインストール済みです)
1 2 3 4 5 6 7 8 9 |
# ライブラリのインポート import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib.finance as mpf from matplotlib.finance import candlestick2_ohlc %matplotlib inline |
続いて過去の為替データを読み込みます。過去為替データですがFX API経由で取得が可能です。FX APIの詳しい使い方は「OANDA FX APIの基本的な使い方」をご覧ください。今回は私がOANDA APIから取得したドル円1分足の過去データを使います。
下記のURLからCSVファイルをダウンロードしましょう。
これで準備完了です!次のステップへ移りましょう。
STEP2 データの読み込みと前処理
それではCSVファイルをPandasのデータフレーム形式で読み込みます。Google Colabを使っている方、CSVファイルをGoogle Colabへアップロードが必要ですのでご注意ください。
1 2 3 4 5 6 7 |
# CSVファイルの読み込み df = pd.read_csv("../../algoFX/priceaction/usd_1min_api.csv") # 最初の5行を表示 df.head() |
1 2 3 4 5 6 7 8 9 |
--出力 time close high low open 0 2018-09-14 09:00:00 112.050 112.060 112.037 112.037 1 2018-09-14 09:01:00 112.057 112.062 112.053 112.053 2 2018-09-14 09:02:00 112.057 112.062 112.056 112.059 3 2018-09-14 09:03:00 112.062 112.074 112.059 112.059 4 2018-09-14 09:04:00 112.065 112.075 112.065 112.065 |
ご覧の通り2018年9月14日の1分足データです。ドル円の終値、高値、安値、始値のデータが入っています。扱いやすいようにカラム名を短縮した名前に変更してあげましょう。
1 2 3 4 |
# カラム名を短縮名に変更 df.columns = ['t', 'c', 'h', 'l', 'o'] |
続いて単純移動平均(Simple Moving Average)の期間200を算出します。単純移動平均とは、期間内のプライスの単純な平均を意味します。(詳しくはPythonで単純移動平均を算出をご覧ください)
1 2 3 4 5 6 7 8 9 10 11 |
# SMA200を計算 df['sma200'] = df['c'].rolling(200).mean() # SMA200が算出不可な最初の199行をドロップ df = df[199:] df = df.reset_index(drop=True) # データの確認 df.head() |
1 2 3 4 5 6 7 8 9 |
--出力 t c h l o sma200 0 2018-09-14 12:23:00 111.901 111.901 111.877 111.877 111.977415 1 2018-09-14 12:24:00 111.899 111.901 111.892 111.899 111.976660 2 2018-09-14 12:25:00 111.884 111.898 111.884 111.896 111.975795 3 2018-09-14 12:26:00 111.882 111.888 111.882 111.886 111.974920 4 2018-09-14 12:27:00 111.877 111.879 111.870 111.879 111.973995 |
大丈夫そうですね。
今回はプライスアクション(中でもスラスト)を算出するのに、なぜSMA100を事前に計算したのでしょうか?答えは為替相場の「高値」「安値」を検出するためです。
為替レートから安値・高値の検出方法は多数あります。以前に当ブログで紹介した酒田五法の検出の時はテクニカル指標「ボリンジャーバンド」を使いました。
前回と同じ手法ではつまらないので、今回は高値・安値の検出方法として単純移動平均の期間100を利用します。単純移動平均とは決まった期間の平均値です。つまり100分の平均レートと比較して今のレートが大幅に下回る=安値圏、逆に大幅に上回る=高値圏という使い方をします。
最後に念のため1分足レートとSMA200をMatplotlibを使ってローソク足チャートに落としてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# ローソク足表示 fig = plt.figure(figsize=(18, 9)) ax = plt.subplot(1, 1, 1) candle_temp = df[2500:2600] candle_temp = candle_temp.reset_index() candlestick2_ohlc( ax, candle_temp["o"], candle_temp["h"], candle_temp["l"], candle_temp["c"], width=0.9, colorup="r", colordown="b" ) ax.plot(candle_temp['sma200']) |
大丈夫そうですね。チャートの下側にある青線がSMA200です。上記の期間ではSMA200に対してローソク足は大幅に上にあります=つまり比較的高値圏と言うのが分かります。
STEP3 スラストアップの検出
データの前準備も整いましたので、実際にプライスアクションの「スラストアップ」をデータから検出してみましょう。
スラストアップの検出条件ですが、今回は下記の3つを適用することとします。あくまで検出方法が主題ですので、この条件の細かい検証は本記事では行いません。
より強力なプライスアクションの検出を行い方はこの条件を色々と検証してみてください!(かなり細かく調整をするとFXトレードで強力な武器となります!私は本番トレードで愛用しています)
ルール1:sma200 – 2本前の終値 > 0.2
ルール2:1本前の終値 – 2本前の高値 > 0.0
ルール3:現在の終値 – 1本前の高値 > 0.0
それぞれ閾値を適当に設けています。検証してみたい方は、これらの閾値の調整を行ってみください。また、他のテクニカル指標と組み合わせてルールの追加をすることで、より強度な検出も可能です!
では上の通りの処理をPythonを使ってデータに加えましょう。まずはストラスアップ用にデータフレームを新しい変数にコピーします。
1 2 3 4 |
#データフレームをコピー thrust_up = df.copy() |
続いて終値(c)と高値(h)を2期間づつずらしましょう。Pandasのshift()メソッドを使うと簡単に行うことが可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 終値と高値の期間をずらす thrust_up['c1'] = thrust_up['c'].shift(1) thrust_up['c2'] = thrust_up['c'].shift(2) thrust_up['h1'] = thrust_up['h'].shift(1) thrust_up['h2'] = thrust_up['h'].shift(2) # データ取れない最初の2行を削除 thrust_up = thrust_up[2:] # データ確認 thrust_up.head() |
1 2 3 4 5 6 7 8 9 |
--出力 t c h l o sma200 c1 c2 h1 h2 2 2018-09-14 12:25:00 111.884 111.898 111.884 111.896 111.975795 111.899 111.901 111.901 111.901 3 2018-09-14 12:26:00 111.882 111.888 111.882 111.886 111.974920 111.884 111.899 111.898 111.901 4 2018-09-14 12:27:00 111.877 111.879 111.870 111.879 111.973995 111.882 111.884 111.888 111.898 5 2018-09-14 12:28:00 111.872 111.878 111.872 111.875 111.973030 111.877 111.882 111.879 111.888 6 2018-09-14 12:29:00 111.871 111.871 111.868 111.870 111.972050 111.872 111.877 111.878 111.879 |
カラムの「c」が現在の終値です。対して「c1」が1分前の終値、「c2」が2分前の終値です。高値(h)も同様に1分前、2分まえとずらしています。
スラストアップの検出ルールその1を実装しましょう。ルール1はSMA200から2本前の終値を差分が0.2より大きいか否かです。つまりSMA200との乖離が大きい=安値圏と捉えることが可能です。
1 2 3 4 5 6 |
# ルール1 thrust_up['rule1'] = 0 rule_1_mask = (thrust_up['sma200'] - thrust_up['c2']) > 0.2 thrust_up['rule1'][rule_1_mask] = 1 |
続いてルール2とルール3の処理を行いましょう。ルール2、3は単純にスラストアップのローソク足の形をデータから検出するルールです。ルールの条件を読めば、自ずとどのようなローソク足が検出可能かわかるかと思います。
1 2 3 4 5 6 |
# ルール2 thrust_up['rule2'] = 0 rule_2_mask = (thrust_up['c1'] - thrust_up['h2']) > 0.0 thrust_up['rule2'][rule_2_mask] = 1 |
1 2 3 4 5 6 |
# ルール3 thrust_up['rule3'] = 0 rule_3_mask = (thrust_up['c'] - thrust_up['h1']) > 0.0 thrust_up['rule3'][rule_3_mask] = 1 |
これで3つのルール全てのフラグがデータフレームに入りました。それでは全ルールのフラグが1のレコードを探してあげましょう。3つのルールが全て適合=安値圏でスラストアップが出現していることを表します。
1 2 3 4 5 6 7 |
# 条件に合っているところがあるか探す rule1 = thrust_up['rule1'] == 1.0 rule2 = thrust_up['rule2'] == 1.0 rule3 = thrust_up['rule3'] == 1.0 thrust_up[ rule1 & rule2 & rule3].head() |
1 2 3 4 5 6 7 8 9 |
--出力 t c h l o sma200 c1 c2 h1 h2 rule1 rule2 rule3 11442 2018-09-27 05:15:00 112.683 112.683 112.678 112.678 112.891075 112.675 112.656 112.679 112.671 1 1 1 11452 2018-09-27 05:26:00 112.709 112.709 112.693 112.693 112.878250 112.690 112.677 112.690 112.678 1 1 1 19071 2018-10-04 21:50:00 114.059 114.059 114.049 114.052 114.261925 114.055 114.051 114.055 114.052 1 1 1 19072 2018-10-04 21:51:00 114.071 114.076 114.061 114.062 114.260765 114.059 114.055 114.059 114.055 1 1 1 19168 2018-10-04 23:27:00 113.730 113.732 113.706 113.714 114.116080 113.712 113.647 113.723 113.693 1 1 1 |
いくつか検出されていますね!では上記の該当箇所の一つをピックアップしてローソク足チャートで確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# ローソク足表示 その1 fig = plt.figure(figsize=(18, 9)) ax = plt.subplot(1, 1, 1) candle_temp = df[11422:11462] candle_temp = candle_temp.reset_index() candlestick2_ohlc( ax, candle_temp["o"], candle_temp["h"], candle_temp["l"], candle_temp["c"], width=0.9, colorup="r", colordown="b" ) ax.plot(candle_temp['sma200']) |
おおお!思った以上にスラストアップを検出した最初の場所はうまくはまっていますね!左側の黒矢印が指す2つのローソク足に注目してください。しっかりスラストアップのパターンが出現しています。また、安値圏(SMA200から大幅に下回っている)場所なので、その後はしっかり上昇トレンドの相場となっています。
もう一つ確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# ローソク足表示 その2 fig = plt.figure(figsize=(18, 9)) ax = plt.subplot(1, 1, 1) candle_temp = df[19051:19091] candle_temp = candle_temp.reset_index() candlestick2_ohlc( ax, candle_temp["o"], candle_temp["h"], candle_temp["l"], candle_temp["c"], width=0.9, colorup="r", colordown="b" ) ax.plot(candle_temp['sma200']) |
同様にスラストアップが出現、上昇トレンド出現となっていますね!
STEP4 スラストダウンを検出
続いてスラストダウンも検出してみましょう。考え方としてはスラストアップの逆です。今回は詳細のコード説明は行いません。一気に検出の処理を実行しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# データをコピー thrust_down = df.copy() # 終値と安値を2期間づらす thrust_down['c1'] = thrust_down['c'].shift(1) thrust_down['c2'] = thrust_down['c'].shift(2) thrust_down['l1'] = thrust_down['l'].shift(1) thrust_down['l2'] = thrust_down['l'].shift(2) # 不要なレコードを削除 thrust_down = thrust_down[2:] # ルール1 thrust_down['rule1'] = 0 rule_1_mask = (thrust_down['sma200'] - thrust_down['c2']) < -0.2 thrust_down['rule1'][rule_1_mask] = 1 # ルール2 thrust_down['rule2'] = 0 rule_2_mask = (thrust_down['c1'] - thrust_down['l2']) < -0.005 thrust_down['rule2'][rule_2_mask] = 1 # ツール3 thrust_down['rule3'] = 0 rule_3_mask = (thrust_down['c'] - thrust_down['l1']) < -0.005 thrust_down['rule3'][rule_3_mask] = 1 # スラストダウンの出現箇所を確認 # 条件に合っているところがあるか探す rule1 = thrust_down['rule1'] == 1.0 rule2 = thrust_down['rule2'] == 1.0 rule3 = thrust_down['rule3'] == 1.0 thrust_down[ rule1 & rule2 & rule3].head() |
1 2 3 4 5 6 7 8 9 |
--出力 t c h l o sma200 c1 c2 l1 l2 rule1 rule2 rule3 2788 2018-09-18 15:53:00 112.229 112.252 112.229 112.252 112.029030 112.254 112.279 112.252 112.267 1 1 1 6031 2018-09-21 00:48:00 112.509 112.513 112.509 112.512 112.260875 112.515 112.527 112.515 112.524 1 1 1 6032 2018-09-21 00:49:00 112.491 112.506 112.491 112.506 112.262790 112.509 112.515 112.509 112.515 1 1 1 6074 2018-09-21 01:31:00 112.551 112.562 112.551 112.562 112.355590 112.565 112.576 112.565 112.571 1 1 1 6075 2018-09-21 01:32:00 112.542 112.550 112.542 112.550 112.357485 112.551 112.565 112.551 112.565 1 1 1 |
今回は一気に処理を書いてしまいましたが、詳細はコードでご確認ください。気づいたかともいるかと思いますが、スラストアップとは異なる閾値を設定しています。
では、スラストダウンもローソク足で確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# ローソク足表示 その1 fig = plt.figure(figsize=(18, 9)) ax = plt.subplot(1, 1, 1) candle_temp = df[2768:2808] candle_temp = candle_temp.reset_index() candlestick2_ohlc( ax, candle_temp["o"], candle_temp["h"], candle_temp["l"], candle_temp["c"], width=0.9, colorup="r", colordown="b" ) ax.plot(candle_temp['sma200']) |
これまた綺麗なスラストダウンの検出ができました!プライスアクションのシグナル通り、トレンドが下降トレンドへしっかり移行しているのが確認できます。
まとめと課題
如何でしたでしょうか?今回はローソク足パターン分析の「プライスアクション」をPythonを使って過去為替レートのデータから検出する流れを行いました。
酒田五法は日本生まれ、プライスアクションは欧米生まれのローソク足分析パターンです。どちらが強い・弱いはありません。
ローソク足分析で重要なのはその時々の相場観、さらに別のテクニカル指標と巧みに組み合わせることにより威力を発揮します!
他の機械学習手法でのFX予想チュートリアルもまとめています。興味がある方は、ぜひこちらのチュートリアルも挑戦してみてください!
・LSTMでFX予想する方法
・ディープラーニングでFX予想する方法
・ロジスティック回帰でFX予想する方法
ブログ読んでいただきありがとうございます!Twitterでも色々と発信しているので、是非フォローお願いします!
ディスカッション
コメント一覧
アルゴンさんプライスアクションの記事みました。素晴らしいですね❗