NUNA/Logs/Indicators/Downloads/candel 2.mq5
2026-01-06 05:44:21 +00:00

156 行
11 KiB
MQL5

//+------------------------------------------------------------------+
//| BoomSpikeBoxMitigationFinal.mq5 |
//| Spike pattern + entry line that expires at mitigation |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property version "1.0"
#property strict
//==== Input Parameters ====
input color BoxColor = clrBlue;
input color LineColor = clrLimeGreen;
input int BoxWidth = 2;
input int LineWidth = 1;
input ENUM_LINE_STYLE BoxStyle = STYLE_SOLID;
input ENUM_LINE_STYLE LineStyle = STYLE_SOLID;
//==== Zone Struct ====
struct Zone
{
datetime boxTime;
double entryPrice;
string lineName;
bool mitigated;
};
Zone zones[100];
int zoneCount = 0;
//+------------------------------------------------------------------+
//| Initialization |
//+------------------------------------------------------------------+
int OnInit()
{
zoneCount = 0;
ObjectsDeleteAll(0, "Box_");
ObjectsDeleteAll(0, "Line_");
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| OnDeinit |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, "Box_");
ObjectsDeleteAll(0, "Line_");
}
//+------------------------------------------------------------------+
//| OnCalculate |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if (rates_total < 10)
return prev_calculated;
// ---- Pattern Detection ----
for (int i = rates_total - 4; i >= 2; i--)
{
double body1 = MathAbs(open[i] - close[i]);
double wick1 = high[i] - low[i];
bool isGreenSpike1 = close[i] > open[i] && body1 > 0.7 * wick1;
bool isRedMid = close[i+1] < open[i+1];
double body3 = MathAbs(open[i+2] - close[i+2]);
double wick3 = high[i+2] - low[i+2];
bool isGreenSpike2 = close[i+2] > open[i+2] && body3 > 0.7 * wick3;
if (isGreenSpike1 && isRedMid && isGreenSpike2)
{
datetime boxTime = time[i+2];
double entryPrice = open[i+1];
// Check duplicate
bool exists = false;
for (int j = 0; j < zoneCount; j++)
{
if (zones[j].boxTime == boxTime)
{
exists = true;
break;
}
}
if (!exists && zoneCount < ArraySize(zones))
{
double top = MathMax(MathMax(high[i], high[i+1]), high[i+2]);
double bottom = MathMin(MathMin(low[i], low[i+1]), low[i+2]);
string boxName = "Box_" + IntegerToString((int)boxTime);
ObjectCreate(0, boxName, OBJ_RECTANGLE, 0, time[i], top, boxTime, bottom);
ObjectSetInteger(0, boxName, OBJPROP_COLOR, BoxColor);
ObjectSetInteger(0, boxName, OBJPROP_WIDTH, BoxWidth);
ObjectSetInteger(0, boxName, OBJPROP_STYLE, BoxStyle);
ObjectSetInteger(0, boxName, OBJPROP_BACK, true);
// Draw extending entry line
datetime futureTime = TimeCurrent() + PeriodSeconds() * 100;
string lineName = "Line_" + IntegerToString((int)boxTime);
ObjectCreate(0, lineName, OBJ_TREND, 0, boxTime, entryPrice, futureTime, entryPrice);
ObjectSetInteger(0, lineName, OBJPROP_COLOR, LineColor);
ObjectSetInteger(0, lineName, OBJPROP_WIDTH, LineWidth);
ObjectSetInteger(0, lineName, OBJPROP_STYLE, LineStyle);
zones[zoneCount].boxTime = boxTime;
zones[zoneCount].entryPrice = entryPrice;
zones[zoneCount].lineName = lineName;
zones[zoneCount].mitigated = false;
zoneCount++;
}
}
}
// ---- Mitigation Detection ----
for (int j = 0; j < zoneCount; j++)
{
if (zones[j].mitigated)
continue;
for (int i = 1; i < rates_total; i++)
{
if (time[i] <= zones[j].boxTime)
continue;
if (low[i] <= zones[j].entryPrice && high[i] >= zones[j].entryPrice)
{
if (ObjectFind(0, zones[j].lineName) >= 0)
ObjectDelete(0, zones[j].lineName);
string fixedName = zones[j].lineName + "_Fixed";
ObjectCreate(0, fixedName, OBJ_TREND, 0,
zones[j].boxTime, zones[j].entryPrice,
time[i], zones[j].entryPrice);
ObjectSetInteger(0, fixedName, OBJPROP_COLOR, LineColor);
ObjectSetInteger(0, fixedName, OBJPROP_WIDTH, LineWidth);
ObjectSetInteger(0, fixedName, OBJPROP_STYLE, LineStyle);
zones[j].mitigated = true;
break;
}
}
}
return rates_total;
}