インジケータからEAを停止、再稼働する方法について

インジケータからEAのON/OFFを行う方法を調べていたのですが、win32APIのPostMessageを使い、
MT4のルートウィンドウにWM_COMMANDでwParamに33020を渡してやる事で、
ツールバーの自動売買ボタンをクリックしたのと同じ効果が得られる様です。具体的には、
PostMessageA(GetAncestor(WindowHandle(Symbol(),0), 2), WM_COMMAND, 33020,0);
あとはスケジュールを入力するUIを実装して、入力した情報をファイルに保存・読み込む機能をプラスし、
スケジュールに従ってEAをON/OFFするコードを書けば、
比較的容易にEATradeStopの様なプロダクトができあがります。
「じゃあお前が作れ」と思った方は

ランキング100位以内に入ったら製作してフリーソフトとして公開しようかなぁ^^
自動売買機能をON/OFFするデモンストレーションインジケータを用意しました。
仕様としては、だいたい10秒間隔で自動売買状態を切り替え、現在の状態をチャートにアイコン表示します。
ファイルはこちらからダウンロードできます。
zip内のEAOnOff.mq4を、MT4のファイルメニューからデータフォルダを開いたMQL4下のIndicatorsフォルダに格納し、
ナビゲータウィンドウからチャートにセットして下さい。win32APIのDLLを呼び出しているので、
パラメータ設定で「DLLの使用を許可する」のチェックを入れるようにしてください。
ソースコードを掲載しておきます。
//+------------------------------------------------------------------+
//| EAOnOff.mq4 |
//| Copyright 2022, yuki |
//| https://paopao46.blog.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, yuki"
#property link "https://paopao46.blog.fc2.com/"
#property version "1.00"
#property strict
#import "user32.dll"
int GetAncestor(int,int);
#import
#include <WinUser32.mqh>
#define ICON_LABAL "EAEnableLabel"
string NikonikoChar = CharToStr(74);
string PunpunChar = CharToStr(76);
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//ニコニコプンプンアイコン表示
void _DispNikoPunIcon()
{
static bool bLastStatusIsOn;
if((bLastStatusIsOn && IsExpertEnabled()) ||
(!bLastStatusIsOn && !IsExpertEnabled()))
return;
bLastStatusIsOn = IsExpertEnabled();
if(ObjectFind(ICON_LABAL) >= 0)
ObjectDelete(ICON_LABAL);
int xoffset = 10;
int yoffset = 15;
string statusIcon;
color c;
if(bLastStatusIsOn){
c = C'40,180,40';
statusIcon = NikonikoChar;
}else{
c = C'220,40,40';
statusIcon = PunpunChar;
}
ObjectCreate(0, ICON_LABAL, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0,ICON_LABAL,OBJPROP_HIDDEN,true);
ObjectSetInteger(0,ICON_LABAL,OBJPROP_SELECTABLE,false);
ObjectSet(ICON_LABAL, OBJPROP_CORNER, CORNER_LEFT_LOWER);
ObjectSet(ICON_LABAL, OBJPROP_XDISTANCE, xoffset);
ObjectSet(ICON_LABAL, OBJPROP_YDISTANCE, yoffset);
ObjectSetText(ICON_LABAL, statusIcon, 48, "Wingdings", c);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
static string HHMMS0; //前回切替時刻の10秒未満を切った文字列
_DispNikoPunIcon(); //アイコン表示
//現在時刻の HH:MM:S0
string now0 = TimeToStr(TimeLocal(), TIME_SECONDS);
now0 = StringSubstr(now0, 0, StringLen(now0) - 1);
if(HHMMS0 != now0){
//だいたい十秒ごとにON/OFFする
HHMMS0 = now0;
PostMessageA(GetAncestor(WindowHandle(Symbol(),0), 2), WM_COMMAND, 33020, 0);
_DispNikoPunIcon(); //アイコン表示
ChartRedraw(0);
}
return(rates_total - 1);
}
//+------------------------------------------------------------------+
| h o m e |