234 lines
8.9 KiB
Plaintext
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.");
|
|
}
|
|
}
|