Pythonで自動売買に挑戦④

EA・インディケーター

PythonによるEA(エキスパートアドバイザー)は、自動的に市場データに基づいてトレードを行うプログラムです。自動売買の効率化と一貫性、システムの自動化と効率性を図るためには、フレームワークを設定することは非常に重要となります。フレームワークの基本は、次のようになります。

  • 市場データの取得:チャートからローソク足データやティックデータを収集。
  • トレードシグナルの生成:戦略に基づいて売買のサインを生成。
  • 注文管理:生成したサインに基づいて売買注文を発注。
  • ポジション管理:開いているポジションを監視し、利確や損切りを行う。

ライブラリのインポート

美来
美来

いよいよ、本格的なEA作成だね。大丈夫かな?

ネズミ先生
ネズミ先生

ここまでくれば、簡単なPythonのプログラムの組み立てになるチュー。心配ないチュー!

1. MetaTrader5

import MetaTrader5 as mt5

MetaTrader5(MT5)は外国為替(FX)や株式、先物などの取引をリアルタイムで行うためのトレーディングプラットフォームです。このライブラリを使うと、Pythonから直接MT5の機能を利用して取引を行ったり、市場データを取得したり、注文を管理したりすることができます。このプラットフォームとPythonを連携させることで、自動取引システムの構築などが可能になるチュー。

2. pandas

import pandas as pd

Pandasはデータ解析ライブラリです。データを行と列で整理された表形式(DataFrame)で扱うことができ、データの読み込み、書き出し、変換、操作、集計、可視化を効率的に行えます。金融データの解析や視覚化に非常に便利です。

3. time

import time

timeライブラリは、時間に関する様々な機能を提供します。例えば、現在の時刻を取得したり、プログラムを一定時間停止させたり、時間の経過を計測したりすることができます。取引プログラムでは、一定の間隔でデータを取得したり、スリープ時間を設定したりする際に利用されます。

4. datetime

from datetime import datetime

datetimeライブラリも時間と日付を扱うためのライブラリです。datetimeモジュールは日時の計算、日付フォーマットの変換、現在の日時の取得などを行うためのクラスと関数を提供します。マーケットデータは通常、タイムスタンプ付きで提供されるので、これを解析・操作する際に便利です。

5.os

import os

Pythonスクリプトがオペレーティングシステムと対話するために使用される標準ライブラリの一つです。環境変数の取得や設定、プログラムのパスやディレクトリの取得操作などを行うために使われます。

基本的なフレームワークでは、これらのライブラリを組み合わせてトレーディングの自動化やデータ解析を効率的に行っていきます。

市場データの取得関数

MetaTrader 5から必要なシンボルの価格データを取得

# データ取得のための関数
def get_data(symbol, timeframe, n=100):
    # データを取得する
    rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, n)
    # データをpandas DataFrameに変換する
    df = pd.DataFrame(rates)
    # UNIX時間を人間が読みやすい日時形式に変換する
    df['time'] = pd.to_datetime(df['time'], unit='s')
    # 変換されたDataFrameを返す
    return df

この関数は、MetaTrader 5からget_data特定のシンボル(通貨ペアなど)の価格データを取得し、pandas DataFrame形式に変換して返すものです。

定義

def get_data(symbol, timeframe, n=100):
  • symbol: データを取得する対象のシンボル(通貨ペアなど)の名前です。例えば、「GBPJPY」など。
  • timeframe: データのタイムフレームを指定します。例えば、15分足(mt5.TIMEFRAME_M15)や1時間足(mt5.TIMEFRAME_H1)など。
  • n: 取得するデータの数です。指定なしでは100個のデータを取得しますが、呼び出す際に変更可能です。

データの取得

rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, n)

mt5.copy_rates_from_pos: MetaTrader 5から指定されたシンボルの指定されたタイムフレームの価格データを取得する関数になります。

  • symbol:データを取得するシンボル。
  • timeframe: データのタイムフレーム。
  • 0: 何番目のバーからデータを取得するかを指定します。ここでは最新のデータから取得するため0を指定しています。
  • n: 何番目のバーまで取得するかを指定します。ここでは関数の引数nを使用します。

pandas DataFrameの作成

df = pd.DataFrame(rates)

pd.DataFrame(rates): 取得した価格データ(rates)をpandasのDataFrameに変換します。

日付時刻の変換

df['time'] = pd.to_datetime(df['time'], unit='s')
  • df[‘time’]: DataFrame のtime列を操作します。この列には、UNIX 時間(1970 年 1 月 1 日からの秒数)形式のタイムスタンプが含まれています。
  • pd.to_datetime(df[‘time’], unit=’s’): UNIX時間を人間が読みやすい日付形式に変換します。unit=’s’を指定することで、UNIX時間秒単位であることを示しています。

DataFrame の返却

return df

このDataFrameには指定された数のバーの時間、および各価格(始値、高値、安値、終値、出来高など)が含まれています。

実行結果

# データ取得のシンボルとタイムフレーム
symbol = "EURUSD"
timeframe = mt5.TIMEFRAME_M15
n = 100
# データ取得
data = get_data(symbol, timeframe, n)
# 取得したデータを表示
print(data.head())

取得したデータの先頭5行を表示させてみます。

ログインに成功しましたチュー
                 time     open     high      low    close  tick_volume  \
0 2024-09-12 23:00:00  1.10695  1.10709  1.10675  1.10706          625   
1 2024-09-12 23:15:00  1.10707  1.10741  1.10702  1.10735          328   
2 2024-09-12 23:30:00  1.10734  1.10739  1.10716  1.10737          393   
3 2024-09-12 23:45:00  1.10739  1.10741  1.10718  1.10733          454   
4 2024-09-13 00:00:00  1.10729  1.10734  1.10642  1.10721           78   
美来
美来

シンボルと時間を変えるだけで、欲しいデータを読み込むことができているわ。このデータを使って取引を行うのね。

ネズミ先生
ネズミ先生

とっても簡単チュー。本当に便利だチュー。

美来
美来

次は、売買注文を行う関数ですね。

ネズミ先生
ネズミ先生

その前にトレード戦略を定義するチュー。戦略は、後でいろいろ検証するチュー。

トレード 戦略の定義

MetaTrader 5 (MT5)を使った自動取引戦略を構築するための基本的なステップです。ここでは、シンプルなMoving Average Crossover(移動平均クロスオーバー)戦略を使います。

SMAを計算する関数

所定の期間(window)にわたる単純移動平均(SMA)を計算して返す関数を定義します。

def calculate_sma(data, window):
    return data['close'].rolling(window=window).mean()

data[‘close’]でDataFrameの中の ‘close’ 列(一般的に終値を示す)を指定
.rolling(window=window) は、指定した期間のローリングオブジェクトを生成。これで指定した期間のデータを動かしながら処理できます。

.mean()でローリングオブジェクトに対して平均値を計算し、各ウィンドウの平均が計算できます。

クロスオーバーのシグナルを検出する関数

# SMAを計算する関数
def calculate_sma(data, window): 
   return data['close'].rolling(window=window).mean()
# クロスオーバーのシグナルを検出する関数
def crossover_strategy(data, short_window=5, long_window=20):
    # 短期と長期のSMAを計算
    data['short_sma'] = calculate_sma(data, short_window)
    data['long_sma'] = calculate_sma(data, long_window)
    # シグナル列を初期化
    data['signal'] = 0
    # 短期SMAが長期SMAを上回っている場合、シグナルを1に、そうでなければ-1にセット
    data['signal'][max(short_window,long_window:] = np.where(data['short_sma'][max(short_window,long_window:] >       data['long_sma'][max(short_window,long_window:],1,-1)
    # シグナルの変化をポジションとして記録(1なら買い、-1なら売り)
    data['position'] = data['signal'].diff()
    return data

1. calculate_sma関数で、短期移動平均 (short_sma) と長期移動平均 (long_sma) を計算します。
2. 短期移動平均が長期移動平均を上抜けした場合にシグナルを `1`(買いシグナル) に設定し、下抜けした場合には `0` のままとします。
3. data[‘position’] = data[‘signal’].diff()でシグナルの変化(クロスオーバー)を検出して、`position` 列にその変化を保存します。`.diff()` は、一つ前との値の差分を計算する関数です。 `1` は買いのシグナル、 `-1` は売りのシグナルを示します。

美来
美来

いよいよ、トレードを行う関数ですね。

ネズミ先生
ネズミ先生

実際に、トレードのリクエストをMT5サーバーに送信する関数だチュー。

トレードリクエスト送信関数

def place_trade(symbol, action, lot_size):
    request = {
        'action': mt5.TRADE_ACTION_DEAL,
        'symbol': symbol,
        'volume': lot_size,
        'type': mt5.ORDER_TYPE_BUY if action == 'buy' else mt5.ORDER_TYPE_SELL,
        'price': mt5.symbol_info_tick(symbol).ask if action == 'buy' else      mt5.symbol_info_tick(symbol).bid,
        'deviation': 10,
        'magic': 234000,
        'comment': 'python script order',
        'type_time': mt5.ORDER_TIME_GTC,
        'type_filling': mt5.ORDER_FILLING_IOC,
    }

    result = mt5.order_send(request)
    return result

売買関数の定義

def place_trade(symbol, action, lot_size):

それぞれの引数は、以下のようになっています。

  • symbol: 取引する金融商品のシンボル(例: “EURUSD”)。
  • action: 取引きの種類(buy または、sell)。
  • lot_size: 注文のロットサイズ(取引量)。
  • sl_points(任意): ストップロス(SL)を設定するポイント数(指定しない場合はNone)。
  • tp_points(任意): テイクプロフィット(TP)を設定するポイント数(指定しない場合はNone)
request = {
    "action": mt5.TRADE_ACTION_DEAL,
    "symbol": symbol,
    "volume": lot_size,
    "type": mt5.ORDER_TYPE_BUY if action == 'buy' else mt5.ORDER_TYPE_SELL,
    "price": mt5.symbol_info_tick(symbol).ask if action == 'buy' else      mt5.symbol_info_tick(symbol).bid,
    "deviation": 10,
    "magic": 234000,
    "comment": "Python script order",
    "type_time": mt5.ORDER_TIME_GTC,
    "type_filling": mt5.ORDER_FILLING_IOC,
}

注文の詳細を定義するために、リクエストオブジェクトを作成します。

"action": mt5.TRADE_ACTION_DEAL,

取引のアクションタイプを指定します。`mt5.TRADE_ACTION_DEAL` は成行注文を意味します。

"symbol": symbol,

取引する金融商品のシンボルを指定します。

"volume": lot_size,

オーダーの取引量(ロット数)。

"type": order_type,

注文の種類。買い注文(`mt5.ORDER_TYPE_BUY`)または売り注文(`mt5.ORDER_TYPE_SELL`)。

"price": price,

注文を発注する価格。

"sl": price - sl_points * point if sl_points else None,

ストップロスの価格設定。`sl_points` が指定されている場合にのみ計算し、それ以外の場合は None(指定なし)とします。買い注文の場合、現在の価格から指定したポイント数引いた価格がストップロス価格になります。売り注文の場合は逆になります。

"tp": price + tp_points * point if tp_points else None

テイクプロフィットの価格設定。`tp_points` が指定されている場合にのみ計算し、それ以外の場合は None(指定なし)とします。買い注文の場合、現在の価格に指定したポイント数を加えた価格がテイクプロフィット価格になります。売り注文の場合は逆になります。

"deviation": 10

スリッページ(許容滑り幅)の設定。スリッページとは、発注価格と実際の約定価格のズレを意味します。

 "magic": 234000

マジックナンバー。EAが特定の注文を識別するために使用する識別子です。

"comment": "Python script order"

注文に付けるコメント。ここでは “Python script order” としています。

"type_time": mt5.ORDER_TIME_GTC"

注文の有効期限の種類。 `mt5.ORDER_TIME_GTC` は Good Till Canceled(キャンセルされるまで有効)を意味します。

type_filling": mt5.ORDER_FILLING_IOC

注文がどのように埋められるかを指定します。mt5.ORDER_FILLING_IOCは即時またはキャンセル(Immediate Or Cancel)という意味です。

result = mt5.order_send(request)

構築した注文リクエストを送信します。`mt5.order_send(request)` によって、注文がMT5に送信されます。

return result

注文送信の結果をリターンします。この結果には、注文が成功したかどうか、エラーメッセージ、約定された価格などの詳細な情報が含まれます。

place_trade 関数は市場のシンボル、注文タイプ、ロットサイズなどを引数として受け取り、適切な注文リクエストを作成してMT5に送信します。

美来
美来

仕上げね。エントリーとエグジットする関数だね。

ネズミ先生
ネズミ先生

その前に一つ、ポジションを閉じる関数を付け加えるチュー。

美来
美来

まだあるのね。ちょっと休みたいです。休憩しまーす。

FXで目標利益や決済幅を決めて、裁量トレードに近いフレームワークを作りたいので、今回はここまでとします。この後は、クローズする関数と、自動取引を実行する関数だけで完成となります。

コメント

タイトルとURLをコピーしました