last ...
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| MajorStructure_Zones_EA.mq5 |
|
||||
//| Step 1.5: BOS Confirmation + Zone Drawing + Bias |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Professional Trader & AI Assistant"
|
||||
#property version "1.50"
|
||||
#property strict
|
||||
|
||||
//--- Input Parameters
|
||||
input int MinorPivotLookback = 3; // تعداد کندل چپ/راست برای شناسایی مینور (در 15m = 3 یعنی 45 دقیقه)
|
||||
input int MaxBarsToScan = 500; // حداکثر کندلهای 4H برای جستجو
|
||||
input color BullishZoneColor = clrLime; // رنگ ناحیه کف ماژور (حمایت)
|
||||
input color BearishZoneColor = clrRed; // رنگ ناحیه سقف ماژور (مقاومت)
|
||||
input int ZoneTransparency = 80; // شفافیت ناحیه (0-255)
|
||||
|
||||
//--- Global Variables
|
||||
// نواحی ماژور (High و Low کندل مربوطه)
|
||||
double majorLowZoneHigh = 0, majorLowZoneLow = 0;
|
||||
datetime majorLowZoneTime = 0;
|
||||
int majorLowBarIndex = -1;
|
||||
|
||||
double majorHighZoneHigh = 0, majorHighZoneLow = 0;
|
||||
datetime majorHighZoneTime = 0;
|
||||
int majorHighBarIndex = -1;
|
||||
|
||||
string biasDirection = "NEUTRAL";
|
||||
|
||||
// نام آبجکتهای گرافیکی
|
||||
string lowZoneName = "MajorLowZone";
|
||||
string highZoneName = "MajorHighZone";
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
Print("EA v1.5 Initialized. Scanning for BOS-confirmed Major Zones...");
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
// پاک کردن تمام آبجکتهای رسم شده
|
||||
ObjectDelete(0, lowZoneName);
|
||||
ObjectDelete(0, highZoneName);
|
||||
Comment("");
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
// فقط یک بار در هر کندل جدید 4 ساعته محاسبات را انجام میدهیم
|
||||
static datetime lastBarTime = 0;
|
||||
datetime currentBarTime = iTime(_Symbol, PERIOD_H4, 0);
|
||||
|
||||
if (lastBarTime == currentBarTime)
|
||||
{
|
||||
// در تیکهای میانی، فقط ناحیه جاری را تا زمان حال گسترش میدهیم
|
||||
ExtendZonesToCurrentTime();
|
||||
return;
|
||||
}
|
||||
lastBarTime = currentBarTime;
|
||||
|
||||
// 1. دریافت دادههای تایم فریم 4 ساعته
|
||||
double high[], low[], close[];
|
||||
datetime time[];
|
||||
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(time, true);
|
||||
|
||||
int copied = CopyHigh(_Symbol, PERIOD_H4, 0, MaxBarsToScan, high);
|
||||
CopyLow(_Symbol, PERIOD_H4, 0, MaxBarsToScan, low);
|
||||
CopyClose(_Symbol, PERIOD_H4, 0, MaxBarsToScan, close);
|
||||
CopyTime(_Symbol, PERIOD_H4, 0, MaxBarsToScan, time);
|
||||
|
||||
if (copied <= 0)
|
||||
{
|
||||
Print("Error copying 4H data.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. اسکن تاریخی برای شناسایی BOS و نواحی ماژور
|
||||
ScanForMajorZones(high, low, close, time, copied);
|
||||
|
||||
// 3. تعیین بایاس
|
||||
DetermineBias();
|
||||
|
||||
// 4. رسم نواحی روی چارت
|
||||
DrawMajorZones();
|
||||
|
||||
// 5. نمایش داشبورد
|
||||
DisplayDashboard();
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| اسکن تاریخی برای شناسایی نواحی ماژور با تاییدیه BOS |
|
||||
//+------------------------------------------------------------------+
|
||||
void ScanForMajorZones(double &high[], double &low[], double &close[], datetime &time[], int total)
|
||||
{
|
||||
// ریست کردن متغیرها
|
||||
majorLowBarIndex = -1;
|
||||
majorHighBarIndex = -1;
|
||||
|
||||
int lastMinorHighIdx = -1;
|
||||
int lastMinorLowIdx = -1;
|
||||
|
||||
// حلقه از گذشته به حال (اندیس بزرگ به کوچک)
|
||||
for (int i = total - MinorPivotLookback - 1; i >= MinorPivotLookback; i--)
|
||||
{
|
||||
// بررسی آیا کندل i یک سقف مینور است
|
||||
if (IsMinorPivot(high, i, true))
|
||||
{
|
||||
lastMinorHighIdx = i;
|
||||
}
|
||||
|
||||
// بررسی آیا کندل i یک کف مینور است
|
||||
if (IsMinorPivot(low, i, false))
|
||||
{
|
||||
lastMinorLowIdx = i;
|
||||
}
|
||||
|
||||
// بررسی BOS صعودی: آیا Close کندل i بالاتر از آخرین سقف مینور است؟
|
||||
if (lastMinorHighIdx != -1 && i < lastMinorHighIdx && close[i] > high[lastMinorHighIdx])
|
||||
{
|
||||
// BOS صعودی رخ داد -> کف مینور قبلی حالا کف ماژور تایید شده است
|
||||
if (lastMinorLowIdx != -1 && lastMinorLowIdx > lastMinorHighIdx)
|
||||
{
|
||||
majorLowBarIndex = lastMinorLowIdx;
|
||||
majorLowZoneHigh = high[lastMinorLowIdx];
|
||||
majorLowZoneLow = low[lastMinorLowIdx];
|
||||
majorLowZoneTime = time[lastMinorLowIdx];
|
||||
}
|
||||
}
|
||||
|
||||
// بررسی BOS نزولی: آیا Close کندل i پایینتر از آخرین کف مینور است؟
|
||||
if (lastMinorLowIdx != -1 && i < lastMinorLowIdx && close[i] < low[lastMinorLowIdx])
|
||||
{
|
||||
// BOS نزولی رخ داد -> سقف مینور قبلی حالا سقف ماژور تایید شده است
|
||||
if (lastMinorHighIdx != -1 && lastMinorHighIdx > lastMinorLowIdx)
|
||||
{
|
||||
majorHighBarIndex = lastMinorHighIdx;
|
||||
majorHighZoneHigh = high[lastMinorHighIdx];
|
||||
majorHighZoneLow = low[lastMinorHighIdx];
|
||||
majorHighZoneTime = time[lastMinorHighIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| بررسی آیا کندل idx یک پراوت مینور است |
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsMinorPivot(double &data[], int idx, bool isHigh)
|
||||
{
|
||||
for (int j = 1; j <= MinorPivotLookback; j++)
|
||||
{
|
||||
if (isHigh)
|
||||
{
|
||||
if (data[idx] <= data[idx - j] || data[idx] <= data[idx + j])
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data[idx] >= data[idx - j] || data[idx] >= data[idx + j])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| تعیین بایاس بر اساس قانون تازگی |
|
||||
//+------------------------------------------------------------------+
|
||||
void DetermineBias()
|
||||
{
|
||||
if (majorHighBarIndex == -1 && majorLowBarIndex == -1)
|
||||
{
|
||||
biasDirection = "NEUTRAL (No Major Structure)";
|
||||
return;
|
||||
}
|
||||
|
||||
if (majorHighBarIndex == -1)
|
||||
{
|
||||
biasDirection = "BULLISH (Only Major Low Found)";
|
||||
return;
|
||||
}
|
||||
|
||||
if (majorLowBarIndex == -1)
|
||||
{
|
||||
biasDirection = "BEARISH (Only Major High Found)";
|
||||
return;
|
||||
}
|
||||
|
||||
// در آرایه سری، اندیس کوچکتر = زمان جدیدتر
|
||||
if (majorHighBarIndex < majorLowBarIndex)
|
||||
{
|
||||
biasDirection = "BEARISH (Short Only)";
|
||||
}
|
||||
else if (majorLowBarIndex < majorHighBarIndex)
|
||||
{
|
||||
biasDirection = "BULLISH (Long Only)";
|
||||
}
|
||||
else
|
||||
{
|
||||
biasDirection = "NEUTRAL (Equal Time)";
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| رسم نواحی ماژور روی چارت |
|
||||
//+------------------------------------------------------------------+
|
||||
void DrawMajorZones()
|
||||
{
|
||||
// رسم ناحیه کف ماژور (حمایت)
|
||||
if (majorLowBarIndex != -1)
|
||||
{
|
||||
if (ObjectFind(0, lowZoneName) < 0)
|
||||
{
|
||||
ObjectCreate(0, lowZoneName, OBJ_RECTANGLE, 0, 0, 0, 0, 0);
|
||||
ObjectSetInteger(0, lowZoneName, OBJPROP_COLOR, BullishZoneColor);
|
||||
ObjectSetInteger(0, lowZoneName, OBJPROP_FILL, true);
|
||||
ObjectSetInteger(0, lowZoneName, OBJPROP_BACK, true);
|
||||
}
|
||||
ObjectSetDouble(0, lowZoneName, OBJPROP_PRICE, 0, majorLowZoneHigh);
|
||||
ObjectSetDouble(0, lowZoneName, OBJPROP_PRICE, 1, majorLowZoneLow);
|
||||
ObjectSetInteger(0, lowZoneName, OBJPROP_TIME, 0, majorLowZoneTime);
|
||||
ObjectSetInteger(0, lowZoneName, OBJPROP_TIME, 1, TimeCurrent());
|
||||
}
|
||||
|
||||
// رسم ناحیه سقف ماژور (مقاومت)
|
||||
if (majorHighBarIndex != -1)
|
||||
{
|
||||
if (ObjectFind(0, highZoneName) < 0)
|
||||
{
|
||||
ObjectCreate(0, highZoneName, OBJ_RECTANGLE, 0, 0, 0, 0, 0);
|
||||
ObjectSetInteger(0, highZoneName, OBJPROP_COLOR, BearishZoneColor);
|
||||
ObjectSetInteger(0, highZoneName, OBJPROP_FILL, true);
|
||||
ObjectSetInteger(0, highZoneName, OBJPROP_BACK, true);
|
||||
}
|
||||
ObjectSetDouble(0, highZoneName, OBJPROP_PRICE, 0, majorHighZoneHigh);
|
||||
ObjectSetDouble(0, highZoneName, OBJPROP_PRICE, 1, majorHighZoneLow);
|
||||
ObjectSetInteger(0, highZoneName, OBJPROP_TIME, 0, majorHighZoneTime);
|
||||
ObjectSetInteger(0, highZoneName, OBJPROP_TIME, 1, TimeCurrent());
|
||||
}
|
||||
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| گسترش نواحی تا زمان حال (در هر تیک) |
|
||||
//+------------------------------------------------------------------+
|
||||
void ExtendZonesToCurrentTime()
|
||||
{
|
||||
if (majorLowBarIndex != -1)
|
||||
{
|
||||
ObjectSetInteger(0, lowZoneName, OBJPROP_TIME, 1, TimeCurrent());
|
||||
}
|
||||
if (majorHighBarIndex != -1)
|
||||
{
|
||||
ObjectSetInteger(0, highZoneName, OBJPROP_TIME, 1, TimeCurrent());
|
||||
}
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| نمایش داشبورد روی چارت |
|
||||
//+------------------------------------------------------------------+
|
||||
void DisplayDashboard()
|
||||
{
|
||||
string dash = "\n========== 4H MAJOR STRUCTURE (BOS) ==========\n";
|
||||
dash += "Symbol: " + _Symbol + " | Bias: " + biasDirection + "\n";
|
||||
dash += "--------------------------------------------------\n";
|
||||
|
||||
if (majorLowBarIndex != -1)
|
||||
{
|
||||
dash += "MAJOR LOW ZONE (Support):\n";
|
||||
dash += " High: " + DoubleToString(majorLowZoneHigh, _Digits) + "\n";
|
||||
dash += " Low: " + DoubleToString(majorLowZoneLow, _Digits) + "\n";
|
||||
dash += " Time: " + TimeToString(majorLowZoneTime, TIME_DATE | TIME_MINUTES) + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
dash += "MAJOR LOW ZONE: Not Found\n";
|
||||
}
|
||||
|
||||
dash += "--------------------------------------------------\n";
|
||||
|
||||
if (majorHighBarIndex != -1)
|
||||
{
|
||||
dash += "MAJOR HIGH ZONE (Resistance):\n";
|
||||
dash += " High: " + DoubleToString(majorHighZoneHigh, _Digits) + "\n";
|
||||
dash += " Low: " + DoubleToString(majorHighZoneLow, _Digits) + "\n";
|
||||
dash += " Time: " + TimeToString(majorHighZoneTime, TIME_DATE | TIME_MINUTES) + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
dash += "MAJOR HIGH ZONE: Not Found\n";
|
||||
}
|
||||
|
||||
dash += "==================================================\n";
|
||||
|
||||
Comment(dash);
|
||||
Print("Bias: ", biasDirection);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user