FX自動売買

FX自動売買ツールの開発用ソースコードを公開【MT4で自作EA】

 

自作EAのベースに使えるサンプルを無料公開。
対象はドル円の15分足、ダウ理論に基づくトレンドフォロー型です。
MT4からメタエディタを起動して全文コピペで動きます。

 

HAZU
自分であれこれいじってみると理解が深まるかと思います。
分からないことがあれば都度この記事に戻ってきてください。

 

 

1.サンプルソースコード

本ブログで公開しているソースコードは学習用のサンプルです。
リアル口座で稼働させる場合は自己責任で行ってください。

 

ソースコードの使い方や改編方法は以下の記事を参照。

 

・ソースコード全文

 command
//------------------------------------------------------------------+
// jisakuEA.mq4
// Copyright 2019, Hazu
//------------------------------------------------------------------+
#property copyright "Copyright 2019, Hazu" // 作成者名
#property link "https://hazu-hobby.net/" // Webサイトリンク
#property version "4.0" // バージョン
#property strict // 厳格なコンパイルモード
#property description "自作EA" // EA説明文
#define MAGICMA 20191007 // EA識別用マジックナンバー
#define DEBUG //バックテスト用
#ifdef DEBUG
int prevsec;
int BScnt = 0;
bool ForBackTest(int Timerseconds)
{
if (Seconds() != prevsec)
BScnt ++;
prevsec = Seconds();
if (BScnt >= Timerseconds){
BScnt = 0;
return(true);
}
return(false);
}
#endif
// OnInit(初期化)イベント
int OnInit() {
EventSetTimer(60);
return(INIT_SUCCEEDED);
}
// OnDeinit(アンロード)イベント
void OnDeinit(const int reason) {
EventKillTimer();
}
//バックテスト用
void OnTick(){
#ifdef DEBUG
if (ForBackTest(60))
OnTimer();
#endif
}
// OnTick(tick受信)イベント
void OnTimer(){
if ( IsTradeAllowed() == false ) {
return;
}
main(); //Main logic
}
//------------------------------------------------------------------------------------
// 0. main : メインロジック
//------------------------------------------------------------------------------------
input int Ma1 = 1; // MA1(now)
input int Ma2 = 7; // MA2(short)
input int Ma3 = 25; // MA3(mid)
input int time = 15; // time
input string rcur = "USDJPY";
double M0[5],M1[5],U1[5],L1[5],M2[5],M3[5];
int result;
bool goflg;
void main(){
getprm();
check();
position();
return;
}
//------------------------------------------------------------------------------------
// 1. getprm : パラメータ取得
//------------------------------------------------------------------------------------
void getprm(){
for(int i=4; i>=0; i=i-1){
M0[i] = iMA(rcur,time, Ma1, 0, 0, 0, i);
M1[i] = iMA(rcur,time, Ma2, 0, 0, 0, i);
U1[i] = iBands(rcur,time,Ma2,1.5,0,PRICE_CLOSE,1,i);
L1[i] = iBands(rcur,time,Ma2,1.5,0,PRICE_CLOSE,2,i);
M2[i] = iMA(rcur,time,Ma3, 0, 0, 0, i);
M3[i] = iMA(rcur,time,50, 0, 0, 0, i);
}
}
//------------------------------------------------------------------------------------
// 2. check : 取引条件確認
//------------------------------------------------------------------------------------
void check(){
//条件処理
for(int i=4; i>=0; i=i-1){
if(M1[i]<=M2[i]){
result = -1;
if(M0[i]>=U1[i])
goflg = true;
else
goflg = false;
}
else if(M1[i]>=M2[i]){
result = 1;
if(M0[i]<=L1[i])
goflg = true;
else
goflg = false;
}
else{
result = 0;
goflg = false;
}
}
}
//------------------------------------------------------------------------------------
// 3. position : ポジション管理
//------------------------------------------------------------------------------------
void position(){
//ポジション数取得
int res;
int tpoji = 0;
int pojilim = 1;
int torder = OrdersTotal();
//ポジション数カウント
for(int i = torder-1; i >= 0; i--){
res = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==rcur&&((OrderType()==0&&result==1)||(OrderType()==1&&result==-1)))
tpoji += 1;
}
//ポジション構築
if(tpoji<pojilim&&result!=0&&goflg)
ordersend();
}
//------------------------------------------------------------------------------------
// 4. ordersend : ポジション構築
//------------------------------------------------------------------------------------
void ordersend(){
int res = 0;
double BID = MarketInfo(rcur,MODE_BID);
double ASK = MarketInfo(rcur,MODE_ASK);
double PIP = MarketInfo(rcur,MODE_SPREAD);
//売り指示
if(result==-1&&PIP<=100){
res = OrderSend(rcur,OP_SELL,0.5,BID,100,ASK+0.2,ASK-0.4,"Short",MAGICMA,0,clrRed);
Sleep(3000);
}
//買い指示
else if(result==1&&PIP<=100){
res = OrderSend(rcur,OP_BUY,0.5,ASK,100,BID-0.2,BID+0.4,"Long",MAGICMA,0,clrRed);
Sleep(3000);
}
}

※2020年5月動作確認済

 

2.サンプルソースコード解説

上記ソースコードはメイン関数とサブ関数の組み合わせで出来ています。
プログラムがすっきりするだけでなく、修正も最小限で済みます。

 

 

・メイン関数(必須プログラム)

EAを動かすために必要な条件が記載されています。

 

✔ 初期宣言 OnInit()、OnDeinit()、OnTick() など

EAを起動した際に行う処理などを記載しています。

 

 command
//------------------------------------------------------------------+
// jisakuEA.mq4
// Copyright 2019, Hazu
//------------------------------------------------------------------+
#property copyright "Copyright 2019, Hazu" // 作成者名
#property link "https://hazu-hobby.net/" // Webサイトリンク
#property version "4.0" // バージョン
#property strict // 厳格なコンパイルモード
#property description "自作EA" // EA説明文
#define MAGICMA 20191007 // EA識別用マジックナンバー
#define DEBUG //バックテスト用
#ifdef DEBUG
int prevsec;
int BScnt = 0;
bool ForBackTest(int Timerseconds)
{
if (Seconds() != prevsec)
BScnt ++;
prevsec = Seconds();
if (BScnt >= Timerseconds){
BScnt = 0;
return(true);
}
return(false);
}
#endif
// OnInit(初期化)イベント
int OnInit() {
EventSetTimer(60);
return(INIT_SUCCEEDED);
}
// OnDeinit(アンロード)イベント
void OnDeinit(const int reason) {
EventKillTimer();
}
//バックテスト用
void OnTick(){
#ifdef DEBUG
if (ForBackTest(60))
OnTimer();
#endif
}
// OnTick(tick受信)イベント
void OnTimer(){
if ( IsTradeAllowed() == false ) {
return;
}
main(); //Main logic
}

 

✔ メイン関数 main()

グローバル変数(プログラム全体で使う変数)の定義やサブ関数の呼び出しなどをここで管理します。

 

 command
//------------------------------------------------------------------------------------
// 0. main : メインロジック
//------------------------------------------------------------------------------------
input int Ma1 = 1;                    // 現在値
input int Ma2 = 7;                    // 7区間移動平均
input int Ma3 = 25;                  // 25区間移動平均
input int time = 15;                  // 時間足指定
input string rcur = "USDJPY";   //通貨ペア指定
//グローバル変数
double M0[5],M1[5],U1[5],L1[5],M2[5],M3[5];
int result;
bool goflg;
//メイン関数
void main(){
getprm();
check();
position();
return;
}

 

・サブ関数(追加プログラム)

このサイトで独自定義している関数です。
外部のEAと組み合わせる場合は定義などが被っていないか確認して下さい。

 

✔ パラメータ取得 getprm()

チャート5本分のデータを1本ずつ行列に格納します。
これにより「少し前の時間足でも条件が成立しているか」を条件とすることが可能です。

 

 command
//------------------------------------------------------------------------------------
// 1. getprm : パラメータ取得
//------------------------------------------------------------------------------------
void getprm(){
//for関数で必要本数分のデータ保存
for(int i=4; i>=0; i=i-1){
M0[i] = iMA(rcur,time, Ma1, 0, 0, 0, i);
M1[i] = iMA(rcur,time, Ma2, 0, 0, 0, i);
U1[i] = iBands(rcur,time,Ma2,1.5,0,PRICE_CLOSE,1,i);
L1[i] = iBands(rcur,time,Ma2,1.5,0,PRICE_CLOSE,2,i);
M2[i] = iMA(rcur,time,Ma3, 0, 0, 0, i);
M3[i] = iMA(rcur,time,50, 0, 0, 0, i);
}
}

 

 取引条件確認 check()

getprm() で取得したパラメータを利用して取引条件を満たしているか確認します。
自作EA開発講座で紹介しているように取引条件の変更はここで行います。
グローバル変数 goflg が True になった場合に発注を行います。

 

 command
//------------------------------------------------------------------------------------
// 2. check : 取引条件確認
//------------------------------------------------------------------------------------
void check(){
//条件処理
for(int i=4; i>=0; i=i-1){
if(M1[i]<=M2[i]){
result = -1;                   //売り判定
if(M0[i]>=U1[i])
goflg = true;                //売買指示
else
goflg = false;
}
else if(M1[i]>=M2[i]){
result = 1;                    //買い判定
if(M0[i]<=L1[i])
goflg = true;                //売買指示
else
goflg = false;
}
else{
result = 0;
goflg = false;
}
}
}

 

 ポジション管理  position()

保有するポジションを管理します。
例えば『ポジションは同時に3個まで』といった条件付けが可能です。

 

 command
//------------------------------------------------------------------------------------
// 3. position : ポジション管理
//------------------------------------------------------------------------------------
void position(){
//ポジション数取得
int res;
int tpoji = 0;
int pojilim = 1;
int torder = OrdersTotal();
//ポジション数カウント
for(int i = torder-1; i >= 0; i--){
res = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==rcur&&((OrderType()==0&&result==1)||(OrderType()==1&&result==-1)))
tpoji += 1;
}
//ポジション構築
if(tpoji<pojilim&&result!=0&&goflg)
ordersend();
}

 

✔ ポジション構築 ordersend()

check(), position() の条件を満たしていたらいよいよ発注になります。
グローバル変数 result の値に従い発注を行います。

 

 command
//------------------------------------------------------------------------------------
// 4. ordersend : ポジション構築
//------------------------------------------------------------------------------------
void ordersend(){
int res = 0;
double BID = MarketInfo(rcur,MODE_BID);
double ASK = MarketInfo(rcur,MODE_ASK);
double PIP = MarketInfo(rcur,MODE_SPREAD);
//売り指示
if(result==-1&&PIP<=100){
res = OrderSend(rcur,OP_SELL,0.5,BID,100,ASK+0.2,ASK-0.4,"Short",MAGICMA,0,clrRed);
Sleep(3000);
}
//買い指示
else if(result==1&&PIP<=100){
res = OrderSend(rcur,OP_BUY,0.5,ASK,100,BID-0.2,BID+0.4,"Long",MAGICMA,0,clrRed);
Sleep(3000);
}
}

 

3.使えるコードか判断する方法

EAの評価手法は一般的に以下の2種類があります。
どちらかで十分ということはなく、合わせて評価が必要です。

 

過去の相場データから評価する『バックテスト』

実稼働で成績を確認する『フォワードテスト』

 

・MT4の機能を使ったバックテスト

シンプルなロジックですが、しっかりプラス収支です。

 

テスト条件

通貨ペア:ドル円
時間足:M15
モデル:全ティック
スプレッド: 5
期間:20014/4/1-2020/4/22

 

結果:100万円⇒210万円

 

HAZU
後半で紹介する拡張コードでさらに成績は伸ばせます。

 

・VPSを使ったフォワードテスト

フォワードテストをするにはMT4を24時間起動する必要があります。
本ブログではVPS(仮想PCサービス)の使用をおすすめしています。

 

MT4対応のVPS

お名前.comデスクトップクラウド
・リモートデスクトップ込みの明朗な料金プラン
・主要な国内業者のMT4がプリインストール済み

ConoHa for Windows Server
・初心者でも扱いやすい設定画面
・時間単位、1日単位での料金請求

さくらのVPS for Windows Server
・業界最安レベルの利用料金
・設定画面は多少分かり辛い(PC中級者向け)

 

以下の記事で詳しく紹介しています。

【MT4/MT5】FX自動売買用VPSの比較!EA開発者がおすすめを紹介

続きを見る

 

4.拡張ソースコード

以下でメジャーからマイナーまで様々なロジックのソースコードを公開。
組み合わせ次第で戦えるEAが作れます。

 

以下が比較的よく使われるコードです。

 

その他のコードは以下の記事で紹介しています。

EA開発で使える拡張ソースコードまとめ【MT4でFX自動売買】

続きを見る

 

・トレーリングストップを実装する

トレーリングストップはメジャーな決済手法ですがMT4には実装されていません。
本記事ではロジックに加え自分が使いやすいようカスタマイズする方法を紹介しています。

>>自作EAでトレーリングストップを実現する方法

 

・ナンピン買いを実装する

本記事ではナンピンをするためのロジックを以下の2つに分けて実装しています。
・ポジションを分割して取得する方法
・ポジション数に応じてロット数を変更する方法
複雑な条件を持つEAを開発したい場合にもこれらの考え方が役に立ちます。

>>ナンピンをする方法

 

・ポジションを全決済、分割決済する

「ある時間でポジションを全決済したい」「利益が出たら一部決済したい」という希望を叶えます。
一部を修正すれば通貨ペアの指定や売りポジション、買いポジションごとの決済も可能です。

>>保有ポジションを全決済、分割決済する方法

 

5.開発に役立つ知識をインプット

EA開発に必要なのはトレードスキルとプログラミングスキルです。
どちらが欠けていても良いEAは作れません。
以下に知識やスキル不足を補うツールを紹介します。

 

コスパが良いおすすめサービス

FXメタトレーダー入門【約2千円】
EA開発者のバイブル、初心者から上級者まで

EAつくーる【月3千円】
プログラミング無しでEA開発

EAプログラミングセミナー【約4万円】
講師からの指導を受けつつEA開発の基礎を学べます

 

・FXメタトレーダー入門

EA開発者を目指すなら以下のシリーズは押さえておきたいです。
筆者は書籍版を持っていますが、電子版が半額で売られています。
これから購入される方は電子版をお勧めします。

AMAZON 楽天

 

・EAつくーる

プログラミング初心者におすすめしたいのがEAつくーるです。
これを使えばノーコード(プログラミング無し)でEA開発が可能。

 

お試しなら1ヶ月版(2980円)で十分です。
やる気があれば初めから1年版(29800円)がおすすめ。

 

HAZU
私がEA開発を始めた当時には無かったサービスです。
これがあれば学習期間含め100時間くらい短縮できます。

 

 

MQL言語の学習ができ、裁量トレーダーもEA開発が可能になる! | GogoJungle

>>1年版の販売ページ
>>1ヶ月版の販売ページ

 

・EAプログラミングセミナー

がっつり取り組みたいのであればEAプログラミングセミナーもおすすめです。
難易度別に3つの講座が提供されているので、レベルに合わせて選択しましょう。

 

>>スタンダード講座
>>実践講座
>>裏口座

 

6.よくある質問

Q. MT4はどこから入手できますか

A. MT4は以下の国内FX業者からダウンロードできます

MT4でFX自動売買できる国内証券会社おすすめ。EA開発者が徹底比較

続きを見る

 

Q. ソースコードの使い方が分かりません

A. サンプルEAの動かし方や改編方法は以下の記事を参照下さい

無料ソフトを使ったFX自動売買ツールの作り方【MT4で自作EA】

続きを見る

 

Q. 作成済のEAをいただくことはできますか。

A. EA自体の配布は現在行っていません。販売サイトで有料EAを購入して下さい。
MT4に限らず自動化できればいいなら以下のサービスも選択肢です。

国内証券会社のFX自動売買サービスおすすめ。種類別に徹底比較

続きを見る

 

7.まとめ

本記事では自作EAのベースとして使えるソースコードを紹介しました。
一度動かしてみることで理解が進むかと思います。

 

以上、参考になれば幸いです。

 

  • この記事を書いた人

HAZU

静岡の一部上場企業で働くサラリーマン。 投資7年目で20代からコツコツ資産形成中。 ブログではFXの始め方から自動化までを解説。 特にFX自動売買ツールの自作記事が好評で検索上位も多数維持しています。

-FX自動売買

© 2022 HAZUの資産形成ラボ Powered by AFFINGER5