601 行
无行尾
19 KiB
MQL5
601 行
无行尾
19 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| CandlePatterns.mqh |
|
|
//| Comprehensive Candlestick Pattern Detection |
|
|
//| STANDALONE VERSION - No external dependencies |
|
|
//+------------------------------------------------------------------+
|
|
|
|
#property copyright "QuarterTheory x VIZION"
|
|
#property version "2.00"
|
|
#property strict
|
|
|
|
//================ PATTERN ENUMS ==================//
|
|
enum ENUM_PATTERN_TYPE
|
|
{
|
|
PATTERN_NONE,
|
|
PATTERN_REVERSAL_BULLISH,
|
|
PATTERN_REVERSAL_BEARISH,
|
|
PATTERN_CONTINUATION_BULL,
|
|
PATTERN_CONTINUATION_BEAR,
|
|
PATTERN_INDECISION
|
|
};
|
|
|
|
enum ENUM_PATTERN_NAME
|
|
{
|
|
// 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
|
|
};
|
|
|
|
//================ PATTERN STRUCTURE ==================//
|
|
struct PatternSignal
|
|
{
|
|
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;
|
|
};
|
|
|
|
//================ GLOBAL VARIABLES ==================//
|
|
PatternSignal g_ActivePatterns[];
|
|
int g_PatternCount = 0;
|
|
const int MAX_PATTERNS = 100;
|
|
|
|
// 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;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialize Pattern Detection System |
|
|
//+------------------------------------------------------------------+
|
|
bool InitializePatternDetection()
|
|
{
|
|
ArrayResize(g_ActivePatterns, MAX_PATTERNS);
|
|
g_PatternCount = 0;
|
|
|
|
Print("✅ Candlestick Pattern Detection System Initialized");
|
|
Print(" - 37 pattern types supported");
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Main Pattern Detection Entry Point |
|
|
//+------------------------------------------------------------------+
|
|
void DetectAllCandlestickPatterns()
|
|
{
|
|
g_PatternCount = 0;
|
|
|
|
MqlRates rates[];
|
|
ArraySetAsSeries(rates, true);
|
|
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");
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| SINGLE CANDLE PATTERNS |
|
|
//+------------------------------------------------------------------+
|
|
void DetectSingleCandlePatterns(const MqlRates &rates[])
|
|
{
|
|
int idx = 1;
|
|
|
|
if(idx >= ArraySize(rates)) return;
|
|
|
|
double o = rates[idx].open;
|
|
double h = rates[idx].high;
|
|
double l = rates[idx].low;
|
|
double c = rates[idx].close;
|
|
|
|
double body = MathAbs(c - o);
|
|
double total_range = h - l;
|
|
double upper_shadow = h - MathMax(o, c);
|
|
double lower_shadow = MathMin(o, c) - l;
|
|
|
|
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))
|
|
{
|
|
AddPattern(PATT_HAMMER, PATTERN_REVERSAL_BULLISH, idx, l, rates[idx].time, 85);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// DOJI
|
|
if(body / total_range < DOJI_RATIO)
|
|
{
|
|
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);
|
|
else
|
|
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);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| TWO CANDLE PATTERNS |
|
|
//+------------------------------------------------------------------+
|
|
void DetectTwoCandlePatterns(const MqlRates &rates[])
|
|
{
|
|
if(ArraySize(rates) < 3) return;
|
|
|
|
int curr = 1, prev = 2;
|
|
|
|
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;
|
|
|
|
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)
|
|
{
|
|
AddPattern(PATT_ENGULFING_BULL, PATTERN_REVERSAL_BULLISH, curr, c2, rates[curr].time, 90);
|
|
}
|
|
|
|
// BEARISH ENGULFING
|
|
if(c1 > o1 && c2 < o2 &&
|
|
o2 >= c1 && c2 <= o1 &&
|
|
body2 > body1 * ENGULF_RATIO)
|
|
{
|
|
AddPattern(PATT_ENGULFING_BEAR, PATTERN_REVERSAL_BEARISH, curr, c2, rates[curr].time, 90);
|
|
}
|
|
|
|
// PIERCING LINE
|
|
if(c1 < o1 && c2 > o2 &&
|
|
o2 < l1 &&
|
|
c2 > (o1 + c1) / 2 &&
|
|
c2 < o1)
|
|
{
|
|
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);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// BULLISH HARAMI
|
|
if(c1 < o1 && c2 > o2 &&
|
|
o2 > c1 && c2 < o1 &&
|
|
body2 < body1 * 0.5)
|
|
{
|
|
AddPattern(PATT_HARAMI_BULL, PATTERN_REVERSAL_BULLISH, curr, c2, rates[curr].time, 70);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// BULLISH KICKER
|
|
if(c1 < o1 && c2 > o2 &&
|
|
o2 > c1 &&
|
|
body1 > (h1 - l1) * 0.7 &&
|
|
body2 > (h2 - l2) * 0.7)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| THREE+ CANDLE PATTERNS |
|
|
//+------------------------------------------------------------------+
|
|
void DetectThreeCandlePatterns(const MqlRates &rates[])
|
|
{
|
|
if(ArraySize(rates) < 4) return;
|
|
|
|
int c1 = 3, c2 = 2, c3 = 1;
|
|
|
|
// THREE WHITE SOLDIERS
|
|
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 &&
|
|
rates[c3].close > rates[c2].close)
|
|
{
|
|
AddPattern(PATT_THREE_WHITE_SOLDIERS, PATTERN_CONTINUATION_BULL, c3,
|
|
rates[c3].close, rates[c3].time, 90);
|
|
}
|
|
|
|
// THREE BLACK CROWS
|
|
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 &&
|
|
rates[c3].close < rates[c2].close)
|
|
{
|
|
AddPattern(PATT_THREE_BLACK_CROWS, PATTERN_CONTINUATION_BEAR, c3,
|
|
rates[c3].close, rates[c3].time, 90);
|
|
}
|
|
|
|
// MORNING 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)
|
|
{
|
|
AddPattern(PATT_MORNING_STAR, PATTERN_REVERSAL_BULLISH, c3,
|
|
rates[c3].close, rates[c3].time, 95);
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
AddPattern(PATT_EVENING_STAR, PATTERN_REVERSAL_BEARISH, c3,
|
|
rates[c3].close, rates[c3].time, 95);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| THESTRAT PATTERNS |
|
|
//+------------------------------------------------------------------+
|
|
void DetectTheStratPatterns(const MqlRates &rates[])
|
|
{
|
|
if(ArraySize(rates) < 4) return;
|
|
|
|
int strat_type[3];
|
|
|
|
for(int i = 1; i <= 3; i++)
|
|
{
|
|
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)
|
|
else
|
|
strat_type[i-1] = 3;
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// 2-1-2 BEARISH 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_BEAR_CONT, PATTERN_CONTINUATION_BEAR, 1,
|
|
rates[1].close, rates[1].time, 88);
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
AddPattern(PATT_3_1_2_BULL_REV, PATTERN_REVERSAL_BULLISH, 1,
|
|
rates[1].close, rates[1].time, 92);
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
AddPattern(PATT_3_1_2_BEAR_REV, PATTERN_REVERSAL_BEARISH, 1,
|
|
rates[1].close, rates[1].time, 92);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Helper Functions |
|
|
//+------------------------------------------------------------------+
|
|
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)
|
|
{
|
|
return !IsBullishTrend(rates, index);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Add Pattern to Array |
|
|
//+------------------------------------------------------------------+
|
|
void AddPattern(ENUM_PATTERN_NAME name, ENUM_PATTERN_TYPE type,
|
|
int candle_idx, double price, datetime time, int strength)
|
|
{
|
|
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++;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Get Pattern Name String |
|
|
//+------------------------------------------------------------------+
|
|
string GetPatternName(ENUM_PATTERN_NAME name)
|
|
{
|
|
switch(name)
|
|
{
|
|
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";
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Generate WARN/PRAISE Signals |
|
|
//+------------------------------------------------------------------+
|
|
void GenerateSignalsFromPatterns()
|
|
{
|
|
for(int i = 0; i < g_PatternCount; i++)
|
|
{
|
|
if(g_ActivePatterns[i].type == PATTERN_REVERSAL_BULLISH ||
|
|
g_ActivePatterns[i].type == PATTERN_REVERSAL_BEARISH)
|
|
{
|
|
g_ActivePatterns[i].generates_warn = true;
|
|
}
|
|
|
|
if(g_ActivePatterns[i].type == PATTERN_CONTINUATION_BULL ||
|
|
g_ActivePatterns[i].type == PATTERN_CONTINUATION_BEAR)
|
|
{
|
|
g_ActivePatterns[i].generates_praise = true;
|
|
}
|
|
|
|
if(g_ActivePatterns[i].adjusted_strength >= 85)
|
|
{
|
|
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, "%]");
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Get Pattern Count by Type |
|
|
//+------------------------------------------------------------------+
|
|
int GetPatternCount(ENUM_PATTERN_TYPE type)
|
|
{
|
|
int count = 0;
|
|
for(int i = 0; i < g_PatternCount; i++)
|
|
{
|
|
if(g_ActivePatterns[i].type == type)
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Get Strongest Pattern |
|
|
//+------------------------------------------------------------------+
|
|
PatternSignal GetStrongestPattern()
|
|
{
|
|
PatternSignal strongest;
|
|
strongest.strength = 0;
|
|
strongest.adjusted_strength = 0;
|
|
|
|
for(int i = 0; i < g_PatternCount; i++)
|
|
{
|
|
if(g_ActivePatterns[i].adjusted_strength > strongest.adjusted_strength)
|
|
strongest = g_ActivePatterns[i];
|
|
}
|
|
|
|
return strongest;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Integration Functions |
|
|
//+------------------------------------------------------------------+
|
|
int GetPatternWarnCount()
|
|
{
|
|
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;
|
|
return false;
|
|
} |