Refactor EA codebase and update project docs

This commit is contained in:
Hiroaki86
2026-06-13 23:22:06 +09:00
parent f9012e19e2
commit 7b11d44d66
13 changed files with 80 additions and 3486 deletions
-642
View File
@@ -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_state0..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_state0..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_state0..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_state0..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_state0..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_state0..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>
+17 -15
View File
@@ -5,7 +5,7 @@
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, 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 spread_limit = 60; // 許容スプレッド(point)
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 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_FIXED; // 分割ロット配分モード
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を取消
@@ -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 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停止を継続する足数
// Existing shared HIT include files read these runtime globals.
int magic_number = 10001;
@@ -200,18 +208,9 @@ bool g_bars_M15_check = false;
ulong g_cancel_retry_tickets[];
datetime g_cancel_retry_at[];
// Compatibility settings for the shared trade manager.
// HITEntryEA does not run the range-breakout monitor, so the guard remains disabled.
bool input_range_breakout_guard_enabled = false;
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;
// Range-breakout guard state for adverse reversal Limit orders.
int g_range_breakout_guard_direction = RANGE_BREAKOUT_NONE;
datetime g_range_breakout_guard_until = 0;
// ティックごとの価格情報
struct TickContext
@@ -442,6 +441,9 @@ void OnTick()
// Expired pending orders are managed by the entry EA before any Python wait state.
ManageExpiredEntryOrders();
// Delete and pause adverse limit orders before breakout spikes can fill them.
ManageRangeBreakoutLimitGuard(ctx);
// 外部Pythonがdoneを返さない場合に、一定時間で待機状態を解除して再実行対象にする。
RecoverTimedOutPythonProcesses();
+9 -9
View File
@@ -5,7 +5,7 @@
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, 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/HITPositionLifecycleManager.mqh>
@@ -15,23 +15,23 @@
input int input_managed_magic_number = 10001; // 管理対象のマジックナンバー
input ulong input_slippage_points = 10; // 決済/SL変更の許容偏差(point)
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_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 = true; // 保有時間BEを有効化
input double input_sltp_elapsed_breakeven_hours = 2.0; // 保有時間BE開始時間
input double input_sltp_elapsed_breakeven_buffer_pips = 5.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 = true; // TP進捗SLを有効化
input double input_sltp_tp_progress_trigger_percent = 85.0; // TP進捗SL開始率
input double input_sltp_tp_progress_sl_lock_percent = 60.0; // TP距離固定率
input bool input_sltp_use_high_volatility_limit = true; // 急変時SL引き締めを有効化
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引き締めを有効化
CSLTPManager g_sltp_manager;
CSLTPManagerPanel g_sltp_panel;
-395
View File
@@ -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);
}
}
+11
View File
@@ -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_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_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
@@ -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.
- 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.
- 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.
## 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`.
- 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.
- 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.
- 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
- 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-07: Split entry responsibilities from `HIT-EA_refactor_ver6.mq5`; moved SLTP panel and filled-position management responsibilities to `HITPositionManagerEA.mq5`.
+11
View File
@@ -28,6 +28,14 @@
- `input_tp_multiplier = 1.25`: APIから取得したTP距離を、エントリー価格からの距離ベースで拡大する倍率。`1.0` 未満は `1.0``100.0` 超は `100.0` に丸めます。
- `input_min_tp_points = 0`: 拡大後TP距離の最小値(point)。`0` の場合は無効です。
- `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. エントリー/エグジット条件
@@ -36,6 +44,7 @@
- 分割エントリーではslotごとのエントリー価格を基準に、各slotの最終TPを個別に計算します。
- pending注文には `input_entry_magic_number` を付与します。
- H4状態と矛盾するpending注文、期限切れpending注文、古い分割pending注文は発注EAが取消します。
- レンジブレイクガードがONの場合、M15監視足で上方向ブレイク警戒/確定を検出すると既存T4 Sell Limitを取消し、T4新規発注をクールダウン終了まで停止します。下方向ブレイクでは既存T2 Buy Limitを取消し、T2新規発注を停止します。
- 約定後ポジションのSL変更、時間決済、トレーリングは発注EAでは行いません。
## 5. リスク管理
@@ -43,6 +52,7 @@
- 発注上限は口座全体ではなく `_Symbol``input_entry_magic_number` が一致するpending注文 + ポジションで判定します。
- Python連携は起動中/完了ファイルとプロセスIDを監視し、二重起動と古い結果の再利用を抑止します。
- API由来TPの方向がBuy/Sell条件と逆の場合、EAは方向を補正せず既存の価格整合チェックで発注を見送ります。
- レンジブレイクガードは `_Symbol``input_entry_magic_number` が一致するpending注文だけを対象にし、上方向ではT4 Sell Limit、下方向ではT2 Buy Limitのみを取消します。
- `OrderSend` の戻り値と `MqlTradeResult.retcode` を確認し、失敗時はエラーまたはretcodeをログに出します。
- hedging口座前提のため、約定後の複数ticket管理は `HITPositionManagerEA.mq5` が担当します。
@@ -54,5 +64,6 @@
## 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-07: `HIT-EA_refactor_ver6.mq5` から発注責務を分離し、SLTPパネルとポジション管理を `HITPositionManagerEA.mq5` へ移管する仕様を追加。
+16 -5
View File
@@ -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_sltp_manager_enabled = false`: Master switch for SLTP management.
- `input_sltp_show_panel = true`: Shows the SLTP control panel.
- `input_sltp_use_breakeven`: Standard breakeven.
- `input_sltp_use_elapsed_breakeven`: Elapsed-time breakeven.
- `input_sltp_use_active_trailing`: Active trailing.
- `input_sltp_use_tp_progress_stop`: TP-progress stop.
- `input_sltp_use_high_volatility_limit`: High-volatility stop tightening.
- `input_sltp_use_breakeven = false`: Standard breakeven.
- `input_sltp_breakeven_trigger_pips = 30.0`: Profit threshold for standard breakeven.
- `input_sltp_breakeven_buffer_pips = 3.0`: Profit-side entry buffer used by standard breakeven.
- `input_sltp_use_elapsed_breakeven = false`: Elapsed-time breakeven.
- `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
@@ -48,4 +58,5 @@ The managed set is limited to positions whose `POSITION_SYMBOL` equals `_Symbol`
## 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.
+16 -5
View File
@@ -19,11 +19,21 @@
- `input_position_close_after_h1_bars = 12`: 保有時間決済のH1本数。0で無効。
- `input_sltp_manager_enabled = false`: SLTP管理全体のON/OFF。
- `input_sltp_show_panel = true`: SLTP操作パネルを表示するか。
- `input_sltp_use_breakeven`: 通常ブレークイーブン。
- `input_sltp_use_elapsed_breakeven`: 保有時間ベースのブレークイーブン。
- `input_sltp_use_active_trailing`: アクティブトレーリング
- `input_sltp_use_tp_progress_stop`: TP進捗率SL
- `input_sltp_use_high_volatility_limit`: 急変時SL引き締め
- `input_sltp_use_breakeven = false`: 通常ブレークイーブン。
- `input_sltp_breakeven_trigger_pips = 30.0`: 通常ブレークイーブン開始pips
- `input_sltp_breakeven_buffer_pips = 3.0`: 通常ブレークイーブン時の利益方向バッファpips
- `input_sltp_use_elapsed_breakeven = false`: 保有時間ベースのブレークイーブン
- `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. エントリー/エグジット条件
@@ -48,4 +58,5 @@
## 7. 変更履歴
- 2026-06-13: SLTP関連inputの既定値を `HIT-EA_refactor_ver6.mq5` と同じ初期状態に同期し、仕様書へ各既定値を明記。
- 2026-06-07: `HIT-EA_refactor_ver6.mq5` からポジション管理責務を分離し、hedging口座専用のticket単位管理EAとして新規定義。