Files
EA_with_Python/Experts/MyProject/HITPositionManagerEA.mq5
T
2026-06-07 22:06:30 +09:00

234 lines
8.9 KiB
Plaintext

//+------------------------------------------------------------------+
//| HITPositionManagerEA.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.00"
#include <MyLib/Trading/SLTPManager.mqh>
#include <MyLib/Trading/HITPositionLifecycleManager.mqh>
#include <MyLib/Panel/SLTPManagerPanel.mqh>
// This EA never opens new positions. It manages hedging-account tickets created by HITEntryEA.
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 = 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引き締めを有効化
CSLTPManager g_sltp_manager;
CSLTPManagerPanel g_sltp_panel;
SLTPManagerPanelSettings g_sltp_settings;
CHITPositionLifecycleManager g_position_lifecycle;
bool g_sltp_settings_valid = false;
bool g_sltp_panel_created = false;
int EffectiveCloseAfterSeconds()
{
int close_bars = input_position_close_after_h1_bars;
if(close_bars < 0)
close_bars = 0;
if(close_bars > 240)
close_bars = 240;
const int h1_seconds = PeriodSeconds(PERIOD_H1);
if(close_bars <= 0 || h1_seconds <= 0)
return 0;
return close_bars * h1_seconds;
}
bool IsHedgingAccount()
{
return (AccountInfoInteger(ACCOUNT_MARGIN_MODE) == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
}
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)input_managed_magic_number);
g_sltp_manager.SetSymbol(_Symbol);
g_sltp_manager.SetDeviationInPoints(input_slippage_points);
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 position manager 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 position manager 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),
" magic=", input_managed_magic_number);
}
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 position manager SLTP panel is unavailable. EA continues with input-based settings.");
return true;
}
g_sltp_panel.SetInitialValues();
g_sltp_panel_created = true;
}
return true;
}
bool InitializePositionLifecycleManager()
{
return g_position_lifecycle.Init(_Symbol,
(ulong)input_managed_magic_number,
input_slippage_points,
EffectiveCloseAfterSeconds());
}
void ManageTargetPositions()
{
g_position_lifecycle.SetCloseAfterSeconds(EffectiveCloseAfterSeconds());
g_position_lifecycle.CloseExpiredPositions();
if(!g_sltp_settings_valid)
return;
if(!g_sltp_settings.manager_enabled)
return;
g_sltp_manager.ManagePositions();
g_sltp_manager.HighVolatilityLimit();
}
int OnInit()
{
if(!IsHedgingAccount())
{
Print("HITPositionManagerEA requires a retail hedging account. account_margin_mode=",
AccountInfoInteger(ACCOUNT_MARGIN_MODE));
return INIT_FAILED;
}
if(!InitializePositionLifecycleManager())
return INIT_FAILED;
if(!InitializeSLTPManager())
return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(g_sltp_panel_created)
g_sltp_panel.Destroy(reason);
Comment("");
ChartRedraw(0);
}
void OnTick()
{
ManageTargetPositions();
}
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 position manager panel apply failed. Please review panel values.");
}
}