FXプライムの「ぱっと見テクニカル」をPythonで実装する方法(初歩編)
こんばんは、新米データサイエンティスト(@algon_fx)です。最近は本業が忙しいのですが、仕事が楽しくてたまりません。
データ解析は仕事・趣味を含めてやりますが、それ以外の仕事も「やりがい」のある仕事が多いです。業界の風潮としては、データ解析以外はやらん!という方が多いのですが・・私はデータ解析以外も楽しんで出来るタイプのようです。
さて、突然ですが質問です。FXプライムという業者が提供している「ぱっと見テクニカル」をお使いの方はいらっしゃいますでしょうか?
ぱっと見テクニカルとは、FXプライムが独自で開発したトレードツールです。未来の値動きを1クリックでかんたん予想でき、特に初心者の方に人気があるようです。
このツール、とても面白いです!!テクニカル分析手法としてシンプルかつ、とても強力だと思います!
ってことで、今日はFXプライムの「ぱっと見テクニカル」改め、新米サイエンティストの「なんちゃってテクニカル」をPythonで作る流れをまとめます!
なお、今回は「初級編」ですので作り込みは行いません。ぱっと見テクニカルの考え方と、Pythonを使って実装を行う方法です。実践のFXトレードで使える代物ではありませんのでご了承ください。(ただし、作り込めばかなり便利になります!!)
ぱっと見テクニカルとは?
FXプライムが独自で開発したトレーディングサポートツールです。このツール、何がすごいかと言うと、テクニカル分析の知識が一切なくても、ある程度の将来の値動きが予測できてしまうのです!
では、どのような仕組みなのでしょうか。実は非常に単純です。ぱっと見テクニカルは過去の為替レートの値動きをデータとして持っています。
それらの過去のレートの動きの中から、現在の値動きと類似した動きを抽出して「将来の値動き」の参考として出力してくれます。言葉でも説明しても解りづらいかと思うので、下記の図をみてください。
上のローソク足チャートが現在のものです。対して下のチャートは過去のレートのものです。ぱっと見テクニカルは現在の値動きを読み取り、過去に類似した値動きを表示してくるのです。
赤矢印に注目ください。ここが現在の為替レートです。この先、レートが上がるのか下がるのか解りません。しかし、下の過去レートのチャートを見ると上がっているのが解ります。このように、今のチャートパターンを過去のチャートパターンと照らし合わせることで、近い将来の値動きの参考にするわけです。(好きです、この手法!)
青矢印に注目すると「一致率」とあります。これも一つの参考指標です。今と過去のチャートパターンの一致率を見ることで、本当に過去のパターン通りに行くかどうかを判断できるわけです。
FX初心者のみならず、チャートパターンをこのように分析してトレードの参考にするのは上級者にも使える考えだと私は思います。より詳しくはこちらのFXプライム公式ページをご覧ください。
当然、このぱっと見テクニカルを開発するとなると、途方も無い労力が必要です。ですので、今回はこの現在と過去のチャートパターンを抽出すると言う考えをPythonを使って実装してみましょう!
STEP1 実行環境とデータ
毎回の流れですが、今回もGoogle Colabを使う前提で本記事は進めます。
Google Colabを初めて使う方は「知らないと損をするGoogle Colabの隠し技と基本操作」の記事をご参照ください。ブラウザのみで5分もあれば機械学習の実行環境が整います。またXGBoostも事前にインストールされていますので、環境構築も不要です。
使う為替レートはドル円の10分足を使います。下記のリンクからCSVファイルのダウンロード可能です。こちらは私がOANDA FX APIから作成したデータです。
【使うCSVファイル】
usd_10min_api.csv
これで準備完了です!次のステップへ行きましょう。
STEP2 データとライブラリの読み込み
では、サクサクと下準備を進めて行きましょう。今回使うライブラリは下記の通りです。Google Colabでは事前にインストールされているものなので、追加でのインストールは不要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# ライブラリのインポート import pandas as pd import numpy as np # ローソク足描写 import matplotlib.pyplot as plt import matplotlib.finance as mpf from matplotlib.finance import candlestick2_ohlc from matplotlib import ticker import matplotlib.dates as mdates %matplotlib inline |
ローソク足チャートを使いますので、matplotlibの関連モジュールもインポートしています。
では、続いて先ほどのドル円10分足のデータをPandasのデータフレームとして読み込みましょう。
1 2 3 4 5 6 7 8 9 |
# データの読み込み masta = pd.read_csv("../../algoFX/tensorFlow/usd_10min_api.csv") df = masta.copy() chart = masta.copy() del df['Unnamed: 0'] del df['volume'] df.head() |
1 2 3 4 5 6 7 8 9 |
-- 出力 time close open high low 0 2018/03/01 15:40:00 106.792 106.817 106.817 106.777 1 2018/03/01 15:50:00 106.766 106.796 106.796 106.738 2 2018/03/01 16:00:00 106.774 106.769 106.822 106.762 3 2018/03/01 16:10:00 106.815 106.777 106.828 106.765 4 2018/03/01 16:20:00 106.844 106.813 106.864 106.809 |
ご覧通りドル円の終値(close)、始値(open)、高値(high)、安値(low)が10分ごとに格納されています。FXの過去データを自分で取得してみたい方は、「Pythonを使ったOANDA API v1で知っておきたい10の基本操作」に手順をまとめています。
では、こちらのデータからMatplotlibを使ってローソク足を描いてみましょう!データが膨大ですので、450行〜650行の2000分間に絞って書き出します。
1 2 3 4 5 6 7 |
# ローソク足表示 fig = plt.figure(figsize=(18, 9)) ax = plt.subplot(1, 1, 1) candle_temp = df[450:650] candlestick2_ohlc(ax, candle_temp["open"], candle_temp["high"], candle_temp["low"], candle_temp["close"], width=0.9, colorup="r", colordown="b") |
為替データからローソク足の描写ですがmatplotlibのcnadlestick2_ohlcを使うと非常に便利です。最後にカラム名を短くしておきましょう。
1 2 3 4 5 |
# カラム名を短く変更 df.columns = ['t', 'c', 'o', 'h', 'l'] df.head() |
1 2 3 4 5 6 7 8 9 |
-- 出力 t c o h l 0 2018/03/01 15:40:00 106.792 106.817 106.817 106.777 1 2018/03/01 15:50:00 106.766 106.796 106.796 106.738 2 2018/03/01 16:00:00 106.774 106.769 106.822 106.762 3 2018/03/01 16:10:00 106.815 106.777 106.828 106.765 4 2018/03/01 16:20:00 106.844 106.813 106.864 106.809 |
大丈夫そうですね。では次のステップに移りましょう。
STEP3 現在から過去50分のレートを比較
先ほども説明をしましたが「ぱっと見テクニカル」は現在のチャートパターンと過去のパターンをマッチングする手法です。FXプライムが提供している本家は10分足〜月足まで選択が可能かつ、参照する過去レートも幅が広いです。(本当に便利なツールので是非使ってみてください → ぱっと見テクニカル本家)
さて、本家のように作り込むのは後にするとして、今回はそれっぽいものを実装してみましょう。こっちの「なんちゃってテクニカル」は現在から50分前までの10分足の動きを参考にして、過去の同期間で類似したチャートパターンを抽出します。
まずは、OHCL(終値・始値・高値・安値)を10〜50分までずらしてあげましょう。なお、今回はあえてループ処理は書いていません。後ほど皆さんがカスタムしやすいにです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 終値・始値・高値・安値を10〜50分ずらす df['c1'] = df['c'].shift(1) df['c2'] = df['c'].shift(2) df['c3'] = df['c'].shift(3) df['c4'] = df['c'].shift(4) df['c5'] = df['c'].shift(5) df['o1'] = df['o'].shift(1) df['o2'] = df['o'].shift(2) df['o3'] = df['o'].shift(3) df['o4'] = df['o'].shift(4) df['o5'] = df['o'].shift(5) df['h1'] = df['h'].shift(1) df['h2'] = df['h'].shift(2) df['h3'] = df['h'].shift(3) df['h4'] = df['h'].shift(4) df['h5'] = df['h'].shift(5) df['l1'] = df['l'].shift(1) df['l2'] = df['l'].shift(2) df['l3'] = df['l'].shift(3) df['l4'] = df['l'].shift(4) df['l5'] = df['l'].shift(5) |
コードが非常に醜いですが・・・今回ばかりは我慢ください(笑)。では、それぞれのカラムを並び替えて、さらにNaNを含む最初の5行をデータから落としてあげましょう。
1 2 3 4 5 6 7 8 9 10 11 |
df = df[[ 't', 'c', 'c1', 'c2', 'c3', 'c4', 'c5', 'o1', 'o2', 'o3', 'o4', 'o5', 'h1', 'h2', 'h3', 'h4', 'h5', 'l1', 'l2', 'l3', 'l4', 'l5' ]] df2 = df[5:] df2.head() |
1 2 3 4 5 6 7 8 9 10 |
-- 出力 t c c1 c2 c3 c4 c5 o1 o2 o3 ... h1 h2 h3 h4 h5 l1 l2 l3 l4 l5 5 2018/03/01 16:30:00 106.824 106.844 106.815 106.774 106.766 106.792 106.813 106.777 106.769 ... 106.864 106.828 106.822 106.796 106.817 106.809 106.765 106.762 106.738 106.777 6 2018/03/01 16:40:00 106.779 106.824 106.844 106.815 106.774 106.766 106.847 106.813 106.777 ... 106.871 106.864 106.828 106.822 106.796 106.807 106.809 106.765 106.762 106.738 7 2018/03/01 16:50:00 106.809 106.779 106.824 106.844 106.815 106.774 106.826 106.847 106.813 ... 106.829 106.871 106.864 106.828 106.822 106.775 106.807 106.809 106.765 106.762 8 2018/03/01 17:00:00 106.848 106.809 106.779 106.824 106.844 106.815 106.781 106.826 106.847 ... 106.843 106.829 106.871 106.864 106.828 106.781 106.775 106.807 106.809 106.765 9 2018/03/01 17:10:00 106.889 106.848 106.809 106.779 106.824 106.844 106.806 106.781 106.826 ... 106.905 106.843 106.829 106.871 106.864 106.792 106.781 106.775 106.807 106.809 5 rows × 22 columns |
大丈夫そうですね!次の処理に移ります。
次は現在の終値を基準にそれ以外のレートを正規化してあげましょう。なぜそんな面倒な処理が必要かというと、単純にローソク足のパターンを読み取りたいからです。
つまり、そのままの為替レートのデータを使ってしまうと、仮に140円から138円に下がって142円に上がったというパターンを探したいときに、同じレート(140→138→142)しか見つけられないからです。
今の終値を基準に正規化することで、140→ -2 → +2というデータになります。ですのえ、仮に今の終値が138円だっとしても、138→ -2 → +2という値動きパターンを検出できるからです。
では処理を加えてあげましょう。
1 2 3 4 5 6 7 |
# 現在の終値を基準に正規化 df2 = df2.reset_index(drop=True) for column in df2.columns[2:]: df2[column] = df2['c'] - df2[column] df2.head(6) |
1 2 3 4 5 6 7 8 9 10 |
--出力 t c c1 c2 c3 c4 c5 o o1 o2 ... h2 h3 h4 h5 l l1 l2 l3 l4 l5 0 2018/03/01 16:30:00 106.824 -0.020 0.009 0.050 0.058 0.032 -0.023 0.011 0.047 ... -0.004 0.002 0.028 0.007 0.017 0.015 0.059 0.062 0.086 0.047 1 2018/03/01 16:40:00 106.779 -0.045 -0.065 -0.036 0.005 0.013 -0.047 -0.068 -0.034 ... -0.085 -0.049 -0.043 -0.017 0.004 -0.028 -0.030 0.014 0.017 0.041 2 2018/03/01 16:50:00 106.809 0.030 -0.015 -0.035 -0.006 0.035 0.028 -0.017 -0.038 ... -0.062 -0.055 -0.019 -0.013 0.028 0.034 0.002 0.000 0.044 0.047 3 2018/03/01 17:00:00 106.848 0.039 0.069 0.024 0.004 0.033 0.042 0.067 0.022 ... 0.019 -0.023 -0.016 0.020 0.056 0.067 0.073 0.041 0.039 0.083 4 2018/03/01 17:10:00 106.889 0.041 0.080 0.110 0.065 0.045 0.043 0.083 0.108 ... 0.046 0.060 0.018 0.025 0.058 0.097 0.108 0.114 0.082 0.080 5 2018/03/01 17:20:00 106.803 -0.086 -0.045 -0.006 0.024 -0.021 -0.084 -0.043 -0.003 ... -0.102 -0.040 -0.026 -0.068 0.005 -0.028 0.011 0.022 0.028 -0.004 |
ご覧のとり今の終値(c)を基準に全ての指標がプラス・マイナスの値動きとなりました。
STEP4 ローソク足パターンを検出
ではいよいよ「ぱっと見テクニカル」・・ではなくて「なんちゃってテクニカル」の最も重要な部分となる現在と過去のローソク足パターンを検出してあげましょう。
しつこいようですが、今回はイテレーションで処理を行いません。とっても、とっても、醜いコードですが・・後ほどカスタマイズしやすいようにそのままにしています。
まずはパターンの検出する閾値を決めてあげます。これも各自、色々な閾値を検証してみください。今回は最大1.3、最低0.7という閾値を設定してあげました。
1 2 3 4 5 |
-- パターン検出の閾値設定 high = 1.3 low = 0.7 |
では、実際にパターン検出できるかやってみましょう。現在のレートとして扱いたいインデックスをsearchに指定します。下記のコードでは4600と指定しています。searchの値は現在の終値を意味します。これも各自で色々と確認してみてください。
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 36 37 38 39 40 41 42 43 44 45 46 |
# 現在の終値のインデックスを設定 search = 4600 # 現在の終値を基準に類似したローソク足パターンを検索 cond1 = (df2.iloc[search]['c1'] / df2['c1']) <=high cond2 = (df2.iloc[search]['c1'] / df2['c1']) >=low cond3 = (df2.iloc[search]['c2'] / df2['c2']) <=high cond4 = (df2.iloc[search]['c2'] / df2['c2']) >=low cond5 = (df2.iloc[search]['c3'] / df2['c3']) <=high cond6 = (df2.iloc[search]['c3'] / df2['c3']) >=low cond7 = (df2.iloc[search]['c4'] / df2['c4']) <=high cond8 = (df2.iloc[search]['c4'] / df2['c4']) >=low cond9 = (df2.iloc[search]['c5'] / df2['c5']) <=high cond10 = (df2.iloc[search]['c5'] / df2['c5']) >=low cond11 = (df2.iloc[search]['o1'] / df2['o1']) <=high cond12 = (df2.iloc[search]['o1'] / df2['o1']) >=low cond13 = (df2.iloc[search]['o2'] / df2['o2']) <=high cond14 = (df2.iloc[search]['o2'] / df2['o2']) >=low cond15 = (df2.iloc[search]['o3'] / df2['o3']) <=high cond16 = (df2.iloc[search]['o3'] / df2['o3']) >=low cond17 = (df2.iloc[search]['o4'] / df2['o4']) <=high cond18 = (df2.iloc[search]['o4'] / df2['o4']) >=low cond19 = (df2.iloc[search]['o5'] / df2['o5']) <=high cond20 = (df2.iloc[search]['o5'] / df2['o5']) >=low cond21 = (df2.iloc[search]['h1'] / df2['h1']) <=high cond22 = (df2.iloc[search]['h1'] / df2['h1']) >=low cond23 = (df2.iloc[search]['h2'] / df2['h2']) <=high cond24 = (df2.iloc[search]['h2'] / df2['h2']) >=low cond25 = (df2.iloc[search]['h3'] / df2['h3']) <=high cond26 = (df2.iloc[search]['h3'] / df2['h3']) >=low cond27 = (df2.iloc[search]['h4'] / df2['h4']) <=high cond28 = (df2.iloc[search]['h4'] / df2['h4']) >=low cond29 = (df2.iloc[search]['h5'] / df2['h5']) <=high cond30 = (df2.iloc[search]['h5'] / df2['h5']) >=low cond31 = (df2.iloc[search]['l1'] / df2['l1']) <=high cond32 = (df2.iloc[search]['l1'] / df2['l1']) >=low cond33 = (df2.iloc[search]['l2'] / df2['l2']) <=high cond34 = (df2.iloc[search]['l2'] / df2['l2']) >=low cond35 = (df2.iloc[search]['l3'] / df2['l3']) <=high cond36 = (df2.iloc[search]['l3'] / df2['l3']) >=low cond37 = (df2.iloc[search]['l4'] / df2['l4']) <=high cond38 = (df2.iloc[search]['l4'] / df2['l4']) >=low cond39 = (df2.iloc[search]['l5'] / df2['l5']) <=high cond40 = (df2.iloc[search]['l5'] / df2['l5']) >=low |
上記の処理もFOR文で綺麗にまとめることが可能ですが、今回はあえてそのままにしています。細かい調整などを加えて検証してみたい方は是非挑戦してみてください。
では、現在の終値と類似したローソク足パターンが抽出できたかどうか確認してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 類似したローソク足パターンを確認 mask = ( cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7 & cond8 & cond9 & cond10 & cond11 & cond12 & cond13 & cond14 & cond15 & cond16 & cond17 & cond18 & cond19 & cond20 & cond21 & cond22 & cond23 & cond24 & cond25 & cond26 & cond27 & cond28 & cond29 & cond30 & cond31 & cond32 & cond33 & cond34 & cond35 & cond36 & cond37 & cond38 & cond39 & cond40 ) df2[mask] |
1 2 3 4 5 6 7 8 |
--出力 t c c1 c2 c3 c4 c5 o o1 o2 ... h2 h3 h4 h5 l l1 l2 l3 l4 l5 26 2018/03/01 20:50:00 106.685 -0.026 -0.064 -0.067 -0.094 -0.101 -0.028 -0.062 -0.070 ... -0.082 -0.107 -0.114 -0.117 0.016 -0.019 -0.039 -0.063 -0.091 -0.085 4600 2018/04/16 14:30:00 107.166 -0.024 -0.050 -0.084 -0.091 -0.082 -0.021 -0.048 -0.082 ... -0.082 -0.095 -0.096 -0.093 0.028 -0.024 -0.047 -0.064 -0.077 -0.068 8309 2018/05/23 08:50:00 110.745 -0.023 -0.063 -0.091 -0.090 -0.087 -0.022 -0.060 -0.089 ... -0.094 -0.113 -0.094 -0.111 0.015 -0.019 -0.055 -0.091 -0.061 -0.078 15123 2018/07/30 16:40:00 111.037 -0.033 -0.062 -0.090 -0.089 -0.091 -0.035 -0.060 -0.088 ... -0.088 -0.092 -0.117 -0.108 0.007 -0.023 -0.053 -0.053 -0.074 -0.055 |
おお、できていますね!先ほど現在の終値の設定として4600行目を指定しました。ご覧の通り26、8309、15123行目のローソク足の動きが類似していると出ています。
本当に類似しているのか・・ローソク足に落として確認してみましょう。
1 2 3 4 5 6 7 |
# 現在(4600行)から20本のローソク足 fig = plt.figure(figsize=(18, 5)) ax = plt.subplot(1, 1, 1) candle_temp = chart[4600:4620] candlestick2_ohlc(ax, candle_temp["open"], candle_temp["high"], candle_temp["low"], candle_temp["close"], width=0.9, colorup="r", colordown="b") |
上のローソク足チャートの一番左が4600行目( 2018/04/16 14:30:00)です。今回書いたコードでは、一番左の足から5本目までのデータを基に類似したパターンを抽出するものです。では本当にパターン抽出出来ているのか確認します。(ドキドキ)
1 2 3 4 5 6 7 |
# 類似したとされるローソク足パターン fig = plt.figure(figsize=(18, 5)) ax = plt.subplot(1, 1, 1) candle_near = chart[8309:8329] candlestick2_ohlc(ax, candle_near["open"], candle_near["high"], candle_near["low"], candle_near["close"], width=0.9, colorup="r", colordown="b") |
う〜〜ん、それとなーく類似したパータンと言えないこともありませんね(笑)。最初の3本(左側)はもつれ合い、その後に下がっているという部分では大枠似ているとも見えます。
6本目からは全く関係のない値動きですが、ご覧の通り上のチャートも下のチャートも下がって上がるという類似したパターンが出ていますね!これの通りトレードしたら、少しは儲けていたかもしれません。
まとめ
今回はFXプライムの「ぱっと見テクニカル」のトレード分析手法の考えを基にPythonで類似したローソク足パターンの抽出を行なってみました。
個人的には、本当にこのツールはシンプルかつ強力だと思っています。下手にMACDやらRSIやら、テクニカル指標を使うよりよっぽど上手くトレード出来るのでは?と思っています。
今回は少し雑、いや初歩的な流れでしたが、より作り込むことでとても強力なツールになります。私のFX機械学習トレードにも「ぱっと見テクニカル」の考えを基にしたモデルを活用しています。
FXで機械学習を使うための初心者向けチュートリアルもまとめています!Pythonの初歩的な知識があれば実装が可能ですので、興味がある方は是非ご覧ください!
決定木を使ってFX予想をやってみる
FXトレードでロジスティック回帰を独自テクニカル指標として活用する方法
ブログ読んでいただきありがとうございます!Twitterでも色々と発信しているので、是非フォローお願いします!
ディスカッション
コメント一覧
まだ、コメントがありません