RSI-Stoch-MA-EA/Candlepatterns.mqh

601 行
19 KiB
MQL5

2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
//| CandlePatterns.mqh |
2026-01-21 08:11:54 +00:00
//| Comprehensive Candlestick Pattern Detection |
//| STANDALONE VERSION - No external dependencies |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
#property copyright "QuarterTheory x VIZION"
#property version "2.00"
#property strict
2026-01-20 20:06:19 +00:00
//================ PATTERN ENUMS ==================//
enum ENUM_PATTERN_TYPE
{
2026-01-21 08:11:54 +00:00
PATTERN_NONE,
PATTERN_REVERSAL_BULLISH,
PATTERN_REVERSAL_BEARISH,
PATTERN_CONTINUATION_BULL,
PATTERN_CONTINUATION_BEAR,
PATTERN_INDECISION
2026-01-20 20:06:19 +00:00
};
2026-01-21 08:11:54 +00:00
enum ENUM_PATTERN_NAME
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
// Single Candle Patterns
PATT_HAMMER,
PATT_INVERTED_HAMMER,
PATT_HANGING_MAN,
PATT_SHOOTING_STAR,
PATT_DOJI,
PATT_DRAGONFLY_DOJI,
PATT_GRAVESTONE_DOJI,
PATT_SPINNING_TOP,
PATT_MARUBOZU_BULL,
PATT_MARUBOZU_BEAR,
// Two Candle Patterns
PATT_ENGULFING_BULL,
PATT_ENGULFING_BEAR,
PATT_PIERCING_LINE,
PATT_DARK_CLOUD,
PATT_TWEEZER_TOP,
PATT_TWEEZER_BOTTOM,
PATT_HARAMI_BULL,
PATT_HARAMI_BEAR,
PATT_BULLISH_KICKER,
PATT_BEARISH_KICKER,
// Three+ Candle Patterns
PATT_THREE_WHITE_SOLDIERS,
PATT_THREE_BLACK_CROWS,
PATT_MORNING_STAR,
PATT_EVENING_STAR,
PATT_MORNING_DOJI_STAR,
PATT_EVENING_DOJI_STAR,
PATT_THREE_INSIDE_UP,
PATT_THREE_INSIDE_DOWN,
PATT_THREE_OUTSIDE_UP,
PATT_THREE_OUTSIDE_DOWN,
// TheStrat Patterns
PATT_2_1_2_BULL_CONT,
PATT_2_1_2_BEAR_CONT,
PATT_3_1_2_BULL_REV,
PATT_3_1_2_BEAR_REV,
PATT_2_2_REVERSAL_BULL,
PATT_2_2_REVERSAL_BEAR,
PATT_2_2_CONTINUATION_BULL,
PATT_2_2_CONTINUATION_BEAR
2026-01-20 20:06:19 +00:00
};
//================ PATTERN STRUCTURE ==================//
struct PatternSignal
{
2026-01-21 08:11:54 +00:00
ENUM_PATTERN_NAME name;
ENUM_PATTERN_TYPE type;
string name_str;
int strength;
int candle_index;
double pattern_price;
datetime time;
bool generates_warn;
bool generates_praise;
double adjusted_strength;
2026-01-20 20:06:19 +00:00
};
2026-01-21 08:11:54 +00:00
//================ GLOBAL VARIABLES ==================//
PatternSignal g_ActivePatterns[];
int g_PatternCount = 0;
const int MAX_PATTERNS = 100;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
// Candle measurement constants
const double CANDLE_BODY_RATIO = 0.6;
const double SHADOW_RATIO = 2.0;
const double DOJI_RATIO = 0.1;
const double ENGULF_RATIO = 1.0;
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
//| Initialize Pattern Detection System |
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
bool InitializePatternDetection()
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
ArrayResize(g_ActivePatterns, MAX_PATTERNS);
g_PatternCount = 0;
Print("✅ Candlestick Pattern Detection System Initialized");
Print(" - 37 pattern types supported");
return true;
2026-01-20 20:06:19 +00:00
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| Main Pattern Detection Entry Point |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
void DetectAllCandlestickPatterns()
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
g_PatternCount = 0;
2026-01-20 20:06:19 +00:00
MqlRates rates[];
ArraySetAsSeries(rates, true);
2026-01-21 08:11:54 +00:00
int copied = CopyRates(_Symbol, _Period, 0, 100, rates);
if(copied < 20) return;
DetectSingleCandlePatterns(rates);
DetectTwoCandlePatterns(rates);
DetectThreeCandlePatterns(rates);
DetectTheStratPatterns(rates);
GenerateSignalsFromPatterns();
if(g_PatternCount > 0)
Print("🕯️ Detected ", g_PatternCount, " candlestick patterns");
2026-01-20 20:06:19 +00:00
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| SINGLE CANDLE PATTERNS |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
void DetectSingleCandlePatterns(const MqlRates &rates[])
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
int idx = 1;
if(idx >= ArraySize(rates)) return;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
double o = rates[idx].open;
double h = rates[idx].high;
double l = rates[idx].low;
double c = rates[idx].close;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
double body = MathAbs(c - o);
double total_range = h - l;
double upper_shadow = h - MathMax(o, c);
double lower_shadow = MathMin(o, c) - l;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
if(total_range == 0) return;
// HAMMER
if(lower_shadow >= SHADOW_RATIO * body &&
upper_shadow <= 0.3 * body &&
body / total_range >= 0.2 &&
IsBearishTrend(rates, idx))
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_HAMMER, PATTERN_REVERSAL_BULLISH, idx, l, rates[idx].time, 85);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// INVERTED HAMMER
if(upper_shadow >= SHADOW_RATIO * body &&
lower_shadow <= 0.3 * body &&
body / total_range >= 0.2 &&
IsBearishTrend(rates, idx))
{
AddPattern(PATT_INVERTED_HAMMER, PATTERN_REVERSAL_BULLISH, idx, h, rates[idx].time, 75);
}
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
// SHOOTING STAR
if(upper_shadow >= SHADOW_RATIO * body &&
lower_shadow <= 0.3 * body &&
body / total_range >= 0.2 &&
IsBullishTrend(rates, idx))
{
AddPattern(PATT_SHOOTING_STAR, PATTERN_REVERSAL_BEARISH, idx, h, rates[idx].time, 85);
}
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
// HANGING MAN
if(lower_shadow >= SHADOW_RATIO * body &&
upper_shadow <= 0.3 * body &&
body / total_range >= 0.2 &&
IsBullishTrend(rates, idx))
{
AddPattern(PATT_HANGING_MAN, PATTERN_REVERSAL_BEARISH, idx, l, rates[idx].time, 75);
}
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
// DOJI
if(body / total_range < DOJI_RATIO)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
if(lower_shadow > 2 * upper_shadow)
AddPattern(PATT_DRAGONFLY_DOJI, PATTERN_REVERSAL_BULLISH, idx, c, rates[idx].time, 70);
else if(upper_shadow > 2 * lower_shadow)
AddPattern(PATT_GRAVESTONE_DOJI, PATTERN_REVERSAL_BEARISH, idx, c, rates[idx].time, 70);
2026-01-20 20:06:19 +00:00
else
2026-01-21 08:11:54 +00:00
AddPattern(PATT_DOJI, PATTERN_INDECISION, idx, c, rates[idx].time, 60);
}
// SPINNING TOP
if(body / total_range > DOJI_RATIO && body / total_range < 0.3 &&
upper_shadow > body && lower_shadow > body)
{
AddPattern(PATT_SPINNING_TOP, PATTERN_INDECISION, idx, c, rates[idx].time, 55);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// MARUBOZU
if(c > o && body / total_range > 0.9)
AddPattern(PATT_MARUBOZU_BULL, PATTERN_CONTINUATION_BULL, idx, c, rates[idx].time, 80);
if(c < o && body / total_range > 0.9)
AddPattern(PATT_MARUBOZU_BEAR, PATTERN_CONTINUATION_BEAR, idx, c, rates[idx].time, 80);
2026-01-20 20:06:19 +00:00
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| TWO CANDLE PATTERNS |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
void DetectTwoCandlePatterns(const MqlRates &rates[])
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
if(ArraySize(rates) < 3) return;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
int curr = 1, prev = 2;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
double o1 = rates[prev].open, h1 = rates[prev].high;
double l1 = rates[prev].low, c1 = rates[prev].close;
double o2 = rates[curr].open, h2 = rates[curr].high;
double l2 = rates[curr].low, c2 = rates[curr].close;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
double body1 = MathAbs(c1 - o1);
double body2 = MathAbs(c2 - o2);
// BULLISH ENGULFING
if(c1 < o1 && c2 > o2 &&
o2 <= c1 && c2 >= o1 &&
body2 > body1 * ENGULF_RATIO)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_ENGULFING_BULL, PATTERN_REVERSAL_BULLISH, curr, c2, rates[curr].time, 90);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// BEARISH ENGULFING
if(c1 > o1 && c2 < o2 &&
o2 >= c1 && c2 <= o1 &&
body2 > body1 * ENGULF_RATIO)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_ENGULFING_BEAR, PATTERN_REVERSAL_BEARISH, curr, c2, rates[curr].time, 90);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// PIERCING LINE
if(c1 < o1 && c2 > o2 &&
o2 < l1 &&
c2 > (o1 + c1) / 2 &&
c2 < o1)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_PIERCING_LINE, PATTERN_REVERSAL_BULLISH, curr, c2, rates[curr].time, 85);
}
// DARK CLOUD COVER
if(c1 > o1 && c2 < o2 &&
o2 > h1 &&
c2 < (o1 + c1) / 2 &&
c2 > o1)
{
AddPattern(PATT_DARK_CLOUD, PATTERN_REVERSAL_BEARISH, curr, c2, rates[curr].time, 85);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// TWEEZER TOP
if(MathAbs(h1 - h2) < (h1 - l1) * 0.02 && IsBullishTrend(rates, curr))
{
AddPattern(PATT_TWEEZER_TOP, PATTERN_REVERSAL_BEARISH, curr, h2, rates[curr].time, 75);
}
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
// TWEEZER BOTTOM
if(MathAbs(l1 - l2) < (h1 - l1) * 0.02 && IsBearishTrend(rates, curr))
{
AddPattern(PATT_TWEEZER_BOTTOM, PATTERN_REVERSAL_BULLISH, curr, l2, rates[curr].time, 75);
}
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
// BULLISH HARAMI
if(c1 < o1 && c2 > o2 &&
o2 > c1 && c2 < o1 &&
body2 < body1 * 0.5)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_HARAMI_BULL, PATTERN_REVERSAL_BULLISH, curr, c2, rates[curr].time, 70);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// BEARISH HARAMI
if(c1 > o1 && c2 < o2 &&
o2 < c1 && c2 > o1 &&
body2 < body1 * 0.5)
{
AddPattern(PATT_HARAMI_BEAR, PATTERN_REVERSAL_BEARISH, curr, c2, rates[curr].time, 70);
}
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
// BULLISH KICKER
if(c1 < o1 && c2 > o2 &&
o2 > c1 &&
body1 > (h1 - l1) * 0.7 &&
body2 > (h2 - l2) * 0.7)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_BULLISH_KICKER, PATTERN_REVERSAL_BULLISH, curr, o2, rates[curr].time, 95);
}
// BEARISH KICKER
if(c1 > o1 && c2 < o2 &&
o2 < c1 &&
body1 > (h1 - l1) * 0.7 &&
body2 > (h2 - l2) * 0.7)
{
AddPattern(PATT_BEARISH_KICKER, PATTERN_REVERSAL_BEARISH, curr, o2, rates[curr].time, 95);
2026-01-20 20:06:19 +00:00
}
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| THREE+ CANDLE PATTERNS |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
void DetectThreeCandlePatterns(const MqlRates &rates[])
2026-01-20 20:06:19 +00:00
{
if(ArraySize(rates) < 4) return;
int c1 = 3, c2 = 2, c3 = 1;
2026-01-21 08:11:54 +00:00
// THREE WHITE SOLDIERS
2026-01-20 20:06:19 +00:00
if(rates[c1].close > rates[c1].open &&
rates[c2].close > rates[c2].open &&
rates[c3].close > rates[c3].open &&
rates[c2].close > rates[c1].close &&
2026-01-21 08:11:54 +00:00
rates[c3].close > rates[c2].close)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_THREE_WHITE_SOLDIERS, PATTERN_CONTINUATION_BULL, c3,
rates[c3].close, rates[c3].time, 90);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// THREE BLACK CROWS
2026-01-20 20:06:19 +00:00
if(rates[c1].close < rates[c1].open &&
rates[c2].close < rates[c2].open &&
rates[c3].close < rates[c3].open &&
rates[c2].close < rates[c1].close &&
2026-01-21 08:11:54 +00:00
rates[c3].close < rates[c2].close)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_THREE_BLACK_CROWS, PATTERN_CONTINUATION_BEAR, c3,
rates[c3].close, rates[c3].time, 90);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// MORNING STAR
if(rates[c1].close < rates[c1].open &&
MathAbs(rates[c2].close - rates[c2].open) < (rates[c1].high - rates[c1].low) * 0.3 &&
2026-01-20 20:06:19 +00:00
rates[c3].close > rates[c3].open &&
2026-01-21 08:11:54 +00:00
rates[c3].close > (rates[c1].open + rates[c1].close) / 2)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_MORNING_STAR, PATTERN_REVERSAL_BULLISH, c3,
rates[c3].close, rates[c3].time, 95);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// EVENING STAR
if(rates[c1].close > rates[c1].open &&
MathAbs(rates[c2].close - rates[c2].open) < (rates[c1].high - rates[c1].low) * 0.3 &&
rates[c3].close < rates[c3].open &&
rates[c3].close < (rates[c1].open + rates[c1].close) / 2)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_EVENING_STAR, PATTERN_REVERSAL_BEARISH, c3,
rates[c3].close, rates[c3].time, 95);
2026-01-20 20:06:19 +00:00
}
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| THESTRAT PATTERNS |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
void DetectTheStratPatterns(const MqlRates &rates[])
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
if(ArraySize(rates) < 4) return;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
int strat_type[3];
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
for(int i = 1; i <= 3; i++)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
if(i >= ArraySize(rates)) continue;
int curr = i;
int prev = i + 1;
// Inside bar (1)
if(rates[curr].high <= rates[prev].high && rates[curr].low >= rates[prev].low)
strat_type[i-1] = 1;
// Outside bar (2)
else if(rates[curr].high > rates[prev].high && rates[curr].low < rates[prev].low)
strat_type[i-1] = 2;
// Directional (3)
2026-01-20 20:06:19 +00:00
else
2026-01-21 08:11:54 +00:00
strat_type[i-1] = 3;
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// 2-1-2 BULLISH CONTINUATION
if(strat_type[2] == 2 && strat_type[1] == 1 && strat_type[0] == 2 &&
rates[1].close > rates[1].open)
{
AddPattern(PATT_2_1_2_BULL_CONT, PATTERN_CONTINUATION_BULL, 1,
rates[1].close, rates[1].time, 88);
}
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
// 2-1-2 BEARISH CONTINUATION
if(strat_type[2] == 2 && strat_type[1] == 1 && strat_type[0] == 2 &&
rates[1].close < rates[1].open)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_2_1_2_BEAR_CONT, PATTERN_CONTINUATION_BEAR, 1,
rates[1].close, rates[1].time, 88);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// 3-1-2 BULLISH REVERSAL
if(strat_type[2] == 3 && strat_type[1] == 1 && strat_type[0] == 2 &&
rates[3].close < rates[3].open && rates[1].close > rates[1].open)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_3_1_2_BULL_REV, PATTERN_REVERSAL_BULLISH, 1,
rates[1].close, rates[1].time, 92);
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
// 3-1-2 BEARISH REVERSAL
if(strat_type[2] == 3 && strat_type[1] == 1 && strat_type[0] == 2 &&
rates[3].close > rates[3].open && rates[1].close < rates[1].open)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
AddPattern(PATT_3_1_2_BEAR_REV, PATTERN_REVERSAL_BEARISH, 1,
rates[1].close, rates[1].time, 92);
2026-01-20 20:06:19 +00:00
}
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| Helper Functions |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
bool IsBullishTrend(const MqlRates &rates[], int index)
{
if(index + 10 >= ArraySize(rates)) return false;
double ma_fast = 0, ma_slow = 0;
for(int i = index; i < index + 5; i++)
ma_fast += rates[i].close;
ma_fast /= 5;
for(int i = index; i < index + 10; i++)
ma_slow += rates[i].close;
ma_slow /= 10;
return ma_fast > ma_slow;
}
bool IsBearishTrend(const MqlRates &rates[], int index)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
return !IsBullishTrend(rates, index);
2026-01-20 20:06:19 +00:00
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| Add Pattern to Array |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
void AddPattern(ENUM_PATTERN_NAME name, ENUM_PATTERN_TYPE type,
int candle_idx, double price, datetime time, int strength)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
if(g_PatternCount >= MAX_PATTERNS) return;
PatternSignal signal;
signal.name = name;
signal.type = type;
signal.name_str = GetPatternName(name);
signal.strength = strength;
signal.candle_index = candle_idx;
signal.pattern_price = price;
signal.time = time;
signal.generates_warn = false;
signal.generates_praise = false;
signal.adjusted_strength = strength;
g_ActivePatterns[g_PatternCount] = signal;
g_PatternCount++;
2026-01-20 20:06:19 +00:00
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| Get Pattern Name String |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
string GetPatternName(ENUM_PATTERN_NAME name)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
switch(name)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
case PATT_HAMMER: return "HAMMER";
case PATT_INVERTED_HAMMER: return "INVERTED_HAMMER";
case PATT_SHOOTING_STAR: return "SHOOTING_STAR";
case PATT_HANGING_MAN: return "HANGING_MAN";
case PATT_DOJI: return "DOJI";
case PATT_DRAGONFLY_DOJI: return "DRAGONFLY_DOJI";
case PATT_GRAVESTONE_DOJI: return "GRAVESTONE_DOJI";
case PATT_SPINNING_TOP: return "SPINNING_TOP";
case PATT_MARUBOZU_BULL: return "MARUBOZU_BULL";
case PATT_MARUBOZU_BEAR: return "MARUBOZU_BEAR";
case PATT_ENGULFING_BULL: return "BULLISH_ENGULFING";
case PATT_ENGULFING_BEAR: return "BEARISH_ENGULFING";
case PATT_PIERCING_LINE: return "PIERCING_LINE";
case PATT_DARK_CLOUD: return "DARK_CLOUD_COVER";
case PATT_TWEEZER_TOP: return "TWEEZER_TOP";
case PATT_TWEEZER_BOTTOM: return "TWEEZER_BOTTOM";
case PATT_HARAMI_BULL: return "BULLISH_HARAMI";
case PATT_HARAMI_BEAR: return "BEARISH_HARAMI";
case PATT_BULLISH_KICKER: return "BULLISH_KICKER";
case PATT_BEARISH_KICKER: return "BEARISH_KICKER";
case PATT_THREE_WHITE_SOLDIERS: return "THREE_WHITE_SOLDIERS";
case PATT_THREE_BLACK_CROWS: return "THREE_BLACK_CROWS";
case PATT_MORNING_STAR: return "MORNING_STAR";
case PATT_EVENING_STAR: return "EVENING_STAR";
case PATT_2_1_2_BULL_CONT: return "2-1-2_BULL_CONTINUATION";
case PATT_2_1_2_BEAR_CONT: return "2-1-2_BEAR_CONTINUATION";
case PATT_3_1_2_BULL_REV: return "3-1-2_BULL_REVERSAL";
case PATT_3_1_2_BEAR_REV: return "3-1-2_BEAR_REVERSAL";
default: return "UNKNOWN";
2026-01-20 20:06:19 +00:00
}
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| Generate WARN/PRAISE Signals |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
void GenerateSignalsFromPatterns()
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
for(int i = 0; i < g_PatternCount; i++)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
if(g_ActivePatterns[i].type == PATTERN_REVERSAL_BULLISH ||
g_ActivePatterns[i].type == PATTERN_REVERSAL_BEARISH)
{
g_ActivePatterns[i].generates_warn = true;
}
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
if(g_ActivePatterns[i].type == PATTERN_CONTINUATION_BULL ||
g_ActivePatterns[i].type == PATTERN_CONTINUATION_BEAR)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
g_ActivePatterns[i].generates_praise = true;
2026-01-20 20:06:19 +00:00
}
2026-01-21 08:11:54 +00:00
if(g_ActivePatterns[i].adjusted_strength >= 85)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
string signal_type = g_ActivePatterns[i].generates_warn ? "WARN" :
g_ActivePatterns[i].generates_praise ? "PRAISE" : "NEUTRAL";
Print("🕯️ ", signal_type, " - ", g_ActivePatterns[i].name_str,
" [Strength: ", (int)g_ActivePatterns[i].adjusted_strength, "%]");
2026-01-20 20:06:19 +00:00
}
}
}
//+------------------------------------------------------------------+
//| Get Pattern Count by Type |
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
int GetPatternCount(ENUM_PATTERN_TYPE type)
2026-01-20 20:06:19 +00:00
{
int count = 0;
2026-01-21 08:11:54 +00:00
for(int i = 0; i < g_PatternCount; i++)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
if(g_ActivePatterns[i].type == type)
2026-01-20 20:06:19 +00:00
count++;
}
return count;
}
//+------------------------------------------------------------------+
//| Get Strongest Pattern |
//+------------------------------------------------------------------+
PatternSignal GetStrongestPattern()
{
PatternSignal strongest;
strongest.strength = 0;
2026-01-21 08:11:54 +00:00
strongest.adjusted_strength = 0;
2026-01-20 20:06:19 +00:00
2026-01-21 08:11:54 +00:00
for(int i = 0; i < g_PatternCount; i++)
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
if(g_ActivePatterns[i].adjusted_strength > strongest.adjusted_strength)
strongest = g_ActivePatterns[i];
2026-01-20 20:06:19 +00:00
}
return strongest;
}
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
//| Integration Functions |
2026-01-20 20:06:19 +00:00
//+------------------------------------------------------------------+
2026-01-21 08:11:54 +00:00
int GetPatternWarnCount()
2026-01-20 20:06:19 +00:00
{
2026-01-21 08:11:54 +00:00
int count = 0;
for(int i = 0; i < g_PatternCount; i++)
if(g_ActivePatterns[i].generates_warn) count++;
return count;
}
int GetPatternPraiseCount()
{
int count = 0;
for(int i = 0; i < g_PatternCount; i++)
if(g_ActivePatterns[i].generates_praise) count++;
return count;
}
bool IsPatternActive(ENUM_PATTERN_NAME pattern_name)
{
for(int i = 0; i < g_PatternCount; i++)
if(g_ActivePatterns[i].name == pattern_name) return true;
2026-01-20 20:06:19 +00:00
return false;
}