Expand API-derived TP distances

This commit is contained in:
Hiroaki86
2026-06-13 11:58:49 +09:00
parent 4de3d24dcd
commit f9012e19e2
7 changed files with 218 additions and 15 deletions
@@ -117,6 +117,9 @@ 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; // レンジ高値安値の参照本数
+20
View File
@@ -115,6 +115,9 @@ 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)
// Existing shared HIT include files read these runtime globals.
int magic_number = 10001;
@@ -146,6 +149,10 @@ ulong slippage = 10;
#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
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
@@ -193,6 +200,19 @@ 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;
// ティックごとの価格情報
struct TickContext
{
+167 -15
View File
@@ -1,6 +1,131 @@
#ifndef HIT_ENTRY_SIGNAL_MQH
#define HIT_ENTRY_SIGNAL_MQH
//+------------------------------------------------------------------+
//| TP expansion settings
//+------------------------------------------------------------------+
double EffectiveTpMultiplier()
{
double multiplier = input_tp_multiplier;
if(multiplier < 1.0)
multiplier = 1.0;
if(multiplier > 100.0)
multiplier = 100.0;
return multiplier;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double EffectiveMinTpPoints()
{
if(input_min_tp_points <= 0)
return 0.0;
return (double)input_min_tp_points;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double EffectiveMaxTpPoints()
{
if(input_max_tp_points <= 0)
return 0.0;
return (double)input_max_tp_points;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsBuyTargetOrderType(const int orderType)
{
return (orderType == 1 || orderType == 2);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsSellTargetOrderType(const int orderType)
{
return (orderType == 3 || orderType == 4);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsTakeProfitDirectionValid(const int orderType, const double en, const double tp)
{
if(IsBuyTargetOrderType(orderType))
return (tp > en);
if(IsSellTargetOrderType(orderType))
return (tp < en);
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double ExpandedTakeProfitPrice(const int orderType, const double en, const double api_tp)
{
int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
double normalized_api_tp = NormalizeDouble(api_tp, digits);
if(en <= 0.0 || api_tp <= 0.0)
return normalized_api_tp;
if(!IsTakeProfitDirectionValid(orderType, en, api_tp))
{
Print("[TP Adjust Skip] invalid API TP direction. orderType=", orderType,
" en=", en, " api_tp=", api_tp);
return normalized_api_tp;
}
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(point <= 0.0)
point = Point();
if(point <= 0.0)
return normalized_api_tp;
double base_points = MathAbs(api_tp - en) / point;
if(base_points <= 0.0)
return normalized_api_tp;
double final_points = base_points * EffectiveTpMultiplier();
double min_points = EffectiveMinTpPoints();
double max_points = EffectiveMaxTpPoints();
if(min_points > 0.0 && final_points < min_points)
final_points = min_points;
if(max_points > 0.0 && final_points > max_points)
final_points = max_points;
// Never make the final target closer than the API-provided TP.
if(final_points < base_points)
final_points = base_points;
double final_tp = 0.0;
if(IsBuyTargetOrderType(orderType))
final_tp = en + final_points * point;
else
final_tp = en - final_points * point;
final_tp = NormalizeDouble(final_tp, digits);
if(MathAbs(final_tp - normalized_api_tp) >= point * 0.5)
Print("[TP Adjust] orderType=", orderType,
" en=", en,
" api_tp=", normalized_api_tp,
" final_tp=", final_tp,
" base_points=", DoubleToString(base_points, 1),
" final_points=", DoubleToString(final_points, 1),
" multiplier=", DoubleToString(EffectiveTpMultiplier(), 2));
return final_tp;
}
//| エントリー判定が必要な場合のみ注文処理を実行する関数
//+------------------------------------------------------------------+
/**
@@ -302,6 +427,19 @@ double SplitEntryPrice(const double zone_low, const double zone_high, const int
return NormalizeDouble(zone_low + (zone_high - zone_low) * ratio, digits);
}
//+------------------------------------------------------------------+
//| Split-zone TP reference price
//+------------------------------------------------------------------+
double SplitTakeProfitReferenceEntry(const int orderType, const double zone_low, const double zone_high)
{
if(IsBuyTargetOrderType(orderType))
return zone_high;
if(IsSellTargetOrderType(orderType))
return zone_low;
return (zone_low + zone_high) / 2.0;
}
//+------------------------------------------------------------------+
//| 注文ロットがブローカー制約を満たすか判定する関数
//+------------------------------------------------------------------+
@@ -462,13 +600,17 @@ int TrySendSplitEntryOrders(const int orderType, EAState &state, TickContext &ct
double zone_low = state.zone_low[orderType];
double zone_high = state.zone_high[orderType];
double tp = state.zone_tp[orderType];
double raw_tp = state.zone_tp[orderType];
double tp = ExpandedTakeProfitPrice(orderType,
SplitTakeProfitReferenceEntry(orderType, zone_low, zone_high),
raw_tp);
double sl = state.zone_sl[orderType];
if(!HasValidZonePrices(zone_low, zone_high, tp, sl))
{
Print("[Split Skip] invalid target zone. orderType=", orderType,
" zone=", zone_low, "-", zone_high, " tp=", tp, " sl=", sl,
" zone=", zone_low, "-", zone_high,
" api_tp=", raw_tp, " tp=", tp, " sl=", sl,
" candidate_id=", state.zone_candidate_id);
return 0;
}
@@ -514,29 +656,34 @@ int TrySendSplitEntryOrders(const int orderType, EAState &state, TickContext &ct
}
double en = SplitEntryPrice(zone_low, zone_high, slot, split_count);
if(!IsTargetPriceOrderConditionMatched(orderType, ctx, en, tp, sl))
double slot_tp = ExpandedTakeProfitPrice(orderType, en, raw_tp);
if(!IsTargetPriceOrderConditionMatched(orderType, ctx, en, slot_tp, sl))
{
Print("[Split Skip] slot price no longer valid. key=", slot_key,
" cur=", cur_price, " en=", en, " tp=", tp, " sl=", sl);
" cur=", cur_price, " en=", en,
" api_tp=", raw_tp, " tp=", slot_tp, " sl=", sl);
continue;
}
if(!MeetsTradeDistanceRules(orderType, ctx, en, tp, sl))
if(!MeetsTradeDistanceRules(orderType, ctx, en, slot_tp, sl))
continue;
Print("[Split ", entry_type, " Order Try] key=", slot_key,
" en=", en, " tp=", tp, " sl=", sl, " volume=", volume);
" en=", en, " api_tp=", raw_tp, " tp=", slot_tp,
" sl=", sl, " volume=", volume);
if(SendOrder(orderType, en, tp, sl, volume, slot_key, TargetCandidateReferenceTime(state)))
if(SendOrder(orderType, en, slot_tp, sl, volume, slot_key, TargetCandidateReferenceTime(state)))
{
Print("[Split ", entry_type, " Order Sent] key=", slot_key,
" en=", en, " tp=", tp, " sl=", sl, " volume=", volume);
" en=", en, " api_tp=", raw_tp, " tp=", slot_tp,
" sl=", sl, " volume=", volume);
sent_success++;
}
else
{
Print("[Split ", entry_type, " Order Failed] key=", slot_key,
" en=", en, " tp=", tp, " sl=", sl, " volume=", volume);
" en=", en, " api_tp=", raw_tp, " tp=", slot_tp,
" sl=", sl, " volume=", volume);
}
}
@@ -566,13 +713,14 @@ bool TrySendEntryOrder(const int orderType, EAState &state, TickContext &ctx)
}
double en = state.en_price[orderType];
double tp = state.tp_price[orderType];
double raw_tp = state.tp_price[orderType];
double tp = ExpandedTakeProfitPrice(orderType, en, raw_tp);
double sl = state.sl_price[orderType];
if(!HasValidTargetPrices(en, tp, sl))
{
Print("[Skip] invalid target prices. orderType=", orderType,
" en=", en, " tp=", tp, " sl=", sl,
" en=", en, " api_tp=", raw_tp, " tp=", tp, " sl=", sl,
" candidate_age=", TargetCandidateAgeText(state));
return false;
}
@@ -580,7 +728,8 @@ bool TrySendEntryOrder(const int orderType, EAState &state, TickContext &ctx)
bool ok = IsTargetPriceOrderConditionMatched(orderType, ctx, en, tp, sl);
if(!ok)
{
Print("[No ", entry_type, "] cur=", cur_price, " en=", en, " tp=", tp, " sl=", sl,
Print("[No ", entry_type, "] cur=", cur_price, " en=", en,
" api_tp=", raw_tp, " tp=", tp, " sl=", sl,
" candidate_age=", TargetCandidateAgeText(state));
return false;
}
@@ -596,16 +745,19 @@ bool TrySendEntryOrder(const int orderType, EAState &state, TickContext &ctx)
if(!MeetsTradeDistanceRules(orderType, ctx, en, tp, sl))
return false;
Print("[", entry_type, " Order Try at ", cur_price, "] en=", en, " tp=", tp, " sl=", sl);
Print("[", entry_type, " Order Try at ", cur_price, "] en=", en,
" api_tp=", raw_tp, " tp=", tp, " sl=", sl);
if(SendOrder(orderType, en, tp, sl, lot_size,
TargetCandidateCommentSuffix(state), TargetCandidateReferenceTime(state)))
{
Print("[", entry_type, " Order Sent] ticket ok. en=", en, " tp=", tp, " sl=", sl);
Print("[", entry_type, " Order Sent] ticket ok. en=", en,
" api_tp=", raw_tp, " tp=", tp, " sl=", sl);
return true;
}
Print("[", entry_type, " Order Failed] en=", en, " tp=", tp, " sl=", sl);
Print("[", entry_type, " Order Failed] en=", en,
" api_tp=", raw_tp, " tp=", tp, " sl=", sl);
return false;
}
+7
View File
@@ -37,6 +37,9 @@
- `m15_imbalance_min_avg_body_points = 1.0`: Minimum M15 average body in points.
- `use_m15_imbalance_debug_log = false`: Enables detailed M15 impulse-confirmation logs.
- `input_entry_max_candidate_age_minutes = 120`: Maximum age, in minutes, for using an H1 candidate for new execution. This blocks delayed entries when M15 confirmation appears too late.
- `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. The range starts from the bar before the latest closed bar.
@@ -156,6 +159,8 @@ New entries are allowed only when all conditions below are satisfied:
- The H1 candidate set has not exceeded `input_entry_max_candidate_age_minutes`, measured from the closed H1 bar time that produced the candidate.
- The selected order type has valid `entry/tp/sl` values greater than `0.0`.
- The order type is allowed by the H4 `market_state`.
- Before price-consistency and broker-distance checks, TP is recalculated from the distance between entry and the API TP, multiplied by `input_tp_multiplier`. Buy strategies place the final TP above entry, and Sell strategies place it below entry.
- When split entries are enabled, the final TP is recalculated separately for each slot from that slot's entry price.
- The order-type price relationship and broker minimum distance rules are satisfied.
- When `use_m15_entry_filter = true`, T2/T4 satisfy the M15 direction, rejection, and proximity checks. T1/T3 satisfy M15 impulse confirmation when `use_m15_imbalance_confirmation = true`.
- When `input_range_breakout_guard_enabled = true`, T4 Sell Limit is blocked during an upward range-breakout cooldown and T2 Buy Limit is blocked during a downward range-breakout cooldown.
@@ -218,6 +223,7 @@ After an H4 `market_state` reload, the EA cancels existing pending orders whose
- Single and split order comments keep a valid `candidate_id` for candidate-origin expiration handling.
- Split-entry order comments also include order type and slot number to prevent duplicate execution of the same strategy slot.
- When `cancel_old_split_pending_on_new_zone = true`, a new valid `candidate_id` cancels older split pending orders, and an invalid or stopped `target_zones.txt` cancels all existing split pending orders for this EA/symbol/magic.
- 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.
- After an H4 state update, existing pending orders that contradict the refreshed `market_state` are cancelled.
- The range-breakout guard only targets pending orders matching `_Symbol` and `magic_number`; upward breakouts cancel T4 Sell Limit only, and downward breakouts cancel T2 Buy Limit only.
- A failed pending-order cancellation is not retried for the same ticket until `input_cancel_retry_cooldown_seconds` has elapsed, preventing excessive per-tick trade-server requests.
@@ -241,6 +247,7 @@ After an H4 `market_state` reload, the EA cancels existing pending orders whose
- Added a range-breakout guard that retreats adverse reversal Limit orders. Upward breakouts cancel existing T4 Sell Limit orders and temporarily block new T4 entries; downward breakouts cancel existing T2 Buy Limit orders and temporarily block new T2 entries.
- Added guard inputs for monitor timeframe, lookback bars, range-width multiplier, breakout buffer, proximity band, momentum body multiple, and cooldown bars.
- 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-06
+7
View File
@@ -29,6 +29,9 @@
- `m15_imbalance_min_avg_body_points = 1.0`: M15平均実体の最小値(point)。
- `use_m15_imbalance_debug_log = false`: M15初動確認の詳細ログを出すか。
- `input_entry_max_candidate_age_minutes = 120`: H1候補価格を新規発注に使用できる最大経過分数。古い候補でM15条件が後から整った場合の遅延エントリーを抑止する。
- `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`: レンジ高値・安値と平均レンジを計算する確定足本数。直近確定足の1本前から参照する。
@@ -156,6 +159,8 @@ Pythonは `target_prices.txt` と `target_zones.txt` の両方を書き終えて
- H1候補価格が、元になったH1確定足時刻から `input_entry_max_candidate_age_minutes` 分を超えていない。
- 対象注文タイプの `entry/tp/sl` がすべて `0.0` より大きい。
- H4 `market_state` に対して注文タイプが許可されている。
- TPは価格整合条件とブローカー距離制約の判定前に、APIのTP価格そのものではなく「エントリー価格からAPI TPまでの距離」を `input_tp_multiplier` で拡大して最終TPへ変換する。Buy系はエントリーより上、Sell系はエントリーより下へ配置する。
- 分割エントリー有効時は、slotごとのエントリー価格を基準に各slotの最終TPを個別に計算する。
- 注文タイプごとの価格整合条件とブローカー最小距離制約を満たす。
- `use_m15_entry_filter = true` の場合、T2/T4はM15確定足の方向・反発・接近条件を満たす。T1/T3は `use_m15_imbalance_confirmation = true` の場合にM15初動確認を満たす。
- `input_range_breakout_guard_enabled = true` の場合、レンジ上抜け後のT4 Sell Limit、レンジ下抜け後のT2 Buy Limitはクールダウン終了まで新規発注しない。
@@ -218,6 +223,7 @@ H4 `market_state` の再読込後は、更新後の状態で許可されない
- 通常注文と分割注文のコメントには有効な `candidate_id` を入れ、候補時刻起点の期限管理に使用する。
- 分割エントリーの注文コメントには注文タイプとslot番号も入れ、同一戦略slotの二重発注を抑止する。
- `cancel_old_split_pending_on_new_zone = true` の場合、新しい有効 `candidate_id` を読んだ時は旧candidateの分割pending注文を取消し、`target_zones.txt` が無効または停止値の場合は既存の分割pending注文をすべて取消する。
- API由来TPの方向がBuy/Sell条件と逆の場合、EAは方向を補正せず既存の価格整合チェックで発注を見送る。
- H4状態更新後は、更新後の `market_state` と矛盾する既存pending注文を取消する。
- レンジブレイクガードは `_Symbol``magic_number` が一致するpending注文だけを対象にし、上方向ブレイクではT4 Sell Limit、下方向ブレイクではT2 Buy Limitのみを取消する。
- pending取消に失敗したticketは `input_cancel_retry_cooldown_seconds` の間再送せず、毎tickの過剰な取引サーバー要求を防止する。
@@ -241,6 +247,7 @@ H4 `market_state` の再読込後は、更新後の状態で許可されない
- レンジ上抜け/下抜け時に逆方向の逆張りLimitを退避するレンジブレイクガードを追加した。上方向ブレイクでは既存T4 Sell Limitを取消してT4新規発注を一時停止し、下方向ブレイクでは既存T2 Buy Limitを取消してT2新規発注を一時停止する。
- ガード用inputとして、監視時間足、参照本数、レンジ幅倍率、ブレイクバッファ、接近幅、勢い判定倍率、クールダウン本数を追加した。
- API由来TPをエントリー価格からの距離ベースで拡大する `input_tp_multiplier`, `input_min_tp_points`, `input_max_tp_points` を追加し、通常注文と分割slotごとの最終TP計算に反映した。
### 2026-06-06
+7
View File
@@ -25,10 +25,15 @@ The two EAs coordinate through matching `_Symbol` and `input_entry_magic_number`
- `input_cancel_retry_cooldown_seconds = 60`: Ticket-level retry cooldown after pending cancellation failures.
- `use_m15_entry_filter = true`: Enables M15 closed-bar confirmation.
- `input_entry_max_candidate_age_minutes = 120`: Maximum age for using an H1 candidate for new execution.
- `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.
## 4. Entry And Exit Conditions
- New pending orders are sent only after spread, H4 state, H1 candidate, M15 timing, price consistency, broker distance, volume, and same-symbol/same-magic limit checks pass.
- Before order submission, TP is recalculated from the distance between entry and the API TP, multiplied by `input_tp_multiplier`. Buy strategies place the final TP above entry, and Sell strategies place it below entry.
- 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.
- Filled-position SL updates, trailing, and time-based exits are not performed by this EA.
@@ -37,6 +42,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.
- `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`.
@@ -48,4 +54,5 @@ The two EAs coordinate through matching `_Symbol` and `input_entry_magic_number`
## 7. Changelog
- 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`.
+7
View File
@@ -25,10 +25,15 @@
- `input_cancel_retry_cooldown_seconds = 60`: pending取消失敗後のticket単位再試行間隔。
- `use_m15_entry_filter = true`: M15確定足確認を使うか。
- `input_entry_max_candidate_age_minutes = 120`: H1候補を新規発注に使える最大経過分数。
- `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距離を維持します。
## 4. エントリー/エグジット条件
- 新規注文はスプレッド、H4状態、H1候補、M15確認、価格整合、ブローカー距離、ロット制約、同一symbol/magicの上限を満たす場合のみ送信します。
- TPは注文送信前に、APIのTP価格そのものではなく「エントリー価格からAPI TPまでの距離」を `input_tp_multiplier` で拡大して最終TPを計算します。Buy系はエントリーより上、Sell系はエントリーより下へ再配置します。
- 分割エントリーではslotごとのエントリー価格を基準に、各slotの最終TPを個別に計算します。
- pending注文には `input_entry_magic_number` を付与します。
- H4状態と矛盾するpending注文、期限切れpending注文、古い分割pending注文は発注EAが取消します。
- 約定後ポジションのSL変更、時間決済、トレーリングは発注EAでは行いません。
@@ -37,6 +42,7 @@
- 発注上限は口座全体ではなく `_Symbol``input_entry_magic_number` が一致するpending注文 + ポジションで判定します。
- Python連携は起動中/完了ファイルとプロセスIDを監視し、二重起動と古い結果の再利用を抑止します。
- API由来TPの方向がBuy/Sell条件と逆の場合、EAは方向を補正せず既存の価格整合チェックで発注を見送ります。
- `OrderSend` の戻り値と `MqlTradeResult.retcode` を確認し、失敗時はエラーまたはretcodeをログに出します。
- hedging口座前提のため、約定後の複数ticket管理は `HITPositionManagerEA.mq5` が担当します。
@@ -48,4 +54,5 @@
## 7. 変更履歴
- 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` へ移管する仕様を追加。