Expand API-derived TP distances
This commit is contained in:
@@ -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; // レンジ高値安値の参照本数
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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` へ移管する仕様を追加。
|
||||
|
||||
Reference in New Issue
Block a user