この記事では、以下の記事で作成したPythonとMT5を連携させた基本的なFX自動売買ツールを複数のテクニカル指標で拡張させる方法をご紹介します。
初心者向けになるべくコードの意味まで丁寧に解説するように心がけていますので、初心者の方も是非、PythonでのFX自動売買botの作成にチャレンジしてみてください。
FX自動売買ツールの設計概要
前回の記事でもご紹介した通り、基本的なFX自動売買ツール(bot)の設計概要は以下の通りです。
- 四本値(始値、高値、安値、終値)データを取得
- 四本値データを基にテクニカル指標を計算
- テクニカル指標を基に売買判断フラグを生成
- ポジション情報を取得して既存のポジションを確認
- 新規エントリー(買いまたは売り)の条件を満たしている場合、注文を送信
- エントリー時に設定した利確幅またはストップロス幅に到達したらポジションクローズ
- 上記全てをループ処理
ロジック概要
前回作成したFX自動売買ツール(bot)のロジック概要は以下の通りでした。
- テクニカル指標(MAとRSI)を用いて売買判断条件を作成
- 売買判断条件を満たした場合にbuyまたはsellの注文を行う
- ATR(Average True Range)を基準に利確幅とストップロス幅を決める
今回は、このテクニカル指標による売買判断条件を拡張させる方法をご紹介します。
Inputの設定
以下のインプットを用意していますが、今回の拡張に関係してくるのは最後のbar_periodです。
symbol = "GOLD" # 取引対象
first_lot = 0.01 # 初期ロット数
tp_factor = 2.0 # 利確係数
sl_factor = 1.5 # ストップロス係数
magic_number = 10001 # マジックナンバー
slippage = 10 # スリッページ
bar_period = 30 # 取得する四本値の本数
取得する四本値の本数(bar_period)
これは取得するバー(四本値)の本数です。使用するテクニカル指標に合わせて必要な本数を設定するようにしてください。
例えば、MA(移動平均)の期間は15で設定している場合、30本あれば十分ですが、期間を50や100に設定する場合は、その分必要な本数を増やす必要があります。基本的には使用する期間よりも2本くらい多めに設定しておくと良いですが、ロジックがシンプルなのである程度余裕を持たせた本数にしておいてもそれほど処理が遅くなったりはしないと思います。
テクニカル指標の関数定義
今回は、テクニカル指標を計算する関数をATR、MA、RSIだけでなく、MACD、ボリンジャーバンド、ストキャスティクスまで拡張します。
ATR(Average True Range)
def calculate_atr(data, period=14):
data['tr'] = np.maximum((data['high'] - data['low']),
np.maximum(abs(data['high'] - data['close'].shift()), abs(data['low'] - data['close'].shift())))
data['atr'] = data['tr'].rolling(window=period).mean()
return data
引数は、’high’、’low ‘、’close’が入ったデータフレーム(data)です。
期間(period)はデフォルトで14と設定しています。
例えば15分足のdataを与えれば、期間14のATRが15分足ベースで計算されます。
MA(単純移動平均)
def calculate_ma(data, period=15, price_type='close'):
data['ma'] = data[price_type].rolling(window=period).mean()
return data
引数は、’close’が入ったデータフレーム(data)です。
price_type=’close’で終値の単純移動平均を計算します。
期間(period)はデフォルトで15と設定しています。
例えば15分足のdataを与えれば、期間15の終値ベースのMAが15分足ベースで計算されます。
RSI(Relative Strength Index)
def calculate_rsi(data, period=14, price_type='close'):
delta = data[price_type].diff()
gains = delta.where(delta > 0, 0)
losses = -delta.where(delta < 0, 0)
avg_gain = gains.rolling(window=period).mean()
avg_loss = losses.rolling(window=period).mean()
rs = avg_gain / avg_loss
data['rsi'] = 100 - (100 / (1 + rs))
return data
引数は、’close’が入ったデータフレーム(data)です。
price_type=’close’で終値のRSIを計算します。
期間(period)はデフォルトで14と設定しています。
例えば15分足のdataを与えれば、期間14のRSIが15分足ベースで計算されます。
MACD(移動平均収束拡散法)
def calculate_macd(data, short_period=12, long_period=26, signal_period=9, price_type='close'):
short_ema = data[price_type].ewm(span=short_period, adjust=False).mean()
long_ema = data[price_type].ewm(span=long_period, adjust=False).mean()
data['macd'] = short_ema - long_ema
data['signal'] = data['macd'].ewm(span=signal_period, adjust=False).mean()
return data
引数は、’close’が入ったデータフレーム(data)です。
price_type=’close’で終値のMACDを計算します。
期間(period)はデフォルトで12, 26, 9と設定しています。
例えば15分足のdataを与えれば、終値ベースのMACDが15分足ベースで計算されます。
ボリンジャーバンド
def calculate_bollinger(data, period=20, std_dev=2, price_type='close'):
data['middle_band'] = data[price_type].rolling(window=period).mean()
data['upper_band'] = data['middle_band'] + std_dev * data[price_type].rolling(window=period).std()
data['lower_band'] = data['middle_band'] - std_dev * data[price_type].rolling(window=period).std()
return data
引数は、’close’が入ったデータフレーム(data)です。
price_type=’close’で終値のボリンジャーバンドを計算します。
期間(period)はデフォルトで20と設定しています。
std_dev=2で、2σのボリンジャーバンドです。
例えば15分足のdataを与えれば、期間20で2σのボリンジャーバンドが15分足ベースで計算されます。
ストキャスティクス(%K)
def calculate_stochastics(data, k_period=14, d_period=3, slowing=3):
highest_high = data['high'].rolling(window=k_period).max()
lowest_low = data['low'].rolling(window=k_period).min()
data['%K'] = ((data['close'] - lowest_low) / (highest_high - lowest_low)) * 100
data['%K'] = data['%K'].rolling(window=slowing).mean()
data['%D'] = data['%K'].rolling(window=d_period).mean()
return data
引数は、’high’、’low ‘、’close’が入ったデータフレーム(data)です。
期間(period)はデフォルトで14, 3と設定しています。
例えば15分足のdataを与えれば、期間14, 3のストキャスティクスが15分足ベースで計算されます。
売買判断フラグを設定する関数
ここでは、上記で設定したテクニカル指標を組み合わせた売買判断フラグを設定する関数をいくつかのパターンでご紹介します。全体のコードのうち、generate_trade_flgs関数部分を以下のいずれかに変更することで適用可能です。
各パターン共通
引数の設定
引数は四本値のデータフレーム(data)と、現在価格(symbol_tick)です。
売買判断フラグ
買いフラグ(buy_flg)と売りフラグ(sell_flg)をそれぞれ設定します。
パターン1: 単純移動平均とRSIを利用
def generate_trade_flgs(data, symbol_tick):
# テクニカル指標の計算
data = calculate_ma(data)
data = calculate_rsi(data)
# 売買判断フラグ
buy_flg = (symbol_tick.ask > data['ma'].iloc[-2]) & (data['rsi'].iloc[-2] < 30)
sell_flg = (symbol_tick.bid < data['ma'].iloc[-2]) & (data['rsi'].iloc[-2] > 70)
return buy_flg, sell_flg
パターン2: MACDとボリンジャーバンドを利用
def generate_trade_flgs(data, symbol_tick):
# テクニカル指標の計算
data = calculate_macd(data)
data = calculate_bollinger(data)
# 売買判断フラグ
buy_flg = (data['macd'].iloc[-2] > data['macd_signal'].iloc[-2]) & (symbol_tick.ask < data['bollinger_lower'].iloc[-2])
sell_flg = (data['macd'].iloc[-2] < data['macd_signal'].iloc[-2]) & (symbol_tick.bid > data['bollinger_upper'].iloc[-2])
return buy_flg, sell_flg
パターン3: ストキャスティクスとRSIを利用
def generate_trade_flgs(data, symbol_tick):
# テクニカル指標の計算
data = calculate_atr(data)
data = calculate_rsi(data)
data = calculate_stochastics(data)
# 売買判断フラグ
buy_flg = (data['%K'].iloc[-2] < 20) & (data['rsi'].iloc[-2] < 30) sell_flg = (data['%K'].iloc[-2] > 80) & (data['rsi'].iloc[-2] > 70)
return buy_flg, sell_flg
パターン4: 単純移動平均とMACDを利用
def generate_trade_flgs(data, symbol_tick):
# テクニカル指標の計算
data = calculate_ma(data)
data = calculate_macd(data)
# 売買判断フラグ
buy_flg = (symbol_tick.ask > data['ma'].iloc[-2]) & (data['macd'].iloc[-2] > data['macd_signal'].iloc[-2])
sell_flg = (symbol_tick.bid < data['ma'].iloc[-2]) & (data['macd'].iloc[-2] < data['macd_signal'].iloc[-2])
return buy_flg, sell_flg
パターン5: ボリンジャーバンドとストキャスティクスを利用
def generate_trade_flgs(data, symbol_tick):
# テクニカル指標の計算
data = calculate_bollinger(data)
data = calculate_stochastics(data)
# 売買判断フラグ
buy_flg = (symbol_tick.ask < data['bollinger_lower'].iloc[-2]) & (data['%K'].iloc[-2] < 20) sell_flg = (symbol_tick.bid > data['bollinger_upper'].iloc[-2]) & (data['%K'].iloc[-2] > 80)
return buy_flg, sell_flg
まとめ
以上、”売買判断フラグを設定する関数”部分をMAやRSIだけでなく、他のテクニカル指標に置き換える方法をご紹介しました。今回取り上げたパターンだけでなく、各々でこのコードをベースに様々なパターンに発展させることも比較的容易だと思います。
是非、オリジナルの売買判断ロジックを取り入れてみてください。
機械学習モデルの導入
この記事では、テクニカル指標を用いて売買判断を決定するロジックをご紹介しましたが、この売買判断ロジック部分を機械学習モデルによるものに変更するだけで、シンプルなMLbot(機械学習を取り入れたFX自動売買ツール)に変換可能です。
以下の記事では、その方法をご紹介しています。この記事のbotの拡張方法の解説になります。
Pythonでバックテスト
PythonでFX自動売買ツールを開発するために、バックテスト環境を整えることも重要です。以下の記事ではMT4やMT5ではなく、Pythonでバックテストを行う方法をご紹介しています。