forked from ntsinh90/EA_SMC_Mql5
432 lines
40 KiB
MQL5
432 lines
40 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| EA SMC.mq5 |
|
|
//| v23.1 - Final Blueprint Architecture (Complete) |
|
|
//| Written with 'Coding Buddy' by Google |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Your Name"
|
|
#property link "https://github.com"
|
|
#property version "23.1"
|
|
#property description "SMC Expert Advisor with a professional, fully decoupled architecture based on an advanced blueprint."
|
|
|
|
// --- Standard & Custom Library Includes ---
|
|
#include <Trade/Trade.mqh>
|
|
#include <CEnumSharing.mqh>
|
|
#include <SMC_DataStructures.mqh>
|
|
#include <CZoneManager.mqh>
|
|
#include <CChartDrawer.mqh>
|
|
#include <CRiskManager.mqh>
|
|
#include <CSetupScanner.mqh>
|
|
#include <CStructureAnalyzer.mqh>
|
|
#include <CEntryExecutor.mqh>
|
|
#include <CTimeFilter.mqh>
|
|
#include <CTradeManager.mqh>
|
|
|
|
input group "--- Main Exit Strategy ---";
|
|
input ENUM_EXIT_MODE InpExitMode = EXIT_MODE_TRAILING_STOP;
|
|
input double InpRiskToRewardRatio = 0.8;
|
|
input int InpFixedTPPoints = 1400;
|
|
|
|
input group "--- Trade & Risk Settings ---";
|
|
input long InpMagicNumber = 0;
|
|
input string InpEaComment = "EA_SMC_v23.1";
|
|
input int InpMaxOpenTrades = 2;
|
|
input int InpStopLossBufferPoints = 50;
|
|
input ulong InpSlippagePoints = 10;
|
|
input int InpMinStopLossPoints = 1450;
|
|
input int InpMaxStopLossPoints = 1450; // เพดาน SL สูงสุดที่รับได้ (0 = ปิดใช้งาน)
|
|
|
|
input group "--- Money Management Mode ---";
|
|
input ENUM_MONEY_MANAGEMENT_MODE InpMoneyManagementMode = MM_MODE_LOT_PER_BALANCE;
|
|
|
|
input group "--- Settings for: Fixed Lot ---";
|
|
input double InpFixedLotSize = 1; // Lot ที่จะใช้ถ้าเลือก MM_MODE_FIXED_LOT
|
|
|
|
input group "--- Settings for: Risk Percent per Trade ---";
|
|
input double InpRiskPercentPerTrade = 4; // % ความเสี่ยงต่อเทรด (ใช้กับ MM_MODE_RISK_PERCENT)
|
|
|
|
input group "--- Settings for: Lot Scaling by Balance ---";
|
|
input double InpBaseLotForScaling = 1; // ขนาด Lot พื้นฐาน
|
|
input double InpBalanceStepForScaling = 10000.0; // ทุกๆ Balance ที่เพิ่มขึ้นเท่านี้ จะเพิ่ม Lot เท่ากับ InpBaseLotForScaling
|
|
|
|
input group "--- Entry Strategy Toggles ---";
|
|
input int InpMaxTradesPerZone = 1;
|
|
input bool InpUseContinuationRetest = false; // +++ ADD: ท่า Retest ตามเทรนด์ (BOS)
|
|
input bool InpUseReversalRetest = false; // +++ ADD: ท่า Retest หลังเกิด CHoCH
|
|
input bool InpUseBreakoutEntry = true; // เปิด/ปิด ท่า Breakout
|
|
input bool InpUseScaleInOnBreakout = true;
|
|
input int InpBreakout_RetestNumber = 1; // 1 = เทรดรีเทสครั้งแรก, 2 = ครั้งที่สอง, 0 = ปิดใช้งาน
|
|
input bool InpUseFakeoutEntry = false; // เปิด/ปิด ท่า Fakeout (ที่ Major Swing)
|
|
input bool InpUseMajorSwingMomentumEntry = false; // เปิด/ปิด ท่าเข้าตาม Major Swing
|
|
input bool InpUseSfpEntry = false; // เปิด/ปิด ท่า SFP (ที่ Minor Swing)
|
|
input bool InpUseSweepToPoiEntry = false; // เปิด/ปิด ท่า Sweep into POIut)
|
|
input bool InpUseFreshFvgRetestEntry = true;
|
|
|
|
input group "--- Confirmation Pattern Toggles ---";
|
|
input bool InpUseStoForEntryConfirmation = true;
|
|
input bool InpUseSimpleReclaimPattern = true;
|
|
input bool InpUse2BarConfirmation = true; // เปิด/ปิด รูปแบบยืนยัน 2 แท่งเทียน
|
|
input bool InpUse3BarConfirmation = true; // เปิด/ปิด รูปแบบยืนยัน 3 แท่งเทียน
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
input group "--- FVG Retest Settings (Advanced) ---";
|
|
input ENUM_RETEST_CONFIRMATION_MODE InpRetest_ConfirmationMode = CONF_MODE_DISP_AND_STRUCT;
|
|
input double InpRetest_MinAtrMoveAway = 1.0;
|
|
|
|
// --- User-Configurable Inputs ---
|
|
input group "--- Structure Analysis Settings ---";
|
|
input int InpSwingLength = 14; // Length for fractal swing detection
|
|
input double InpAtrNoiseFilter = 0.25; // Swing must be larger than 0.25 * ATR to be considered
|
|
input int InpMaxBarsForBOS = 15; // Max bars to look ahead for a BOS after a takeout
|
|
input ENUM_BOS_TYPE InpBosConfirmationType = BOS_BY_CLOSE;
|
|
input int InpPdArrayLookbackSwings = 15;
|
|
input double InpMinFvgAtrMult = 0.3;
|
|
input ENUM_ZONE_QUALITY_LEVEL InpMinZoneQuality = ZQ_STANDARD; // <<< ตั้งค่าเริ่มต้นให้ "ผ่อนคลาย" ที่สุด
|
|
|
|
input group "--- Advanced Trade Management ---";
|
|
input bool InpUsePartialTP = false;
|
|
input double InpPartialTP_RR = 0.8;
|
|
input double InpPartialClosePercent = 50.0;
|
|
input double InpPsarStep = 0.02;
|
|
input double InpPsarMax = 0.2;
|
|
input group "--- Dynamic Trailing Stop Settings ---";
|
|
input double InpTrail_Tier1_RR = 1.0; // เริ่ม Trail ครั้งแรกเมื่อกำไรถึง 1R
|
|
input int InpTrail_Tier1_Points = 500; // โดยใช้ระยะตาม 500 points
|
|
input double InpTrail_Tier2_RR = 2.0; // เมื่อกำไรถึง 2R
|
|
input int InpTrail_Tier2_Points = 300; // ให้เปลี่ยนระยะตามเป็น 300 points
|
|
input double InpTrail_Tier3_RR = 3.0; // เมื่อกำไรถึง 3R
|
|
input int InpTrail_Tier3_Points = 100; // ให้เปลี่ยนระยะตามเป็น 100 points
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
input group "--- Indicator Filters (Advanced) ---";
|
|
input bool InpFilterSwingsBySweep = true;
|
|
input bool InpFilterSwingsByFVG = true;
|
|
input bool InpUseVolumeFilter = false;
|
|
input bool InpUseRsiFilter = true; // เปิด/ปิด การใช้ฟิลเตอร์ RSI
|
|
input int InpRsiPeriod = 14; // ค่า Period ของ RSI
|
|
input int InpRsiOverbought = 70; // ระดับ Overbought
|
|
input int InpRsiOversold = 30; // ระดับ Oversold
|
|
input bool InpUseStochasticFilter = true; // เปิด/ปิด การใช้ฟิลเตอร์ Stochastic
|
|
input int InpSto_K_Period = 14; // %K Period
|
|
input int InpSto_D_Period = 3; // %D Period
|
|
input int InpSto_Slowing = 3; // Slowing
|
|
input int InpSto_Overbought = 80; // ระดับ Overbought
|
|
input int InpSto_Oversold = 20; // ระดับ Oversold
|
|
|
|
input group "--- Time Filter Settings ---";
|
|
input bool InpUseTimeFilter = false;
|
|
input int InpSession1_StartHour = 14;
|
|
input int InpSession1_EndHour = 22;
|
|
input bool InpUseFridayExit = false;
|
|
input int InpFridayExit_Hour = 22;
|
|
input int InpFridayExit_Minute = 0;
|
|
|
|
// --- Global Pointers to All Modules ---
|
|
CZoneManager* g_zoneManager_ptr = NULL;
|
|
CChartDrawer* g_drawer_ptr = NULL;
|
|
CRiskManager* g_riskManager_ptr = NULL;
|
|
CSetupScanner* g_setupScanner_ptr = NULL;
|
|
CStructureAnalyzer* g_analyzer_ptr = NULL;
|
|
CEntryExecutor* g_entryExecutor_ptr = NULL;
|
|
CTimeFilter* g_timeFilter_ptr = NULL;
|
|
CTradeManager* g_tradeManager_ptr = NULL;
|
|
|
|
// --- Global Indicator Handles ---
|
|
int g_atr_handle = INVALID_HANDLE;
|
|
int g_rsi_handle = INVALID_HANDLE;
|
|
int g_volume_handle = INVALID_HANDLE;
|
|
int g_sto_handle = INVALID_HANDLE;
|
|
// --- Global Timer Variables for OnTick ---
|
|
static bool is_initial_scan_done = false;
|
|
static datetime last_sl_tp_check_time = 0;
|
|
const int SL_TP_CHECK_INTERVAL = 10; // ตรวจสอบทุกๆ 10 วินาที
|
|
static datetime last_processed_bar_time = 0;
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
// --- 1. Initial Print & Seeding Randomizer ---
|
|
Print("EA vFinal (Stateful/Incremental Architecture) Initializing...");
|
|
MathSrand(GetTickCount()); // เพื่อให้การสุ่ม ID ของโซนไม่ซ้ำกัน
|
|
|
|
// --- 2. สร้าง instance ของโมดูลทั้งหมด ---
|
|
g_zoneManager_ptr = new CZoneManager();
|
|
g_drawer_ptr = new CChartDrawer(ChartID(), InpMagicNumber);
|
|
g_riskManager_ptr = new CRiskManager(InpMoneyManagementMode, InpFixedLotSize, InpRiskPercentPerTrade, InpBaseLotForScaling, InpBalanceStepForScaling);
|
|
g_setupScanner_ptr = new CSetupScanner(g_zoneManager_ptr, InpSwingLength, InpMagicNumber, InpMinFvgAtrMult,
|
|
InpUseStochasticFilter, InpSto_Overbought, InpSto_Oversold);
|
|
g_analyzer_ptr = new CStructureAnalyzer(g_zoneManager_ptr, InpAtrNoiseFilter, InpMaxBarsForBOS,
|
|
InpBosConfirmationType, InpPdArrayLookbackSwings,
|
|
InpUseRsiFilter, InpRsiPeriod,InpRsiOverbought, InpRsiOversold, InpFilterSwingsByFVG, InpFilterSwingsBySweep,InpRetest_MinAtrMoveAway,InpMinZoneQuality);
|
|
g_entryExecutor_ptr = new CEntryExecutor(g_zoneManager_ptr, g_analyzer_ptr, InpMaxTradesPerZone,
|
|
InpUseContinuationRetest, InpUseReversalRetest,InpUseBreakoutEntry, InpUseFakeoutEntry,
|
|
InpUseMajorSwingMomentumEntry, InpUseSfpEntry, InpUseSweepToPoiEntry,
|
|
InpUseScaleInOnBreakout, InpBreakout_RetestNumber, InpUseFreshFvgRetestEntry,
|
|
InpUseSimpleReclaimPattern, InpUse2BarConfirmation, InpUse3BarConfirmation,
|
|
InpUseStoForEntryConfirmation, InpSto_Overbought, InpSto_Oversold,
|
|
InpRetest_ConfirmationMode, InpRetest_MinAtrMoveAway);
|
|
g_timeFilter_ptr = new CTimeFilter(InpUseTimeFilter, InpSession1_StartHour, InpSession1_EndHour, 0, 0, 0, 0, false, 0, 0, 0, 0, InpUseFridayExit, InpFridayExit_Hour, InpFridayExit_Minute, ChartID(), InpMagicNumber);
|
|
g_tradeManager_ptr = new CTradeManager(g_riskManager_ptr, InpMagicNumber, InpEaComment, InpSlippagePoints,
|
|
InpStopLossBufferPoints, InpMinStopLossPoints, InpMaxStopLossPoints,
|
|
InpExitMode, InpRiskToRewardRatio, InpFixedTPPoints,
|
|
InpTrail_Tier1_RR, InpTrail_Tier1_Points, InpTrail_Tier2_RR, InpTrail_Tier2_Points, InpTrail_Tier3_RR, InpTrail_Tier3_Points, InpPsarStep, InpPsarMax,
|
|
InpUsePartialTP, InpPartialTP_RR, InpPartialClosePercent);
|
|
|
|
// --- 3. Pointer Validation ---
|
|
if(CheckPointer(g_zoneManager_ptr)==POINTER_INVALID || CheckPointer(g_drawer_ptr)==POINTER_INVALID || CheckPointer(g_riskManager_ptr)==POINTER_INVALID ||
|
|
CheckPointer(g_setupScanner_ptr)==POINTER_INVALID || CheckPointer(g_analyzer_ptr)==POINTER_INVALID || CheckPointer(g_entryExecutor_ptr)==POINTER_INVALID ||
|
|
CheckPointer(g_timeFilter_ptr)==POINTER_INVALID || CheckPointer(g_tradeManager_ptr)==POINTER_INVALID)
|
|
{
|
|
Print("FATAL: A core module failed to initialize.");
|
|
return(INIT_FAILED);
|
|
}
|
|
|
|
// --- 4. สร้าง Indicator Handles ---
|
|
g_atr_handle = iATR(_Symbol, PERIOD_CURRENT, 14);
|
|
if(g_atr_handle == INVALID_HANDLE)
|
|
{
|
|
Print("Failed to create ATR Handle!");
|
|
return(INIT_FAILED);
|
|
}
|
|
|
|
if(InpUseRsiFilter)
|
|
{
|
|
g_rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, InpRsiPeriod, PRICE_CLOSE);
|
|
if(g_rsi_handle == INVALID_HANDLE)
|
|
{
|
|
Print("Failed to create RSI Handle!");
|
|
return(INIT_FAILED);
|
|
}
|
|
}
|
|
if(InpUseVolumeFilter)
|
|
{
|
|
g_volume_handle = iVolume(_Symbol, PERIOD_CURRENT, VOLUME_TICK);
|
|
if(g_volume_handle == INVALID_HANDLE)
|
|
{
|
|
Print("Failed to create Volume Handle!");
|
|
return(INIT_FAILED);
|
|
}
|
|
}
|
|
if(InpUseStochasticFilter)
|
|
{
|
|
g_sto_handle = iStochastic(_Symbol, PERIOD_CURRENT, InpSto_K_Period, InpSto_D_Period, InpSto_Slowing, MODE_SMA, STO_LOWHIGH);
|
|
if(g_sto_handle == INVALID_HANDLE)
|
|
{
|
|
Print("Failed to create Stochastic Handle!");
|
|
return(INIT_FAILED);
|
|
}
|
|
}
|
|
|
|
Print("--- Initialization Complete. Waiting for first tick to perform historical analysis... ---");
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
if(CheckPointer(g_tradeManager_ptr))
|
|
delete g_tradeManager_ptr;
|
|
if(CheckPointer(g_timeFilter_ptr))
|
|
delete g_timeFilter_ptr;
|
|
if(CheckPointer(g_entryExecutor_ptr))
|
|
delete g_entryExecutor_ptr;
|
|
if(CheckPointer(g_analyzer_ptr))
|
|
delete g_analyzer_ptr;
|
|
if(CheckPointer(g_setupScanner_ptr))
|
|
delete g_setupScanner_ptr;
|
|
if(CheckPointer(g_riskManager_ptr))
|
|
delete g_riskManager_ptr;
|
|
if(CheckPointer(g_drawer_ptr))
|
|
delete g_drawer_ptr;
|
|
if(CheckPointer(g_zoneManager_ptr))
|
|
delete g_zoneManager_ptr;
|
|
|
|
if(g_atr_handle != INVALID_HANDLE)
|
|
IndicatorRelease(g_atr_handle);
|
|
Comment("");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
// ==================================================================
|
|
// เฟสที่ 1: การวิเคราะห์ย้อนหลังครั้งแรก (ทำงานแค่ครั้งเดียวตอนเริ่มต้น)
|
|
// ==================================================================
|
|
if(!is_initial_scan_done)
|
|
{
|
|
int history_bars = 500;
|
|
if(Bars(_Symbol, PERIOD_CURRENT) < history_bars + 200)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// --- The Patient Priming Loop (Corrected) ---
|
|
bool all_indicators_ready = false;
|
|
Print("--- Priming Indicator Data... Will wait up to 30 seconds. ---");
|
|
for(int i = 0; i < 300; i++)
|
|
{
|
|
int atr_calc = BarsCalculated(g_atr_handle);
|
|
int rsi_calc = !InpUseRsiFilter ? history_bars : BarsCalculated(g_rsi_handle);
|
|
int vol_calc = !InpUseVolumeFilter ? history_bars : BarsCalculated(g_volume_handle);
|
|
int sto_calc = !InpUseStochasticFilter ? history_bars : BarsCalculated(g_sto_handle);
|
|
|
|
// --- REMOVED: ไม่มีการเช็ค MA ที่ถูกลบไปแล้ว ---
|
|
|
|
PrintFormat("Priming Attempt #%d: ATR(%d/%d), RSI(%d/%d), VOL(%d/%d), STO(%d/%d)",
|
|
i+1, atr_calc, history_bars, rsi_calc, history_bars, vol_calc, history_bars, sto_calc, history_bars);
|
|
|
|
if(atr_calc >= history_bars && rsi_calc >= history_bars && vol_calc >= history_bars && sto_calc >= history_bars)
|
|
{
|
|
all_indicators_ready = true;
|
|
Print("--- All indicator data is ready. ---");
|
|
break;
|
|
}
|
|
Sleep(100);
|
|
}
|
|
|
|
if(!all_indicators_ready)
|
|
{
|
|
Print("FATAL: Failed to prepare indicator data within 30 seconds. Stopping EA.");
|
|
ExpertRemove();
|
|
return;
|
|
}
|
|
|
|
// --- เริ่มการวิเคราะห์ครั้งใหญ่ ---
|
|
Print("--- Performing Initial Historical Analysis on %d bars... ---", history_bars);
|
|
CDataContext initial_context(history_bars);
|
|
|
|
if(CopyRates(_Symbol, PERIOD_CURRENT, 0, history_bars, initial_context.rates) < history_bars)
|
|
return;
|
|
if(CopyBuffer(g_atr_handle, 0, 0, history_bars, initial_context.atr_buffer) < history_bars)
|
|
return;
|
|
if(InpUseRsiFilter)
|
|
if(CopyBuffer(g_rsi_handle, 0, 0, history_bars, initial_context.rsi_buffer) < history_bars)
|
|
return;
|
|
if(InpUseVolumeFilter)
|
|
if(CopyBuffer(g_volume_handle, 0, 0, history_bars, initial_context.volume_buffer) < history_bars)
|
|
return;
|
|
if(InpUseStochasticFilter)
|
|
if(CopyBuffer(g_sto_handle, 0, 0, history_bars, initial_context.sto_main_buffer) < history_bars || CopyBuffer(g_sto_handle, 1, 0, history_bars, initial_context.sto_signal_buffer) < history_bars)
|
|
return;
|
|
// --- REMOVED: ไม่มีการโหลด Buffer ของ MA ที่ถูกลบไปแล้ว ---
|
|
|
|
g_setupScanner_ptr.ScanHistory(initial_context);
|
|
g_analyzer_ptr.Analyze(initial_context);
|
|
|
|
is_initial_scan_done = true;
|
|
last_processed_bar_time = initial_context.rates[0].time;
|
|
Print("--- Initial Analysis Complete. EA is now live. ---");
|
|
ChartRedraw();
|
|
return;
|
|
}
|
|
|
|
// ==================================================================
|
|
// เฟสที่ 2: การทำงานปกติในแต่ละ Tick (หลังจากวิเคราะห์ครั้งแรกเสร็จแล้ว)
|
|
// ==================================================================
|
|
|
|
// --- 2.1 งานที่ต้องทำทุก Tick (Urgent) ---
|
|
if(CheckPointer(g_tradeManager_ptr))
|
|
{
|
|
g_tradeManager_ptr.ManageActiveTrailing();
|
|
}
|
|
|
|
// --- 2.2 งานที่ทำตามเวลา (Scheduled) ---
|
|
if(TimeCurrent() - last_sl_tp_check_time >= SL_TP_CHECK_INTERVAL)
|
|
{
|
|
if(CheckPointer(g_tradeManager_ptr))
|
|
g_tradeManager_ptr.ManageUnsetSLTP();
|
|
last_sl_tp_check_time = TimeCurrent();
|
|
}
|
|
|
|
// --- 2.3 ตรวจจับและทำงานเมื่อเกิดแท่งเทียนใหม่ ---
|
|
datetime current_bar_time = (datetime)SeriesInfoInteger(_Symbol, PERIOD_CURRENT, SERIES_LASTBAR_DATE);
|
|
if(current_bar_time == last_processed_bar_time)
|
|
return;
|
|
|
|
int new_bars_count = (int)((current_bar_time - last_processed_bar_time) / PeriodSeconds(PERIOD_CURRENT));
|
|
last_processed_bar_time = current_bar_time;
|
|
if(new_bars_count <= 0)
|
|
return;
|
|
|
|
// --- เริ่มกระบวนการทำงานของแท่งเทียนใหม่ ---
|
|
|
|
CDataContext context(500);
|
|
// ... (โค้ดโหลดข้อมูล 500 แท่งใส่ context เหมือนใน OnInit เดิม) ...
|
|
for(int i = 0; i < context.bars_to_load; i++)
|
|
{
|
|
context.rates[i].time = iTime(_Symbol, PERIOD_CURRENT, i);
|
|
context.rates[i].open = iOpen(_Symbol, PERIOD_CURRENT, i);
|
|
context.rates[i].high = iHigh(_Symbol, PERIOD_CURRENT, i);
|
|
context.rates[i].low = iLow(_Symbol, PERIOD_CURRENT, i);
|
|
context.rates[i].close = iClose(_Symbol, PERIOD_CURRENT, i);
|
|
}
|
|
|
|
// โหลดข้อมูล Indicators
|
|
if(CopyBuffer(g_atr_handle, 0, 0, context.bars_to_load, context.atr_buffer) < context.bars_to_load)
|
|
return;
|
|
if(InpUseRsiFilter && CopyBuffer(g_rsi_handle, 0, 0, context.bars_to_load, context.rsi_buffer) < 500)
|
|
return;
|
|
if(InpUseVolumeFilter && CopyBuffer(g_volume_handle, 0, 0, context.bars_to_load, context.volume_buffer) < 500)
|
|
return;
|
|
|
|
// +++ ADD THIS BLOCK TO LOAD STOCHASTIC DATA +++
|
|
if(InpUseStochasticFilter && g_sto_handle != INVALID_HANDLE)
|
|
{
|
|
if(CopyBuffer(g_sto_handle, 0, 0, context.bars_to_load, context.sto_main_buffer) < 500 ||
|
|
CopyBuffer(g_sto_handle, 1, 0, context.bars_to_load, context.sto_signal_buffer) < 500)
|
|
{
|
|
Print("Failed to copy Sto buffer in OnTick. Skipping this tick.");
|
|
return;
|
|
}
|
|
}
|
|
// --- 2.4 สายการผลิตแบบ Incremental ---
|
|
if(CheckPointer(g_setupScanner_ptr))
|
|
g_setupScanner_ptr.ScanIncremental(context, new_bars_count);
|
|
if(CheckPointer(g_analyzer_ptr))
|
|
g_analyzer_ptr.Analyze(context);
|
|
|
|
if(CheckPointer(g_tradeManager_ptr) && InpExitMode == EXIT_MODE_STRUCTURAL)
|
|
{
|
|
g_tradeManager_ptr.ManageStructuralExits(g_zoneManager_ptr.GetAllSwings());
|
|
}
|
|
|
|
if(CheckPointer(g_entryExecutor_ptr) && (int)PositionsTotal() < InpMaxOpenTrades)
|
|
{
|
|
CSignalZone* trade_signal = g_entryExecutor_ptr.FindTradeSignal(context, InpMagicNumber);
|
|
if(trade_signal != NULL)
|
|
{
|
|
if(g_tradeManager_ptr.OpenTradeFromSignal(trade_signal))
|
|
{
|
|
if(trade_signal.trigger_level_time > 0)
|
|
g_zoneManager_ptr.IncrementTradeCountForLevel(trade_signal.trigger_level_time);
|
|
}
|
|
if(trade_signal.zone_id == 0)
|
|
delete trade_signal;
|
|
}
|
|
}
|
|
|
|
// --- 2.5 วาดผล ---
|
|
if(CheckPointer(g_drawer_ptr) && CheckPointer(g_zoneManager_ptr))
|
|
{
|
|
CArrayObj* all_zones = g_zoneManager_ptr.GetZoneList(); // ใช้ all_zones เพื่อวาดสถานะ is_significant
|
|
CArrayObj* all_swings = g_zoneManager_ptr.GetAllSwings();
|
|
g_drawer_ptr.SynchronizeDrawings(all_zones, all_swings); // ส่ง all_zones
|
|
|
|
if(all_zones != NULL)
|
|
{
|
|
for(int i = 0; i < all_zones.Total(); i++)
|
|
g_drawer_ptr.DrawZone(all_zones.At(i), context);
|
|
}
|
|
if(all_swings != NULL)
|
|
{
|
|
for(int i = 0; i < all_swings.Total(); i++)
|
|
g_drawer_ptr.DrawSwing(all_swings.At(i), all_swings, context);
|
|
}
|
|
}
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|