大学生が儲けるためにPythonで自動取引BOTを作成してみた(ボリバンとRSIを導入)
目次
大学生が本気で儲ける方法を考えてみた。
前回記事では、ボリンジャーバンドを実装してFx取引を行うBOTを作成しました。
では今回は、少しそれを改良したモデルをご紹介します。
前回記事↓
取引環境について
取引を行うFx会社はOANDAを使用します。理由としては、OANDAは無料で為替情報にアクセスできるAPIを公開しており、
それをPythonで扱えるパイソンのモジュールもあります。
自分はパイソンを使って自動取引BOTを作成するため、非常に都合が言い訳です。なので、今回はOANDAを使用することにしました。
OANDAをPythonで使用するためのガイドラインは以下の記事にあります。
参考記事↓
PythonでOANDA APIを使って、過去レートを5000件以上取得する方法
また、今後の長期利用のためにも作成した取引BOTを外部サーバーで実行できるように、Xサーバーを使用しました。
Xサーバーでパイソン環境を整える記事は以下にあります。
参考記事↓
上記の環境で取引BOTを作成していきます。Pythonのバージョンは最新のものを使用しています。
取引BOTの中身
前回記事はボリンジャーバンドのみで取引条件を決めていきましたが、
今回のBOTはボリンジャーバンドとRSIを組み合わせて、取引条件を決めていきます。
\(\)RSIとは??
聞きなれないものが出てきましたが、RSIとは、テクニカル指標の一つで、相場の買われすぎや売られ過ぎを数値化させたものになっています。
どういうことかというと、簡単な言葉を使った数式を用いると
UP[SUM] = (指定した期間中での陽線の値上がり幅の合計)
DOWN[SUM] = (指定した期間中での陰線の値下がり幅の合計)
とすると、
$$RSI = 100\times\frac{UP[SUM]}{UP[SUM]+DOWN[SUM]}$$
と表せます。
つまり、陽線の値上がり幅の合計値の割合が高くなればなるほど、RSIの値は100に近くなっていき、陰線の値下がり幅の合計値の割合が高くなればなるほど、RSIの値は0に近くなっていきます。
なので、RSIが100に近づけば近づくほど、市場は上昇トレンド、0に近づけば近づくほど市場は下降トレンドを示していることになります。
一般的には70を上回れば市場が買われ過ぎの状態で、明確な上昇トレンドを示していて、30を下回れば市場の売られ過ぎの状態で、明確な下降トレンドを示していることになります。
RSIとボリンジャーバンドを組み合わせる意義
先ほどのRSIの説明より、RSIの値から市場にトレンドが存在しているかどうかの有無を判断することが可能になります。
ボリンジャーバンドの弱点としては、ボリンジャーバンドはそもそも逆張りを判断する時に参照する指標だと思っていているので、市場がトレンドに乗った場合、逆張りは虚しく市場の養分となっていってしまいます。
(中にはバンドの幅が狭まった後に大きく広がったらトレンドに移ったと判断する方もいるので、そのようなモデルも今後作成できればなと思考錯誤中です)
そのようなことから、市場がトレンドに入ったかどうかを判断するためにRSIを導入するという発想に至るわけです。
今回は、30分足を使用するので、ボリンジャーバンドの期間を12時間分の24本、RSIの期間は6時間分のトレンドの有無を見るために12本とすることにします。
取引条件
それでは以上のことを踏まえて取引条件を表にまとめることにします。
以上の条件をもとにプログラムを組んでいきます。
今回は、ドル円の30分足を使用して行うのと、上記で紹介している内容も踏まえており、それらを考慮した上で下記のコードを参照してください。
基本的には、この記事(PythonでOANDA APIを使って、過去レートを5000件以上取得する方法)の通りに環境を整えていれば、コードをコピペするだけで使用することが可能です。
自動取引BOTの作成
それでは、BOTの中身のコードを下記に記します。
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 114 115 116 117 118 119 120 121 122 |
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="M30", 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 #RSIの値を返す関数を定義する。(引数はロウソク足の終値とRSIの期間) def RSIdata(close,Rnum): RSp, RSm, RSI = [],[],[] for i in range(1,len(close)): if close[i]>=close[i-1]: RSp.append(close[i]-close[i-1]) RSm.append(0) else: RSp.append(0) RSm.append(close[i-1]-close[i]) A,B = [],[] for i in range(Rnum,len(RSp)+1): if i==Rnum: A.append(sum(RSp[i-Rnum:i])/Rnum) B.append(sum(RSm[i-Rnum:i])/Rnum) RSI.append(100*A[i-Rnum]/(A[i-Rnum]+B[i-Rnum])) else: A.append((A[i-1-Rnum]*(Rnum-1)+RSp[i-1])/Rnum) B.append((B[i-1-Rnum]*(Rnum-1)+RSm[i-1])/Rnum) RSI.append(100*A[i-Rnum]/(A[i-Rnum]+B[i-Rnum])) return RSI[-1] #実験的に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): #30本分のローソク足を取得 Mdata = get_mdata(30) #現在値はMdataの一番最後のMdata['close']になっている。 now_price = Mdata['close'][len(Mdata)-1] #終値だけを使うので、終値のみを引っ張り出してきます。 close = Mdata['close'] #ボリンジャーバンドの平均線の現在の値を取得 d_mean = mean(close[-24:]) #ボリンジャーバンドのシグマ線を求めるために、標準偏差を求める関数:stdev()を使用します。 sigma = stdev(close[-24:]) #ボリンジャーバンドの各シグマ線の値を求めよう。 #±1σ線の現在の値を求めます。 plus_sigma1 = d_mean + sigma minus_sigma1 = d_mean - sigma #±2σ線の現在の値を求めます。 plus_sigma2 = d_mean + 2*sigma minus_sigma2 = d_mean - 2*sigma #RSIの値を取得 RSI = RSIdata(close,12) #もし現在値がボリンジャーバンドのマイナス2シグマ線の値を下回り、RSIの値が30を下回っていた場合、買いポジションを持つ if minus_sigma2 >= now_price and RSI<=30 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シグマ線の値を上回り、RSIの値が70を上回っていた場合、売りポジションを持つ if plus_sigma2 <= now_price and RSI>=70 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 - d_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 - d_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時間だけ動かしますが、好みに応じて運転時間は調整してください。
総括
まだこちらのモデルは、長期間運用していないので結果はわかりかねますが、前回作成したボリンジャーバンドのみだけのモデルよりは収益率は向上するかと思います。
他にも、思いついたモデルなどがあればツイッターにて随時更新していきますので、Followしていただけると嬉しいです。
今後ともよろしくお願いします。
ではでは、マスオカでした。
報告!!実際に利益の出たプログラムをnoteにて販売中!!
自分が長いこと研究して実際に1週間に3%ほどの利益を上げれている自動取引BOTを下記のリンク先にて公開中です!気になるかたはぜひご覧ください!
FxトレーダーでOANDA使ってる方、Pythonで作ったこの自動売買BOTを試して欲しいです。
また、新しく人工知能の知識を用いた線形回帰をベースとした特殊な強化学習のモデルを作成しました。かなりのパフォーマンスを上げることができたいますので、是非お試しください。
【論文実装編】線形回帰モデルのFx自動売買ー学習パート+取引モデルのパート統合
ディスカッション
コメント一覧
まだ、コメントがありません