Pythonを使ってFxの自動売買システムを作ろう!
目次
システムトレード:ボリンジャーバンドを導入したモデル
前回記事(OANDA APIを使って自動売買プログラムを作ろう!)では、移動平均線を用いてポジションを持って為替取引を行うモデルをご紹介しました。
それでは、今回は、ボリンジャーバンドを使って、2σ線に触れたら逆張りでポジションを持ち平均線に触れたらポジションを手放すモデルを作りましょう。
\(\)ボリンジャーバンドって何?
まず、テクニカル指標の一つであるボリンジャーバンドの紹介をします。
ボリンジャーバンドとは、指定した期間において、現在価格の存在範囲を統計的に推定するテクニカル指標です。
具体的には、表示しているローソク足に関して、大体のFx会社が提供しているテクニカル指標のボリンジャーバンドは、デフォルトでローソク足20本分に設定してあるので、
それを基準にして話を進めて行きます。
このローソク足20本分にはそれぞれ、始値・終値・最安値・最高値の情報が入っていますが、通常ボリンジャーは終値のみの値を使います。
また、便宜上、現在値、一本前のローソク足の終値、n本前のローソク足の終値をそれぞれ
$$f_0, f_1, f_n$$
と表すことにします。
ボリンジャーバンドは、合計5本(または7本)の線で構成されています。
5本線の内訳はそれぞれ
・平均線
$$MEAN = \frac{1}{20}\sum^{19}_{n=0}f_{n}$$
・±1σ線
$$\pm1\sigma = MEAN \pm \sqrt{\frac{1}{20}\sum^{19}_{n=0}\left(f_{n}-MEAN\right)^2}$$
・±2σ線
$$\pm2\sigma = MEAN \pm 2\times\sqrt{\frac{1}{20}\sum^{19}_{n=0}\left(f_{n}-MEAN\right)^2}$$
となっています。
σ線の計算式での右辺第2項は、標準偏差と呼ばれていて、データのバラツキ度合いを表しています。
つまり、標準偏差の値が大きければ、値が平均値から大きくバラついていて、小さければバラツキ度合いは小さいということです。
また、投資家の嗜好によっては、±3σ線も考慮する場合もありますが、その場合は±2σ線の式で2を3に変えればオッケーです。
また、このボリンジャーバンドについてですが、統計学の話を少しすることになるので、詳しい内容はググっていただければいいですが
初学者用に、本当にざっっっっっっっっっっっっっっっっっっっっっっっっっっっっくり説明しますと、
現在価格は、±1σ線の範囲にいる確率が68%であり、±2σ線の範囲にいる確率が95%であり、±3σ線の範囲にいる確率が99%であることを表しています。
つまり、逆に言えば、現在価格が、±2σ線に触れた場合、95%ほどの確率で反発するということがわかります。(厳密にいうと現在値も含めた時点で指定のσ線に触れたとしても、そのまま突き抜ける可能性は往々にしてあるので、一つの基準として考慮する程度に捉えるべきだと後々わかります。)
これが、ボリンジャーバンドの最大の肝になる部分ですので、ここさえ押さえていれば、とりあえずは大丈夫です。
ボリンジャーバンドを意識したシステムトレードを作成
それでは、本題のボリンジャーバンドを使ってトレードをする自動売買システムを構築しましょう。
その前に、どのタイミングでポジションをもち、どのタイミングで利確または損切りを行うかをまとめましょう。
このような条件で、ポジションを持ち、利確損切りの判断を行うようにしました。
いよいよ、モデルを組みましょう。
途中までは、前回記事と同じことを書いているので、内容を詳しく知りたい人は、そちらを参照してください。
【参照記事】
・PythonでOANDA APIを使って、過去レートを5000件以上取得する方法
では、上記の表を参考に、以下のようなコードを作成しました。
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
from statistics import mean,stdev import configparser import pandas as pd import oandapy from datetime import datetime import pytz config = configparser.ConfigParser() config.read('./config/config_v1.txt') # パスの指定が必要です account_id = config['oanda']['account_id'] api_key = config['oanda']['api_key'] # APIへ接続 oanda = oandapy.API(environment="practice",access_token=api_key) #指定した本数分、過去チャートを取得する関数を作成する(今回は1時間足を指定する。) def get_mdata(num): apires = oanda.get_history(instrument="USD_JPY", granularity="H1", count=num) res = apires.get("candles") df = pd.DataFrame(res) cN = [] hN = [] lN = [] oN = [] for i in range(len(df)): cN.append(round(float(df['closeBid'][i]) + (float(df['closeAsk'][i]) - float(df['closeBid'][i])) / 2, 3)) hN.append(round(float(df['highBid'][i]) + (float(df['highAsk'][i]) - float(df['highBid'][i])) / 2, 3)) lN.append(round(float(df['lowBid'][i]) + (float(df['lowAsk'][i]) - float(df['lowBid'][i])) / 2, 3)) oN.append(round(float(df['openBid'][i]) + (float(df['openAsk'][i]) - float(df['openBid'][i])) / 2, 3)) df = pd.DataFrame({'time':df['time'], 'open':oN, 'close':cN, 'high':hN, 'low':lN, 'volume':df['volume']}) return df #ちょっと多めに30本分のローソク足を取得 Mdata = get_mdata(30) #現在値はMdataの一番最後のMdata['close']になっている。 now_price = Mdata['close'][len(Mdata)-1] #ボリンジャーバンドの平均線の現在の値を取得 mean = mean(Mdata['close'][-20:]) #ボリンジャーバンドのシグマ線を求めるために、標準偏差を求める関数:stdev()を使用します。 sigma = stdev(Mdata['close'][-20:]) #ボリンジャーバンドの各シグマ線の値を求めよう。 #±1σ線の現在の値を求めます。 plus_sigma1 = mean + sigma minus_sigma1 = mean - sigma #±2σ線の現在の値を求めます。 plus_sigma2 = mean + 2*sigma minus_sigma2 = mean - 2*sigma #実験的に6時間だけ動かそう #スタート時間を指定 startminute = datetime.now().minute starthour = datetime.now().hour startday = datetime.now().day nowminute = datetime.now().minute nowhour = datetime.now().hour nowday = datetime.now().day #ポジションを複数持たないようにする仕組み(本当はget_order()関数がありますが、めんどくさいので、こちらの形をとることにします。) position = 0 #6時間動かすプログラムを作成(今回は分でカウントしているので、6時間だけ動かしたい場合6×60とする) while((nowday-startday)*24*60+(nowhour-starthour)*60+(nowminute-startminute)<360): #75本分のローソク足を取得 Mdata = get_mdata(30) #現在値はMdataの一番最後のMdata['close']になっている。 now_price = Mdata['close'][len(Mdata)-1] #ボリンジャーバンドの平均線の現在の値を取得 mean = mean(Mdata['close'][-20:]) #ボリンジャーバンドのシグマ線を求めるために、標準偏差を求める関数:stdev()を使用します。 sigma = stdev(Mdata['close'][-20:]) #ボリンジャーバンドの各シグマ線の値を求めよう。 #±1σ線の現在の値を求めます。 plus_sigma1 = mean + sigma minus_sigma1 = mean - sigma #±2σ線の現在の値を求めます。 plus_sigma2 = mean + 2*sigma minus_sigma2 = mean - 2*sigma #もし現在値がボリンジャーバンドのマイナス2シグマ線の値を下回った場合、買いポジションを持つ if minus_sigma2 >= now_price and position==0: ticket = oanda.create_order(account_id,instrument="USD_JPY",units=5000,side='buy',type='market') #関数:create_order()の引数unitsは、注文通貨量のことなので、1000通貨単位で指定してください。 position = 1 #買いのポジション #もし現在値がボリンジャーバンドのプラス2シグマ線の値を上回った場合、売りポジションを持つ if plus_sigma2 <= now_price and position==0: ticket = oanda.create_order(account_id,instrument="USD_JPY",units=5000,side='sell',type='market') position = -1 #売りのポジション #何かしらのポジションを持った状態で、現在値が平均線に触れた場合 #または損切りラインに引っかかった場合ポジションを手放す(損切りをポジションを持った時の値から1シグマ分逆行した場合とする) if (position==-1 and now_price - mean <= 0) or (position==-1 and now_price >= ticket['price'] + sigma): oanda.close_position(account_id,"USD_JPY") #positionを0に戻す。 position = 0 if (position==1 and now_price - mean >= 0) or (position==1 and now_price <= ticket['price'] - sigma): oanda.close_position(account_id,"USD_JPY") #positionを0に戻す。 position = 0 #現在時刻を取得 nowminute = datetime.now().minute nowhour = datetime.now().hour nowday = datetime.now().day |
こんな感じになります。
基本は前回記事と同じで、6時間だけ動くようにしてあり、各々の条件でポジションを持ち、指定した条件で、
利確損切りをするようになっています。
コードが汚いのは、初心者ということでご愛嬌を・・・笑
総括
実は、このコード自分が一番最初に思いついたモデルで、実際にこれをレンタルサーバーにこのファイルをアップロードし、
ssh接続経由で、バックグラウンドで1週間運転させてみました。
参照記事:SSH接続の仕方とXサーバー上でPythonを動かそう!
結果としては
勝利数:20回ほど
敗北数:40回ほど
獲得pips:約80pips
損失pips:約75pips
という結果でした。
一応プラス収益で終えられていますが、相場の環境に大きく作用されることと、勝利回数よりも敗北回数の方が2倍と多く、
資産運用としてはまだまだ課題の多いモデルとなっていくことがわかり、
上記で、95%の確率で反発するというボリンジャーバンドの性質からも大きく外れる結果となっています。
今後は、他のテクニカル指標と組み合わせて、コードを組む必要性があることがよくわかり、メジャーな指標ほどそれ単体では何ら有効ではないということがわかった良い機会となりました。
ではでは、以上マスオカでした。
報告!!実際に利益の出たプログラムをnoteにて販売中!!
自分が長いこと研究して実際に1週間に3%ほどの利益を上げれている自動取引BOTを下記のリンク先にて公開中です!気になるかたはぜひご覧ください!
FxトレーダーでOANDA使ってる方、Pythonで作ったこの自動売買BOTを試して欲しいです。
また、新しく人工知能の知識を用いた線形回帰をベースとした特殊な強化学習のモデルを作成しました。かなりのパフォーマンスを上げることができたいますので、是非お試しください。
【論文実装編】線形回帰モデルのFx自動売買ー学習パート+取引モデルのパート統合
ディスカッション
コメント一覧
まだ、コメントがありません