Refactor EA codebase and update project docs
This commit is contained in:
@@ -1,642 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| HIT_EA.mq5 |
|
|
||||||
//| Copyright 2026, nanpin-martin.com |
|
|
||||||
//| https://www.nanpin-martin.com |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2026, nanpin-martin.com"
|
|
||||||
#property link "https://nanpin-martin.com/"
|
|
||||||
#property version "1.01"
|
|
||||||
|
|
||||||
#include <MyLib/Trading/SLTPManager.mqh>
|
|
||||||
#include <MyLib/Panel/SLTPManagerPanel.mqh>
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| バッチファイル実行用の設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// Windowsプロセス起動・終了確認用
|
|
||||||
#define CREATE_NO_WINDOW 0x08000000
|
|
||||||
#define PROCESS_QUERY_LIMITED_INFORMATION 0x00001000
|
|
||||||
#define SYNCHRONIZE 0x00100000
|
|
||||||
#define WAIT_OBJECT_0 0
|
|
||||||
#define WAIT_TIMEOUT 258
|
|
||||||
#define STILL_ACTIVE 259
|
|
||||||
#define TASKKILL_WAIT_MILLISECONDS 5000
|
|
||||||
|
|
||||||
struct STARTUPINFO_W
|
|
||||||
{
|
|
||||||
uint cb;
|
|
||||||
string lpReserved;
|
|
||||||
string lpDesktop;
|
|
||||||
string lpTitle;
|
|
||||||
uint dwX;
|
|
||||||
uint dwY;
|
|
||||||
uint dwXSize;
|
|
||||||
uint dwYSize;
|
|
||||||
uint dwXCountChars;
|
|
||||||
uint dwYCountChars;
|
|
||||||
uint dwFillAttribute;
|
|
||||||
uint dwFlags;
|
|
||||||
ushort wShowWindow;
|
|
||||||
ushort cbReserved2;
|
|
||||||
long lpReserved2;
|
|
||||||
long hStdInput;
|
|
||||||
long hStdOutput;
|
|
||||||
long hStdError;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PROCESS_INFORMATION
|
|
||||||
{
|
|
||||||
long hProcess;
|
|
||||||
long hThread;
|
|
||||||
uint dwProcessId;
|
|
||||||
uint dwThreadId;
|
|
||||||
};
|
|
||||||
|
|
||||||
#import "kernel32.dll"
|
|
||||||
int CreateProcessW(string lpApplicationName, string lpCommandLine, long lpProcessAttributes, long lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, long lpEnvironment, string lpCurrentDirectory, STARTUPINFO_W &lpStartupInfo, PROCESS_INFORMATION &lpProcessInformation);
|
|
||||||
int WaitForSingleObject(long hHandle, uint dwMilliseconds);
|
|
||||||
int GetExitCodeProcess(long hProcess, uint &lpExitCode);
|
|
||||||
int CloseHandle(long hObject);
|
|
||||||
long OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);
|
|
||||||
#import
|
|
||||||
|
|
||||||
// バッチファイルのパス
|
|
||||||
// Python helper scripts are managed under this MT5 data folder:
|
|
||||||
// <TerminalDataPath>\MQL5\python_for_ea
|
|
||||||
string python_app_dir = "";
|
|
||||||
string get_trend_reply_bat = ""; // H4: trend
|
|
||||||
string get_entry_reply_bat = ""; // H1: entry
|
|
||||||
string mt5_file_prefix = ""; // Python linkage file namespace
|
|
||||||
|
|
||||||
// プロセス完了ファイルの設定
|
|
||||||
string done_trend_file = "process_done_trend.txt";
|
|
||||||
string done_entry_file = "process_done_entry.txt";
|
|
||||||
|
|
||||||
// Python出力ファイル
|
|
||||||
string ohlc_h4_file = "ohlc_H4.csv";
|
|
||||||
string ohlc_h1_file = "ohlc_H1.csv";
|
|
||||||
string trend_state_file = "trend_state.txt";
|
|
||||||
string target_prices_file = "target_prices.txt";
|
|
||||||
string target_zones_file = "target_zones.txt";
|
|
||||||
|
|
||||||
// Python実行中を判定するための管理ファイル
|
|
||||||
string running_trend_file = "process_running_trend.txt";
|
|
||||||
string running_entry_file = "process_running_entry.txt";
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| インプットの設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
enum SplitLotMode
|
|
||||||
{
|
|
||||||
SPLIT_LOT_TOTAL = 0, // 総ロットをN分割
|
|
||||||
SPLIT_LOT_FIXED = 1 // 1注文あたり固定ロット
|
|
||||||
};
|
|
||||||
|
|
||||||
//--- 入力パラメータ
|
|
||||||
input double lot_size = 0.01; // ロット数
|
|
||||||
input double spread_limit = 60; // 許容スプレッド(point)
|
|
||||||
input int magic_number = 10001; // マジックナンバー
|
|
||||||
input int initial_order = 0; // 互換性維持用。起動時H4/H1再構築は常時実行
|
|
||||||
input int input_position_limit = 10; // 自EAの未約定注文+ポジション上限
|
|
||||||
input bool use_split_entry_zone = false; // H1予測ゾーンで分割エントリーする
|
|
||||||
input int split_entry_count = 3; // 分割エントリー本数(1..10)
|
|
||||||
input SplitLotMode split_lot_mode = SPLIT_LOT_TOTAL; // 分割ロット配分モード
|
|
||||||
input double split_total_lot_size = 0.09; // 総量分割モードの合計ロット
|
|
||||||
input double split_fixed_lot_size = 0.01; // 固定ロットモードの1注文ロット
|
|
||||||
input bool cancel_old_split_pending_on_new_zone = true; // 新ゾーン読込時に旧分割pendingを取消
|
|
||||||
input int input_cancel_retry_cooldown_seconds = 60; // pending取消失敗時のticket単位再試行間隔
|
|
||||||
input bool use_m15_entry_filter = true; // M15確定足で発注タイミングを確認
|
|
||||||
input double m15_entry_zone_atr_multiplier = 1.50; // M15平均レンジ何本分まで候補価格への接近を許可
|
|
||||||
input bool use_m15_imbalance_confirmation = true; // T1/T3でM15初動確認を追加
|
|
||||||
input int m15_imbalance_avg_body_period = 20; // M15平均実体計算期間
|
|
||||||
input double m15_imbalance_sensitivity = 2.0; // M15初動検知感度
|
|
||||||
input double m15_imbalance_min_avg_body_points = 1.0; // 平均実体の最小値(point)
|
|
||||||
input bool use_m15_imbalance_debug_log = false; // M15初動確認ログ
|
|
||||||
input int input_entry_max_candidate_age_minutes = 120; // H1候補価格を新規発注に使う最大経過分数
|
|
||||||
input double input_tp_multiplier = 1.25; // TP distance multiplier (1.0=no expansion)
|
|
||||||
input int input_min_tp_points = 0; // Minimum TP distance in points (0=disabled)
|
|
||||||
input int input_max_tp_points = 0; // Maximum expanded TP distance in points (0=disabled)
|
|
||||||
input bool input_range_breakout_guard_enabled = true; // レンジ上抜け/下抜け時に逆張りLimitを退避
|
|
||||||
input ENUM_TIMEFRAMES input_range_breakout_guard_timeframe = PERIOD_M15; // レンジブレイク監視足
|
|
||||||
input int input_range_breakout_lookback_bars = 20; // レンジ高値安値の参照本数
|
|
||||||
input double input_range_breakout_max_width_multiplier = 6.0; // 平均レンジに対する最大レンジ幅
|
|
||||||
input double input_range_breakout_buffer_multiplier = 0.20; // ブレイク確定バッファ倍率
|
|
||||||
input double input_range_breakout_near_multiplier = 0.50; // ブレイク警戒の境界接近幅倍率
|
|
||||||
input double input_range_breakout_body_multiplier = 1.50; // 勢い判定の平均実体倍率
|
|
||||||
input int input_range_breakout_cooldown_bars = 4; // 逆張りLimit停止を継続する足数
|
|
||||||
input bool input_sltp_manager_enabled = false; // UI連動SLTP管理を有効化
|
|
||||||
input bool input_sltp_show_panel = true; // SLTP操作パネルを表示
|
|
||||||
input bool input_sltp_use_breakeven = false; // 通常ブレークイーブンを有効化
|
|
||||||
input double input_sltp_breakeven_trigger_pips = 30.0; // 通常BE開始pips
|
|
||||||
input double input_sltp_breakeven_buffer_pips = 3.0; // 通常BE固定バッファpips
|
|
||||||
input bool input_sltp_use_elapsed_breakeven = false; // 保有時間BEを有効化
|
|
||||||
input double input_sltp_elapsed_breakeven_hours = 4.0; // 保有時間BE開始時間
|
|
||||||
input double input_sltp_elapsed_breakeven_buffer_pips = 3.0; // 保有時間BE固定バッファpips
|
|
||||||
input bool input_sltp_use_active_trailing = false; // アクティブトレーリングを有効化
|
|
||||||
input double input_sltp_active_breakeven_pips = 30.0; // アクティブ開始pips
|
|
||||||
input double input_sltp_active_stop_loss_offset_pips = 5.0; // 初期固定pips
|
|
||||||
input double input_sltp_active_step_trigger_pips = 10.0; // ステップ更新間隔pips
|
|
||||||
input double input_sltp_active_step_move_pips = 5.0; // 1ステップ固定追加pips
|
|
||||||
input bool input_sltp_use_tp_progress_stop = false; // TP進捗SLを有効化
|
|
||||||
input double input_sltp_tp_progress_trigger_percent = 70.0; // TP進捗SL開始率
|
|
||||||
input double input_sltp_tp_progress_sl_lock_percent = 30.0; // TP距離固定率
|
|
||||||
input bool input_sltp_use_high_volatility_limit = false; // 急変時SL引き締めを有効化
|
|
||||||
ulong slippage = 10; // スリッページ
|
|
||||||
|
|
||||||
//--- 主要な定数・設定
|
|
||||||
#define POSITION_LIMIT 48
|
|
||||||
#define ENTRY_H1_LIMIT 2 // H1本数(=2時間)
|
|
||||||
#define CLOSE_H1_LIMIT 12 // H1本数(=12時間)
|
|
||||||
#define HISTORY_BARS 72
|
|
||||||
#define OHLC_START_SHIFT 1 // 1: 確定足のみをPythonへ渡す
|
|
||||||
#define M15_CONFIRM_BARS 30
|
|
||||||
#define M15_MIN_ENTRY_ZONE_POINTS 10
|
|
||||||
#define M15_MIN_BODY_RATIO 0.25
|
|
||||||
#define M15_REJECTION_WICK_RATIO 0.35
|
|
||||||
#define ENTRY_RETRY_SECONDS 60
|
|
||||||
#define ENTRY_RETRY_LIMIT 10
|
|
||||||
// ANALYZE_TIMEFRAME は削除(H4/H1 両方使うため定数ではなく直接指定)
|
|
||||||
#define TARGET_SIZE 13
|
|
||||||
#define TARGET_ZONE_SCHEMA_VERSION 2
|
|
||||||
#define DEFAULT_TARGET_PRICE 0.0
|
|
||||||
#define PYTHON_TIMEOUT_SECONDS 600 // Python完了待ちの上限(秒)
|
|
||||||
|
|
||||||
#define MARKET_LOW_VOL_RANGE 0
|
|
||||||
#define MARKET_HIGH_VOL_RANGE 1
|
|
||||||
#define MARKET_LOW_VOL_UP 2
|
|
||||||
#define MARKET_HIGH_VOL_UP 3
|
|
||||||
#define MARKET_LOW_VOL_DOWN 4
|
|
||||||
#define MARKET_HIGH_VOL_DOWN 5
|
|
||||||
#define MARKET_TECHNICAL_ERROR_STOP 6
|
|
||||||
|
|
||||||
#define RANGE_BREAKOUT_NONE 0
|
|
||||||
#define RANGE_BREAKOUT_UP 1
|
|
||||||
#define RANGE_BREAKOUT_DOWN -1
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| EAの状態をまとめる構造体
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
struct EAState
|
|
||||||
{
|
|
||||||
int trend_state; // H4 market_state(0..5、6は技術エラー停止)を格納する変数
|
|
||||||
int res_chk; // GPTの回答が正しく取得できたか
|
|
||||||
double en_price[5]; // エントリー基準価格
|
|
||||||
double tp_price[5]; // 利益確定価格
|
|
||||||
double sl_price[5]; // ロスカット基準価格
|
|
||||||
int zone_res_chk; // 予測ゾーンが正しく取得できたか
|
|
||||||
string zone_candidate_id; // H1確定足由来の候補ID
|
|
||||||
double zone_low[5]; // 分割エントリー用ゾーン下限
|
|
||||||
double zone_high[5]; // 分割エントリー用ゾーン上限
|
|
||||||
double zone_tp[5]; // 分割エントリー用TP
|
|
||||||
double zone_sl[5]; // 分割エントリー用SL
|
|
||||||
bool load_trend_flg; // ★変更:トレンドを更新するタイミングか
|
|
||||||
bool load_target_flg; // ★変更:ターゲット価格を更新するタイミングか
|
|
||||||
int chk_cnt; // エントリー判定の試行回数
|
|
||||||
datetime last_trend_update; // ★追加:前回トレンドを更新した時刻
|
|
||||||
datetime last_target_update; // ★変更:前回ターゲット価格を更新した時刻
|
|
||||||
datetime target_loaded_at; // H1候補価格をEAへ読み込んだサーバー時刻
|
|
||||||
datetime target_candidate_at; // H1候補価格の元になった確定足時刻
|
|
||||||
datetime last_chk;
|
|
||||||
};
|
|
||||||
|
|
||||||
EAState g_ea; // EA全体の状態をここで管理
|
|
||||||
|
|
||||||
// Startup refresh flags for H4 trend and H1 entry candidates.
|
|
||||||
// Keep them separate to prevent repeated startup launches.
|
|
||||||
bool g_init_trend_pending = false;
|
|
||||||
bool g_init_entry_pending = false;
|
|
||||||
|
|
||||||
// H4/H1のバー更新状態
|
|
||||||
int g_pre_bars_H4 = 0;
|
|
||||||
int g_pre_bars_H1 = 0;
|
|
||||||
int g_pre_bars_M15 = 0;
|
|
||||||
bool g_bars_H1_check = false;
|
|
||||||
bool g_bars_M15_check = false;
|
|
||||||
|
|
||||||
// pending取消失敗時の過剰な取引サーバー要求を防止する。
|
|
||||||
ulong g_cancel_retry_tickets[];
|
|
||||||
datetime g_cancel_retry_at[];
|
|
||||||
|
|
||||||
// レンジブレイク時に逆張りLimitを一時停止する状態。
|
|
||||||
int g_range_breakout_guard_direction = RANGE_BREAKOUT_NONE;
|
|
||||||
datetime g_range_breakout_guard_until = 0;
|
|
||||||
|
|
||||||
// ティックごとの価格情報
|
|
||||||
struct TickContext
|
|
||||||
{
|
|
||||||
double ask;
|
|
||||||
double bid;
|
|
||||||
double spread;
|
|
||||||
double spread_points;
|
|
||||||
int digits;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 外部Pythonプロセスの状態
|
|
||||||
struct ExternalProcessState
|
|
||||||
{
|
|
||||||
long handle;
|
|
||||||
uint process_id;
|
|
||||||
bool active;
|
|
||||||
bool exit_code_ready;
|
|
||||||
uint exit_code;
|
|
||||||
datetime started_at;
|
|
||||||
};
|
|
||||||
|
|
||||||
ExternalProcessState g_trend_process;
|
|
||||||
ExternalProcessState g_entry_process;
|
|
||||||
|
|
||||||
CSLTPManager g_sltp_manager;
|
|
||||||
CSLTPManagerPanel g_sltp_panel;
|
|
||||||
SLTPManagerPanelSettings g_sltp_settings;
|
|
||||||
bool g_sltp_settings_valid = false;
|
|
||||||
bool g_sltp_panel_created = false;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Python連携パスをMT5データフォルダから組み立てる関数
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief MT5データフォルダ配下のMQL5ルートを返します。
|
|
||||||
*/
|
|
||||||
string MQL5RootPath()
|
|
||||||
{
|
|
||||||
return TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5";
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief EAと同じMQL5ツリー内にあるPython補助アプリのルートを返します。
|
|
||||||
*/
|
|
||||||
string PythonAppDir()
|
|
||||||
{
|
|
||||||
return MQL5RootPath() + "\\python_for_ea";
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief Python補助アプリ配下のbatファイル絶対パスを返します。
|
|
||||||
*/
|
|
||||||
string PythonBatchPath(const string filename)
|
|
||||||
{
|
|
||||||
return PythonAppDir() + "\\bat\\" + filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief ファイル名に使える安全なトークン文字か判定します。
|
|
||||||
*/
|
|
||||||
bool IsSafeFileTokenChar(const int ch)
|
|
||||||
{
|
|
||||||
return ((ch >= 48 && ch <= 57) || // 0-9
|
|
||||||
(ch >= 65 && ch <= 90) || // A-Z
|
|
||||||
(ch >= 97 && ch <= 122) || // a-z
|
|
||||||
ch == 95 || ch == 45); // _ or -
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief シンボル名などをファイル名向けの安全なトークンへ変換します。
|
|
||||||
*/
|
|
||||||
string SanitizeFileToken(const string value)
|
|
||||||
{
|
|
||||||
string result = "";
|
|
||||||
int length = StringLen(value);
|
|
||||||
for(int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
int ch = StringGetCharacter(value, i);
|
|
||||||
if(IsSafeFileTokenChar(ch))
|
|
||||||
result += StringSubstr(value, i, 1);
|
|
||||||
else
|
|
||||||
result += "_";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result == "")
|
|
||||||
return "UNKNOWN";
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief 同一Terminal内の複数EA/複数シンボルで連携ファイルが衝突しない接頭辞を返します。
|
|
||||||
*/
|
|
||||||
string BuildMT5FilePrefix()
|
|
||||||
{
|
|
||||||
return "HIT_" + SanitizeFileToken(_Symbol) + "_" + IntegerToString(magic_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief Python連携ファイル名へEA固有の接頭辞を付けます。
|
|
||||||
*/
|
|
||||||
string PrefixedMT5FileName(const string base_name)
|
|
||||||
{
|
|
||||||
if(mt5_file_prefix == "")
|
|
||||||
return base_name;
|
|
||||||
|
|
||||||
return mt5_file_prefix + "_" + base_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief Python連携で使用するMT5 Files配下のファイル名を初期化します。
|
|
||||||
*/
|
|
||||||
void ConfigurePythonGatewayFileNames()
|
|
||||||
{
|
|
||||||
mt5_file_prefix = BuildMT5FilePrefix();
|
|
||||||
|
|
||||||
ohlc_h4_file = PrefixedMT5FileName("ohlc_H4.csv");
|
|
||||||
ohlc_h1_file = PrefixedMT5FileName("ohlc_H1.csv");
|
|
||||||
done_trend_file = PrefixedMT5FileName("process_done_trend.txt");
|
|
||||||
done_entry_file = PrefixedMT5FileName("process_done_entry.txt");
|
|
||||||
trend_state_file = PrefixedMT5FileName("trend_state.txt");
|
|
||||||
target_prices_file = PrefixedMT5FileName("target_prices.txt");
|
|
||||||
target_zones_file = PrefixedMT5FileName("target_zones.txt");
|
|
||||||
running_trend_file = PrefixedMT5FileName("process_running_trend.txt");
|
|
||||||
running_entry_file = PrefixedMT5FileName("process_running_entry.txt");
|
|
||||||
|
|
||||||
Print("Python file prefix: ", mt5_file_prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief Python連携で使用するbatパスを初期化します。
|
|
||||||
*/
|
|
||||||
void ConfigurePythonGatewayPaths()
|
|
||||||
{
|
|
||||||
ConfigurePythonGatewayFileNames();
|
|
||||||
|
|
||||||
python_app_dir = PythonAppDir();
|
|
||||||
get_trend_reply_bat = PythonBatchPath("get_trend_reply.bat");
|
|
||||||
get_entry_reply_bat = PythonBatchPath("get_entry_reply.bat");
|
|
||||||
|
|
||||||
Print("Python app dir: ", python_app_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 起動時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief EA起動時の初期化処理を行います。
|
|
||||||
*
|
|
||||||
* Python連携用のdone/runningファイル状態を確認し、起動直後は安全側として
|
|
||||||
* H4トレンド判定とH1エントリー価格生成をそれぞれ初回実行対象にします。
|
|
||||||
* H4結果を再読込するまでは技術エラー停止値を維持し、古い連携結果での発注を防ぎます。
|
|
||||||
*/
|
|
||||||
int OnInit()
|
|
||||||
// プロセス完了ファイルと実行中ファイルの状態を初期化
|
|
||||||
{
|
|
||||||
ConfigurePythonGatewayPaths();
|
|
||||||
|
|
||||||
PrepareDoneFileOnInit(done_trend_file, running_trend_file, "trend");
|
|
||||||
PrepareDoneFileOnInit(done_entry_file, running_entry_file, "entry");
|
|
||||||
|
|
||||||
// Always rebuild startup state before allowing new orders.
|
|
||||||
g_ea.trend_state = MARKET_TECHNICAL_ERROR_STOP;
|
|
||||||
g_ea.res_chk = 0;
|
|
||||||
g_ea.zone_res_chk = 0;
|
|
||||||
g_ea.zone_candidate_id = "0";
|
|
||||||
g_init_trend_pending = true;
|
|
||||||
g_init_entry_pending = true;
|
|
||||||
ArrayResize(g_cancel_retry_tickets, 0);
|
|
||||||
ArrayResize(g_cancel_retry_at, 0);
|
|
||||||
|
|
||||||
if(!InitializeSLTPManager())
|
|
||||||
return INIT_FAILED;
|
|
||||||
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 終了時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
ResetExternalProcessState(g_trend_process);
|
|
||||||
ResetExternalProcessState(g_entry_process);
|
|
||||||
|
|
||||||
if(g_sltp_panel_created)
|
|
||||||
g_sltp_panel.Destroy(reason);
|
|
||||||
|
|
||||||
// Clear chart status text left by Comment() when the EA is removed.
|
|
||||||
Comment("");
|
|
||||||
ChartRedraw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| ティック毎の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief ティック受信ごとにEA全体の処理を制御します。
|
|
||||||
*
|
|
||||||
* 処理順序は、ティック情報取得、期限切れ注文/ポジション管理、H4トレンド更新、
|
|
||||||
* H1エントリー価格更新、M15エントリータイミング更新、ステータス表示、新規注文判定の順です。
|
|
||||||
* 時間制限処理はPython完了待ちやスプレッド判定より前に実行します。
|
|
||||||
*/
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
TickContext ctx;
|
|
||||||
if(!GetTickContext(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 期限切れ注文・ポジションは、Python待ちやスプレッド制限に関係なく先に処理する。
|
|
||||||
ManageExpiredTrades();
|
|
||||||
|
|
||||||
// Existing-position protection stays active even while Python results are pending.
|
|
||||||
ManageSLTPPositions();
|
|
||||||
|
|
||||||
// Delete and pause adverse limit orders before breakout spikes can fill them.
|
|
||||||
ManageRangeBreakoutLimitGuard(ctx);
|
|
||||||
|
|
||||||
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
|
|
||||||
RecoverTimedOutPythonProcesses();
|
|
||||||
|
|
||||||
// H4新バーまたは初回起動時に、トレンド判定用Pythonを起動する。
|
|
||||||
ProcessTrendUpdate(g_ea);
|
|
||||||
|
|
||||||
// トレンド判定が完了していない場合、新規注文側の処理だけをスキップする。
|
|
||||||
if(!IsTrendResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTrendState(g_ea);
|
|
||||||
|
|
||||||
// H1新バーまたは初回起動時に、エントリー価格生成用Pythonを起動する。
|
|
||||||
ProcessEntryUpdate(g_ea);
|
|
||||||
|
|
||||||
// M15確定足ごとに、H1候補価格を発注してよいタイミングか再判定する。
|
|
||||||
ProcessM15EntryTimingUpdate();
|
|
||||||
|
|
||||||
UpdateStatusComment(ctx);
|
|
||||||
|
|
||||||
// ここから下は新規注文に関する処理。
|
|
||||||
if(!IsSpreadAllowed(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!IsEntryResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTargetPrices(g_ea);
|
|
||||||
ProcessEntryDecisionIfNeeded(g_ea, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| SLTP manager panel and settings bridge
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
string SLTPBoolText(const bool value)
|
|
||||||
{
|
|
||||||
return value ? "ON" : "OFF";
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadSLTPInputSettings(SLTPManagerPanelSettings &settings)
|
|
||||||
{
|
|
||||||
settings.manager_enabled = input_sltp_manager_enabled;
|
|
||||||
|
|
||||||
settings.use_breakeven = input_sltp_use_breakeven;
|
|
||||||
settings.breakeven_trigger_pips = input_sltp_breakeven_trigger_pips;
|
|
||||||
settings.breakeven_buffer_pips = input_sltp_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_elapsed_breakeven = input_sltp_use_elapsed_breakeven;
|
|
||||||
settings.elapsed_breakeven_hours = input_sltp_elapsed_breakeven_hours;
|
|
||||||
settings.elapsed_breakeven_buffer_pips = input_sltp_elapsed_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_active_trailing = input_sltp_use_active_trailing;
|
|
||||||
settings.active_breakeven_pips = input_sltp_active_breakeven_pips;
|
|
||||||
settings.active_stop_loss_offset_pips = input_sltp_active_stop_loss_offset_pips;
|
|
||||||
settings.active_step_trigger_pips = input_sltp_active_step_trigger_pips;
|
|
||||||
settings.active_step_move_pips = input_sltp_active_step_move_pips;
|
|
||||||
|
|
||||||
settings.use_tp_progress_stop = input_sltp_use_tp_progress_stop;
|
|
||||||
settings.tp_progress_trigger_percent = input_sltp_tp_progress_trigger_percent;
|
|
||||||
settings.tp_progress_sl_lock_percent = input_sltp_tp_progress_sl_lock_percent;
|
|
||||||
|
|
||||||
settings.use_high_volatility_limit = input_sltp_use_high_volatility_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApplySLTPSettings(const SLTPManagerPanelSettings &settings,
|
|
||||||
const bool print_summary)
|
|
||||||
{
|
|
||||||
g_sltp_settings_valid = false;
|
|
||||||
|
|
||||||
g_sltp_manager.SetMagicNumber((ulong)magic_number);
|
|
||||||
g_sltp_manager.SetSymbol(_Symbol);
|
|
||||||
g_sltp_manager.SetDeviationInPoints(slippage);
|
|
||||||
g_sltp_manager.SetBreakevenSettings(settings.use_breakeven,
|
|
||||||
settings.breakeven_trigger_pips,
|
|
||||||
settings.breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetElapsedBreakevenSettings(settings.use_elapsed_breakeven,
|
|
||||||
settings.elapsed_breakeven_hours,
|
|
||||||
settings.elapsed_breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetActiveTrailingSettings(settings.use_active_trailing,
|
|
||||||
settings.active_breakeven_pips,
|
|
||||||
settings.active_stop_loss_offset_pips,
|
|
||||||
settings.active_step_trigger_pips,
|
|
||||||
settings.active_step_move_pips);
|
|
||||||
g_sltp_manager.SetTpProgressStopSettings(settings.use_tp_progress_stop,
|
|
||||||
settings.tp_progress_trigger_percent,
|
|
||||||
settings.tp_progress_sl_lock_percent);
|
|
||||||
g_sltp_manager.SetHighVolatilityLimitSettings(settings.use_high_volatility_limit);
|
|
||||||
|
|
||||||
if(!g_sltp_manager.ValidateSettings())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings rejected. Manager is disabled until valid settings are applied.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_settings = settings;
|
|
||||||
g_sltp_settings_valid = true;
|
|
||||||
|
|
||||||
if(print_summary)
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings: Manager=", SLTPBoolText(settings.manager_enabled),
|
|
||||||
" BE=", SLTPBoolText(settings.use_breakeven),
|
|
||||||
" ElapsedBE=", SLTPBoolText(settings.use_elapsed_breakeven),
|
|
||||||
" ActiveTrail=", SLTPBoolText(settings.use_active_trailing),
|
|
||||||
" TPProgress=", SLTPBoolText(settings.use_tp_progress_stop),
|
|
||||||
" HighVol=", SLTPBoolText(settings.use_high_volatility_limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitializeSLTPManager()
|
|
||||||
{
|
|
||||||
SLTPManagerPanelSettings initial_settings;
|
|
||||||
LoadSLTPInputSettings(initial_settings);
|
|
||||||
|
|
||||||
if(!ApplySLTPSettings(initial_settings, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
g_sltp_panel.Init(g_sltp_settings);
|
|
||||||
if(input_sltp_show_panel)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel.CreatePanel())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP panel is unavailable. EA continues with input-based SLTP settings.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_panel.SetInitialValues();
|
|
||||||
g_sltp_panel_created = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManageSLTPPositions()
|
|
||||||
{
|
|
||||||
if(!g_sltp_settings_valid)
|
|
||||||
return;
|
|
||||||
if(!g_sltp_settings.manager_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_sltp_manager.ManagePositions();
|
|
||||||
g_sltp_manager.HighVolatilityLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnChartEvent(const int id,
|
|
||||||
const long &lparam,
|
|
||||||
const double &dparam,
|
|
||||||
const string &sparam)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel_created)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SLTPManagerPanelSettings candidate_settings = g_sltp_settings;
|
|
||||||
if(g_sltp_panel.HandleChartEvent(id, lparam, dparam, sparam, candidate_settings))
|
|
||||||
{
|
|
||||||
if(!ApplySLTPSettings(candidate_settings, true))
|
|
||||||
Print("HIT SLTP panel apply failed. Please review panel values.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Function implementations are kept in project headers so the EA entry points stay compact.
|
|
||||||
#include <MyLib/Common/HITRuntimeController.mqh>
|
|
||||||
#include <MyLib/Signals/HITEntrySignal.mqh>
|
|
||||||
#include <MyLib/Common/HITExternalProcess.mqh>
|
|
||||||
#include <MyLib/Signals/HITPythonSignalGateway.mqh>
|
|
||||||
#include <MyLib/Trading/HITTradeManager.mqh>
|
|
||||||
@@ -1,441 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| HIT_EA.mq5 |
|
|
||||||
//| Copyright 2026, nanpin-martin.com |
|
|
||||||
//| https://www.nanpin-martin.com |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2026, nanpin-martin.com"
|
|
||||||
#property link "https://nanpin-martin.com/"
|
|
||||||
#property version "1.01"
|
|
||||||
|
|
||||||
#include <MyLib/Trading/SLTPManager.mqh>
|
|
||||||
#include <MyLib/Panel/SLTPManagerPanel.mqh>
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| バッチファイル実行用の設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// Windowsプロセス起動・終了確認用
|
|
||||||
#define CREATE_NO_WINDOW 0x08000000
|
|
||||||
#define PROCESS_QUERY_LIMITED_INFORMATION 0x00001000
|
|
||||||
#define SYNCHRONIZE 0x00100000
|
|
||||||
#define WAIT_OBJECT_0 0
|
|
||||||
#define WAIT_TIMEOUT 258
|
|
||||||
#define STILL_ACTIVE 259
|
|
||||||
|
|
||||||
struct STARTUPINFO_W
|
|
||||||
{
|
|
||||||
uint cb;
|
|
||||||
string lpReserved;
|
|
||||||
string lpDesktop;
|
|
||||||
string lpTitle;
|
|
||||||
uint dwX;
|
|
||||||
uint dwY;
|
|
||||||
uint dwXSize;
|
|
||||||
uint dwYSize;
|
|
||||||
uint dwXCountChars;
|
|
||||||
uint dwYCountChars;
|
|
||||||
uint dwFillAttribute;
|
|
||||||
uint dwFlags;
|
|
||||||
ushort wShowWindow;
|
|
||||||
ushort cbReserved2;
|
|
||||||
long lpReserved2;
|
|
||||||
long hStdInput;
|
|
||||||
long hStdOutput;
|
|
||||||
long hStdError;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PROCESS_INFORMATION
|
|
||||||
{
|
|
||||||
long hProcess;
|
|
||||||
long hThread;
|
|
||||||
uint dwProcessId;
|
|
||||||
uint dwThreadId;
|
|
||||||
};
|
|
||||||
|
|
||||||
#import "kernel32.dll"
|
|
||||||
int CreateProcessW(string lpApplicationName, string lpCommandLine, long lpProcessAttributes, long lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, long lpEnvironment, string lpCurrentDirectory, STARTUPINFO_W &lpStartupInfo, PROCESS_INFORMATION &lpProcessInformation);
|
|
||||||
int WaitForSingleObject(long hHandle, uint dwMilliseconds);
|
|
||||||
int GetExitCodeProcess(long hProcess, uint &lpExitCode);
|
|
||||||
int CloseHandle(long hObject);
|
|
||||||
long OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);
|
|
||||||
#import
|
|
||||||
|
|
||||||
// バッチファイルのパス
|
|
||||||
string get_trend_reply_bat = "C:\\ea_py\\bat\\get_trend_reply.bat"; // H4: trend
|
|
||||||
string get_entry_reply_bat = "C:\\ea_py\\bat\\get_entry_reply.bat"; // H1: entry
|
|
||||||
|
|
||||||
// プロセス完了ファイルの設定
|
|
||||||
string done_trend_file = "process_done_trend.txt";
|
|
||||||
string done_entry_file = "process_done_entry.txt";
|
|
||||||
|
|
||||||
// Python出力ファイル
|
|
||||||
string trend_state_file = "trend_state.txt";
|
|
||||||
string target_prices_file = "target_prices.txt";
|
|
||||||
|
|
||||||
// Python実行中を判定するための管理ファイル
|
|
||||||
string running_trend_file = "process_running_trend.txt";
|
|
||||||
string running_entry_file = "process_running_entry.txt";
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| インプットの設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//--- 入力パラメータ
|
|
||||||
input double lot_size = 0.01; // ロット数
|
|
||||||
input double spread_limit = 60; // 許容スプレッド(point)
|
|
||||||
input int magic_number = 10001; // マジックナンバー
|
|
||||||
input int initial_order = 0; // 起動時の注文(0:なし, 1:あり)
|
|
||||||
input bool use_m15_entry_filter = true; // M15確定足で発注タイミングを確認
|
|
||||||
input double m15_entry_zone_atr_multiplier = 1.50; // M15平均レンジ何本分まで候補価格への接近を許可
|
|
||||||
input bool use_m15_imbalance_confirmation = true; // T1/T3でM15初動確認を追加
|
|
||||||
input int m15_imbalance_avg_body_period = 20; // M15平均実体計算期間
|
|
||||||
input double m15_imbalance_sensitivity = 2.0; // M15初動検知感度
|
|
||||||
input double m15_imbalance_min_avg_body_points = 1.0; // 平均実体の最小値(point)
|
|
||||||
input bool use_m15_imbalance_debug_log = false; // M15初動確認ログ
|
|
||||||
input int input_entry_max_candidate_age_minutes = 45; // H1候補価格を新規発注に使う最大経過分数
|
|
||||||
input bool input_sltp_manager_enabled = false; // UI連動SLTP管理を有効化
|
|
||||||
input bool input_sltp_show_panel = true; // SLTP操作パネルを表示
|
|
||||||
input bool input_sltp_use_breakeven = false; // 通常ブレークイーブンを有効化
|
|
||||||
input double input_sltp_breakeven_trigger_pips = 30.0; // 通常BE開始pips
|
|
||||||
input double input_sltp_breakeven_buffer_pips = 3.0; // 通常BE固定バッファpips
|
|
||||||
input bool input_sltp_use_elapsed_breakeven = false; // 保有時間BEを有効化
|
|
||||||
input double input_sltp_elapsed_breakeven_hours = 4.0; // 保有時間BE開始時間
|
|
||||||
input double input_sltp_elapsed_breakeven_buffer_pips = 3.0; // 保有時間BE固定バッファpips
|
|
||||||
input bool input_sltp_use_active_trailing = false; // アクティブトレーリングを有効化
|
|
||||||
input double input_sltp_active_breakeven_pips = 30.0; // アクティブ開始pips
|
|
||||||
input double input_sltp_active_stop_loss_offset_pips = 5.0; // 初期固定pips
|
|
||||||
input double input_sltp_active_step_trigger_pips = 10.0; // ステップ更新間隔pips
|
|
||||||
input double input_sltp_active_step_move_pips = 5.0; // 1ステップ固定追加pips
|
|
||||||
input bool input_sltp_use_tp_progress_stop = false; // TP進捗SLを有効化
|
|
||||||
input double input_sltp_tp_progress_trigger_percent = 70.0; // TP進捗SL開始率
|
|
||||||
input double input_sltp_tp_progress_sl_lock_percent = 30.0; // TP距離固定率
|
|
||||||
input bool input_sltp_use_high_volatility_limit = false; // 急変時SL引き締めを有効化
|
|
||||||
ulong slippage = 10; // スリッページ
|
|
||||||
|
|
||||||
//--- 主要な定数・設定
|
|
||||||
#define POSITION_LIMIT 48
|
|
||||||
#define ENTRY_H1_LIMIT 1 // H1本数(=1時間)
|
|
||||||
#define CLOSE_H1_LIMIT 12 // H1本数(=12時間)
|
|
||||||
#define HISTORY_BARS 72
|
|
||||||
#define OHLC_START_SHIFT 1 // 1: 確定足のみをPythonへ渡す
|
|
||||||
#define M15_CONFIRM_BARS 30
|
|
||||||
#define M15_MIN_ENTRY_ZONE_POINTS 10
|
|
||||||
#define M15_MIN_BODY_RATIO 0.25
|
|
||||||
#define M15_REJECTION_WICK_RATIO 0.35
|
|
||||||
#define ENTRY_RETRY_SECONDS 60
|
|
||||||
#define ENTRY_RETRY_LIMIT 10
|
|
||||||
// ANALYZE_TIMEFRAME は削除(H4/H1 両方使うため定数ではなく直接指定)
|
|
||||||
#define TARGET_SIZE 13
|
|
||||||
#define DEFAULT_TARGET_PRICE 0.0
|
|
||||||
#define PYTHON_TIMEOUT_SECONDS 600 // Python完了待ちの上限(秒)
|
|
||||||
|
|
||||||
#define MARKET_LOW_VOL_RANGE 0
|
|
||||||
#define MARKET_HIGH_VOL_RANGE 1
|
|
||||||
#define MARKET_LOW_VOL_UP 2
|
|
||||||
#define MARKET_HIGH_VOL_UP 3
|
|
||||||
#define MARKET_LOW_VOL_DOWN 4
|
|
||||||
#define MARKET_HIGH_VOL_DOWN 5
|
|
||||||
#define MARKET_TECHNICAL_ERROR_STOP 6
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| EAの状態をまとめる構造体
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
struct EAState
|
|
||||||
{
|
|
||||||
int trend_state; // H4 market_state(0..5、6は技術エラー停止)を格納する変数
|
|
||||||
int res_chk; // GPTの回答が正しく取得できたか
|
|
||||||
double en_price[5]; // エントリー基準価格
|
|
||||||
double tp_price[5]; // 利益確定価格
|
|
||||||
double sl_price[5]; // ロスカット基準価格
|
|
||||||
bool load_trend_flg; // ★変更:トレンドを更新するタイミングか
|
|
||||||
bool load_target_flg; // ★変更:ターゲット価格を更新するタイミングか
|
|
||||||
int chk_cnt; // エントリー判定の試行回数
|
|
||||||
datetime last_trend_update; // ★追加:前回トレンドを更新した時刻
|
|
||||||
datetime last_target_update; // ★変更:前回ターゲット価格を更新した時刻
|
|
||||||
datetime target_loaded_at; // H1候補価格をEAへ読み込んだサーバー時刻
|
|
||||||
datetime last_chk;
|
|
||||||
};
|
|
||||||
|
|
||||||
EAState g_ea; // EA全体の状態をここで管理
|
|
||||||
|
|
||||||
// initial_order 用の初回処理フラグ
|
|
||||||
// H4トレンド処理とH1エントリー処理で別々に管理し、初回起動時の再実行ループを防ぐ。
|
|
||||||
bool g_init_trend_pending = false;
|
|
||||||
bool g_init_entry_pending = false;
|
|
||||||
|
|
||||||
// H4/H1のバー更新状態
|
|
||||||
int g_pre_bars_H4 = 0;
|
|
||||||
int g_pre_bars_H1 = 0;
|
|
||||||
int g_pre_bars_M15 = 0;
|
|
||||||
bool g_bars_H1_check = false;
|
|
||||||
bool g_bars_M15_check = false;
|
|
||||||
|
|
||||||
// ティックごとの価格情報
|
|
||||||
struct TickContext
|
|
||||||
{
|
|
||||||
double ask;
|
|
||||||
double bid;
|
|
||||||
double spread;
|
|
||||||
double spread_points;
|
|
||||||
int digits;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 外部Pythonプロセスの状態
|
|
||||||
struct ExternalProcessState
|
|
||||||
{
|
|
||||||
long handle;
|
|
||||||
uint process_id;
|
|
||||||
bool active;
|
|
||||||
bool exit_code_ready;
|
|
||||||
uint exit_code;
|
|
||||||
datetime started_at;
|
|
||||||
};
|
|
||||||
|
|
||||||
ExternalProcessState g_trend_process;
|
|
||||||
ExternalProcessState g_entry_process;
|
|
||||||
|
|
||||||
CSLTPManager g_sltp_manager;
|
|
||||||
CSLTPManagerPanel g_sltp_panel;
|
|
||||||
SLTPManagerPanelSettings g_sltp_settings;
|
|
||||||
bool g_sltp_settings_valid = false;
|
|
||||||
bool g_sltp_panel_created = false;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 起動時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief EA起動時の初期化処理を行います。
|
|
||||||
*
|
|
||||||
* Python連携用のdone/runningファイル状態を確認し、`initial_order` が有効な場合は
|
|
||||||
* H4トレンド判定とH1エントリー価格生成をそれぞれ初回実行対象にします。
|
|
||||||
* H4/H1の初回フラグを分けることで、起動直後にH4処理だけが繰り返される状態を防ぎます。
|
|
||||||
*/
|
|
||||||
int OnInit()
|
|
||||||
// プロセス完了ファイルと実行中ファイルの状態を初期化
|
|
||||||
{
|
|
||||||
PrepareDoneFileOnInit(done_trend_file, running_trend_file, "trend");
|
|
||||||
PrepareDoneFileOnInit(done_entry_file, running_entry_file, "entry");
|
|
||||||
|
|
||||||
// initial_order=1 の場合でも、H4/H1を別々に1回だけ初回実行する。
|
|
||||||
g_init_trend_pending = (initial_order == 1);
|
|
||||||
g_init_entry_pending = (initial_order == 1);
|
|
||||||
|
|
||||||
if(!InitializeSLTPManager())
|
|
||||||
return INIT_FAILED;
|
|
||||||
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 終了時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
ResetExternalProcessState(g_trend_process);
|
|
||||||
ResetExternalProcessState(g_entry_process);
|
|
||||||
|
|
||||||
if(g_sltp_panel_created)
|
|
||||||
g_sltp_panel.Destroy(reason);
|
|
||||||
|
|
||||||
// Clear chart status text left by Comment() when the EA is removed.
|
|
||||||
Comment("");
|
|
||||||
ChartRedraw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| ティック毎の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief ティック受信ごとにEA全体の処理を制御します。
|
|
||||||
*
|
|
||||||
* 処理順序は、ティック情報取得、期限切れ注文/ポジション管理、H4トレンド更新、
|
|
||||||
* H1エントリー価格更新、M15エントリータイミング更新、ステータス表示、新規注文判定の順です。
|
|
||||||
* 時間制限処理はPython完了待ちやスプレッド判定より前に実行します。
|
|
||||||
*/
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
TickContext ctx;
|
|
||||||
if(!GetTickContext(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 期限切れ注文・ポジションは、Python待ちやスプレッド制限に関係なく先に処理する。
|
|
||||||
ManageExpiredTrades();
|
|
||||||
|
|
||||||
// Existing-position protection stays active even while Python results are pending.
|
|
||||||
ManageSLTPPositions();
|
|
||||||
|
|
||||||
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
|
|
||||||
RecoverTimedOutPythonProcesses();
|
|
||||||
|
|
||||||
// H4新バーまたは初回起動時に、トレンド判定用Pythonを起動する。
|
|
||||||
ProcessTrendUpdate(g_ea);
|
|
||||||
|
|
||||||
// トレンド判定が完了していない場合、新規注文側の処理だけをスキップする。
|
|
||||||
if(!IsTrendResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTrendState(g_ea);
|
|
||||||
|
|
||||||
// H1新バーまたは初回起動時に、エントリー価格生成用Pythonを起動する。
|
|
||||||
ProcessEntryUpdate(g_ea);
|
|
||||||
|
|
||||||
// M15確定足ごとに、H1候補価格を発注してよいタイミングか再判定する。
|
|
||||||
ProcessM15EntryTimingUpdate();
|
|
||||||
|
|
||||||
UpdateStatusComment(ctx);
|
|
||||||
|
|
||||||
// ここから下は新規注文に関する処理。
|
|
||||||
if(!IsSpreadAllowed(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!IsEntryResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTargetPrices(g_ea);
|
|
||||||
ProcessEntryDecisionIfNeeded(g_ea, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| SLTP manager panel and settings bridge
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
string SLTPBoolText(const bool value)
|
|
||||||
{
|
|
||||||
return value ? "ON" : "OFF";
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadSLTPInputSettings(SLTPManagerPanelSettings &settings)
|
|
||||||
{
|
|
||||||
settings.manager_enabled = input_sltp_manager_enabled;
|
|
||||||
|
|
||||||
settings.use_breakeven = input_sltp_use_breakeven;
|
|
||||||
settings.breakeven_trigger_pips = input_sltp_breakeven_trigger_pips;
|
|
||||||
settings.breakeven_buffer_pips = input_sltp_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_elapsed_breakeven = input_sltp_use_elapsed_breakeven;
|
|
||||||
settings.elapsed_breakeven_hours = input_sltp_elapsed_breakeven_hours;
|
|
||||||
settings.elapsed_breakeven_buffer_pips = input_sltp_elapsed_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_active_trailing = input_sltp_use_active_trailing;
|
|
||||||
settings.active_breakeven_pips = input_sltp_active_breakeven_pips;
|
|
||||||
settings.active_stop_loss_offset_pips = input_sltp_active_stop_loss_offset_pips;
|
|
||||||
settings.active_step_trigger_pips = input_sltp_active_step_trigger_pips;
|
|
||||||
settings.active_step_move_pips = input_sltp_active_step_move_pips;
|
|
||||||
|
|
||||||
settings.use_tp_progress_stop = input_sltp_use_tp_progress_stop;
|
|
||||||
settings.tp_progress_trigger_percent = input_sltp_tp_progress_trigger_percent;
|
|
||||||
settings.tp_progress_sl_lock_percent = input_sltp_tp_progress_sl_lock_percent;
|
|
||||||
|
|
||||||
settings.use_high_volatility_limit = input_sltp_use_high_volatility_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApplySLTPSettings(const SLTPManagerPanelSettings &settings,
|
|
||||||
const bool print_summary)
|
|
||||||
{
|
|
||||||
g_sltp_settings_valid = false;
|
|
||||||
|
|
||||||
g_sltp_manager.SetMagicNumber((ulong)magic_number);
|
|
||||||
g_sltp_manager.SetSymbol(_Symbol);
|
|
||||||
g_sltp_manager.SetDeviationInPoints(slippage);
|
|
||||||
g_sltp_manager.SetBreakevenSettings(settings.use_breakeven,
|
|
||||||
settings.breakeven_trigger_pips,
|
|
||||||
settings.breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetElapsedBreakevenSettings(settings.use_elapsed_breakeven,
|
|
||||||
settings.elapsed_breakeven_hours,
|
|
||||||
settings.elapsed_breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetActiveTrailingSettings(settings.use_active_trailing,
|
|
||||||
settings.active_breakeven_pips,
|
|
||||||
settings.active_stop_loss_offset_pips,
|
|
||||||
settings.active_step_trigger_pips,
|
|
||||||
settings.active_step_move_pips);
|
|
||||||
g_sltp_manager.SetTpProgressStopSettings(settings.use_tp_progress_stop,
|
|
||||||
settings.tp_progress_trigger_percent,
|
|
||||||
settings.tp_progress_sl_lock_percent);
|
|
||||||
g_sltp_manager.SetHighVolatilityLimitSettings(settings.use_high_volatility_limit);
|
|
||||||
|
|
||||||
if(!g_sltp_manager.ValidateSettings())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings rejected. Manager is disabled until valid settings are applied.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_settings = settings;
|
|
||||||
g_sltp_settings_valid = true;
|
|
||||||
|
|
||||||
if(print_summary)
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings: Manager=", SLTPBoolText(settings.manager_enabled),
|
|
||||||
" BE=", SLTPBoolText(settings.use_breakeven),
|
|
||||||
" ElapsedBE=", SLTPBoolText(settings.use_elapsed_breakeven),
|
|
||||||
" ActiveTrail=", SLTPBoolText(settings.use_active_trailing),
|
|
||||||
" TPProgress=", SLTPBoolText(settings.use_tp_progress_stop),
|
|
||||||
" HighVol=", SLTPBoolText(settings.use_high_volatility_limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitializeSLTPManager()
|
|
||||||
{
|
|
||||||
SLTPManagerPanelSettings initial_settings;
|
|
||||||
LoadSLTPInputSettings(initial_settings);
|
|
||||||
|
|
||||||
if(!ApplySLTPSettings(initial_settings, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
g_sltp_panel.Init(g_sltp_settings);
|
|
||||||
if(input_sltp_show_panel)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel.CreatePanel())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP panel is unavailable. EA continues with input-based SLTP settings.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_panel.SetInitialValues();
|
|
||||||
g_sltp_panel_created = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManageSLTPPositions()
|
|
||||||
{
|
|
||||||
if(!g_sltp_settings_valid)
|
|
||||||
return;
|
|
||||||
if(!g_sltp_settings.manager_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_sltp_manager.ManagePositions();
|
|
||||||
g_sltp_manager.HighVolatilityLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnChartEvent(const int id,
|
|
||||||
const long &lparam,
|
|
||||||
const double &dparam,
|
|
||||||
const string &sparam)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel_created)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SLTPManagerPanelSettings candidate_settings = g_sltp_settings;
|
|
||||||
if(g_sltp_panel.HandleChartEvent(id, lparam, dparam, sparam, candidate_settings))
|
|
||||||
{
|
|
||||||
if(!ApplySLTPSettings(candidate_settings, true))
|
|
||||||
Print("HIT SLTP panel apply failed. Please review panel values.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Function implementations are kept in project headers so the EA entry points stay compact.
|
|
||||||
#include <MyLib/Common/HITRuntimeController.mqh>
|
|
||||||
#include <MyLib/Signals/HITEntrySignal.mqh>
|
|
||||||
#include <MyLib/Common/HITExternalProcess.mqh>
|
|
||||||
#include <MyLib/Signals/HITPythonSignalGateway.mqh>
|
|
||||||
#include <MyLib/Trading/HITTradeManager.mqh>
|
|
||||||
@@ -1,441 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| HIT_EA.mq5 |
|
|
||||||
//| Copyright 2026, nanpin-martin.com |
|
|
||||||
//| https://www.nanpin-martin.com |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2026, nanpin-martin.com"
|
|
||||||
#property link "https://nanpin-martin.com/"
|
|
||||||
#property version "1.01"
|
|
||||||
|
|
||||||
#include <MyLib/Trading/SLTPManager.mqh>
|
|
||||||
#include <MyLib/Panel/SLTPManagerPanel.mqh>
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| バッチファイル実行用の設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// Windowsプロセス起動・終了確認用
|
|
||||||
#define CREATE_NO_WINDOW 0x08000000
|
|
||||||
#define PROCESS_QUERY_LIMITED_INFORMATION 0x00001000
|
|
||||||
#define SYNCHRONIZE 0x00100000
|
|
||||||
#define WAIT_OBJECT_0 0
|
|
||||||
#define WAIT_TIMEOUT 258
|
|
||||||
#define STILL_ACTIVE 259
|
|
||||||
|
|
||||||
struct STARTUPINFO_W
|
|
||||||
{
|
|
||||||
uint cb;
|
|
||||||
string lpReserved;
|
|
||||||
string lpDesktop;
|
|
||||||
string lpTitle;
|
|
||||||
uint dwX;
|
|
||||||
uint dwY;
|
|
||||||
uint dwXSize;
|
|
||||||
uint dwYSize;
|
|
||||||
uint dwXCountChars;
|
|
||||||
uint dwYCountChars;
|
|
||||||
uint dwFillAttribute;
|
|
||||||
uint dwFlags;
|
|
||||||
ushort wShowWindow;
|
|
||||||
ushort cbReserved2;
|
|
||||||
long lpReserved2;
|
|
||||||
long hStdInput;
|
|
||||||
long hStdOutput;
|
|
||||||
long hStdError;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PROCESS_INFORMATION
|
|
||||||
{
|
|
||||||
long hProcess;
|
|
||||||
long hThread;
|
|
||||||
uint dwProcessId;
|
|
||||||
uint dwThreadId;
|
|
||||||
};
|
|
||||||
|
|
||||||
#import "kernel32.dll"
|
|
||||||
int CreateProcessW(string lpApplicationName, string lpCommandLine, long lpProcessAttributes, long lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, long lpEnvironment, string lpCurrentDirectory, STARTUPINFO_W &lpStartupInfo, PROCESS_INFORMATION &lpProcessInformation);
|
|
||||||
int WaitForSingleObject(long hHandle, uint dwMilliseconds);
|
|
||||||
int GetExitCodeProcess(long hProcess, uint &lpExitCode);
|
|
||||||
int CloseHandle(long hObject);
|
|
||||||
long OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);
|
|
||||||
#import
|
|
||||||
|
|
||||||
// バッチファイルのパス
|
|
||||||
string get_trend_reply_bat = "C:\\ea_py\\bat\\get_trend_reply.bat"; // H4: trend
|
|
||||||
string get_entry_reply_bat = "C:\\ea_py\\bat\\get_entry_reply.bat"; // H1: entry
|
|
||||||
|
|
||||||
// プロセス完了ファイルの設定
|
|
||||||
string done_trend_file = "process_done_trend.txt";
|
|
||||||
string done_entry_file = "process_done_entry.txt";
|
|
||||||
|
|
||||||
// Python出力ファイル
|
|
||||||
string trend_state_file = "trend_state.txt";
|
|
||||||
string target_prices_file = "target_prices.txt";
|
|
||||||
|
|
||||||
// Python実行中を判定するための管理ファイル
|
|
||||||
string running_trend_file = "process_running_trend.txt";
|
|
||||||
string running_entry_file = "process_running_entry.txt";
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| インプットの設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//--- 入力パラメータ
|
|
||||||
input double lot_size = 0.01; // ロット数
|
|
||||||
input double spread_limit = 60; // 許容スプレッド(point)
|
|
||||||
input int magic_number = 10001; // マジックナンバー
|
|
||||||
input int initial_order = 0; // 起動時の注文(0:なし, 1:あり)
|
|
||||||
input bool use_m15_entry_filter = true; // M15確定足で発注タイミングを確認
|
|
||||||
input double m15_entry_zone_atr_multiplier = 1.50; // M15平均レンジ何本分まで候補価格への接近を許可
|
|
||||||
input bool use_m15_imbalance_confirmation = true; // T1/T3でM15初動確認を追加
|
|
||||||
input int m15_imbalance_avg_body_period = 20; // M15平均実体計算期間
|
|
||||||
input double m15_imbalance_sensitivity = 2.0; // M15初動検知感度
|
|
||||||
input double m15_imbalance_min_avg_body_points = 1.0; // 平均実体の最小値(point)
|
|
||||||
input bool use_m15_imbalance_debug_log = false; // M15初動確認ログ
|
|
||||||
input int input_entry_max_candidate_age_minutes = 45; // H1候補価格を新規発注に使う最大経過分数
|
|
||||||
input bool input_sltp_manager_enabled = false; // UI連動SLTP管理を有効化
|
|
||||||
input bool input_sltp_show_panel = true; // SLTP操作パネルを表示
|
|
||||||
input bool input_sltp_use_breakeven = false; // 通常ブレークイーブンを有効化
|
|
||||||
input double input_sltp_breakeven_trigger_pips = 30.0; // 通常BE開始pips
|
|
||||||
input double input_sltp_breakeven_buffer_pips = 3.0; // 通常BE固定バッファpips
|
|
||||||
input bool input_sltp_use_elapsed_breakeven = false; // 保有時間BEを有効化
|
|
||||||
input double input_sltp_elapsed_breakeven_hours = 4.0; // 保有時間BE開始時間
|
|
||||||
input double input_sltp_elapsed_breakeven_buffer_pips = 3.0; // 保有時間BE固定バッファpips
|
|
||||||
input bool input_sltp_use_active_trailing = false; // アクティブトレーリングを有効化
|
|
||||||
input double input_sltp_active_breakeven_pips = 30.0; // アクティブ開始pips
|
|
||||||
input double input_sltp_active_stop_loss_offset_pips = 5.0; // 初期固定pips
|
|
||||||
input double input_sltp_active_step_trigger_pips = 10.0; // ステップ更新間隔pips
|
|
||||||
input double input_sltp_active_step_move_pips = 5.0; // 1ステップ固定追加pips
|
|
||||||
input bool input_sltp_use_tp_progress_stop = false; // TP進捗SLを有効化
|
|
||||||
input double input_sltp_tp_progress_trigger_percent = 70.0; // TP進捗SL開始率
|
|
||||||
input double input_sltp_tp_progress_sl_lock_percent = 30.0; // TP距離固定率
|
|
||||||
input bool input_sltp_use_high_volatility_limit = false; // 急変時SL引き締めを有効化
|
|
||||||
ulong slippage = 10; // スリッページ
|
|
||||||
|
|
||||||
//--- 主要な定数・設定
|
|
||||||
#define POSITION_LIMIT 48
|
|
||||||
#define ENTRY_H1_LIMIT 1 // H1本数(=1時間)
|
|
||||||
#define CLOSE_H1_LIMIT 12 // H1本数(=12時間)
|
|
||||||
#define HISTORY_BARS 72
|
|
||||||
#define OHLC_START_SHIFT 1 // 1: 確定足のみをPythonへ渡す
|
|
||||||
#define M15_CONFIRM_BARS 30
|
|
||||||
#define M15_MIN_ENTRY_ZONE_POINTS 10
|
|
||||||
#define M15_MIN_BODY_RATIO 0.25
|
|
||||||
#define M15_REJECTION_WICK_RATIO 0.35
|
|
||||||
#define ENTRY_RETRY_SECONDS 60
|
|
||||||
#define ENTRY_RETRY_LIMIT 10
|
|
||||||
// ANALYZE_TIMEFRAME は削除(H4/H1 両方使うため定数ではなく直接指定)
|
|
||||||
#define TARGET_SIZE 13
|
|
||||||
#define DEFAULT_TARGET_PRICE 0.0
|
|
||||||
#define PYTHON_TIMEOUT_SECONDS 600 // Python完了待ちの上限(秒)
|
|
||||||
|
|
||||||
#define MARKET_LOW_VOL_RANGE 0
|
|
||||||
#define MARKET_HIGH_VOL_RANGE 1
|
|
||||||
#define MARKET_LOW_VOL_UP 2
|
|
||||||
#define MARKET_HIGH_VOL_UP 3
|
|
||||||
#define MARKET_LOW_VOL_DOWN 4
|
|
||||||
#define MARKET_HIGH_VOL_DOWN 5
|
|
||||||
#define MARKET_TECHNICAL_ERROR_STOP 6
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| EAの状態をまとめる構造体
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
struct EAState
|
|
||||||
{
|
|
||||||
int trend_state; // H4 market_state(0..5、6は技術エラー停止)を格納する変数
|
|
||||||
int res_chk; // GPTの回答が正しく取得できたか
|
|
||||||
double en_price[5]; // エントリー基準価格
|
|
||||||
double tp_price[5]; // 利益確定価格
|
|
||||||
double sl_price[5]; // ロスカット基準価格
|
|
||||||
bool load_trend_flg; // ★変更:トレンドを更新するタイミングか
|
|
||||||
bool load_target_flg; // ★変更:ターゲット価格を更新するタイミングか
|
|
||||||
int chk_cnt; // エントリー判定の試行回数
|
|
||||||
datetime last_trend_update; // ★追加:前回トレンドを更新した時刻
|
|
||||||
datetime last_target_update; // ★変更:前回ターゲット価格を更新した時刻
|
|
||||||
datetime target_loaded_at; // H1候補価格をEAへ読み込んだサーバー時刻
|
|
||||||
datetime last_chk;
|
|
||||||
};
|
|
||||||
|
|
||||||
EAState g_ea; // EA全体の状態をここで管理
|
|
||||||
|
|
||||||
// initial_order 用の初回処理フラグ
|
|
||||||
// H4トレンド処理とH1エントリー処理で別々に管理し、初回起動時の再実行ループを防ぐ。
|
|
||||||
bool g_init_trend_pending = false;
|
|
||||||
bool g_init_entry_pending = false;
|
|
||||||
|
|
||||||
// H4/H1のバー更新状態
|
|
||||||
int g_pre_bars_H4 = 0;
|
|
||||||
int g_pre_bars_H1 = 0;
|
|
||||||
int g_pre_bars_M15 = 0;
|
|
||||||
bool g_bars_H1_check = false;
|
|
||||||
bool g_bars_M15_check = false;
|
|
||||||
|
|
||||||
// ティックごとの価格情報
|
|
||||||
struct TickContext
|
|
||||||
{
|
|
||||||
double ask;
|
|
||||||
double bid;
|
|
||||||
double spread;
|
|
||||||
double spread_points;
|
|
||||||
int digits;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 外部Pythonプロセスの状態
|
|
||||||
struct ExternalProcessState
|
|
||||||
{
|
|
||||||
long handle;
|
|
||||||
uint process_id;
|
|
||||||
bool active;
|
|
||||||
bool exit_code_ready;
|
|
||||||
uint exit_code;
|
|
||||||
datetime started_at;
|
|
||||||
};
|
|
||||||
|
|
||||||
ExternalProcessState g_trend_process;
|
|
||||||
ExternalProcessState g_entry_process;
|
|
||||||
|
|
||||||
CSLTPManager g_sltp_manager;
|
|
||||||
CSLTPManagerPanel g_sltp_panel;
|
|
||||||
SLTPManagerPanelSettings g_sltp_settings;
|
|
||||||
bool g_sltp_settings_valid = false;
|
|
||||||
bool g_sltp_panel_created = false;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 起動時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief EA起動時の初期化処理を行います。
|
|
||||||
*
|
|
||||||
* Python連携用のdone/runningファイル状態を確認し、`initial_order` が有効な場合は
|
|
||||||
* H4トレンド判定とH1エントリー価格生成をそれぞれ初回実行対象にします。
|
|
||||||
* H4/H1の初回フラグを分けることで、起動直後にH4処理だけが繰り返される状態を防ぎます。
|
|
||||||
*/
|
|
||||||
int OnInit()
|
|
||||||
// プロセス完了ファイルと実行中ファイルの状態を初期化
|
|
||||||
{
|
|
||||||
PrepareDoneFileOnInit(done_trend_file, running_trend_file, "trend");
|
|
||||||
PrepareDoneFileOnInit(done_entry_file, running_entry_file, "entry");
|
|
||||||
|
|
||||||
// initial_order=1 の場合でも、H4/H1を別々に1回だけ初回実行する。
|
|
||||||
g_init_trend_pending = (initial_order == 1);
|
|
||||||
g_init_entry_pending = (initial_order == 1);
|
|
||||||
|
|
||||||
if(!InitializeSLTPManager())
|
|
||||||
return INIT_FAILED;
|
|
||||||
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 終了時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
ResetExternalProcessState(g_trend_process);
|
|
||||||
ResetExternalProcessState(g_entry_process);
|
|
||||||
|
|
||||||
if(g_sltp_panel_created)
|
|
||||||
g_sltp_panel.Destroy(reason);
|
|
||||||
|
|
||||||
// Clear chart status text left by Comment() when the EA is removed.
|
|
||||||
Comment("");
|
|
||||||
ChartRedraw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| ティック毎の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief ティック受信ごとにEA全体の処理を制御します。
|
|
||||||
*
|
|
||||||
* 処理順序は、ティック情報取得、期限切れ注文/ポジション管理、H4トレンド更新、
|
|
||||||
* H1エントリー価格更新、M15エントリータイミング更新、ステータス表示、新規注文判定の順です。
|
|
||||||
* 時間制限処理はPython完了待ちやスプレッド判定より前に実行します。
|
|
||||||
*/
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
TickContext ctx;
|
|
||||||
if(!GetTickContext(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 期限切れ注文・ポジションは、Python待ちやスプレッド制限に関係なく先に処理する。
|
|
||||||
ManageExpiredTrades();
|
|
||||||
|
|
||||||
// Existing-position protection stays active even while Python results are pending.
|
|
||||||
ManageSLTPPositions();
|
|
||||||
|
|
||||||
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
|
|
||||||
RecoverTimedOutPythonProcesses();
|
|
||||||
|
|
||||||
// H4新バーまたは初回起動時に、トレンド判定用Pythonを起動する。
|
|
||||||
ProcessTrendUpdate(g_ea);
|
|
||||||
|
|
||||||
// トレンド判定が完了していない場合、新規注文側の処理だけをスキップする。
|
|
||||||
if(!IsTrendResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTrendState(g_ea);
|
|
||||||
|
|
||||||
// H1新バーまたは初回起動時に、エントリー価格生成用Pythonを起動する。
|
|
||||||
ProcessEntryUpdate(g_ea);
|
|
||||||
|
|
||||||
// M15確定足ごとに、H1候補価格を発注してよいタイミングか再判定する。
|
|
||||||
ProcessM15EntryTimingUpdate();
|
|
||||||
|
|
||||||
UpdateStatusComment(ctx);
|
|
||||||
|
|
||||||
// ここから下は新規注文に関する処理。
|
|
||||||
if(!IsSpreadAllowed(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!IsEntryResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTargetPrices(g_ea);
|
|
||||||
ProcessEntryDecisionIfNeeded(g_ea, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| SLTP manager panel and settings bridge
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
string SLTPBoolText(const bool value)
|
|
||||||
{
|
|
||||||
return value ? "ON" : "OFF";
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadSLTPInputSettings(SLTPManagerPanelSettings &settings)
|
|
||||||
{
|
|
||||||
settings.manager_enabled = input_sltp_manager_enabled;
|
|
||||||
|
|
||||||
settings.use_breakeven = input_sltp_use_breakeven;
|
|
||||||
settings.breakeven_trigger_pips = input_sltp_breakeven_trigger_pips;
|
|
||||||
settings.breakeven_buffer_pips = input_sltp_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_elapsed_breakeven = input_sltp_use_elapsed_breakeven;
|
|
||||||
settings.elapsed_breakeven_hours = input_sltp_elapsed_breakeven_hours;
|
|
||||||
settings.elapsed_breakeven_buffer_pips = input_sltp_elapsed_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_active_trailing = input_sltp_use_active_trailing;
|
|
||||||
settings.active_breakeven_pips = input_sltp_active_breakeven_pips;
|
|
||||||
settings.active_stop_loss_offset_pips = input_sltp_active_stop_loss_offset_pips;
|
|
||||||
settings.active_step_trigger_pips = input_sltp_active_step_trigger_pips;
|
|
||||||
settings.active_step_move_pips = input_sltp_active_step_move_pips;
|
|
||||||
|
|
||||||
settings.use_tp_progress_stop = input_sltp_use_tp_progress_stop;
|
|
||||||
settings.tp_progress_trigger_percent = input_sltp_tp_progress_trigger_percent;
|
|
||||||
settings.tp_progress_sl_lock_percent = input_sltp_tp_progress_sl_lock_percent;
|
|
||||||
|
|
||||||
settings.use_high_volatility_limit = input_sltp_use_high_volatility_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApplySLTPSettings(const SLTPManagerPanelSettings &settings,
|
|
||||||
const bool print_summary)
|
|
||||||
{
|
|
||||||
g_sltp_settings_valid = false;
|
|
||||||
|
|
||||||
g_sltp_manager.SetMagicNumber((ulong)magic_number);
|
|
||||||
g_sltp_manager.SetSymbol(_Symbol);
|
|
||||||
g_sltp_manager.SetDeviationInPoints(slippage);
|
|
||||||
g_sltp_manager.SetBreakevenSettings(settings.use_breakeven,
|
|
||||||
settings.breakeven_trigger_pips,
|
|
||||||
settings.breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetElapsedBreakevenSettings(settings.use_elapsed_breakeven,
|
|
||||||
settings.elapsed_breakeven_hours,
|
|
||||||
settings.elapsed_breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetActiveTrailingSettings(settings.use_active_trailing,
|
|
||||||
settings.active_breakeven_pips,
|
|
||||||
settings.active_stop_loss_offset_pips,
|
|
||||||
settings.active_step_trigger_pips,
|
|
||||||
settings.active_step_move_pips);
|
|
||||||
g_sltp_manager.SetTpProgressStopSettings(settings.use_tp_progress_stop,
|
|
||||||
settings.tp_progress_trigger_percent,
|
|
||||||
settings.tp_progress_sl_lock_percent);
|
|
||||||
g_sltp_manager.SetHighVolatilityLimitSettings(settings.use_high_volatility_limit);
|
|
||||||
|
|
||||||
if(!g_sltp_manager.ValidateSettings())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings rejected. Manager is disabled until valid settings are applied.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_settings = settings;
|
|
||||||
g_sltp_settings_valid = true;
|
|
||||||
|
|
||||||
if(print_summary)
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings: Manager=", SLTPBoolText(settings.manager_enabled),
|
|
||||||
" BE=", SLTPBoolText(settings.use_breakeven),
|
|
||||||
" ElapsedBE=", SLTPBoolText(settings.use_elapsed_breakeven),
|
|
||||||
" ActiveTrail=", SLTPBoolText(settings.use_active_trailing),
|
|
||||||
" TPProgress=", SLTPBoolText(settings.use_tp_progress_stop),
|
|
||||||
" HighVol=", SLTPBoolText(settings.use_high_volatility_limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitializeSLTPManager()
|
|
||||||
{
|
|
||||||
SLTPManagerPanelSettings initial_settings;
|
|
||||||
LoadSLTPInputSettings(initial_settings);
|
|
||||||
|
|
||||||
if(!ApplySLTPSettings(initial_settings, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
g_sltp_panel.Init(g_sltp_settings);
|
|
||||||
if(input_sltp_show_panel)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel.CreatePanel())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP panel is unavailable. EA continues with input-based SLTP settings.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_panel.SetInitialValues();
|
|
||||||
g_sltp_panel_created = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManageSLTPPositions()
|
|
||||||
{
|
|
||||||
if(!g_sltp_settings_valid)
|
|
||||||
return;
|
|
||||||
if(!g_sltp_settings.manager_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_sltp_manager.ManagePositions();
|
|
||||||
g_sltp_manager.HighVolatilityLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnChartEvent(const int id,
|
|
||||||
const long &lparam,
|
|
||||||
const double &dparam,
|
|
||||||
const string &sparam)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel_created)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SLTPManagerPanelSettings candidate_settings = g_sltp_settings;
|
|
||||||
if(g_sltp_panel.HandleChartEvent(id, lparam, dparam, sparam, candidate_settings))
|
|
||||||
{
|
|
||||||
if(!ApplySLTPSettings(candidate_settings, true))
|
|
||||||
Print("HIT SLTP panel apply failed. Please review panel values.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Function implementations are kept in project headers so the EA entry points stay compact.
|
|
||||||
#include <MyLib/Common/HITRuntimeController.mqh>
|
|
||||||
#include <MyLib/Signals/HITEntrySignal.mqh>
|
|
||||||
#include <MyLib/Common/HITExternalProcess.mqh>
|
|
||||||
#include <MyLib/Signals/HITPythonSignalGateway.mqh>
|
|
||||||
#include <MyLib/Trading/HITTradeManager.mqh>
|
|
||||||
@@ -1,462 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| HIT_EA.mq5 |
|
|
||||||
//| Copyright 2026, nanpin-martin.com |
|
|
||||||
//| https://www.nanpin-martin.com |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2026, nanpin-martin.com"
|
|
||||||
#property link "https://nanpin-martin.com/"
|
|
||||||
#property version "1.01"
|
|
||||||
|
|
||||||
#include <MyLib/Trading/SLTPManager.mqh>
|
|
||||||
#include <MyLib/Panel/SLTPManagerPanel.mqh>
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| バッチファイル実行用の設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// Windowsプロセス起動・終了確認用
|
|
||||||
#define CREATE_NO_WINDOW 0x08000000
|
|
||||||
#define PROCESS_QUERY_LIMITED_INFORMATION 0x00001000
|
|
||||||
#define SYNCHRONIZE 0x00100000
|
|
||||||
#define WAIT_OBJECT_0 0
|
|
||||||
#define WAIT_TIMEOUT 258
|
|
||||||
#define STILL_ACTIVE 259
|
|
||||||
|
|
||||||
struct STARTUPINFO_W
|
|
||||||
{
|
|
||||||
uint cb;
|
|
||||||
string lpReserved;
|
|
||||||
string lpDesktop;
|
|
||||||
string lpTitle;
|
|
||||||
uint dwX;
|
|
||||||
uint dwY;
|
|
||||||
uint dwXSize;
|
|
||||||
uint dwYSize;
|
|
||||||
uint dwXCountChars;
|
|
||||||
uint dwYCountChars;
|
|
||||||
uint dwFillAttribute;
|
|
||||||
uint dwFlags;
|
|
||||||
ushort wShowWindow;
|
|
||||||
ushort cbReserved2;
|
|
||||||
long lpReserved2;
|
|
||||||
long hStdInput;
|
|
||||||
long hStdOutput;
|
|
||||||
long hStdError;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PROCESS_INFORMATION
|
|
||||||
{
|
|
||||||
long hProcess;
|
|
||||||
long hThread;
|
|
||||||
uint dwProcessId;
|
|
||||||
uint dwThreadId;
|
|
||||||
};
|
|
||||||
|
|
||||||
#import "kernel32.dll"
|
|
||||||
int CreateProcessW(string lpApplicationName, string lpCommandLine, long lpProcessAttributes, long lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, long lpEnvironment, string lpCurrentDirectory, STARTUPINFO_W &lpStartupInfo, PROCESS_INFORMATION &lpProcessInformation);
|
|
||||||
int WaitForSingleObject(long hHandle, uint dwMilliseconds);
|
|
||||||
int GetExitCodeProcess(long hProcess, uint &lpExitCode);
|
|
||||||
int CloseHandle(long hObject);
|
|
||||||
long OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);
|
|
||||||
#import
|
|
||||||
|
|
||||||
// バッチファイルのパス
|
|
||||||
string get_trend_reply_bat = "C:\\ea_py\\bat\\get_trend_reply.bat"; // H4: trend
|
|
||||||
string get_entry_reply_bat = "C:\\ea_py\\bat\\get_entry_reply.bat"; // H1: entry
|
|
||||||
|
|
||||||
// プロセス完了ファイルの設定
|
|
||||||
string done_trend_file = "process_done_trend.txt";
|
|
||||||
string done_entry_file = "process_done_entry.txt";
|
|
||||||
|
|
||||||
// Python出力ファイル
|
|
||||||
string trend_state_file = "trend_state.txt";
|
|
||||||
string target_prices_file = "target_prices.txt";
|
|
||||||
string target_zones_file = "target_zones.txt";
|
|
||||||
|
|
||||||
// Python実行中を判定するための管理ファイル
|
|
||||||
string running_trend_file = "process_running_trend.txt";
|
|
||||||
string running_entry_file = "process_running_entry.txt";
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| インプットの設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
enum SplitLotMode
|
|
||||||
{
|
|
||||||
SPLIT_LOT_TOTAL = 0, // 総ロットをN分割
|
|
||||||
SPLIT_LOT_FIXED = 1 // 1注文あたり固定ロット
|
|
||||||
};
|
|
||||||
|
|
||||||
//--- 入力パラメータ
|
|
||||||
input double lot_size = 0.01; // ロット数
|
|
||||||
input double spread_limit = 60; // 許容スプレッド(point)
|
|
||||||
input int magic_number = 10001; // マジックナンバー
|
|
||||||
input int initial_order = 0; // 起動時の注文(0:なし, 1:あり)
|
|
||||||
input int input_position_limit = 10; // 自EAの未約定注文+ポジション上限
|
|
||||||
input bool use_split_entry_zone = false; // H1予測ゾーンで分割エントリーする
|
|
||||||
input int split_entry_count = 3; // 分割エントリー本数(1..10)
|
|
||||||
input SplitLotMode split_lot_mode = SPLIT_LOT_TOTAL; // 分割ロット配分モード
|
|
||||||
input double split_total_lot_size = 0.09; // 総量分割モードの合計ロット
|
|
||||||
input double split_fixed_lot_size = 0.01; // 固定ロットモードの1注文ロット
|
|
||||||
input bool cancel_old_split_pending_on_new_zone = true; // 新ゾーン読込時に旧分割pendingを取消
|
|
||||||
input bool use_m15_entry_filter = true; // M15確定足で発注タイミングを確認
|
|
||||||
input double m15_entry_zone_atr_multiplier = 1.50; // M15平均レンジ何本分まで候補価格への接近を許可
|
|
||||||
input bool use_m15_imbalance_confirmation = true; // T1/T3でM15初動確認を追加
|
|
||||||
input int m15_imbalance_avg_body_period = 20; // M15平均実体計算期間
|
|
||||||
input double m15_imbalance_sensitivity = 2.0; // M15初動検知感度
|
|
||||||
input double m15_imbalance_min_avg_body_points = 1.0; // 平均実体の最小値(point)
|
|
||||||
input bool use_m15_imbalance_debug_log = false; // M15初動確認ログ
|
|
||||||
input int input_entry_max_candidate_age_minutes = 45; // H1候補価格を新規発注に使う最大経過分数
|
|
||||||
input bool input_sltp_manager_enabled = false; // UI連動SLTP管理を有効化
|
|
||||||
input bool input_sltp_show_panel = true; // SLTP操作パネルを表示
|
|
||||||
input bool input_sltp_use_breakeven = false; // 通常ブレークイーブンを有効化
|
|
||||||
input double input_sltp_breakeven_trigger_pips = 30.0; // 通常BE開始pips
|
|
||||||
input double input_sltp_breakeven_buffer_pips = 3.0; // 通常BE固定バッファpips
|
|
||||||
input bool input_sltp_use_elapsed_breakeven = false; // 保有時間BEを有効化
|
|
||||||
input double input_sltp_elapsed_breakeven_hours = 4.0; // 保有時間BE開始時間
|
|
||||||
input double input_sltp_elapsed_breakeven_buffer_pips = 3.0; // 保有時間BE固定バッファpips
|
|
||||||
input bool input_sltp_use_active_trailing = false; // アクティブトレーリングを有効化
|
|
||||||
input double input_sltp_active_breakeven_pips = 30.0; // アクティブ開始pips
|
|
||||||
input double input_sltp_active_stop_loss_offset_pips = 5.0; // 初期固定pips
|
|
||||||
input double input_sltp_active_step_trigger_pips = 10.0; // ステップ更新間隔pips
|
|
||||||
input double input_sltp_active_step_move_pips = 5.0; // 1ステップ固定追加pips
|
|
||||||
input bool input_sltp_use_tp_progress_stop = false; // TP進捗SLを有効化
|
|
||||||
input double input_sltp_tp_progress_trigger_percent = 70.0; // TP進捗SL開始率
|
|
||||||
input double input_sltp_tp_progress_sl_lock_percent = 30.0; // TP距離固定率
|
|
||||||
input bool input_sltp_use_high_volatility_limit = false; // 急変時SL引き締めを有効化
|
|
||||||
ulong slippage = 10; // スリッページ
|
|
||||||
|
|
||||||
//--- 主要な定数・設定
|
|
||||||
#define POSITION_LIMIT 48
|
|
||||||
#define ENTRY_H1_LIMIT 1 // H1本数(=1時間)
|
|
||||||
#define CLOSE_H1_LIMIT 12 // H1本数(=12時間)
|
|
||||||
#define HISTORY_BARS 72
|
|
||||||
#define OHLC_START_SHIFT 1 // 1: 確定足のみをPythonへ渡す
|
|
||||||
#define M15_CONFIRM_BARS 30
|
|
||||||
#define M15_MIN_ENTRY_ZONE_POINTS 10
|
|
||||||
#define M15_MIN_BODY_RATIO 0.25
|
|
||||||
#define M15_REJECTION_WICK_RATIO 0.35
|
|
||||||
#define ENTRY_RETRY_SECONDS 60
|
|
||||||
#define ENTRY_RETRY_LIMIT 10
|
|
||||||
// ANALYZE_TIMEFRAME は削除(H4/H1 両方使うため定数ではなく直接指定)
|
|
||||||
#define TARGET_SIZE 13
|
|
||||||
#define TARGET_ZONE_SCHEMA_VERSION 2
|
|
||||||
#define DEFAULT_TARGET_PRICE 0.0
|
|
||||||
#define PYTHON_TIMEOUT_SECONDS 600 // Python完了待ちの上限(秒)
|
|
||||||
|
|
||||||
#define MARKET_LOW_VOL_RANGE 0
|
|
||||||
#define MARKET_HIGH_VOL_RANGE 1
|
|
||||||
#define MARKET_LOW_VOL_UP 2
|
|
||||||
#define MARKET_HIGH_VOL_UP 3
|
|
||||||
#define MARKET_LOW_VOL_DOWN 4
|
|
||||||
#define MARKET_HIGH_VOL_DOWN 5
|
|
||||||
#define MARKET_TECHNICAL_ERROR_STOP 6
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| EAの状態をまとめる構造体
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
struct EAState
|
|
||||||
{
|
|
||||||
int trend_state; // H4 market_state(0..5、6は技術エラー停止)を格納する変数
|
|
||||||
int res_chk; // GPTの回答が正しく取得できたか
|
|
||||||
double en_price[5]; // エントリー基準価格
|
|
||||||
double tp_price[5]; // 利益確定価格
|
|
||||||
double sl_price[5]; // ロスカット基準価格
|
|
||||||
int zone_res_chk; // 予測ゾーンが正しく取得できたか
|
|
||||||
string zone_candidate_id; // H1確定足由来の候補ID
|
|
||||||
double zone_low[5]; // 分割エントリー用ゾーン下限
|
|
||||||
double zone_high[5]; // 分割エントリー用ゾーン上限
|
|
||||||
double zone_tp[5]; // 分割エントリー用TP
|
|
||||||
double zone_sl[5]; // 分割エントリー用SL
|
|
||||||
bool load_trend_flg; // ★変更:トレンドを更新するタイミングか
|
|
||||||
bool load_target_flg; // ★変更:ターゲット価格を更新するタイミングか
|
|
||||||
int chk_cnt; // エントリー判定の試行回数
|
|
||||||
datetime last_trend_update; // ★追加:前回トレンドを更新した時刻
|
|
||||||
datetime last_target_update; // ★変更:前回ターゲット価格を更新した時刻
|
|
||||||
datetime target_loaded_at; // H1候補価格をEAへ読み込んだサーバー時刻
|
|
||||||
datetime last_chk;
|
|
||||||
};
|
|
||||||
|
|
||||||
EAState g_ea; // EA全体の状態をここで管理
|
|
||||||
|
|
||||||
// initial_order 用の初回処理フラグ
|
|
||||||
// H4トレンド処理とH1エントリー処理で別々に管理し、初回起動時の再実行ループを防ぐ。
|
|
||||||
bool g_init_trend_pending = false;
|
|
||||||
bool g_init_entry_pending = false;
|
|
||||||
|
|
||||||
// H4/H1のバー更新状態
|
|
||||||
int g_pre_bars_H4 = 0;
|
|
||||||
int g_pre_bars_H1 = 0;
|
|
||||||
int g_pre_bars_M15 = 0;
|
|
||||||
bool g_bars_H1_check = false;
|
|
||||||
bool g_bars_M15_check = false;
|
|
||||||
|
|
||||||
// ティックごとの価格情報
|
|
||||||
struct TickContext
|
|
||||||
{
|
|
||||||
double ask;
|
|
||||||
double bid;
|
|
||||||
double spread;
|
|
||||||
double spread_points;
|
|
||||||
int digits;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 外部Pythonプロセスの状態
|
|
||||||
struct ExternalProcessState
|
|
||||||
{
|
|
||||||
long handle;
|
|
||||||
uint process_id;
|
|
||||||
bool active;
|
|
||||||
bool exit_code_ready;
|
|
||||||
uint exit_code;
|
|
||||||
datetime started_at;
|
|
||||||
};
|
|
||||||
|
|
||||||
ExternalProcessState g_trend_process;
|
|
||||||
ExternalProcessState g_entry_process;
|
|
||||||
|
|
||||||
CSLTPManager g_sltp_manager;
|
|
||||||
CSLTPManagerPanel g_sltp_panel;
|
|
||||||
SLTPManagerPanelSettings g_sltp_settings;
|
|
||||||
bool g_sltp_settings_valid = false;
|
|
||||||
bool g_sltp_panel_created = false;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 起動時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief EA起動時の初期化処理を行います。
|
|
||||||
*
|
|
||||||
* Python連携用のdone/runningファイル状態を確認し、`initial_order` が有効な場合は
|
|
||||||
* H4トレンド判定とH1エントリー価格生成をそれぞれ初回実行対象にします。
|
|
||||||
* H4/H1の初回フラグを分けることで、起動直後にH4処理だけが繰り返される状態を防ぎます。
|
|
||||||
*/
|
|
||||||
int OnInit()
|
|
||||||
// プロセス完了ファイルと実行中ファイルの状態を初期化
|
|
||||||
{
|
|
||||||
PrepareDoneFileOnInit(done_trend_file, running_trend_file, "trend");
|
|
||||||
PrepareDoneFileOnInit(done_entry_file, running_entry_file, "entry");
|
|
||||||
|
|
||||||
// initial_order=1 の場合でも、H4/H1を別々に1回だけ初回実行する。
|
|
||||||
g_init_trend_pending = (initial_order == 1);
|
|
||||||
g_init_entry_pending = (initial_order == 1);
|
|
||||||
|
|
||||||
if(!InitializeSLTPManager())
|
|
||||||
return INIT_FAILED;
|
|
||||||
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 終了時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
ResetExternalProcessState(g_trend_process);
|
|
||||||
ResetExternalProcessState(g_entry_process);
|
|
||||||
|
|
||||||
if(g_sltp_panel_created)
|
|
||||||
g_sltp_panel.Destroy(reason);
|
|
||||||
|
|
||||||
// Clear chart status text left by Comment() when the EA is removed.
|
|
||||||
Comment("");
|
|
||||||
ChartRedraw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| ティック毎の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief ティック受信ごとにEA全体の処理を制御します。
|
|
||||||
*
|
|
||||||
* 処理順序は、ティック情報取得、期限切れ注文/ポジション管理、H4トレンド更新、
|
|
||||||
* H1エントリー価格更新、M15エントリータイミング更新、ステータス表示、新規注文判定の順です。
|
|
||||||
* 時間制限処理はPython完了待ちやスプレッド判定より前に実行します。
|
|
||||||
*/
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
TickContext ctx;
|
|
||||||
if(!GetTickContext(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 期限切れ注文・ポジションは、Python待ちやスプレッド制限に関係なく先に処理する。
|
|
||||||
ManageExpiredTrades();
|
|
||||||
|
|
||||||
// Existing-position protection stays active even while Python results are pending.
|
|
||||||
ManageSLTPPositions();
|
|
||||||
|
|
||||||
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
|
|
||||||
RecoverTimedOutPythonProcesses();
|
|
||||||
|
|
||||||
// H4新バーまたは初回起動時に、トレンド判定用Pythonを起動する。
|
|
||||||
ProcessTrendUpdate(g_ea);
|
|
||||||
|
|
||||||
// トレンド判定が完了していない場合、新規注文側の処理だけをスキップする。
|
|
||||||
if(!IsTrendResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTrendState(g_ea);
|
|
||||||
|
|
||||||
// H1新バーまたは初回起動時に、エントリー価格生成用Pythonを起動する。
|
|
||||||
ProcessEntryUpdate(g_ea);
|
|
||||||
|
|
||||||
// M15確定足ごとに、H1候補価格を発注してよいタイミングか再判定する。
|
|
||||||
ProcessM15EntryTimingUpdate();
|
|
||||||
|
|
||||||
UpdateStatusComment(ctx);
|
|
||||||
|
|
||||||
// ここから下は新規注文に関する処理。
|
|
||||||
if(!IsSpreadAllowed(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!IsEntryResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTargetPrices(g_ea);
|
|
||||||
ProcessEntryDecisionIfNeeded(g_ea, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| SLTP manager panel and settings bridge
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
string SLTPBoolText(const bool value)
|
|
||||||
{
|
|
||||||
return value ? "ON" : "OFF";
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadSLTPInputSettings(SLTPManagerPanelSettings &settings)
|
|
||||||
{
|
|
||||||
settings.manager_enabled = input_sltp_manager_enabled;
|
|
||||||
|
|
||||||
settings.use_breakeven = input_sltp_use_breakeven;
|
|
||||||
settings.breakeven_trigger_pips = input_sltp_breakeven_trigger_pips;
|
|
||||||
settings.breakeven_buffer_pips = input_sltp_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_elapsed_breakeven = input_sltp_use_elapsed_breakeven;
|
|
||||||
settings.elapsed_breakeven_hours = input_sltp_elapsed_breakeven_hours;
|
|
||||||
settings.elapsed_breakeven_buffer_pips = input_sltp_elapsed_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_active_trailing = input_sltp_use_active_trailing;
|
|
||||||
settings.active_breakeven_pips = input_sltp_active_breakeven_pips;
|
|
||||||
settings.active_stop_loss_offset_pips = input_sltp_active_stop_loss_offset_pips;
|
|
||||||
settings.active_step_trigger_pips = input_sltp_active_step_trigger_pips;
|
|
||||||
settings.active_step_move_pips = input_sltp_active_step_move_pips;
|
|
||||||
|
|
||||||
settings.use_tp_progress_stop = input_sltp_use_tp_progress_stop;
|
|
||||||
settings.tp_progress_trigger_percent = input_sltp_tp_progress_trigger_percent;
|
|
||||||
settings.tp_progress_sl_lock_percent = input_sltp_tp_progress_sl_lock_percent;
|
|
||||||
|
|
||||||
settings.use_high_volatility_limit = input_sltp_use_high_volatility_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApplySLTPSettings(const SLTPManagerPanelSettings &settings,
|
|
||||||
const bool print_summary)
|
|
||||||
{
|
|
||||||
g_sltp_settings_valid = false;
|
|
||||||
|
|
||||||
g_sltp_manager.SetMagicNumber((ulong)magic_number);
|
|
||||||
g_sltp_manager.SetSymbol(_Symbol);
|
|
||||||
g_sltp_manager.SetDeviationInPoints(slippage);
|
|
||||||
g_sltp_manager.SetBreakevenSettings(settings.use_breakeven,
|
|
||||||
settings.breakeven_trigger_pips,
|
|
||||||
settings.breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetElapsedBreakevenSettings(settings.use_elapsed_breakeven,
|
|
||||||
settings.elapsed_breakeven_hours,
|
|
||||||
settings.elapsed_breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetActiveTrailingSettings(settings.use_active_trailing,
|
|
||||||
settings.active_breakeven_pips,
|
|
||||||
settings.active_stop_loss_offset_pips,
|
|
||||||
settings.active_step_trigger_pips,
|
|
||||||
settings.active_step_move_pips);
|
|
||||||
g_sltp_manager.SetTpProgressStopSettings(settings.use_tp_progress_stop,
|
|
||||||
settings.tp_progress_trigger_percent,
|
|
||||||
settings.tp_progress_sl_lock_percent);
|
|
||||||
g_sltp_manager.SetHighVolatilityLimitSettings(settings.use_high_volatility_limit);
|
|
||||||
|
|
||||||
if(!g_sltp_manager.ValidateSettings())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings rejected. Manager is disabled until valid settings are applied.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_settings = settings;
|
|
||||||
g_sltp_settings_valid = true;
|
|
||||||
|
|
||||||
if(print_summary)
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings: Manager=", SLTPBoolText(settings.manager_enabled),
|
|
||||||
" BE=", SLTPBoolText(settings.use_breakeven),
|
|
||||||
" ElapsedBE=", SLTPBoolText(settings.use_elapsed_breakeven),
|
|
||||||
" ActiveTrail=", SLTPBoolText(settings.use_active_trailing),
|
|
||||||
" TPProgress=", SLTPBoolText(settings.use_tp_progress_stop),
|
|
||||||
" HighVol=", SLTPBoolText(settings.use_high_volatility_limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitializeSLTPManager()
|
|
||||||
{
|
|
||||||
SLTPManagerPanelSettings initial_settings;
|
|
||||||
LoadSLTPInputSettings(initial_settings);
|
|
||||||
|
|
||||||
if(!ApplySLTPSettings(initial_settings, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
g_sltp_panel.Init(g_sltp_settings);
|
|
||||||
if(input_sltp_show_panel)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel.CreatePanel())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP panel is unavailable. EA continues with input-based SLTP settings.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_panel.SetInitialValues();
|
|
||||||
g_sltp_panel_created = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManageSLTPPositions()
|
|
||||||
{
|
|
||||||
if(!g_sltp_settings_valid)
|
|
||||||
return;
|
|
||||||
if(!g_sltp_settings.manager_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_sltp_manager.ManagePositions();
|
|
||||||
g_sltp_manager.HighVolatilityLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnChartEvent(const int id,
|
|
||||||
const long &lparam,
|
|
||||||
const double &dparam,
|
|
||||||
const string &sparam)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel_created)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SLTPManagerPanelSettings candidate_settings = g_sltp_settings;
|
|
||||||
if(g_sltp_panel.HandleChartEvent(id, lparam, dparam, sparam, candidate_settings))
|
|
||||||
{
|
|
||||||
if(!ApplySLTPSettings(candidate_settings, true))
|
|
||||||
Print("HIT SLTP panel apply failed. Please review panel values.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Function implementations are kept in project headers so the EA entry points stay compact.
|
|
||||||
#include <MyLib/Common/HITRuntimeController.mqh>
|
|
||||||
#include <MyLib/Signals/HITEntrySignal.mqh>
|
|
||||||
#include <MyLib/Common/HITExternalProcess.mqh>
|
|
||||||
#include <MyLib/Signals/HITPythonSignalGateway.mqh>
|
|
||||||
#include <MyLib/Trading/HITTradeManager.mqh>
|
|
||||||
@@ -1,462 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| HIT_EA.mq5 |
|
|
||||||
//| Copyright 2026, nanpin-martin.com |
|
|
||||||
//| https://www.nanpin-martin.com |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2026, nanpin-martin.com"
|
|
||||||
#property link "https://nanpin-martin.com/"
|
|
||||||
#property version "1.01"
|
|
||||||
|
|
||||||
#include <MyLib/Trading/SLTPManager.mqh>
|
|
||||||
#include <MyLib/Panel/SLTPManagerPanel.mqh>
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| バッチファイル実行用の設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// Windowsプロセス起動・終了確認用
|
|
||||||
#define CREATE_NO_WINDOW 0x08000000
|
|
||||||
#define PROCESS_QUERY_LIMITED_INFORMATION 0x00001000
|
|
||||||
#define SYNCHRONIZE 0x00100000
|
|
||||||
#define WAIT_OBJECT_0 0
|
|
||||||
#define WAIT_TIMEOUT 258
|
|
||||||
#define STILL_ACTIVE 259
|
|
||||||
|
|
||||||
struct STARTUPINFO_W
|
|
||||||
{
|
|
||||||
uint cb;
|
|
||||||
string lpReserved;
|
|
||||||
string lpDesktop;
|
|
||||||
string lpTitle;
|
|
||||||
uint dwX;
|
|
||||||
uint dwY;
|
|
||||||
uint dwXSize;
|
|
||||||
uint dwYSize;
|
|
||||||
uint dwXCountChars;
|
|
||||||
uint dwYCountChars;
|
|
||||||
uint dwFillAttribute;
|
|
||||||
uint dwFlags;
|
|
||||||
ushort wShowWindow;
|
|
||||||
ushort cbReserved2;
|
|
||||||
long lpReserved2;
|
|
||||||
long hStdInput;
|
|
||||||
long hStdOutput;
|
|
||||||
long hStdError;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PROCESS_INFORMATION
|
|
||||||
{
|
|
||||||
long hProcess;
|
|
||||||
long hThread;
|
|
||||||
uint dwProcessId;
|
|
||||||
uint dwThreadId;
|
|
||||||
};
|
|
||||||
|
|
||||||
#import "kernel32.dll"
|
|
||||||
int CreateProcessW(string lpApplicationName, string lpCommandLine, long lpProcessAttributes, long lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, long lpEnvironment, string lpCurrentDirectory, STARTUPINFO_W &lpStartupInfo, PROCESS_INFORMATION &lpProcessInformation);
|
|
||||||
int WaitForSingleObject(long hHandle, uint dwMilliseconds);
|
|
||||||
int GetExitCodeProcess(long hProcess, uint &lpExitCode);
|
|
||||||
int CloseHandle(long hObject);
|
|
||||||
long OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);
|
|
||||||
#import
|
|
||||||
|
|
||||||
// バッチファイルのパス
|
|
||||||
string get_trend_reply_bat = "C:\\ea_py\\bat\\get_trend_reply.bat"; // H4: trend
|
|
||||||
string get_entry_reply_bat = "C:\\ea_py\\bat\\get_entry_reply.bat"; // H1: entry
|
|
||||||
|
|
||||||
// プロセス完了ファイルの設定
|
|
||||||
string done_trend_file = "process_done_trend.txt";
|
|
||||||
string done_entry_file = "process_done_entry.txt";
|
|
||||||
|
|
||||||
// Python出力ファイル
|
|
||||||
string trend_state_file = "trend_state.txt";
|
|
||||||
string target_prices_file = "target_prices.txt";
|
|
||||||
string target_zones_file = "target_zones.txt";
|
|
||||||
|
|
||||||
// Python実行中を判定するための管理ファイル
|
|
||||||
string running_trend_file = "process_running_trend.txt";
|
|
||||||
string running_entry_file = "process_running_entry.txt";
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| インプットの設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
enum SplitLotMode
|
|
||||||
{
|
|
||||||
SPLIT_LOT_TOTAL = 0, // 総ロットをN分割
|
|
||||||
SPLIT_LOT_FIXED = 1 // 1注文あたり固定ロット
|
|
||||||
};
|
|
||||||
|
|
||||||
//--- 入力パラメータ
|
|
||||||
input double lot_size = 0.01; // ロット数
|
|
||||||
input double spread_limit = 60; // 許容スプレッド(point)
|
|
||||||
input int magic_number = 10001; // マジックナンバー
|
|
||||||
input int initial_order = 0; // 起動時の注文(0:なし, 1:あり)
|
|
||||||
input int input_position_limit = 10; // 自EAの未約定注文+ポジション上限
|
|
||||||
input bool use_split_entry_zone = false; // H1予測ゾーンで分割エントリーする
|
|
||||||
input int split_entry_count = 3; // 分割エントリー本数(1..10)
|
|
||||||
input SplitLotMode split_lot_mode = SPLIT_LOT_TOTAL; // 分割ロット配分モード
|
|
||||||
input double split_total_lot_size = 0.09; // 総量分割モードの合計ロット
|
|
||||||
input double split_fixed_lot_size = 0.01; // 固定ロットモードの1注文ロット
|
|
||||||
input bool cancel_old_split_pending_on_new_zone = true; // 新ゾーン読込時に旧分割pendingを取消
|
|
||||||
input bool use_m15_entry_filter = true; // M15確定足で発注タイミングを確認
|
|
||||||
input double m15_entry_zone_atr_multiplier = 1.50; // M15平均レンジ何本分まで候補価格への接近を許可
|
|
||||||
input bool use_m15_imbalance_confirmation = true; // T1/T3でM15初動確認を追加
|
|
||||||
input int m15_imbalance_avg_body_period = 20; // M15平均実体計算期間
|
|
||||||
input double m15_imbalance_sensitivity = 2.0; // M15初動検知感度
|
|
||||||
input double m15_imbalance_min_avg_body_points = 1.0; // 平均実体の最小値(point)
|
|
||||||
input bool use_m15_imbalance_debug_log = false; // M15初動確認ログ
|
|
||||||
input int input_entry_max_candidate_age_minutes = 120; // H1候補価格を新規発注に使う最大経過分数
|
|
||||||
input bool input_sltp_manager_enabled = false; // UI連動SLTP管理を有効化
|
|
||||||
input bool input_sltp_show_panel = true; // SLTP操作パネルを表示
|
|
||||||
input bool input_sltp_use_breakeven = false; // 通常ブレークイーブンを有効化
|
|
||||||
input double input_sltp_breakeven_trigger_pips = 30.0; // 通常BE開始pips
|
|
||||||
input double input_sltp_breakeven_buffer_pips = 3.0; // 通常BE固定バッファpips
|
|
||||||
input bool input_sltp_use_elapsed_breakeven = false; // 保有時間BEを有効化
|
|
||||||
input double input_sltp_elapsed_breakeven_hours = 4.0; // 保有時間BE開始時間
|
|
||||||
input double input_sltp_elapsed_breakeven_buffer_pips = 3.0; // 保有時間BE固定バッファpips
|
|
||||||
input bool input_sltp_use_active_trailing = false; // アクティブトレーリングを有効化
|
|
||||||
input double input_sltp_active_breakeven_pips = 30.0; // アクティブ開始pips
|
|
||||||
input double input_sltp_active_stop_loss_offset_pips = 5.0; // 初期固定pips
|
|
||||||
input double input_sltp_active_step_trigger_pips = 10.0; // ステップ更新間隔pips
|
|
||||||
input double input_sltp_active_step_move_pips = 5.0; // 1ステップ固定追加pips
|
|
||||||
input bool input_sltp_use_tp_progress_stop = false; // TP進捗SLを有効化
|
|
||||||
input double input_sltp_tp_progress_trigger_percent = 70.0; // TP進捗SL開始率
|
|
||||||
input double input_sltp_tp_progress_sl_lock_percent = 30.0; // TP距離固定率
|
|
||||||
input bool input_sltp_use_high_volatility_limit = false; // 急変時SL引き締めを有効化
|
|
||||||
ulong slippage = 10; // スリッページ
|
|
||||||
|
|
||||||
//--- 主要な定数・設定
|
|
||||||
#define POSITION_LIMIT 48
|
|
||||||
#define ENTRY_H1_LIMIT 2 // H1本数(=2時間)
|
|
||||||
#define CLOSE_H1_LIMIT 12 // H1本数(=12時間)
|
|
||||||
#define HISTORY_BARS 72
|
|
||||||
#define OHLC_START_SHIFT 1 // 1: 確定足のみをPythonへ渡す
|
|
||||||
#define M15_CONFIRM_BARS 30
|
|
||||||
#define M15_MIN_ENTRY_ZONE_POINTS 10
|
|
||||||
#define M15_MIN_BODY_RATIO 0.25
|
|
||||||
#define M15_REJECTION_WICK_RATIO 0.35
|
|
||||||
#define ENTRY_RETRY_SECONDS 60
|
|
||||||
#define ENTRY_RETRY_LIMIT 10
|
|
||||||
// ANALYZE_TIMEFRAME は削除(H4/H1 両方使うため定数ではなく直接指定)
|
|
||||||
#define TARGET_SIZE 13
|
|
||||||
#define TARGET_ZONE_SCHEMA_VERSION 2
|
|
||||||
#define DEFAULT_TARGET_PRICE 0.0
|
|
||||||
#define PYTHON_TIMEOUT_SECONDS 600 // Python完了待ちの上限(秒)
|
|
||||||
|
|
||||||
#define MARKET_LOW_VOL_RANGE 0
|
|
||||||
#define MARKET_HIGH_VOL_RANGE 1
|
|
||||||
#define MARKET_LOW_VOL_UP 2
|
|
||||||
#define MARKET_HIGH_VOL_UP 3
|
|
||||||
#define MARKET_LOW_VOL_DOWN 4
|
|
||||||
#define MARKET_HIGH_VOL_DOWN 5
|
|
||||||
#define MARKET_TECHNICAL_ERROR_STOP 6
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| EAの状態をまとめる構造体
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
struct EAState
|
|
||||||
{
|
|
||||||
int trend_state; // H4 market_state(0..5、6は技術エラー停止)を格納する変数
|
|
||||||
int res_chk; // GPTの回答が正しく取得できたか
|
|
||||||
double en_price[5]; // エントリー基準価格
|
|
||||||
double tp_price[5]; // 利益確定価格
|
|
||||||
double sl_price[5]; // ロスカット基準価格
|
|
||||||
int zone_res_chk; // 予測ゾーンが正しく取得できたか
|
|
||||||
string zone_candidate_id; // H1確定足由来の候補ID
|
|
||||||
double zone_low[5]; // 分割エントリー用ゾーン下限
|
|
||||||
double zone_high[5]; // 分割エントリー用ゾーン上限
|
|
||||||
double zone_tp[5]; // 分割エントリー用TP
|
|
||||||
double zone_sl[5]; // 分割エントリー用SL
|
|
||||||
bool load_trend_flg; // ★変更:トレンドを更新するタイミングか
|
|
||||||
bool load_target_flg; // ★変更:ターゲット価格を更新するタイミングか
|
|
||||||
int chk_cnt; // エントリー判定の試行回数
|
|
||||||
datetime last_trend_update; // ★追加:前回トレンドを更新した時刻
|
|
||||||
datetime last_target_update; // ★変更:前回ターゲット価格を更新した時刻
|
|
||||||
datetime target_loaded_at; // H1候補価格をEAへ読み込んだサーバー時刻
|
|
||||||
datetime last_chk;
|
|
||||||
};
|
|
||||||
|
|
||||||
EAState g_ea; // EA全体の状態をここで管理
|
|
||||||
|
|
||||||
// initial_order 用の初回処理フラグ
|
|
||||||
// H4トレンド処理とH1エントリー処理で別々に管理し、初回起動時の再実行ループを防ぐ。
|
|
||||||
bool g_init_trend_pending = false;
|
|
||||||
bool g_init_entry_pending = false;
|
|
||||||
|
|
||||||
// H4/H1のバー更新状態
|
|
||||||
int g_pre_bars_H4 = 0;
|
|
||||||
int g_pre_bars_H1 = 0;
|
|
||||||
int g_pre_bars_M15 = 0;
|
|
||||||
bool g_bars_H1_check = false;
|
|
||||||
bool g_bars_M15_check = false;
|
|
||||||
|
|
||||||
// ティックごとの価格情報
|
|
||||||
struct TickContext
|
|
||||||
{
|
|
||||||
double ask;
|
|
||||||
double bid;
|
|
||||||
double spread;
|
|
||||||
double spread_points;
|
|
||||||
int digits;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 外部Pythonプロセスの状態
|
|
||||||
struct ExternalProcessState
|
|
||||||
{
|
|
||||||
long handle;
|
|
||||||
uint process_id;
|
|
||||||
bool active;
|
|
||||||
bool exit_code_ready;
|
|
||||||
uint exit_code;
|
|
||||||
datetime started_at;
|
|
||||||
};
|
|
||||||
|
|
||||||
ExternalProcessState g_trend_process;
|
|
||||||
ExternalProcessState g_entry_process;
|
|
||||||
|
|
||||||
CSLTPManager g_sltp_manager;
|
|
||||||
CSLTPManagerPanel g_sltp_panel;
|
|
||||||
SLTPManagerPanelSettings g_sltp_settings;
|
|
||||||
bool g_sltp_settings_valid = false;
|
|
||||||
bool g_sltp_panel_created = false;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 起動時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief EA起動時の初期化処理を行います。
|
|
||||||
*
|
|
||||||
* Python連携用のdone/runningファイル状態を確認し、`initial_order` が有効な場合は
|
|
||||||
* H4トレンド判定とH1エントリー価格生成をそれぞれ初回実行対象にします。
|
|
||||||
* H4/H1の初回フラグを分けることで、起動直後にH4処理だけが繰り返される状態を防ぎます。
|
|
||||||
*/
|
|
||||||
int OnInit()
|
|
||||||
// プロセス完了ファイルと実行中ファイルの状態を初期化
|
|
||||||
{
|
|
||||||
PrepareDoneFileOnInit(done_trend_file, running_trend_file, "trend");
|
|
||||||
PrepareDoneFileOnInit(done_entry_file, running_entry_file, "entry");
|
|
||||||
|
|
||||||
// initial_order=1 の場合でも、H4/H1を別々に1回だけ初回実行する。
|
|
||||||
g_init_trend_pending = (initial_order == 1);
|
|
||||||
g_init_entry_pending = (initial_order == 1);
|
|
||||||
|
|
||||||
if(!InitializeSLTPManager())
|
|
||||||
return INIT_FAILED;
|
|
||||||
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 終了時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
ResetExternalProcessState(g_trend_process);
|
|
||||||
ResetExternalProcessState(g_entry_process);
|
|
||||||
|
|
||||||
if(g_sltp_panel_created)
|
|
||||||
g_sltp_panel.Destroy(reason);
|
|
||||||
|
|
||||||
// Clear chart status text left by Comment() when the EA is removed.
|
|
||||||
Comment("");
|
|
||||||
ChartRedraw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| ティック毎の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief ティック受信ごとにEA全体の処理を制御します。
|
|
||||||
*
|
|
||||||
* 処理順序は、ティック情報取得、期限切れ注文/ポジション管理、H4トレンド更新、
|
|
||||||
* H1エントリー価格更新、M15エントリータイミング更新、ステータス表示、新規注文判定の順です。
|
|
||||||
* 時間制限処理はPython完了待ちやスプレッド判定より前に実行します。
|
|
||||||
*/
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
TickContext ctx;
|
|
||||||
if(!GetTickContext(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 期限切れ注文・ポジションは、Python待ちやスプレッド制限に関係なく先に処理する。
|
|
||||||
ManageExpiredTrades();
|
|
||||||
|
|
||||||
// Existing-position protection stays active even while Python results are pending.
|
|
||||||
ManageSLTPPositions();
|
|
||||||
|
|
||||||
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
|
|
||||||
RecoverTimedOutPythonProcesses();
|
|
||||||
|
|
||||||
// H4新バーまたは初回起動時に、トレンド判定用Pythonを起動する。
|
|
||||||
ProcessTrendUpdate(g_ea);
|
|
||||||
|
|
||||||
// トレンド判定が完了していない場合、新規注文側の処理だけをスキップする。
|
|
||||||
if(!IsTrendResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTrendState(g_ea);
|
|
||||||
|
|
||||||
// H1新バーまたは初回起動時に、エントリー価格生成用Pythonを起動する。
|
|
||||||
ProcessEntryUpdate(g_ea);
|
|
||||||
|
|
||||||
// M15確定足ごとに、H1候補価格を発注してよいタイミングか再判定する。
|
|
||||||
ProcessM15EntryTimingUpdate();
|
|
||||||
|
|
||||||
UpdateStatusComment(ctx);
|
|
||||||
|
|
||||||
// ここから下は新規注文に関する処理。
|
|
||||||
if(!IsSpreadAllowed(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!IsEntryResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTargetPrices(g_ea);
|
|
||||||
ProcessEntryDecisionIfNeeded(g_ea, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| SLTP manager panel and settings bridge
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
string SLTPBoolText(const bool value)
|
|
||||||
{
|
|
||||||
return value ? "ON" : "OFF";
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadSLTPInputSettings(SLTPManagerPanelSettings &settings)
|
|
||||||
{
|
|
||||||
settings.manager_enabled = input_sltp_manager_enabled;
|
|
||||||
|
|
||||||
settings.use_breakeven = input_sltp_use_breakeven;
|
|
||||||
settings.breakeven_trigger_pips = input_sltp_breakeven_trigger_pips;
|
|
||||||
settings.breakeven_buffer_pips = input_sltp_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_elapsed_breakeven = input_sltp_use_elapsed_breakeven;
|
|
||||||
settings.elapsed_breakeven_hours = input_sltp_elapsed_breakeven_hours;
|
|
||||||
settings.elapsed_breakeven_buffer_pips = input_sltp_elapsed_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_active_trailing = input_sltp_use_active_trailing;
|
|
||||||
settings.active_breakeven_pips = input_sltp_active_breakeven_pips;
|
|
||||||
settings.active_stop_loss_offset_pips = input_sltp_active_stop_loss_offset_pips;
|
|
||||||
settings.active_step_trigger_pips = input_sltp_active_step_trigger_pips;
|
|
||||||
settings.active_step_move_pips = input_sltp_active_step_move_pips;
|
|
||||||
|
|
||||||
settings.use_tp_progress_stop = input_sltp_use_tp_progress_stop;
|
|
||||||
settings.tp_progress_trigger_percent = input_sltp_tp_progress_trigger_percent;
|
|
||||||
settings.tp_progress_sl_lock_percent = input_sltp_tp_progress_sl_lock_percent;
|
|
||||||
|
|
||||||
settings.use_high_volatility_limit = input_sltp_use_high_volatility_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApplySLTPSettings(const SLTPManagerPanelSettings &settings,
|
|
||||||
const bool print_summary)
|
|
||||||
{
|
|
||||||
g_sltp_settings_valid = false;
|
|
||||||
|
|
||||||
g_sltp_manager.SetMagicNumber((ulong)magic_number);
|
|
||||||
g_sltp_manager.SetSymbol(_Symbol);
|
|
||||||
g_sltp_manager.SetDeviationInPoints(slippage);
|
|
||||||
g_sltp_manager.SetBreakevenSettings(settings.use_breakeven,
|
|
||||||
settings.breakeven_trigger_pips,
|
|
||||||
settings.breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetElapsedBreakevenSettings(settings.use_elapsed_breakeven,
|
|
||||||
settings.elapsed_breakeven_hours,
|
|
||||||
settings.elapsed_breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetActiveTrailingSettings(settings.use_active_trailing,
|
|
||||||
settings.active_breakeven_pips,
|
|
||||||
settings.active_stop_loss_offset_pips,
|
|
||||||
settings.active_step_trigger_pips,
|
|
||||||
settings.active_step_move_pips);
|
|
||||||
g_sltp_manager.SetTpProgressStopSettings(settings.use_tp_progress_stop,
|
|
||||||
settings.tp_progress_trigger_percent,
|
|
||||||
settings.tp_progress_sl_lock_percent);
|
|
||||||
g_sltp_manager.SetHighVolatilityLimitSettings(settings.use_high_volatility_limit);
|
|
||||||
|
|
||||||
if(!g_sltp_manager.ValidateSettings())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings rejected. Manager is disabled until valid settings are applied.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_settings = settings;
|
|
||||||
g_sltp_settings_valid = true;
|
|
||||||
|
|
||||||
if(print_summary)
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings: Manager=", SLTPBoolText(settings.manager_enabled),
|
|
||||||
" BE=", SLTPBoolText(settings.use_breakeven),
|
|
||||||
" ElapsedBE=", SLTPBoolText(settings.use_elapsed_breakeven),
|
|
||||||
" ActiveTrail=", SLTPBoolText(settings.use_active_trailing),
|
|
||||||
" TPProgress=", SLTPBoolText(settings.use_tp_progress_stop),
|
|
||||||
" HighVol=", SLTPBoolText(settings.use_high_volatility_limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitializeSLTPManager()
|
|
||||||
{
|
|
||||||
SLTPManagerPanelSettings initial_settings;
|
|
||||||
LoadSLTPInputSettings(initial_settings);
|
|
||||||
|
|
||||||
if(!ApplySLTPSettings(initial_settings, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
g_sltp_panel.Init(g_sltp_settings);
|
|
||||||
if(input_sltp_show_panel)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel.CreatePanel())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP panel is unavailable. EA continues with input-based SLTP settings.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_panel.SetInitialValues();
|
|
||||||
g_sltp_panel_created = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManageSLTPPositions()
|
|
||||||
{
|
|
||||||
if(!g_sltp_settings_valid)
|
|
||||||
return;
|
|
||||||
if(!g_sltp_settings.manager_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_sltp_manager.ManagePositions();
|
|
||||||
g_sltp_manager.HighVolatilityLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnChartEvent(const int id,
|
|
||||||
const long &lparam,
|
|
||||||
const double &dparam,
|
|
||||||
const string &sparam)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel_created)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SLTPManagerPanelSettings candidate_settings = g_sltp_settings;
|
|
||||||
if(g_sltp_panel.HandleChartEvent(id, lparam, dparam, sparam, candidate_settings))
|
|
||||||
{
|
|
||||||
if(!ApplySLTPSettings(candidate_settings, true))
|
|
||||||
Print("HIT SLTP panel apply failed. Please review panel values.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Function implementations are kept in project headers so the EA entry points stay compact.
|
|
||||||
#include <MyLib/Common/HITRuntimeController.mqh>
|
|
||||||
#include <MyLib/Signals/HITEntrySignal.mqh>
|
|
||||||
#include <MyLib/Common/HITExternalProcess.mqh>
|
|
||||||
#include <MyLib/Signals/HITPythonSignalGateway.mqh>
|
|
||||||
#include <MyLib/Trading/HITTradeManager.mqh>
|
|
||||||
@@ -1,609 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| HIT_EA.mq5 |
|
|
||||||
//| Copyright 2026, nanpin-martin.com |
|
|
||||||
//| https://www.nanpin-martin.com |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2026, nanpin-martin.com"
|
|
||||||
#property link "https://nanpin-martin.com/"
|
|
||||||
#property version "1.01"
|
|
||||||
|
|
||||||
#include <MyLib/Trading/SLTPManager.mqh>
|
|
||||||
#include <MyLib/Panel/SLTPManagerPanel.mqh>
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| バッチファイル実行用の設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// Windowsプロセス起動・終了確認用
|
|
||||||
#define CREATE_NO_WINDOW 0x08000000
|
|
||||||
#define PROCESS_QUERY_LIMITED_INFORMATION 0x00001000
|
|
||||||
#define SYNCHRONIZE 0x00100000
|
|
||||||
#define WAIT_OBJECT_0 0
|
|
||||||
#define WAIT_TIMEOUT 258
|
|
||||||
#define STILL_ACTIVE 259
|
|
||||||
#define TASKKILL_WAIT_MILLISECONDS 5000
|
|
||||||
|
|
||||||
struct STARTUPINFO_W
|
|
||||||
{
|
|
||||||
uint cb;
|
|
||||||
string lpReserved;
|
|
||||||
string lpDesktop;
|
|
||||||
string lpTitle;
|
|
||||||
uint dwX;
|
|
||||||
uint dwY;
|
|
||||||
uint dwXSize;
|
|
||||||
uint dwYSize;
|
|
||||||
uint dwXCountChars;
|
|
||||||
uint dwYCountChars;
|
|
||||||
uint dwFillAttribute;
|
|
||||||
uint dwFlags;
|
|
||||||
ushort wShowWindow;
|
|
||||||
ushort cbReserved2;
|
|
||||||
long lpReserved2;
|
|
||||||
long hStdInput;
|
|
||||||
long hStdOutput;
|
|
||||||
long hStdError;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PROCESS_INFORMATION
|
|
||||||
{
|
|
||||||
long hProcess;
|
|
||||||
long hThread;
|
|
||||||
uint dwProcessId;
|
|
||||||
uint dwThreadId;
|
|
||||||
};
|
|
||||||
|
|
||||||
#import "kernel32.dll"
|
|
||||||
int CreateProcessW(string lpApplicationName, string lpCommandLine, long lpProcessAttributes, long lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, long lpEnvironment, string lpCurrentDirectory, STARTUPINFO_W &lpStartupInfo, PROCESS_INFORMATION &lpProcessInformation);
|
|
||||||
int WaitForSingleObject(long hHandle, uint dwMilliseconds);
|
|
||||||
int GetExitCodeProcess(long hProcess, uint &lpExitCode);
|
|
||||||
int CloseHandle(long hObject);
|
|
||||||
long OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);
|
|
||||||
#import
|
|
||||||
|
|
||||||
// バッチファイルのパス
|
|
||||||
// Python helper scripts are managed under this MT5 data folder:
|
|
||||||
// <TerminalDataPath>\MQL5\python_for_ea
|
|
||||||
string python_app_dir = "";
|
|
||||||
string get_trend_reply_bat = ""; // H4: trend
|
|
||||||
string get_entry_reply_bat = ""; // H1: entry
|
|
||||||
string mt5_file_prefix = ""; // Python linkage file namespace
|
|
||||||
|
|
||||||
// プロセス完了ファイルの設定
|
|
||||||
string done_trend_file = "process_done_trend.txt";
|
|
||||||
string done_entry_file = "process_done_entry.txt";
|
|
||||||
|
|
||||||
// Python出力ファイル
|
|
||||||
string ohlc_h4_file = "ohlc_H4.csv";
|
|
||||||
string ohlc_h1_file = "ohlc_H1.csv";
|
|
||||||
string trend_state_file = "trend_state.txt";
|
|
||||||
string target_prices_file = "target_prices.txt";
|
|
||||||
string target_zones_file = "target_zones.txt";
|
|
||||||
|
|
||||||
// Python実行中を判定するための管理ファイル
|
|
||||||
string running_trend_file = "process_running_trend.txt";
|
|
||||||
string running_entry_file = "process_running_entry.txt";
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| インプットの設定
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
enum SplitLotMode
|
|
||||||
{
|
|
||||||
SPLIT_LOT_TOTAL = 0, // 総ロットをN分割
|
|
||||||
SPLIT_LOT_FIXED = 1 // 1注文あたり固定ロット
|
|
||||||
};
|
|
||||||
|
|
||||||
//--- 入力パラメータ
|
|
||||||
input double lot_size = 0.01; // ロット数
|
|
||||||
input double spread_limit = 60; // 許容スプレッド(point)
|
|
||||||
input int magic_number = 10001; // マジックナンバー
|
|
||||||
input int initial_order = 0; // 起動時の注文(0:なし, 1:あり)
|
|
||||||
input int input_position_limit = 10; // 自EAの未約定注文+ポジション上限
|
|
||||||
input bool use_split_entry_zone = false; // H1予測ゾーンで分割エントリーする
|
|
||||||
input int split_entry_count = 3; // 分割エントリー本数(1..10)
|
|
||||||
input SplitLotMode split_lot_mode = SPLIT_LOT_TOTAL; // 分割ロット配分モード
|
|
||||||
input double split_total_lot_size = 0.09; // 総量分割モードの合計ロット
|
|
||||||
input double split_fixed_lot_size = 0.01; // 固定ロットモードの1注文ロット
|
|
||||||
input bool cancel_old_split_pending_on_new_zone = true; // 新ゾーン読込時に旧分割pendingを取消
|
|
||||||
input bool use_m15_entry_filter = true; // M15確定足で発注タイミングを確認
|
|
||||||
input double m15_entry_zone_atr_multiplier = 1.50; // M15平均レンジ何本分まで候補価格への接近を許可
|
|
||||||
input bool use_m15_imbalance_confirmation = true; // T1/T3でM15初動確認を追加
|
|
||||||
input int m15_imbalance_avg_body_period = 20; // M15平均実体計算期間
|
|
||||||
input double m15_imbalance_sensitivity = 2.0; // M15初動検知感度
|
|
||||||
input double m15_imbalance_min_avg_body_points = 1.0; // 平均実体の最小値(point)
|
|
||||||
input bool use_m15_imbalance_debug_log = false; // M15初動確認ログ
|
|
||||||
input int input_entry_max_candidate_age_minutes = 120; // H1候補価格を新規発注に使う最大経過分数
|
|
||||||
input bool input_sltp_manager_enabled = false; // UI連動SLTP管理を有効化
|
|
||||||
input bool input_sltp_show_panel = true; // SLTP操作パネルを表示
|
|
||||||
input bool input_sltp_use_breakeven = false; // 通常ブレークイーブンを有効化
|
|
||||||
input double input_sltp_breakeven_trigger_pips = 30.0; // 通常BE開始pips
|
|
||||||
input double input_sltp_breakeven_buffer_pips = 3.0; // 通常BE固定バッファpips
|
|
||||||
input bool input_sltp_use_elapsed_breakeven = false; // 保有時間BEを有効化
|
|
||||||
input double input_sltp_elapsed_breakeven_hours = 4.0; // 保有時間BE開始時間
|
|
||||||
input double input_sltp_elapsed_breakeven_buffer_pips = 3.0; // 保有時間BE固定バッファpips
|
|
||||||
input bool input_sltp_use_active_trailing = false; // アクティブトレーリングを有効化
|
|
||||||
input double input_sltp_active_breakeven_pips = 30.0; // アクティブ開始pips
|
|
||||||
input double input_sltp_active_stop_loss_offset_pips = 5.0; // 初期固定pips
|
|
||||||
input double input_sltp_active_step_trigger_pips = 10.0; // ステップ更新間隔pips
|
|
||||||
input double input_sltp_active_step_move_pips = 5.0; // 1ステップ固定追加pips
|
|
||||||
input bool input_sltp_use_tp_progress_stop = false; // TP進捗SLを有効化
|
|
||||||
input double input_sltp_tp_progress_trigger_percent = 70.0; // TP進捗SL開始率
|
|
||||||
input double input_sltp_tp_progress_sl_lock_percent = 30.0; // TP距離固定率
|
|
||||||
input bool input_sltp_use_high_volatility_limit = false; // 急変時SL引き締めを有効化
|
|
||||||
ulong slippage = 10; // スリッページ
|
|
||||||
|
|
||||||
//--- 主要な定数・設定
|
|
||||||
#define POSITION_LIMIT 48
|
|
||||||
#define ENTRY_H1_LIMIT 2 // H1本数(=2時間)
|
|
||||||
#define CLOSE_H1_LIMIT 12 // H1本数(=12時間)
|
|
||||||
#define HISTORY_BARS 72
|
|
||||||
#define OHLC_START_SHIFT 1 // 1: 確定足のみをPythonへ渡す
|
|
||||||
#define M15_CONFIRM_BARS 30
|
|
||||||
#define M15_MIN_ENTRY_ZONE_POINTS 10
|
|
||||||
#define M15_MIN_BODY_RATIO 0.25
|
|
||||||
#define M15_REJECTION_WICK_RATIO 0.35
|
|
||||||
#define ENTRY_RETRY_SECONDS 60
|
|
||||||
#define ENTRY_RETRY_LIMIT 10
|
|
||||||
// ANALYZE_TIMEFRAME は削除(H4/H1 両方使うため定数ではなく直接指定)
|
|
||||||
#define TARGET_SIZE 13
|
|
||||||
#define TARGET_ZONE_SCHEMA_VERSION 2
|
|
||||||
#define DEFAULT_TARGET_PRICE 0.0
|
|
||||||
#define PYTHON_TIMEOUT_SECONDS 600 // Python完了待ちの上限(秒)
|
|
||||||
|
|
||||||
#define MARKET_LOW_VOL_RANGE 0
|
|
||||||
#define MARKET_HIGH_VOL_RANGE 1
|
|
||||||
#define MARKET_LOW_VOL_UP 2
|
|
||||||
#define MARKET_HIGH_VOL_UP 3
|
|
||||||
#define MARKET_LOW_VOL_DOWN 4
|
|
||||||
#define MARKET_HIGH_VOL_DOWN 5
|
|
||||||
#define MARKET_TECHNICAL_ERROR_STOP 6
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| EAの状態をまとめる構造体
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
struct EAState
|
|
||||||
{
|
|
||||||
int trend_state; // H4 market_state(0..5、6は技術エラー停止)を格納する変数
|
|
||||||
int res_chk; // GPTの回答が正しく取得できたか
|
|
||||||
double en_price[5]; // エントリー基準価格
|
|
||||||
double tp_price[5]; // 利益確定価格
|
|
||||||
double sl_price[5]; // ロスカット基準価格
|
|
||||||
int zone_res_chk; // 予測ゾーンが正しく取得できたか
|
|
||||||
string zone_candidate_id; // H1確定足由来の候補ID
|
|
||||||
double zone_low[5]; // 分割エントリー用ゾーン下限
|
|
||||||
double zone_high[5]; // 分割エントリー用ゾーン上限
|
|
||||||
double zone_tp[5]; // 分割エントリー用TP
|
|
||||||
double zone_sl[5]; // 分割エントリー用SL
|
|
||||||
bool load_trend_flg; // ★変更:トレンドを更新するタイミングか
|
|
||||||
bool load_target_flg; // ★変更:ターゲット価格を更新するタイミングか
|
|
||||||
int chk_cnt; // エントリー判定の試行回数
|
|
||||||
datetime last_trend_update; // ★追加:前回トレンドを更新した時刻
|
|
||||||
datetime last_target_update; // ★変更:前回ターゲット価格を更新した時刻
|
|
||||||
datetime target_loaded_at; // H1候補価格をEAへ読み込んだサーバー時刻
|
|
||||||
datetime target_candidate_at; // H1候補価格の元になった確定足時刻
|
|
||||||
datetime last_chk;
|
|
||||||
};
|
|
||||||
|
|
||||||
EAState g_ea; // EA全体の状態をここで管理
|
|
||||||
|
|
||||||
// initial_order 用の初回処理フラグ
|
|
||||||
// H4トレンド処理とH1エントリー処理で別々に管理し、初回起動時の再実行ループを防ぐ。
|
|
||||||
bool g_init_trend_pending = false;
|
|
||||||
bool g_init_entry_pending = false;
|
|
||||||
|
|
||||||
// H4/H1のバー更新状態
|
|
||||||
int g_pre_bars_H4 = 0;
|
|
||||||
int g_pre_bars_H1 = 0;
|
|
||||||
int g_pre_bars_M15 = 0;
|
|
||||||
bool g_bars_H1_check = false;
|
|
||||||
bool g_bars_M15_check = false;
|
|
||||||
|
|
||||||
// ティックごとの価格情報
|
|
||||||
struct TickContext
|
|
||||||
{
|
|
||||||
double ask;
|
|
||||||
double bid;
|
|
||||||
double spread;
|
|
||||||
double spread_points;
|
|
||||||
int digits;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 外部Pythonプロセスの状態
|
|
||||||
struct ExternalProcessState
|
|
||||||
{
|
|
||||||
long handle;
|
|
||||||
uint process_id;
|
|
||||||
bool active;
|
|
||||||
bool exit_code_ready;
|
|
||||||
uint exit_code;
|
|
||||||
datetime started_at;
|
|
||||||
};
|
|
||||||
|
|
||||||
ExternalProcessState g_trend_process;
|
|
||||||
ExternalProcessState g_entry_process;
|
|
||||||
|
|
||||||
CSLTPManager g_sltp_manager;
|
|
||||||
CSLTPManagerPanel g_sltp_panel;
|
|
||||||
SLTPManagerPanelSettings g_sltp_settings;
|
|
||||||
bool g_sltp_settings_valid = false;
|
|
||||||
bool g_sltp_panel_created = false;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Python連携パスをMT5データフォルダから組み立てる関数
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief MT5データフォルダ配下のMQL5ルートを返します。
|
|
||||||
*/
|
|
||||||
string MQL5RootPath()
|
|
||||||
{
|
|
||||||
return TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5";
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief EAと同じMQL5ツリー内にあるPython補助アプリのルートを返します。
|
|
||||||
*/
|
|
||||||
string PythonAppDir()
|
|
||||||
{
|
|
||||||
return MQL5RootPath() + "\\python_for_ea";
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief Python補助アプリ配下のbatファイル絶対パスを返します。
|
|
||||||
*/
|
|
||||||
string PythonBatchPath(const string filename)
|
|
||||||
{
|
|
||||||
return PythonAppDir() + "\\bat\\" + filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief ファイル名に使える安全なトークン文字か判定します。
|
|
||||||
*/
|
|
||||||
bool IsSafeFileTokenChar(const int ch)
|
|
||||||
{
|
|
||||||
return ((ch >= 48 && ch <= 57) || // 0-9
|
|
||||||
(ch >= 65 && ch <= 90) || // A-Z
|
|
||||||
(ch >= 97 && ch <= 122) || // a-z
|
|
||||||
ch == 95 || ch == 45); // _ or -
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief シンボル名などをファイル名向けの安全なトークンへ変換します。
|
|
||||||
*/
|
|
||||||
string SanitizeFileToken(const string value)
|
|
||||||
{
|
|
||||||
string result = "";
|
|
||||||
int length = StringLen(value);
|
|
||||||
for(int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
int ch = StringGetCharacter(value, i);
|
|
||||||
if(IsSafeFileTokenChar(ch))
|
|
||||||
result += StringSubstr(value, i, 1);
|
|
||||||
else
|
|
||||||
result += "_";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result == "")
|
|
||||||
return "UNKNOWN";
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief 同一Terminal内の複数EA/複数シンボルで連携ファイルが衝突しない接頭辞を返します。
|
|
||||||
*/
|
|
||||||
string BuildMT5FilePrefix()
|
|
||||||
{
|
|
||||||
return "HIT_" + SanitizeFileToken(_Symbol) + "_" + IntegerToString(magic_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief Python連携ファイル名へEA固有の接頭辞を付けます。
|
|
||||||
*/
|
|
||||||
string PrefixedMT5FileName(const string base_name)
|
|
||||||
{
|
|
||||||
if(mt5_file_prefix == "")
|
|
||||||
return base_name;
|
|
||||||
|
|
||||||
return mt5_file_prefix + "_" + base_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief Python連携で使用するMT5 Files配下のファイル名を初期化します。
|
|
||||||
*/
|
|
||||||
void ConfigurePythonGatewayFileNames()
|
|
||||||
{
|
|
||||||
mt5_file_prefix = BuildMT5FilePrefix();
|
|
||||||
|
|
||||||
ohlc_h4_file = PrefixedMT5FileName("ohlc_H4.csv");
|
|
||||||
ohlc_h1_file = PrefixedMT5FileName("ohlc_H1.csv");
|
|
||||||
done_trend_file = PrefixedMT5FileName("process_done_trend.txt");
|
|
||||||
done_entry_file = PrefixedMT5FileName("process_done_entry.txt");
|
|
||||||
trend_state_file = PrefixedMT5FileName("trend_state.txt");
|
|
||||||
target_prices_file = PrefixedMT5FileName("target_prices.txt");
|
|
||||||
target_zones_file = PrefixedMT5FileName("target_zones.txt");
|
|
||||||
running_trend_file = PrefixedMT5FileName("process_running_trend.txt");
|
|
||||||
running_entry_file = PrefixedMT5FileName("process_running_entry.txt");
|
|
||||||
|
|
||||||
Print("Python file prefix: ", mt5_file_prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief Python連携で使用するbatパスを初期化します。
|
|
||||||
*/
|
|
||||||
void ConfigurePythonGatewayPaths()
|
|
||||||
{
|
|
||||||
ConfigurePythonGatewayFileNames();
|
|
||||||
|
|
||||||
python_app_dir = PythonAppDir();
|
|
||||||
get_trend_reply_bat = PythonBatchPath("get_trend_reply.bat");
|
|
||||||
get_entry_reply_bat = PythonBatchPath("get_entry_reply.bat");
|
|
||||||
|
|
||||||
Print("Python app dir: ", python_app_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 起動時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief EA起動時の初期化処理を行います。
|
|
||||||
*
|
|
||||||
* Python連携用のdone/runningファイル状態を確認し、`initial_order` が有効な場合は
|
|
||||||
* H4トレンド判定とH1エントリー価格生成をそれぞれ初回実行対象にします。
|
|
||||||
* H4/H1の初回フラグを分けることで、起動直後にH4処理だけが繰り返される状態を防ぎます。
|
|
||||||
*/
|
|
||||||
int OnInit()
|
|
||||||
// プロセス完了ファイルと実行中ファイルの状態を初期化
|
|
||||||
{
|
|
||||||
ConfigurePythonGatewayPaths();
|
|
||||||
|
|
||||||
PrepareDoneFileOnInit(done_trend_file, running_trend_file, "trend");
|
|
||||||
PrepareDoneFileOnInit(done_entry_file, running_entry_file, "entry");
|
|
||||||
|
|
||||||
// initial_order=1 の場合でも、H4/H1を別々に1回だけ初回実行する。
|
|
||||||
g_init_trend_pending = (initial_order == 1);
|
|
||||||
g_init_entry_pending = (initial_order == 1);
|
|
||||||
|
|
||||||
if(!InitializeSLTPManager())
|
|
||||||
return INIT_FAILED;
|
|
||||||
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 終了時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
ResetExternalProcessState(g_trend_process);
|
|
||||||
ResetExternalProcessState(g_entry_process);
|
|
||||||
|
|
||||||
if(g_sltp_panel_created)
|
|
||||||
g_sltp_panel.Destroy(reason);
|
|
||||||
|
|
||||||
// Clear chart status text left by Comment() when the EA is removed.
|
|
||||||
Comment("");
|
|
||||||
ChartRedraw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| ティック毎の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
/**
|
|
||||||
* @brief ティック受信ごとにEA全体の処理を制御します。
|
|
||||||
*
|
|
||||||
* 処理順序は、ティック情報取得、期限切れ注文/ポジション管理、H4トレンド更新、
|
|
||||||
* H1エントリー価格更新、M15エントリータイミング更新、ステータス表示、新規注文判定の順です。
|
|
||||||
* 時間制限処理はPython完了待ちやスプレッド判定より前に実行します。
|
|
||||||
*/
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
TickContext ctx;
|
|
||||||
if(!GetTickContext(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 期限切れ注文・ポジションは、Python待ちやスプレッド制限に関係なく先に処理する。
|
|
||||||
ManageExpiredTrades();
|
|
||||||
|
|
||||||
// Existing-position protection stays active even while Python results are pending.
|
|
||||||
ManageSLTPPositions();
|
|
||||||
|
|
||||||
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
|
|
||||||
RecoverTimedOutPythonProcesses();
|
|
||||||
|
|
||||||
// H4新バーまたは初回起動時に、トレンド判定用Pythonを起動する。
|
|
||||||
ProcessTrendUpdate(g_ea);
|
|
||||||
|
|
||||||
// トレンド判定が完了していない場合、新規注文側の処理だけをスキップする。
|
|
||||||
if(!IsTrendResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTrendState(g_ea);
|
|
||||||
|
|
||||||
// H1新バーまたは初回起動時に、エントリー価格生成用Pythonを起動する。
|
|
||||||
ProcessEntryUpdate(g_ea);
|
|
||||||
|
|
||||||
// M15確定足ごとに、H1候補価格を発注してよいタイミングか再判定する。
|
|
||||||
ProcessM15EntryTimingUpdate();
|
|
||||||
|
|
||||||
UpdateStatusComment(ctx);
|
|
||||||
|
|
||||||
// ここから下は新規注文に関する処理。
|
|
||||||
if(!IsSpreadAllowed(ctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!IsEntryResultReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
RefreshTargetPrices(g_ea);
|
|
||||||
ProcessEntryDecisionIfNeeded(g_ea, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| SLTP manager panel and settings bridge
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
string SLTPBoolText(const bool value)
|
|
||||||
{
|
|
||||||
return value ? "ON" : "OFF";
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadSLTPInputSettings(SLTPManagerPanelSettings &settings)
|
|
||||||
{
|
|
||||||
settings.manager_enabled = input_sltp_manager_enabled;
|
|
||||||
|
|
||||||
settings.use_breakeven = input_sltp_use_breakeven;
|
|
||||||
settings.breakeven_trigger_pips = input_sltp_breakeven_trigger_pips;
|
|
||||||
settings.breakeven_buffer_pips = input_sltp_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_elapsed_breakeven = input_sltp_use_elapsed_breakeven;
|
|
||||||
settings.elapsed_breakeven_hours = input_sltp_elapsed_breakeven_hours;
|
|
||||||
settings.elapsed_breakeven_buffer_pips = input_sltp_elapsed_breakeven_buffer_pips;
|
|
||||||
|
|
||||||
settings.use_active_trailing = input_sltp_use_active_trailing;
|
|
||||||
settings.active_breakeven_pips = input_sltp_active_breakeven_pips;
|
|
||||||
settings.active_stop_loss_offset_pips = input_sltp_active_stop_loss_offset_pips;
|
|
||||||
settings.active_step_trigger_pips = input_sltp_active_step_trigger_pips;
|
|
||||||
settings.active_step_move_pips = input_sltp_active_step_move_pips;
|
|
||||||
|
|
||||||
settings.use_tp_progress_stop = input_sltp_use_tp_progress_stop;
|
|
||||||
settings.tp_progress_trigger_percent = input_sltp_tp_progress_trigger_percent;
|
|
||||||
settings.tp_progress_sl_lock_percent = input_sltp_tp_progress_sl_lock_percent;
|
|
||||||
|
|
||||||
settings.use_high_volatility_limit = input_sltp_use_high_volatility_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApplySLTPSettings(const SLTPManagerPanelSettings &settings,
|
|
||||||
const bool print_summary)
|
|
||||||
{
|
|
||||||
g_sltp_settings_valid = false;
|
|
||||||
|
|
||||||
g_sltp_manager.SetMagicNumber((ulong)magic_number);
|
|
||||||
g_sltp_manager.SetSymbol(_Symbol);
|
|
||||||
g_sltp_manager.SetDeviationInPoints(slippage);
|
|
||||||
g_sltp_manager.SetBreakevenSettings(settings.use_breakeven,
|
|
||||||
settings.breakeven_trigger_pips,
|
|
||||||
settings.breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetElapsedBreakevenSettings(settings.use_elapsed_breakeven,
|
|
||||||
settings.elapsed_breakeven_hours,
|
|
||||||
settings.elapsed_breakeven_buffer_pips);
|
|
||||||
g_sltp_manager.SetActiveTrailingSettings(settings.use_active_trailing,
|
|
||||||
settings.active_breakeven_pips,
|
|
||||||
settings.active_stop_loss_offset_pips,
|
|
||||||
settings.active_step_trigger_pips,
|
|
||||||
settings.active_step_move_pips);
|
|
||||||
g_sltp_manager.SetTpProgressStopSettings(settings.use_tp_progress_stop,
|
|
||||||
settings.tp_progress_trigger_percent,
|
|
||||||
settings.tp_progress_sl_lock_percent);
|
|
||||||
g_sltp_manager.SetHighVolatilityLimitSettings(settings.use_high_volatility_limit);
|
|
||||||
|
|
||||||
if(!g_sltp_manager.ValidateSettings())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings rejected. Manager is disabled until valid settings are applied.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_settings = settings;
|
|
||||||
g_sltp_settings_valid = true;
|
|
||||||
|
|
||||||
if(print_summary)
|
|
||||||
{
|
|
||||||
Print("HIT SLTP settings: Manager=", SLTPBoolText(settings.manager_enabled),
|
|
||||||
" BE=", SLTPBoolText(settings.use_breakeven),
|
|
||||||
" ElapsedBE=", SLTPBoolText(settings.use_elapsed_breakeven),
|
|
||||||
" ActiveTrail=", SLTPBoolText(settings.use_active_trailing),
|
|
||||||
" TPProgress=", SLTPBoolText(settings.use_tp_progress_stop),
|
|
||||||
" HighVol=", SLTPBoolText(settings.use_high_volatility_limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitializeSLTPManager()
|
|
||||||
{
|
|
||||||
SLTPManagerPanelSettings initial_settings;
|
|
||||||
LoadSLTPInputSettings(initial_settings);
|
|
||||||
|
|
||||||
if(!ApplySLTPSettings(initial_settings, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
g_sltp_panel.Init(g_sltp_settings);
|
|
||||||
if(input_sltp_show_panel)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel.CreatePanel())
|
|
||||||
{
|
|
||||||
Print("HIT SLTP panel is unavailable. EA continues with input-based SLTP settings.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sltp_panel.SetInitialValues();
|
|
||||||
g_sltp_panel_created = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManageSLTPPositions()
|
|
||||||
{
|
|
||||||
if(!g_sltp_settings_valid)
|
|
||||||
return;
|
|
||||||
if(!g_sltp_settings.manager_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_sltp_manager.ManagePositions();
|
|
||||||
g_sltp_manager.HighVolatilityLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnChartEvent(const int id,
|
|
||||||
const long &lparam,
|
|
||||||
const double &dparam,
|
|
||||||
const string &sparam)
|
|
||||||
{
|
|
||||||
if(!g_sltp_panel_created)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SLTPManagerPanelSettings candidate_settings = g_sltp_settings;
|
|
||||||
if(g_sltp_panel.HandleChartEvent(id, lparam, dparam, sparam, candidate_settings))
|
|
||||||
{
|
|
||||||
if(!ApplySLTPSettings(candidate_settings, true))
|
|
||||||
Print("HIT SLTP panel apply failed. Please review panel values.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Function implementations are kept in project headers so the EA entry points stay compact.
|
|
||||||
#include <MyLib/Common/HITRuntimeController.mqh>
|
|
||||||
#include <MyLib/Signals/HITEntrySignal.mqh>
|
|
||||||
#include <MyLib/Common/HITExternalProcess.mqh>
|
|
||||||
#include <MyLib/Signals/HITPythonSignalGateway.mqh>
|
|
||||||
#include <MyLib/Trading/HITTradeManager.mqh>
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
#property copyright "Copyright 2026, nanpin-martin.com"
|
#property copyright "Copyright 2026, nanpin-martin.com"
|
||||||
#property link "https://nanpin-martin.com/"
|
#property link "https://nanpin-martin.com/"
|
||||||
#property version "1.10"
|
#property version "1.11"
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| バッチファイル実行用の設定
|
//| バッチファイル実行用の設定
|
||||||
@@ -97,12 +97,12 @@ enum SplitLotMode
|
|||||||
input double lot_size = 0.01; // ロット数
|
input double lot_size = 0.01; // ロット数
|
||||||
input double spread_limit = 60; // 許容スプレッド(point)
|
input double spread_limit = 60; // 許容スプレッド(point)
|
||||||
input int input_entry_magic_number = 10001; // 発注EAのマジックナンバー
|
input int input_entry_magic_number = 10001; // 発注EAのマジックナンバー
|
||||||
input ulong input_slippage_points = 20; // 許容スリッページ(point)
|
input ulong input_slippage_points = 10; // 許容スリッページ(point)
|
||||||
input int initial_order = 0; // 互換性維持用。起動時H4/H1再構築は常時実行
|
input int initial_order = 0; // 互換性維持用。起動時H4/H1再構築は常時実行
|
||||||
input int input_position_limit = 10; // 自EAの未約定注文+ポジション上限
|
input int input_position_limit = 10; // 自EAの未約定注文+ポジション上限
|
||||||
input bool use_split_entry_zone = false; // H1予測ゾーンで分割エントリーする
|
input bool use_split_entry_zone = false; // H1予測ゾーンで分割エントリーする
|
||||||
input int split_entry_count = 3; // 分割エントリー本数(1..10)
|
input int split_entry_count = 3; // 分割エントリー本数(1..10)
|
||||||
input SplitLotMode split_lot_mode = SPLIT_LOT_FIXED; // 分割ロット配分モード
|
input SplitLotMode split_lot_mode = SPLIT_LOT_TOTAL; // 分割ロット配分モード
|
||||||
input double split_total_lot_size = 0.09; // 総量分割モードの合計ロット
|
input double split_total_lot_size = 0.09; // 総量分割モードの合計ロット
|
||||||
input double split_fixed_lot_size = 0.01; // 固定ロットモードの1注文ロット
|
input double split_fixed_lot_size = 0.01; // 固定ロットモードの1注文ロット
|
||||||
input bool cancel_old_split_pending_on_new_zone = true; // 新ゾーン読込時に旧分割pendingを取消
|
input bool cancel_old_split_pending_on_new_zone = true; // 新ゾーン読込時に旧分割pendingを取消
|
||||||
@@ -118,6 +118,14 @@ input int input_entry_max_candidate_age_minutes = 120; // H1候補価格を
|
|||||||
input double input_tp_multiplier = 1.25; // TP distance multiplier (1.0=no expansion)
|
input double input_tp_multiplier = 1.25; // TP distance multiplier (1.0=no expansion)
|
||||||
input int input_min_tp_points = 0; // Minimum TP distance in points (0=disabled)
|
input int input_min_tp_points = 0; // Minimum TP distance in points (0=disabled)
|
||||||
input int input_max_tp_points = 0; // Maximum expanded TP distance in points (0=disabled)
|
input int input_max_tp_points = 0; // Maximum expanded TP distance in points (0=disabled)
|
||||||
|
input bool input_range_breakout_guard_enabled = true; // レンジ上抜け/下抜け時に逆張りLimitを退避
|
||||||
|
input ENUM_TIMEFRAMES input_range_breakout_guard_timeframe = PERIOD_M15; // レンジブレイク監視足
|
||||||
|
input int input_range_breakout_lookback_bars = 20; // レンジ高値安値の参照本数
|
||||||
|
input double input_range_breakout_max_width_multiplier = 6.0; // 平均レンジに対する最大レンジ幅
|
||||||
|
input double input_range_breakout_buffer_multiplier = 0.20; // ブレイク確定バッファ倍率
|
||||||
|
input double input_range_breakout_near_multiplier = 0.50; // ブレイク警戒の境界接近幅倍率
|
||||||
|
input double input_range_breakout_body_multiplier = 1.50; // 勢い判定の平均実体倍率
|
||||||
|
input int input_range_breakout_cooldown_bars = 4; // 逆張りLimit停止を継続する足数
|
||||||
|
|
||||||
// Existing shared HIT include files read these runtime globals.
|
// Existing shared HIT include files read these runtime globals.
|
||||||
int magic_number = 10001;
|
int magic_number = 10001;
|
||||||
@@ -200,18 +208,9 @@ bool g_bars_M15_check = false;
|
|||||||
ulong g_cancel_retry_tickets[];
|
ulong g_cancel_retry_tickets[];
|
||||||
datetime g_cancel_retry_at[];
|
datetime g_cancel_retry_at[];
|
||||||
|
|
||||||
// Compatibility settings for the shared trade manager.
|
// Range-breakout guard state for adverse reversal Limit orders.
|
||||||
// HITEntryEA does not run the range-breakout monitor, so the guard remains disabled.
|
int g_range_breakout_guard_direction = RANGE_BREAKOUT_NONE;
|
||||||
bool input_range_breakout_guard_enabled = false;
|
datetime g_range_breakout_guard_until = 0;
|
||||||
ENUM_TIMEFRAMES input_range_breakout_guard_timeframe = PERIOD_M15;
|
|
||||||
int input_range_breakout_lookback_bars = 20;
|
|
||||||
double input_range_breakout_max_width_multiplier = 6.0;
|
|
||||||
double input_range_breakout_buffer_multiplier = 0.20;
|
|
||||||
double input_range_breakout_near_multiplier = 0.50;
|
|
||||||
double input_range_breakout_body_multiplier = 1.50;
|
|
||||||
int input_range_breakout_cooldown_bars = 4;
|
|
||||||
int g_range_breakout_guard_direction = RANGE_BREAKOUT_NONE;
|
|
||||||
datetime g_range_breakout_guard_until = 0;
|
|
||||||
|
|
||||||
// ティックごとの価格情報
|
// ティックごとの価格情報
|
||||||
struct TickContext
|
struct TickContext
|
||||||
@@ -442,6 +441,9 @@ void OnTick()
|
|||||||
// Expired pending orders are managed by the entry EA before any Python wait state.
|
// Expired pending orders are managed by the entry EA before any Python wait state.
|
||||||
ManageExpiredEntryOrders();
|
ManageExpiredEntryOrders();
|
||||||
|
|
||||||
|
// Delete and pause adverse limit orders before breakout spikes can fill them.
|
||||||
|
ManageRangeBreakoutLimitGuard(ctx);
|
||||||
|
|
||||||
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
|
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
|
||||||
RecoverTimedOutPythonProcesses();
|
RecoverTimedOutPythonProcesses();
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
#property copyright "Copyright 2026, nanpin-martin.com"
|
#property copyright "Copyright 2026, nanpin-martin.com"
|
||||||
#property link "https://nanpin-martin.com/"
|
#property link "https://nanpin-martin.com/"
|
||||||
#property version "1.00"
|
#property version "1.01"
|
||||||
|
|
||||||
#include <MyLib/Trading/SLTPManager.mqh>
|
#include <MyLib/Trading/SLTPManager.mqh>
|
||||||
#include <MyLib/Trading/HITPositionLifecycleManager.mqh>
|
#include <MyLib/Trading/HITPositionLifecycleManager.mqh>
|
||||||
@@ -15,23 +15,23 @@
|
|||||||
input int input_managed_magic_number = 10001; // 管理対象のマジックナンバー
|
input int input_managed_magic_number = 10001; // 管理対象のマジックナンバー
|
||||||
input ulong input_slippage_points = 10; // 決済/SL変更の許容偏差(point)
|
input ulong input_slippage_points = 10; // 決済/SL変更の許容偏差(point)
|
||||||
input int input_position_close_after_h1_bars = 12; // 保有時間決済(H1本数、0で無効)
|
input int input_position_close_after_h1_bars = 12; // 保有時間決済(H1本数、0で無効)
|
||||||
input bool input_sltp_manager_enabled = true; // UI連動SLTP管理を有効化
|
input bool input_sltp_manager_enabled = false; // UI連動SLTP管理を有効化
|
||||||
input bool input_sltp_show_panel = true; // SLTP操作パネルを表示
|
input bool input_sltp_show_panel = true; // SLTP操作パネルを表示
|
||||||
input bool input_sltp_use_breakeven = false; // 通常ブレークイーブンを有効化
|
input bool input_sltp_use_breakeven = false; // 通常ブレークイーブンを有効化
|
||||||
input double input_sltp_breakeven_trigger_pips = 30.0; // 通常BE開始pips
|
input double input_sltp_breakeven_trigger_pips = 30.0; // 通常BE開始pips
|
||||||
input double input_sltp_breakeven_buffer_pips = 3.0; // 通常BE固定バッファpips
|
input double input_sltp_breakeven_buffer_pips = 3.0; // 通常BE固定バッファpips
|
||||||
input bool input_sltp_use_elapsed_breakeven = true; // 保有時間BEを有効化
|
input bool input_sltp_use_elapsed_breakeven = false; // 保有時間BEを有効化
|
||||||
input double input_sltp_elapsed_breakeven_hours = 2.0; // 保有時間BE開始時間
|
input double input_sltp_elapsed_breakeven_hours = 4.0; // 保有時間BE開始時間
|
||||||
input double input_sltp_elapsed_breakeven_buffer_pips = 5.0; // 保有時間BE固定バッファpips
|
input double input_sltp_elapsed_breakeven_buffer_pips = 3.0; // 保有時間BE固定バッファpips
|
||||||
input bool input_sltp_use_active_trailing = false; // アクティブトレーリングを有効化
|
input bool input_sltp_use_active_trailing = false; // アクティブトレーリングを有効化
|
||||||
input double input_sltp_active_breakeven_pips = 30.0; // アクティブ開始pips
|
input double input_sltp_active_breakeven_pips = 30.0; // アクティブ開始pips
|
||||||
input double input_sltp_active_stop_loss_offset_pips = 5.0; // 初期固定pips
|
input double input_sltp_active_stop_loss_offset_pips = 5.0; // 初期固定pips
|
||||||
input double input_sltp_active_step_trigger_pips = 10.0; // ステップ更新間隔pips
|
input double input_sltp_active_step_trigger_pips = 10.0; // ステップ更新間隔pips
|
||||||
input double input_sltp_active_step_move_pips = 5.0; // 1ステップ固定追加pips
|
input double input_sltp_active_step_move_pips = 5.0; // 1ステップ固定追加pips
|
||||||
input bool input_sltp_use_tp_progress_stop = true; // TP進捗SLを有効化
|
input bool input_sltp_use_tp_progress_stop = false; // TP進捗SLを有効化
|
||||||
input double input_sltp_tp_progress_trigger_percent = 85.0; // TP進捗SL開始率
|
input double input_sltp_tp_progress_trigger_percent = 70.0; // TP進捗SL開始率
|
||||||
input double input_sltp_tp_progress_sl_lock_percent = 60.0; // TP距離固定率
|
input double input_sltp_tp_progress_sl_lock_percent = 30.0; // TP距離固定率
|
||||||
input bool input_sltp_use_high_volatility_limit = true; // 急変時SL引き締めを有効化
|
input bool input_sltp_use_high_volatility_limit = false; // 急変時SL引き締めを有効化
|
||||||
|
|
||||||
CSLTPManager g_sltp_manager;
|
CSLTPManager g_sltp_manager;
|
||||||
CSLTPManagerPanel g_sltp_panel;
|
CSLTPManagerPanel g_sltp_panel;
|
||||||
|
|||||||
@@ -1,395 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| TradingPanel EA entry point
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#include <MyLib/Trading/TradingPanelTradingManagers.mqh>
|
|
||||||
#include <MyLib/Panel/TradingPanelPanel.mqh>
|
|
||||||
|
|
||||||
#define POSITION_TYPE_ALL ((ENUM_POSITION_TYPE) - 1) // フィルタ無し
|
|
||||||
|
|
||||||
// トータルブレークイーブン
|
|
||||||
#define BE_BUY "BreakEvenBuy"
|
|
||||||
#define BE_SELL "BreakEvenSell"
|
|
||||||
|
|
||||||
//--- カテゴリ1:取引設定
|
|
||||||
input group "■ 取引設定";
|
|
||||||
input int exit_time_interval = 4; // 時間制限クローズまでの保有時間(時間)
|
|
||||||
|
|
||||||
//--- カテゴリ2:基本設定
|
|
||||||
input group "■ 基本設定";
|
|
||||||
input ulong slippage = 10; // スリッページ
|
|
||||||
input int magic_number = 10001; // マジックナンバー
|
|
||||||
|
|
||||||
input group "■ SLTP設定: Common";
|
|
||||||
input double take_profit_pips = 150.0; // TP設定値
|
|
||||||
input double default_sl = 100.0; // SL初期値
|
|
||||||
input double stop_offset_pips = 10.0; // ストップロスオフセット(pips)
|
|
||||||
|
|
||||||
input group "■ SLTP設定: TRAIL";
|
|
||||||
input bool enable_breakeven = true; // ブレークイーブンを有効化
|
|
||||||
input double breakeven_pips = 30.0; // ブレークイーブン判定利幅
|
|
||||||
input double stop_loss_offset_pips = 5.0; // 建値からのマージン
|
|
||||||
input double step_trigger_pips = 10.0; // トレール更新トリガーpips
|
|
||||||
input double step_move_pips = 8.0; // トレール更新pips
|
|
||||||
input double tp_edit_pips = 10.0; // TP更新初期pips
|
|
||||||
|
|
||||||
//--- カテゴリ4:フィルター設定
|
|
||||||
input group "■ レンジフィルター設定";
|
|
||||||
input double range_pips = 80.0; // レンジ幅pips1
|
|
||||||
|
|
||||||
//--- カテゴリ5:時間設定
|
|
||||||
input group "■ 取引時間設定";
|
|
||||||
input bool isTradingTimeEnabled = true; // 取引時間を制限
|
|
||||||
input int TradeStartHour = 4; // 開始時間GMT(時間)
|
|
||||||
input int TradeStartMin = 0; // 開始時間GMT(分)
|
|
||||||
input int TradeEndHour = 23; // 終了時間GMT(時間)
|
|
||||||
input int TradeEndMin = 0; // 終了時間GMT(分)
|
|
||||||
|
|
||||||
int TimerPeriod_sec = 1; // n 秒ごとに OnTimer
|
|
||||||
|
|
||||||
bool wasInTradingTime = false;
|
|
||||||
bool beforeTradingInitDone = false;
|
|
||||||
bool afterTradingInitDone = false;
|
|
||||||
|
|
||||||
bool timelimit_exit = true; // 時間制限クローズ 初期状態
|
|
||||||
|
|
||||||
bool input_lock = true; // 時間制限クローズ 初期状態
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
// EAとの共有用グローバル変数
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
int gl_exitTimeIntervalInSeconds = exit_time_interval * 3600;
|
|
||||||
double gl_breakeven_pips = breakeven_pips;
|
|
||||||
double gl_stop_loss_offset_pips = stop_loss_offset_pips;
|
|
||||||
double gl_step_trigger_pips = step_trigger_pips;
|
|
||||||
double gl_step_move_pips = step_move_pips;
|
|
||||||
double gl_default_sl_pips = default_sl;
|
|
||||||
double gl_take_profit_pips = take_profit_pips;
|
|
||||||
double gl_stop_offset_pips = stop_offset_pips;
|
|
||||||
|
|
||||||
int buy_position = 0; // CountPositions() で随時更新
|
|
||||||
int sell_position = 0;
|
|
||||||
datetime last_buy_time = 0;
|
|
||||||
datetime last_sell_time = 0;
|
|
||||||
bool buy_total_be_flg = false;
|
|
||||||
bool sell_total_be_flg = false;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| トータルのブレークイーブン用変数
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool InpShowBuyLine = true; // 買いのブレークイーブンライン
|
|
||||||
bool InpShowSellLine = true; // 売りのブレークイーブンライン
|
|
||||||
double BufferPips = 2.0; // BE バッファ
|
|
||||||
int LabelShiftBars = 60; // 何本前のバーにラベルを置くか
|
|
||||||
double LabelOffsetPips = 4.0; // ライン ⇔ ラベルの距離
|
|
||||||
|
|
||||||
CTradingPanelStopManager g_stop_manager;
|
|
||||||
CTradingPanelPositionManager g_position_manager;
|
|
||||||
CTradingPanelBreakEvenLineManager g_break_even_manager;
|
|
||||||
CTradingPanelPanel g_panel;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 起動時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
g_stop_manager.Init(_Symbol, (ulong)magic_number, slippage);
|
|
||||||
g_position_manager.Init(_Symbol, (ulong)magic_number, slippage);
|
|
||||||
g_break_even_manager.Init(_Symbol, (ulong)magic_number);
|
|
||||||
g_panel.Init(exit_time_interval,
|
|
||||||
range_pips,
|
|
||||||
breakeven_pips,
|
|
||||||
stop_loss_offset_pips,
|
|
||||||
step_trigger_pips,
|
|
||||||
step_move_pips,
|
|
||||||
default_sl,
|
|
||||||
take_profit_pips,
|
|
||||||
tp_edit_pips,
|
|
||||||
stop_offset_pips);
|
|
||||||
|
|
||||||
// EA設定変更用のパネルを表示
|
|
||||||
if (!g_panel.CreatePanel(input_lock))
|
|
||||||
return INIT_FAILED;
|
|
||||||
g_panel.SetInitialValues();
|
|
||||||
|
|
||||||
// Backfill missing initial stops for existing matching positions.
|
|
||||||
g_position_manager.ApplyInitialStops(gl_default_sl_pips, gl_take_profit_pips);
|
|
||||||
|
|
||||||
// タイマーをセット
|
|
||||||
EventSetTimer(TimerPeriod_sec);
|
|
||||||
|
|
||||||
return (INIT_SUCCEEDED); // 成功コードを明示しておく
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 削除時の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
EventKillTimer();
|
|
||||||
|
|
||||||
// EA適用後のプロパティで変更すると、EAを再読み込みする。
|
|
||||||
g_panel.Destroy(reason);
|
|
||||||
|
|
||||||
// トータルブレークイーブンラインを削除
|
|
||||||
if (InpShowBuyLine)
|
|
||||||
g_break_even_manager.DeleteLine(BE_BUY);
|
|
||||||
|
|
||||||
if (InpShowSellLine)
|
|
||||||
g_break_even_manager.DeleteLine(BE_SELL);
|
|
||||||
|
|
||||||
// EAが削除された際にコメントを消す
|
|
||||||
Comment("");
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| タイマー処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnTimer()
|
|
||||||
{
|
|
||||||
// 時間状態の変化を検知
|
|
||||||
HandleTradingTimeTransition();
|
|
||||||
|
|
||||||
// ティックが少ない時間帯でも時間制限クローズを監視する。
|
|
||||||
g_position_manager.CloseTimedPositions(POSITION_TYPE_BUY, ORDER_TYPE_SELL,
|
|
||||||
timelimit_exit, gl_exitTimeIntervalInSeconds, slippage);
|
|
||||||
g_position_manager.CloseTimedPositions(POSITION_TYPE_SELL, ORDER_TYPE_BUY,
|
|
||||||
timelimit_exit, gl_exitTimeIntervalInSeconds, slippage);
|
|
||||||
|
|
||||||
// 取引時間が指定時間内か確認
|
|
||||||
if (!IsTradingTime())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| ティック毎の処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
// 時間状態の変化を検知
|
|
||||||
HandleTradingTimeTransition();
|
|
||||||
|
|
||||||
// EAの設定を画面上に表示
|
|
||||||
DisplayEAValues();
|
|
||||||
|
|
||||||
// 時間制限クローズは取引時間フィルターとは独立して実行する。
|
|
||||||
g_position_manager.CloseTimedPositions(POSITION_TYPE_BUY, ORDER_TYPE_SELL,
|
|
||||||
timelimit_exit, gl_exitTimeIntervalInSeconds, slippage);
|
|
||||||
g_position_manager.CloseTimedPositions(POSITION_TYPE_SELL, ORDER_TYPE_BUY,
|
|
||||||
timelimit_exit, gl_exitTimeIntervalInSeconds, slippage);
|
|
||||||
|
|
||||||
// 取引時間が指定時間内か確認
|
|
||||||
if (!IsTradingTime())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// レート急伸SL
|
|
||||||
g_stop_manager.HighVolatilityLimit();
|
|
||||||
|
|
||||||
//------------------------------------
|
|
||||||
// ブレークイーブン / トレールストップ監視
|
|
||||||
//------------------------------------
|
|
||||||
g_stop_manager.ManageStops(enable_breakeven,
|
|
||||||
gl_breakeven_pips,
|
|
||||||
gl_stop_loss_offset_pips,
|
|
||||||
gl_step_trigger_pips,
|
|
||||||
gl_step_move_pips);
|
|
||||||
|
|
||||||
g_break_even_manager.ManageBuy(buy_total_be_flg && InpShowBuyLine,
|
|
||||||
buy_total_be_flg,
|
|
||||||
BufferPips,
|
|
||||||
LabelShiftBars,
|
|
||||||
LabelOffsetPips,
|
|
||||||
gl_default_sl_pips,
|
|
||||||
g_stop_manager);
|
|
||||||
g_break_even_manager.ManageSell(sell_total_be_flg && InpShowSellLine,
|
|
||||||
sell_total_be_flg,
|
|
||||||
BufferPips,
|
|
||||||
LabelShiftBars,
|
|
||||||
LabelOffsetPips,
|
|
||||||
gl_default_sl_pips,
|
|
||||||
g_stop_manager);
|
|
||||||
|
|
||||||
// 保有ポジションの確認
|
|
||||||
buy_position = g_position_manager.CountPositions(POSITION_TYPE_BUY, magic_number);
|
|
||||||
sell_position = g_position_manager.CountPositions(POSITION_TYPE_SELL, magic_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 取引時間を指定する関数
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool IsTradingTime()
|
|
||||||
{
|
|
||||||
// 取引時間が有効化されていない場合、常にtrueを返す
|
|
||||||
if (!isTradingTimeEnabled)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MqlDateTime structTime;
|
|
||||||
TimeCurrent(structTime);
|
|
||||||
structTime.sec = 0;
|
|
||||||
|
|
||||||
structTime.hour = TradeStartHour;
|
|
||||||
structTime.min = TradeStartMin;
|
|
||||||
datetime timeStart = StructToTime(structTime);
|
|
||||||
|
|
||||||
structTime.hour = TradeEndHour;
|
|
||||||
structTime.min = TradeEndMin;
|
|
||||||
datetime timeEnd = StructToTime(structTime);
|
|
||||||
|
|
||||||
// エラーチェック
|
|
||||||
if (TradeStartHour >= TradeEndHour && TradeStartMin >= TradeEndMin)
|
|
||||||
{
|
|
||||||
Print("Error: Invalid Time input");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 現在の時間を取得
|
|
||||||
datetime now = TimeCurrent();
|
|
||||||
|
|
||||||
// 時間内かどうかをチェック
|
|
||||||
return (now >= timeStart && now < timeEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| 取引時間内外に状態が変化した時の初期化処理
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void HandleTradingTimeTransition()
|
|
||||||
{
|
|
||||||
bool nowInTradingTime = IsTradingTime();
|
|
||||||
|
|
||||||
// --- 時間内に入った瞬間 ---
|
|
||||||
if (nowInTradingTime && !wasInTradingTime)
|
|
||||||
{
|
|
||||||
if (!beforeTradingInitDone)
|
|
||||||
{
|
|
||||||
Print("取引時間内 初期化処理");
|
|
||||||
beforeTradingInitDone = true;
|
|
||||||
}
|
|
||||||
afterTradingInitDone = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 時間外に出た瞬間 ---
|
|
||||||
if (!nowInTradingTime && wasInTradingTime)
|
|
||||||
{
|
|
||||||
if (!afterTradingInitDone)
|
|
||||||
{
|
|
||||||
Print("取引時間外 初期化処理");
|
|
||||||
afterTradingInitDone = true;
|
|
||||||
}
|
|
||||||
beforeTradingInitDone = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wasInTradingTime = nowInTradingTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| pipsを価格に換算する関数
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
// 出力処理を関数にまとめる
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void DisplayEAValues()
|
|
||||||
{
|
|
||||||
Comment("\n",
|
|
||||||
"ブレークイーブン: ", (int)gl_breakeven_pips, "pips\n",
|
|
||||||
"時間制限クローズ: ", timelimit_exit ? "ON" : "OFF",
|
|
||||||
" | 保有時間: ", gl_exitTimeIntervalInSeconds / 3600, "時間\n",
|
|
||||||
"------------------------------------------------------------------------------------\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// +------------------------------------------------------------------+
|
|
||||||
// | チャートイベントのハンドラ
|
|
||||||
// +------------------------------------------------------------------+
|
|
||||||
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
|
|
||||||
{
|
|
||||||
ENUM_POSITION_TYPE tp_side = POSITION_TYPE_ALL;
|
|
||||||
double tp_adjust_pips = 0.0;
|
|
||||||
|
|
||||||
if (g_panel.HandleChartEvent(id,
|
|
||||||
lparam,
|
|
||||||
dparam,
|
|
||||||
sparam,
|
|
||||||
exit_time_interval,
|
|
||||||
range_pips,
|
|
||||||
breakeven_pips,
|
|
||||||
stop_loss_offset_pips,
|
|
||||||
step_trigger_pips,
|
|
||||||
step_move_pips,
|
|
||||||
default_sl,
|
|
||||||
take_profit_pips,
|
|
||||||
tp_edit_pips,
|
|
||||||
stop_offset_pips,
|
|
||||||
timelimit_exit,
|
|
||||||
input_lock,
|
|
||||||
buy_total_be_flg,
|
|
||||||
sell_total_be_flg,
|
|
||||||
gl_exitTimeIntervalInSeconds,
|
|
||||||
gl_breakeven_pips,
|
|
||||||
gl_stop_loss_offset_pips,
|
|
||||||
gl_step_trigger_pips,
|
|
||||||
gl_step_move_pips,
|
|
||||||
gl_default_sl_pips,
|
|
||||||
gl_take_profit_pips,
|
|
||||||
gl_stop_offset_pips,
|
|
||||||
tp_side,
|
|
||||||
tp_adjust_pips))
|
|
||||||
{
|
|
||||||
g_position_manager.AdjustTakeProfit(tp_adjust_pips, tp_side);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
|
||||||
// 取引イベントコールバック(再エントリーを防止)
|
|
||||||
//------------------------------------------------------------------
|
|
||||||
void OnTradeTransaction(const MqlTradeTransaction &trans,
|
|
||||||
const MqlTradeRequest &request,
|
|
||||||
const MqlTradeResult &result)
|
|
||||||
{
|
|
||||||
bool recalc_needed = false; // ポジション再集計フラグ
|
|
||||||
|
|
||||||
// 1) Deal が追加された(約定)
|
|
||||||
if (trans.type == TRADE_TRANSACTION_DEAL_ADD)
|
|
||||||
{
|
|
||||||
recalc_needed = true;
|
|
||||||
|
|
||||||
//---- Deal 詳細を取得 --------------------------------------
|
|
||||||
if (HistoryDealSelect(trans.deal)) // Deal を選択
|
|
||||||
{
|
|
||||||
ENUM_DEAL_REASON deal_reason = (ENUM_DEAL_REASON)
|
|
||||||
HistoryDealGetInteger(trans.deal, DEAL_REASON);
|
|
||||||
|
|
||||||
ENUM_DEAL_ENTRY deal_entry = (ENUM_DEAL_ENTRY)
|
|
||||||
HistoryDealGetInteger(trans.deal, DEAL_ENTRY);
|
|
||||||
|
|
||||||
//==== ★ クローズ条件(手動 or SL/TP) ===================
|
|
||||||
bool is_close =
|
|
||||||
(deal_entry == DEAL_ENTRY_OUT) &&
|
|
||||||
(deal_reason == DEAL_REASON_CLIENT || // 手動決済
|
|
||||||
deal_reason == DEAL_REASON_MOBILE || // スマホアプリ決済
|
|
||||||
deal_reason == DEAL_REASON_WEB || // WEB版決済
|
|
||||||
deal_reason == DEAL_REASON_EXPERT || // EAのタイマー決済
|
|
||||||
deal_reason == DEAL_REASON_SL || // SL ヒット(部分/全量とも)
|
|
||||||
deal_reason == DEAL_REASON_TP); // TP ヒット(部分/全量とも)
|
|
||||||
|
|
||||||
if (is_close)
|
|
||||||
{
|
|
||||||
Print("Position closed (", EnumToString(deal_reason), ") — EA waits for next prediction.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2) サーバ側でポジション内容が変更 (数量減少・SL変更等)
|
|
||||||
else if (trans.type == TRADE_TRANSACTION_POSITION)
|
|
||||||
{
|
|
||||||
recalc_needed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3) 必要に応じてポジション再集計
|
|
||||||
if (recalc_needed)
|
|
||||||
{
|
|
||||||
g_position_manager.CheckPositions(buy_position, sell_position, last_buy_time, last_sell_time);
|
|
||||||
g_position_manager.ApplyInitialStops(gl_default_sl_pips, gl_take_profit_pips);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -28,6 +28,14 @@ The two EAs coordinate through matching `_Symbol` and `input_entry_magic_number`
|
|||||||
- `input_tp_multiplier = 1.25`: Expands the API TP distance from the entry price. Values below `1.0` are clamped to `1.0`, and values above `100.0` are clamped to `100.0`.
|
- `input_tp_multiplier = 1.25`: Expands the API TP distance from the entry price. Values below `1.0` are clamped to `1.0`, and values above `100.0` are clamped to `100.0`.
|
||||||
- `input_min_tp_points = 0`: Minimum final TP distance in points. `0` disables the floor.
|
- `input_min_tp_points = 0`: Minimum final TP distance in points. `0` disables the floor.
|
||||||
- `input_max_tp_points = 0`: Maximum expanded TP distance in points. `0` disables the cap. The EA never makes the final TP closer than the API-provided TP distance.
|
- `input_max_tp_points = 0`: Maximum expanded TP distance in points. `0` disables the cap. The EA never makes the final TP closer than the API-provided TP distance.
|
||||||
|
- `input_range_breakout_guard_enabled = true`: Cancels adverse reversal Limit orders during range breakouts and temporarily blocks new ones.
|
||||||
|
- `input_range_breakout_guard_timeframe = PERIOD_M15`: Timeframe used by the range-breakout monitor.
|
||||||
|
- `input_range_breakout_lookback_bars = 20`: Closed-bar count used for range high/low and average range.
|
||||||
|
- `input_range_breakout_max_width_multiplier = 6.0`: Maximum allowed range width versus average range. `0` disables the width filter.
|
||||||
|
- `input_range_breakout_buffer_multiplier = 0.20`: Average-range multiplier used as the confirmed-breakout buffer.
|
||||||
|
- `input_range_breakout_near_multiplier = 0.50`: Average-range multiplier used as the pre-breakout proximity band.
|
||||||
|
- `input_range_breakout_body_multiplier = 1.50`: Required latest closed-bar body multiple for momentum warning.
|
||||||
|
- `input_range_breakout_cooldown_bars = 4`: Number of monitor-timeframe bars to block adverse Limit entries after detection.
|
||||||
|
|
||||||
## 4. Entry And Exit Conditions
|
## 4. Entry And Exit Conditions
|
||||||
|
|
||||||
@@ -36,6 +44,7 @@ The two EAs coordinate through matching `_Symbol` and `input_entry_magic_number`
|
|||||||
- Split entries recalculate the final TP separately for each slot, using that slot's entry price.
|
- Split entries recalculate the final TP separately for each slot, using that slot's entry price.
|
||||||
- Pending orders receive `input_entry_magic_number`.
|
- Pending orders receive `input_entry_magic_number`.
|
||||||
- The entry EA cancels expired pending orders, pending orders that conflict with the refreshed H4 state, and stale split-entry pending orders.
|
- The entry EA cancels expired pending orders, pending orders that conflict with the refreshed H4 state, and stale split-entry pending orders.
|
||||||
|
- When the range-breakout guard is enabled, upward breakout warning/confirmation cancels existing T4 Sell Limit orders and blocks new T4 entries until cooldown expiry. Downward breakout warning/confirmation cancels existing T2 Buy Limit orders and blocks new T2 entries.
|
||||||
- Filled-position SL updates, trailing, and time-based exits are not performed by this EA.
|
- Filled-position SL updates, trailing, and time-based exits are not performed by this EA.
|
||||||
|
|
||||||
## 5. Risk Management
|
## 5. Risk Management
|
||||||
@@ -43,6 +52,7 @@ The two EAs coordinate through matching `_Symbol` and `input_entry_magic_number`
|
|||||||
- The order limit counts only pending orders and positions matching `_Symbol` and `input_entry_magic_number`.
|
- The order limit counts only pending orders and positions matching `_Symbol` and `input_entry_magic_number`.
|
||||||
- Python process markers, process IDs, done files, and timeouts are monitored to prevent duplicate launches and stale-result reuse.
|
- Python process markers, process IDs, done files, and timeouts are monitored to prevent duplicate launches and stale-result reuse.
|
||||||
- If the API TP direction contradicts the Buy/Sell price rules, the EA does not repair it; the existing price-consistency checks skip the order.
|
- If the API TP direction contradicts the Buy/Sell price rules, the EA does not repair it; the existing price-consistency checks skip the order.
|
||||||
|
- The range-breakout guard only touches pending orders matching `_Symbol` and `input_entry_magic_number`; upward breakouts cancel T4 Sell Limit only, and downward breakouts cancel T2 Buy Limit only.
|
||||||
- `OrderSend` return values and `MqlTradeResult.retcode` are checked and logged.
|
- `OrderSend` return values and `MqlTradeResult.retcode` are checked and logged.
|
||||||
- Because the design assumes hedging accounts, per-ticket position management is handled by `HITPositionManagerEA.mq5`.
|
- Because the design assumes hedging accounts, per-ticket position management is handled by `HITPositionManagerEA.mq5`.
|
||||||
|
|
||||||
@@ -54,5 +64,6 @@ The two EAs coordinate through matching `_Symbol` and `input_entry_magic_number`
|
|||||||
|
|
||||||
## 7. Changelog
|
## 7. Changelog
|
||||||
|
|
||||||
|
- 2026-06-13: Connected the range-breakout guard from `HIT-EA_refactor_ver6.mq5` to the entry EA, including T4 Sell Limit retreat on upward breakouts, T2 Buy Limit retreat on downward breakouts, and cooldown-based new-entry blocking.
|
||||||
- 2026-06-13: Added `input_tp_multiplier`, `input_min_tp_points`, and `input_max_tp_points` to expand API-derived TP distances for both standard orders and per-slot split entries.
|
- 2026-06-13: Added `input_tp_multiplier`, `input_min_tp_points`, and `input_max_tp_points` to expand API-derived TP distances for both standard orders and per-slot split entries.
|
||||||
- 2026-06-07: Split entry responsibilities from `HIT-EA_refactor_ver6.mq5`; moved SLTP panel and filled-position management responsibilities to `HITPositionManagerEA.mq5`.
|
- 2026-06-07: Split entry responsibilities from `HIT-EA_refactor_ver6.mq5`; moved SLTP panel and filled-position management responsibilities to `HITPositionManagerEA.mq5`.
|
||||||
|
|||||||
@@ -28,6 +28,14 @@
|
|||||||
- `input_tp_multiplier = 1.25`: APIから取得したTP距離を、エントリー価格からの距離ベースで拡大する倍率。`1.0` 未満は `1.0`、`100.0` 超は `100.0` に丸めます。
|
- `input_tp_multiplier = 1.25`: APIから取得したTP距離を、エントリー価格からの距離ベースで拡大する倍率。`1.0` 未満は `1.0`、`100.0` 超は `100.0` に丸めます。
|
||||||
- `input_min_tp_points = 0`: 拡大後TP距離の最小値(point)。`0` の場合は無効です。
|
- `input_min_tp_points = 0`: 拡大後TP距離の最小値(point)。`0` の場合は無効です。
|
||||||
- `input_max_tp_points = 0`: 拡大後TP距離の最大値(point)。`0` の場合は無効です。ただしAPI由来TPより近くなる場合は縮小せず、API距離を維持します。
|
- `input_max_tp_points = 0`: 拡大後TP距離の最大値(point)。`0` の場合は無効です。ただしAPI由来TPより近くなる場合は縮小せず、API距離を維持します。
|
||||||
|
- `input_range_breakout_guard_enabled = true`: レンジ上抜け/下抜け時に逆方向の逆張りLimit注文を退避し、新規発注も一時停止するか。
|
||||||
|
- `input_range_breakout_guard_timeframe = PERIOD_M15`: レンジブレイクを監視する時間足。
|
||||||
|
- `input_range_breakout_lookback_bars = 20`: レンジ高値・安値と平均レンジを計算する確定足本数。
|
||||||
|
- `input_range_breakout_max_width_multiplier = 6.0`: 平均レンジに対して許容する最大レンジ幅。`0` の場合はレンジ幅フィルタを無効化します。
|
||||||
|
- `input_range_breakout_buffer_multiplier = 0.20`: 確定ブレイク判定に使う平均レンジ倍率。
|
||||||
|
- `input_range_breakout_near_multiplier = 0.50`: ブレイク警戒判定に使うレンジ境界への接近幅倍率。
|
||||||
|
- `input_range_breakout_body_multiplier = 1.50`: ブレイク警戒に必要な直近確定足実体の平均実体倍率。
|
||||||
|
- `input_range_breakout_cooldown_bars = 4`: ブレイク検知後に逆方向Limitの新規発注を停止する足数。
|
||||||
|
|
||||||
## 4. エントリー/エグジット条件
|
## 4. エントリー/エグジット条件
|
||||||
|
|
||||||
@@ -36,6 +44,7 @@
|
|||||||
- 分割エントリーではslotごとのエントリー価格を基準に、各slotの最終TPを個別に計算します。
|
- 分割エントリーではslotごとのエントリー価格を基準に、各slotの最終TPを個別に計算します。
|
||||||
- pending注文には `input_entry_magic_number` を付与します。
|
- pending注文には `input_entry_magic_number` を付与します。
|
||||||
- H4状態と矛盾するpending注文、期限切れpending注文、古い分割pending注文は発注EAが取消します。
|
- H4状態と矛盾するpending注文、期限切れpending注文、古い分割pending注文は発注EAが取消します。
|
||||||
|
- レンジブレイクガードがONの場合、M15監視足で上方向ブレイク警戒/確定を検出すると既存T4 Sell Limitを取消し、T4新規発注をクールダウン終了まで停止します。下方向ブレイクでは既存T2 Buy Limitを取消し、T2新規発注を停止します。
|
||||||
- 約定後ポジションのSL変更、時間決済、トレーリングは発注EAでは行いません。
|
- 約定後ポジションのSL変更、時間決済、トレーリングは発注EAでは行いません。
|
||||||
|
|
||||||
## 5. リスク管理
|
## 5. リスク管理
|
||||||
@@ -43,6 +52,7 @@
|
|||||||
- 発注上限は口座全体ではなく `_Symbol` と `input_entry_magic_number` が一致するpending注文 + ポジションで判定します。
|
- 発注上限は口座全体ではなく `_Symbol` と `input_entry_magic_number` が一致するpending注文 + ポジションで判定します。
|
||||||
- Python連携は起動中/完了ファイルとプロセスIDを監視し、二重起動と古い結果の再利用を抑止します。
|
- Python連携は起動中/完了ファイルとプロセスIDを監視し、二重起動と古い結果の再利用を抑止します。
|
||||||
- API由来TPの方向がBuy/Sell条件と逆の場合、EAは方向を補正せず既存の価格整合チェックで発注を見送ります。
|
- API由来TPの方向がBuy/Sell条件と逆の場合、EAは方向を補正せず既存の価格整合チェックで発注を見送ります。
|
||||||
|
- レンジブレイクガードは `_Symbol` と `input_entry_magic_number` が一致するpending注文だけを対象にし、上方向ではT4 Sell Limit、下方向ではT2 Buy Limitのみを取消します。
|
||||||
- `OrderSend` の戻り値と `MqlTradeResult.retcode` を確認し、失敗時はエラーまたはretcodeをログに出します。
|
- `OrderSend` の戻り値と `MqlTradeResult.retcode` を確認し、失敗時はエラーまたはretcodeをログに出します。
|
||||||
- hedging口座前提のため、約定後の複数ticket管理は `HITPositionManagerEA.mq5` が担当します。
|
- hedging口座前提のため、約定後の複数ticket管理は `HITPositionManagerEA.mq5` が担当します。
|
||||||
|
|
||||||
@@ -54,5 +64,6 @@
|
|||||||
|
|
||||||
## 7. 変更履歴
|
## 7. 変更履歴
|
||||||
|
|
||||||
|
- 2026-06-13: `HIT-EA_refactor_ver6.mq5` と同等のレンジブレイクガードを発注EAへ接続。レンジ上抜け時のT4 Sell Limit退避、レンジ下抜け時のT2 Buy Limit退避、およびクールダウン中の新規発注停止を反映。
|
||||||
- 2026-06-13: API由来TPをエントリー価格からの距離ベースで拡大する `input_tp_multiplier`, `input_min_tp_points`, `input_max_tp_points` を追加し、通常注文と分割slotごとの最終TP計算に反映。
|
- 2026-06-13: API由来TPをエントリー価格からの距離ベースで拡大する `input_tp_multiplier`, `input_min_tp_points`, `input_max_tp_points` を追加し、通常注文と分割slotごとの最終TP計算に反映。
|
||||||
- 2026-06-07: `HIT-EA_refactor_ver6.mq5` から発注責務を分離し、SLTPパネルとポジション管理を `HITPositionManagerEA.mq5` へ移管する仕様を追加。
|
- 2026-06-07: `HIT-EA_refactor_ver6.mq5` から発注責務を分離し、SLTPパネルとポジション管理を `HITPositionManagerEA.mq5` へ移管する仕様を追加。
|
||||||
|
|||||||
@@ -19,11 +19,21 @@ The managed set is limited to positions whose `POSITION_SYMBOL` equals `_Symbol`
|
|||||||
- `input_position_close_after_h1_bars = 12`: Time-based close threshold in H1 bars. `0` disables it.
|
- `input_position_close_after_h1_bars = 12`: Time-based close threshold in H1 bars. `0` disables it.
|
||||||
- `input_sltp_manager_enabled = false`: Master switch for SLTP management.
|
- `input_sltp_manager_enabled = false`: Master switch for SLTP management.
|
||||||
- `input_sltp_show_panel = true`: Shows the SLTP control panel.
|
- `input_sltp_show_panel = true`: Shows the SLTP control panel.
|
||||||
- `input_sltp_use_breakeven`: Standard breakeven.
|
- `input_sltp_use_breakeven = false`: Standard breakeven.
|
||||||
- `input_sltp_use_elapsed_breakeven`: Elapsed-time breakeven.
|
- `input_sltp_breakeven_trigger_pips = 30.0`: Profit threshold for standard breakeven.
|
||||||
- `input_sltp_use_active_trailing`: Active trailing.
|
- `input_sltp_breakeven_buffer_pips = 3.0`: Profit-side entry buffer used by standard breakeven.
|
||||||
- `input_sltp_use_tp_progress_stop`: TP-progress stop.
|
- `input_sltp_use_elapsed_breakeven = false`: Elapsed-time breakeven.
|
||||||
- `input_sltp_use_high_volatility_limit`: High-volatility stop tightening.
|
- `input_sltp_elapsed_breakeven_hours = 4.0`: Holding time required before elapsed-time breakeven is allowed.
|
||||||
|
- `input_sltp_elapsed_breakeven_buffer_pips = 3.0`: Profit-side entry buffer used by elapsed-time breakeven.
|
||||||
|
- `input_sltp_use_active_trailing = false`: Active trailing.
|
||||||
|
- `input_sltp_active_breakeven_pips = 30.0`: Profit threshold that starts active trailing.
|
||||||
|
- `input_sltp_active_stop_loss_offset_pips = 5.0`: Initial locked profit offset from entry.
|
||||||
|
- `input_sltp_active_step_trigger_pips = 10.0`: Additional profit interval required for each SL step.
|
||||||
|
- `input_sltp_active_step_move_pips = 5.0`: SL movement added per completed step.
|
||||||
|
- `input_sltp_use_tp_progress_stop = false`: TP-progress stop.
|
||||||
|
- `input_sltp_tp_progress_trigger_percent = 70.0`: TP progress required before the SL lock is applied.
|
||||||
|
- `input_sltp_tp_progress_sl_lock_percent = 30.0`: Entry-to-TP distance percentage locked by SL.
|
||||||
|
- `input_sltp_use_high_volatility_limit = false`: High-volatility stop tightening.
|
||||||
|
|
||||||
## 4. Entry And Exit Conditions
|
## 4. Entry And Exit Conditions
|
||||||
|
|
||||||
@@ -48,4 +58,5 @@ The managed set is limited to positions whose `POSITION_SYMBOL` equals `_Symbol`
|
|||||||
|
|
||||||
## 7. Changelog
|
## 7. Changelog
|
||||||
|
|
||||||
|
- 2026-06-13: Synchronized SLTP input defaults with `HIT-EA_refactor_ver6.mq5` and documented each default value.
|
||||||
- 2026-06-07: Split position-management responsibilities from `HIT-EA_refactor_ver6.mq5` and defined a hedging-account, ticket-based manager EA.
|
- 2026-06-07: Split position-management responsibilities from `HIT-EA_refactor_ver6.mq5` and defined a hedging-account, ticket-based manager EA.
|
||||||
|
|||||||
@@ -19,11 +19,21 @@
|
|||||||
- `input_position_close_after_h1_bars = 12`: 保有時間決済のH1本数。0で無効。
|
- `input_position_close_after_h1_bars = 12`: 保有時間決済のH1本数。0で無効。
|
||||||
- `input_sltp_manager_enabled = false`: SLTP管理全体のON/OFF。
|
- `input_sltp_manager_enabled = false`: SLTP管理全体のON/OFF。
|
||||||
- `input_sltp_show_panel = true`: SLTP操作パネルを表示するか。
|
- `input_sltp_show_panel = true`: SLTP操作パネルを表示するか。
|
||||||
- `input_sltp_use_breakeven`: 通常ブレークイーブン。
|
- `input_sltp_use_breakeven = false`: 通常ブレークイーブン。
|
||||||
- `input_sltp_use_elapsed_breakeven`: 保有時間ベースのブレークイーブン。
|
- `input_sltp_breakeven_trigger_pips = 30.0`: 通常ブレークイーブン開始pips。
|
||||||
- `input_sltp_use_active_trailing`: アクティブトレーリング。
|
- `input_sltp_breakeven_buffer_pips = 3.0`: 通常ブレークイーブン時の利益方向バッファpips。
|
||||||
- `input_sltp_use_tp_progress_stop`: TP進捗率SL。
|
- `input_sltp_use_elapsed_breakeven = false`: 保有時間ベースのブレークイーブン。
|
||||||
- `input_sltp_use_high_volatility_limit`: 急変時SL引き締め。
|
- `input_sltp_elapsed_breakeven_hours = 4.0`: 保有時間ベースのブレークイーブン開始時間。
|
||||||
|
- `input_sltp_elapsed_breakeven_buffer_pips = 3.0`: 保有時間ベースのブレークイーブン時の利益方向バッファpips。
|
||||||
|
- `input_sltp_use_active_trailing = false`: アクティブトレーリング。
|
||||||
|
- `input_sltp_active_breakeven_pips = 30.0`: アクティブトレーリング開始pips。
|
||||||
|
- `input_sltp_active_stop_loss_offset_pips = 5.0`: 開始時に建値から固定する利益pips。
|
||||||
|
- `input_sltp_active_step_trigger_pips = 10.0`: SLを1段進めるために必要な追加利益pips。
|
||||||
|
- `input_sltp_active_step_move_pips = 5.0`: 1段ごとにSLを利益方向へ動かすpips。
|
||||||
|
- `input_sltp_use_tp_progress_stop = false`: TP進捗率SL。
|
||||||
|
- `input_sltp_tp_progress_trigger_percent = 70.0`: TP進捗率SL開始率。
|
||||||
|
- `input_sltp_tp_progress_sl_lock_percent = 30.0`: 建値からTPまでの距離のうちSLで固定する割合。
|
||||||
|
- `input_sltp_use_high_volatility_limit = false`: 急変時SL引き締め。
|
||||||
|
|
||||||
## 4. エントリー/エグジット条件
|
## 4. エントリー/エグジット条件
|
||||||
|
|
||||||
@@ -48,4 +58,5 @@
|
|||||||
|
|
||||||
## 7. 変更履歴
|
## 7. 変更履歴
|
||||||
|
|
||||||
|
- 2026-06-13: SLTP関連inputの既定値を `HIT-EA_refactor_ver6.mq5` と同じ初期状態に同期し、仕様書へ各既定値を明記。
|
||||||
- 2026-06-07: `HIT-EA_refactor_ver6.mq5` からポジション管理責務を分離し、hedging口座専用のticket単位管理EAとして新規定義。
|
- 2026-06-07: `HIT-EA_refactor_ver6.mq5` からポジション管理責務を分離し、hedging口座専用のticket単位管理EAとして新規定義。
|
||||||
|
|||||||
Reference in New Issue
Block a user