MQL4プログラミング 第13回 バイナリーの自動エントリー(1)
AMT本来の使い方 自動エントリー
前回(MQL4プログラミング 第12回 AMTで簡単エントリー)では簡単操作でハイローにエントリーできる連動インジケーターを作成しました。
今回、次回ではAMT本来の使い方である自動エントリーについて解説していきます。
①今回:自作サインツールにAMTの自動エントリー機能を構築する方法
②次回:既成のバッファ型サインツールにAMTの自動エントリー機能を構築する方法
の内容を予定しています。
自作サインツールにAMTの自動エントリー機能を構築する方法
では、早速「自作サインツールにAMTの自動エントリー機能を構築する方法」の解説をいたします。
まず、プログラムの概要ですが前回「MQL4プログラミング 第12回 AMTで簡単エントリー」と「MQL4プログラミング 第3回 インジケーターを作成してみよう(処理の関数化)」をドッキングさせたイメージとなります。
①サイン確定すると次足でAMTにエントリーメッセージ(アラート)を自動で送る
②MT4からのアラートを受け取りハイローに自動エントリーする
それでは今回のソースコードを示します。
// prg-0013.mq4
#property copyright "Copyright 2024, smile-invest-blog.com"
#property link "https://www.smile-invest-blog.com/prg-0013/"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Yellow
#property indicator_color2 Red
#property indicator_width1 2
#property indicator_width2 2
#define PREFIX_VLINE "VLine_"
double Log1Up[]; // Highサイン用バッファ
double Log1Down[]; // Low サイン用バッファ
int realBars = 0;
int shortMaPeriod = 10; // 短期移動平均線の期間
int longMaPeriod = 30; // 長期移動平均線の期間
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexStyle(0, DRAW_ARROW, EMPTY);
SetIndexArrow(0, 233);
SetIndexBuffer(0, Log1Up);
SetIndexStyle(1, DRAW_ARROW, EMPTY);
SetIndexArrow(1, 234);
SetIndexBuffer(1, Log1Down);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| start function
//+------------------------------------------------------------------+
int start() {
bool ret_hantei; // hantei関数の結果格納用
int counted_bars=IndicatorCounted();
int limit = Bars - counted_bars;
for(int i = limit - 1; i >= 0; i--) {
if(i == 0) {
Log1Down[i] = EMPTY_VALUE;
Log1Up[i] = EMPTY_VALUE;
ret_hantei = hantei(i); // 上下サイン表示の判定を関数化した
if (ret_hantei == true) { // hantei関数の結果がtrueの時
if (realBars < Bars) { // 1本のローソク足で1回だけ実行するための条件
realBars = Bars; // realBarsをBarsにする事で同じローソク足では1回だけ実行する
if (Log1Up[i] != EMPTY_VALUE) { // hantei関数内で上サイン表示と判定された
Alert(Symbol(), " *** High ***");
}
else if (Log1Down[i] != EMPTY_VALUE) { // hantei関数内で下サイン表示と判定された
Alert(Symbol(), " *** Low ***");
}
}
}
if (TaskPeriod()){
if (Log1Up[i+1] != EMPTY_VALUE) {
entry(1, true);
}
if (Log1Down[i+1] != EMPTY_VALUE) {
entry(0, true);
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
//| エントリーの条件判定関数
//| int i メイン関数からのiの値
//+------------------------------------------------------------------+
bool hantei(int i) {
double shortMaPrevious, longMaPrevious;
double shortMaCurrent, longMaCurrent;
// 前回の移動平均値を取得
shortMaPrevious = iMA(NULL, 0, shortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i+1);
longMaPrevious = iMA(NULL, 0, longMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i+1);
// 現在の移動平均値を取得
shortMaCurrent = iMA(NULL, 0, shortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i);
longMaCurrent = iMA(NULL, 0, longMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i);
// 移動平均線のクロスを確認
if (shortMaPrevious < longMaPrevious && shortMaCurrent > longMaCurrent) {
// ゴールデンクロス → Highサイン
Log1Up[i] = Low[i] - 10 * Point;
return true;
}
else if (shortMaPrevious > longMaPrevious && shortMaCurrent < longMaCurrent) {
// デッドクロス → Lowサイン
Log1Down[i] = High[i] + 10 * Point;
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| entry function |
//| 引数1 1:Highエントリー、0:Lowエントリー、
//| 引数2 false:手動エントリー、true:自動エントリー、
//+------------------------------------------------------------------+
void entry(int high_low, bool isAuto) {
string strEntryCmd = " AMT";
/*
アラートコマンドリスト(AMT側で設定すること)
AMT1MA
AMT1MM
AMT5MA
AMT5MM
AMT15MA
AMT15MM
AMT60MA
AMT60MM
(AMTの個別アラート設定でそれぞれにHigh, Low の文字列を設定する)
*/
if (Period() == 1) {
strEntryCmd += "1M";
}
if (Period() == 5) {
strEntryCmd += "5M";
}
if (Period() == 15) {
strEntryCmd += "15M";
}
if (Period() == 60) {
strEntryCmd += "1H";
}
if (isAuto) {
strEntryCmd += "A";
}
else {
strEntryCmd += "M";
}
if (high_low == 1) {
strEntryCmd += " ***HIGH***";
}
else {
strEntryCmd += " ***LOW***";
}
Alert(Symbol(), strEntryCmd);
if (high_low == 1) {
drawVLine(Lime);
}
if (high_low == 0) {
drawVLine(Red);
}
}
//+------------------------------------------------------------------+
//| ローソク足確定時の処理
//+------------------------------------------------------------------+
bool TaskPeriod() {
static datetime s_lasttime; // 最後に記録した時間軸時間
// staticはこの関数が終了してもデータは保持される
datetime temptime = iTime( Symbol(), Period() ,0 ); // 現在の時間軸の時間取得
if ( temptime == s_lasttime ) { // 時間に変化が無い場合
return false; // 処理終了
}
s_lasttime = temptime; // 最後に記録した時間軸時間を保存
// ----- 処理はこれ以降に追加 -----------
return true; // 移動平均線のクロス判定
}
void drawVLine(color clr) {
string obj_name = StringFormat("%s_%d", PREFIX_VLINE, Bars);
int chart_id = 0;
ObjectCreate(chart_id,obj_name, // オブジェクト作成
OBJ_VLINE, // オブジェクトタイプ
0, // サブウインドウ番号
Time[0], // 1番目の時間のアンカーポイント
0 // 1番目の価格のアンカーポイント
);
ObjectSetInteger(chart_id,obj_name,OBJPROP_COLOR,clr); // ラインの色設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_STYLE,STYLE_SOLID); // ラインのスタイル設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_WIDTH,1); // ラインの幅設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_BACK,false); // オブジェクトの背景表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTABLE,true); // オブジェクトの選択可否設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTED,false); // オブジェクトの選択状態
ObjectSetInteger(chart_id,obj_name,OBJPROP_HIDDEN,true); // オブジェクトリスト表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_ZORDER,0); // オブジェクトのチャートクリックイベント優先順位
}
では、解説していきます。
14,15行目:サイン表示用のバッファ変数です。サイン表示の条件を満たす場合にこのバッファ変数に有効な値が入ります。
48,49行目:サイン表示用のバッファ変数をクリア(EMPTY_VALUEを代入)します。ループの中で毎回クリアしているので、条件を満たすか満たさないかの微妙な状態の時には未確定足(今足)ではサインがついたり消えたりします。次足に移った時には確定します。
51行目:サイン表示の条件を判定する関数(hantei)を呼んで、その戻り値(ret_hantei)を取得する。hantei関数の実体は82行目になります。
hantei関数の詳細については「MQL4プログラミング 第3回 インジケーターを作成してみよう(処理の関数化)」を参照してください。
55~60行目:上下どちらかのサインが出たタイミングでアラートを出します。この時のアラートではまだ自動エントリーはしません。次足でエントリーの可能性があるという意味合いのアラートです。
64~71行目:上下どちらかのサインが確定した時、entry関数を呼んでAMT側に自動エントリー用アラートを表示します。
115行目:entry関数の実体です。
116行目:アラート表示用文字列変数の定義と初期化をおこないます。文字列変数は” AMT”と初期化されています。
130~141行目:表示しているチャート足の期間を判別してアラート表示用文字列変数に文字列を追加しています。
143~148行目:entry関数の第二引数によりアラート表示用文字列変数に「A」(Auto)か「M」(Manual)を追加します。今回はAutoになります。
150~155行目:entry関数の第一引数によりHighサイン ” ***HIGH***” か Lowサイン ” ***LOW***” をアラート表示用文字列変数に追加します。
157行目:通貨ペア名称を添えてアラート表示用文字列をアラート表示します。この行を実行することによりAMTはハイローへの自動エントリーを実行します。
159~164行目:HighエントリーであればLime、LowエントリーであればRedの立てラインをチャート上に描画します。あとでチャート分析する時に便利です。
ライン描画の実体は185行目からのdrawVLine関数です。ソースコードのコメントを見ながら疑問点があればグーグル先生に聞いて調べてみて下さい。
自動エントリーの動作確認
それでは、今回の自動エントリーをおこなうインジケーターの動作確認をしましょう。
今回作成のサインツールでサインが表示されました。
サインが残ったまま確定しました。
チャート画面右下にAMTの「エントリー完了」のメッセージが表示されました。
ここでAMTの「エントリー完了」のメッセージが表示されない場合は、前回投稿の「AMT側の設定」で正しく設定をおこなって下さい。
ATM側のエントリーが正常にできるとATMの履歴データに上記のような行が先頭に追加されます。
次回は「既成のバッファ型サインツールにAMTの自動エントリー機能を構築する方法」の投稿を予定しております。
※重要事項! この自動エントリーの動作確認は必ずデモ口座でおこなって下さい。信頼できる結果が出せる自作のサインツールが作れたら十分テストをおこなった上で自己責任で本番口座でのトレードをお願いします。
今回の関連情報
・AMT(AutoMultiTrader)の無料ダウンロードは「AMT V2 ダウンロードサイト」、「AMT V1 ダウンロードサイト」から。
・ハイローのデモ口座は「ハイロー紹介ページ」から。