やまちゃんのオーディオブログ

真空管アンプ、最近は資金調達のためのFX,MetaTrader4ネタもやっています。

mt4 fx自動売買 mql4

MT4 インジケータをEAに一瞬で切り替える(改造する)フレームワーク本邦初公開

投稿日:2022年4月27日 更新日:

MetaTrader4においてインジケータをEA(自動売買)に一瞬で切り替える(改造する)方法について説明していきます。FXネタです。

これもネットでは、公開されていません。2022年4月、インジケータを自動売買にEAに一瞬で切り替える方法を開発したので、公開します。#IFDEF、#IFNDEFを使います。a new method on mt4 for changing an indicater to EA in a moment

mt4自動売買プログラムEA開発におけるインジケータの重要性とEAに迅速に改造する必要性

前回には、mt4のプロジェクト管理やその手法について説明してきました。

その中で、EAのプログラムではチャートに表示できないため、特定の売買条件に基づいて、参入、撤退の時期と終値を格納した配列に基づいて、独自のインジケータを作ることをお勧めしました。また、起動直後だけ一瞬で利益計算を行い、利益計算をCommentに表示し、これに基づいて適切な売買ができる予測がついた場合のみ、このインジケータを自動売買のEAに切り替えることを説明してきました。

そうなると、開発を早くするには、インジケータで作った売買条件を、そのまま流用して、なるべく早くEAに改造する必要が出てきます。しかし、そもそも、元プログラムの形式からして全く違うので結構面倒です。当初は、インジケータができても、EAで運用を始めるには数か月かかりそうだと思っていました。どこが違うのか説明していきます。

1 mt4のインジケータとEAの違い

mt4のインジケータとEAとでは以下のような違いがあります。

int OnCalculate()とvoid OnTick()

そもそも、メインルーチンからして関数名が違います。インジケータがメイン関数をint OnCalculate(){}内に記述することを要請されるに対し、EAではOnTick(){}内に記述することを要請されます。関数名が違うので、フラグ変数で流れを変えるようなことはできません。

インジケータとして表示する項目設定の命令の挿入/削除

EAでは、インジケータで必要だった、インジケータに表示する設定の命令が、すべてコンパイルエラーになります。

インジケータでは、インジケータに表示する設定が必要ですが、それらはすべてコンパイルエラーになる可能性があります。例えば以下のものです。

IndicatorBuffers(14);
IndicatorDigits(Digit);
SetIndexStyle(0,DRAW_LINE,0,3,ExtColor5);
SetIndexBuffer(0,A);
SetIndexLabel(0,”A”);

EAに改造するには、これらは削除が必要です。なお、昔は、インジケータは8個までと制限されていましたが、現在はもっとたくさんのインジケータを表示できます。今年グッピーの多数移動平均線が10個以上のインジケータが使われているのを見て、初めてその仕様の変更に気づきました。

売買の指示命令の挿入/削除

インジケータでは売買を行うことはできませんから、売買の指示命令を入れると、(どちらか忘れましたが)コンパイルエラーか、警告が出て動かなくなります。逆に、EAのプログラムをインジケータとして動かすと、On culcuate()がないとして1行のみエラーが生じ動かすことができません。この点も削除や変更が必要です。ただし、インジケータでも現在保有するポジションなどを調べることは可能です。

インジケータにおける仮想ポジションの設定/EAにおけるポジション検出

EAでは、当然ながらポジションがあれば、撤退を指示することができます。インジケータでは売買ができない以上、ポジションを自身で取得できませんから、ポジションはあくまで仮想のものとなり、例えば買い参入条件を満たしたら直ちに買いポジションを得たとという仮想ポジションの変数を記録させた状態で、シミュレーションを行うことになります。これに対し、EAでは、現実にポジションが存在することを前提に撤退するかを決めます。ですので、ポジションの管理方法が異なります。

以上の通り、結構面倒です。インジケータ→EA→インジケータ→EAの繰り返しでを速めて練り上げる必要があります。

ではどうやって、インジケータをEAに一瞬で切り替えるのか、説明していきます。

2 MT4のインジケータをEAに一瞬で切り替える手法(本邦初)

基本的な手法 ~ コンパイルの制御を変える

まず、メインのファイルの一番上に以下を設けます。

//#define EA

インジケータをコンパイルするときは、上記の通り、コメントアウトしておきます。

EAをコンパイルするときは、コメントアウト//を外します。これにより、コンパイルの制御を変えます。

メイン関数の切り替えの方法

この制御によれば、メイン関数を、#define EAの定義をしているか否かで、int OnCalculate()とvoid OnTick()を変えることも可能です。すなわち、

#ifdef “EA”
void OnTick()
{

#else

int OnCalculate(const int rates_total,const int prev_calculated,const datetime &time[],const double &open[],const double &high[],const double &low[],
const double &close[],const long &tick_volume[],const long &volume[],const int &spread[])
{

#endif

・・・

#ifndef EA
return rates_total;
#endif
}

とします。インジケータでは、「return rates_total;」という値を返すことも求められますから、EAが定義されていなければ、これもコンパイルするよう指示しておきます。確かに、調べてみれば#ifndef の説明はありましたよ。でも、こういう方法に使うという説明は皆無でしたし、インジケータをEAに切り替えるという表題や内容のサイトも皆無でした。

なお、これらを切り替え可能にする見地から、OnCalculateの引数となるrates_total,prev_calculated,time[],open[],close[],high[]などは使わないようにします。これらを利用した場合、EAの方では変数が定義されていないとしてエラーになるからです。ここで、rates_total,prev_calculated,は、一度計算すれば重複計算を回避して、直近の時間だけを計算するようにするために用いられます。しかし、これらを使わなくても、Barsを検出すればrates_totalの代わりになりますし、一度計算すれば、要素番号0だけを計算すればよく、prev_calculatedも必要ありません。prev_calculatedがどうしても必要なら、一度計算すればprev_calculated=bar-1;とすればよいだけの話です。open[],close[],high[]は、あらかじめセットされたグローバル関数のOpen[],Close[]などを用いることができ、必要ありません。

インジケータとして表示する項目設定の命令の挿入/削除の方法

EAに改造するのに、インジケータの設定を削除したり、またインジケータに戻して挿入したりで面倒です。そこで以下の通りにします。

void chart_init_Part()
{
#ifndef EA
IndicatorBuffers(14);
IndicatorDigits(Digit);
SetIndexStyle(0,DRAW_LINE,0,3,ExtColor5);
SetIndexBuffer(0,MACD);
SetIndexLabel(0,”MACD”);
#endif
}
int OnInit(void)
{
chart_init_Part();
MAIN_init_Part();

上記の通り、「chart_init_Part();」においてチャート設定の部分を、「EA」の定義がない場合に限り実行します。初期設定メインルーチンであるint OnInit(void)において、「chart_init_Part();」の前後で、#ifndef EA、#endifを設けても構いません。これにより、「EA」の定義がされていないインジケータでは表示項目の設定を行い、「EA」が定義されている場合にはこれをしないので、エラーなく切り替えることができます。

売買の指示命令の挿入/削除の切り替え方法、インジケータにおける仮想ポジションの設定/EAにおけるポジション検出の切り替え方法

上記の通りインジケータとEAとの違いは以下の通りです。

インジケータ : 売買するサブルーチンを回避。仮想の売買ポジションを記憶する変数を設ける。

EA     : 売買を指示するコマンドを含むサブルーチンを用意。現実の売買ポジションの存否を調査して、記憶する変数を設ける。

メインのほうでは、売買条件の設定の工夫にエネルギーを注ぎたいので、売買指示だけにとどめ、サブルーチンのほうで、売買指示コマンドを設けます。サブルーチンの売買指示コマンドでは、定義EAの存否に基づき、コンパイル制御を変えて、仮装売買をするのか、現実の売買の指示をするのかを振り分けます。私は現在は、売買条件は別ファイルにサブルーチンとして記述しています。これにより、シミュレーションでもこの条件を回すだけとなり、参入撤退のシミュレーションがとEAとほぼ同じ条件にすることができます。

void EnterAndExit_part(int i)
{・・・
if(condtion==true)
{
Buy_enter_orderPart();

「Buy_enter_orderPart();」という関数を設けて、上位関数の売買条件の設定では、インジケータもEAも処理を同じにし、EAとインジケータを切り替えた場合でも、いつの間にか条件が異なっていたというようなことがないようにします。以下は、買い参入の例です。

int Buy_enter_orderPart()
{#ifndef EA
updownmode_L=1;
Enter_data_recordingPart(1);
return(0);
#endif// 参入撤退中の保留モード
updownmode_L=-100; // 保留モード
TL=OrderSend(Symbol(),OP_BUY,EnterLot,Ask,Slip,0,0,comments,magic,0,blue);
Alert(“buy=”,TL);
if(TL!=-1)
{
//ここでは、updownmode_Lを変化させない。メインルーチンで一元的に変化させる。
//Alert(“buy enter”);
Enter_data_recordingPart(1);
}
else
{
Alert(“buy enter failed”);
Alert(“ticket_L=”,Ticket_L);
updownmode_L=0;
}
return(Ticket_L);
}

ここで、updownmode_Lというのは、参入撤退の条件を表す(仮想ないし現実)のポジション状態フラグに使っています。Buy_enter_orderPartにおいては、EAが定義されていない場合、即ちインジケータでは、直ちにupdownmode_Lを1にして参入したことにしてしまって、returnによりサブルーチンを終えています。これに対し、リアルトレードの「EA」を定義した場合には、updownmode_L=-100という参入撤退も許さない保留モードを設けています。参入撤退は、メインルーチンの上のほうで、予めポジションを調査し(ここまではインジケータでもエラーにならない)、ポジションがあることを認定した場合に限り、ポジション状態フラグupdownmode_Lを1に切り替えるので、ここではポジション状態フラグを設定することはしません。このように売買条件のルーチンで、インジケータとEAの処理を切り替えているので、メインとなる作業の売買条件設定のところでは作業を共通化して、そういう切り替えを考えなくてよいようにしているので、インジケータを直ちにEAに移行できます。売買条件もインジケータとEAでずれることがなくなります。

プロジェクトファイル*.projのコピー

EAとインジケータの切り替えが多くなると、プロジェクトファイル*.projをいじるのさえ、面倒になってきます。
そこで、プロジェクトファイル*.projをコピーし、*EA.projなるものを、プロジェクトフォルダに入れます。メインのプログラムと同じフォルダ階層ですね。

そのファイルを開けて、種別をインジケータから、EAに変えます。インジケータのプロジェクトを閉じて、EAのプロジェクトを開きます。

先ほどの定義の#deffine EAを有効にし、コンパイルを行います。もしかすると、*EA.projのコピーだけでは足りず、テキストエディタで関連付けを修正する必要があるかもしれません。

プロジェクトフォルダのコピーを行うバッチファイル

さらに、EA側のプロジェクトフォルダの削除&コピーすら面倒になります。そこで、通常はindicaaterで中心に編集する本体ファイルを置き、エキスバートアドバイザーのフォルダであるExpertsへ、実行ファイル*.ex4のコピーを行うバッチファイルを設けます。indicaterのフォルダでも、種別をエキスバートアドバイザーにしておけば、EAとしてコンパイルは可能だったと思います(逆に上記Expertsのフォルダ内で、.projのファイルの中で、種別をインジケータとして、インジケータをコンパイルするのも可能だったと思います)。なので、インジケータのフォルダの下でコンパイルを行い、my_MACD_projEA.ex4という実行ファイルだけをコピーします。例えば、以下のような内容のテキストデータを作り(・・・・は環境に合わせて変えてください)、例えば、cp.batという名前に変更し、バッチファイルとして実行可能にし、ダブルクリックだけで、エキスバートアドバイザーへ送り込むことができます。

copy C:\Users\PC\AppData\Roaming\MetaQuotes\Terminal\・・・・\MQL4\Indicators\my_expertbb_project\my_MACD_projEA.ex4 C:\Users\PC\AppData\Roaming\MetaQuotes\Terminal\・・・・・\MQL4\Experts\my_MACD_proj\

Follow me!

-mt4 fx自動売買 mql4
-

執筆者:


comment

メールアドレスが公開されることはありません。

CAPTCHA


関連記事

no image

linuxの格安vps webarenaでmt4,セキュアにリモートデスクトップ(ubuntu,vnc,超軽量lxde利用):3 ubuntuのターミナルから、wineをインストールする

目次 0 導入編 1 vpsであるwebarenaでインスタンスを作成する。 2 ubuntuのターミナルに暗号化した通信ssh(Secure Shell)でログインする。 3 ubuntuのターミナ …

no image

linuxの格安vps webarenaでmt4,セキュアにリモートデスクトップ(ubuntu,vnc,超軽量lxde利用)4 vncを使って、仮想デスクトップと接続する(パスワードのみで接続)。

目次 0 導入編 1 vpsであるwebarenaでインスタンスを作成する。 2 ubuntuのターミナルに暗号化した通信ssh(Secure Shell)でログインする。 3 ubuntuのターミナ …

no image

linuxの格安vps webarenaでmt4,セキュアにリモートデスクトップ(ubuntu,vnc,超軽量lxde利用)5 秘密鍵を利用して、ターミナルと仮想デスクトップとを接続し、ポートフォア―ドを利用し、仮想デスクトップvncとセキュアに接続する。

目次 0 導入編 1 vpsであるwebarenaでインスタンスを作成する。 2 ubuntuのターミナルに暗号化した通信ssh(Secure Shell)でログインする。 3 ubuntuのターミナ …

no image

linuxの格安vps webarenaでmt4,セキュアにリモートデスクトップ(ubuntu,vnc,超軽量lxde利用)8 mt4をインストール

目次 0 導入編 1 vpsであるwebarenaでインスタンスを作成する。 2 ubuntuのターミナルに暗号化した通信ssh(Secure Shell)でログインする。 3 ubuntuのターミナ …

no image

linuxの格安vps webarenaでmt4,セキュアにリモートデスクトップ(ubuntu,vnc,超軽量lxde利用)7 仮想デスクトップvncで、セキュアな接続においてクリップボードを使えるようにする

目次 0 導入編 1 vpsであるwebarenaでインスタンスを作成する。 2 ubuntuのターミナルに暗号化した通信ssh(Secure Shell)でログインする。 3 ubuntuのターミナ …

[最近の記事]
2022年4月
 12
3456789
10111213141516
17181920212223
24252627282930

3PR エリア3 タイトル

PAGE TOP