Warrior_EA/Signals/SignalPB.mqh

166 lines
6.7 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:35:54 +02:00
//+------------------------------------------------------------------+
//| SignalPB.mqh |
//+------------------------------------------------------------------+
#property copyright "AnimateDread"
#property version "1.0"
#property description "Pin Bar Signal"
#include "..\Expert\ExpertSignalCustom.mqh"
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Signal of candle pattern 'Pin Bar' |
//| Type=SignalAdvanced |
//| Name=Pin Bar Pattern |
//| ShortName=PB |
//| Class=CSignalPB |
//| Page= |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| CSignalPB class. |
//| Purpose: Class of trading signal Pin Bar Pattern |
//| It is derived from the CExpertSignalCustom class. |
//+------------------------------------------------------------------+
class CSignalPB : public CExpertSignalCustom
{
protected:
//--- Pattern weights
int m_pattern_0; // Weight for pattern 0, weak
int m_pattern_1; // Weight for pattern 1, moderate
int m_pattern_2; // Weight for pattern 2, strong
public:
CSignalPB();
~CSignalPB();
//--- methods of adjusting "weights" of market models
void Pattern_0(int value) { m_pattern_0 = value; }
void Pattern_1(int value) { m_pattern_1 = value; }
void Pattern_2(int value) { m_pattern_2 = value; }
virtual void ApplyPatternWeight(int patternNumber, int weight);
//--- Methods to generate signals to enter the market
int CalculateConditions(bool isLong);
virtual int LongCondition(void);
virtual int ShortCondition(void);
protected:
};
//+------------------------------------------------------------------+
//| Constructor. |
//+------------------------------------------------------------------+
CSignalPB::CSignalPB() : m_pattern_0(10),
m_pattern_1(20),
m_pattern_2(40)
{
m_id = "PB";
m_pattern_count = 3;
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CSignalPB::~CSignalPB(void)
{
}
//+------------------------------------------------------------------+
//| Common function to calculate conditions |
//+------------------------------------------------------------------+
int CSignalPB::CalculateConditions(bool isLong)
{
int idx = StartIndex(); // Current candle index, usually 0
int prevIdx = idx + 1; // Previous candle index, usually 1
int prevPrevIdx = prevIdx + 1; // Candle before the previous one, usually 2
int result = 0;
int conditionCount = 0;
//--- Preparing the data
double bodySize = fabs(Close(idx) - Open(idx));
double wholeRange = High(idx) - Low(idx);
double wickSize = fmax(High(idx) - fmin(Open(idx), Close(idx)), fmax(Open(idx), Close(idx)) - Low(idx));
// Check if bodySize is zero to prevent division by zero
double wickBodyRatio = (bodySize != 0) ? wickSize / bodySize : 0;
//--- Checking the Pin Bar pattern
// Condition 1: The open and close prices of the Pin Bar should fall within the range of the bars on either side
if((Open(idx) >= Low(prevIdx) && Open(idx) <= High(prevIdx) && Close(idx) >= Low(prevIdx) && Close(idx) <= High(prevIdx)) &&
(Open(idx) >= Low(prevPrevIdx) && Open(idx) <= High(prevPrevIdx) && Close(idx) >= Low(prevPrevIdx) && Close(idx) <= High(prevPrevIdx)))
{
conditionCount++;
}
// Condition 2: The open and close prices of the Pin Bar should be close together
if(bodySize <= wholeRange * 0.2)
{
conditionCount++;
}
// Condition 3: The open and close prices of the Pin Bar should be towards the end of the bar
if(isLong)
{
if((Close(idx) >= Open(idx) && Close(idx) >= High(idx) - (wholeRange * 0.2)) ||
(Open(idx) >= Close(idx) && Open(idx) >= High(idx) - (wholeRange * 0.2)))
{
conditionCount++;
}
}
else
{
if((Close(idx) <= Open(idx) && Close(idx) <= Low(idx) + (wholeRange * 0.2)) ||
(Open(idx) <= Close(idx) && Open(idx) <= Low(idx) + (wholeRange * 0.2)))
{
conditionCount++;
}
}
// Condition 4: Wick-to-body ratio check
if(wickBodyRatio >= 2)
{
conditionCount++;
}
// If all conditions are met, assign Pattern_0
if(conditionCount == 4)
{
result = m_pattern_0;
m_active_pattern = "Pattern_0";
}
return result;
}
//+------------------------------------------------------------------+
//| "Voting" that price will grow. |
//+------------------------------------------------------------------+
int CSignalPB::LongCondition(void)
{
int result = CalculateConditions(true);
if(result != 0)
{
m_active_direction = "Buy";
}
return result;
}
//+------------------------------------------------------------------+
//| "Voting" that price will fall. |
//+------------------------------------------------------------------+
int CSignalPB::ShortCondition(void)
{
int result = CalculateConditions(false);
if(result != 0)
{
m_active_direction = "Sell";
}
return result;
}
//+------------------------------------------------------------------+
//| Set the specified pattern's weight to the specified value |
//+------------------------------------------------------------------+
void CSignalPB::ApplyPatternWeight(int patternNumber, int weight)
{
switch(patternNumber)
{
default:
break;
case 0:
Pattern_0(weight);
break;
case 1:
Pattern_1(weight);
break;
case 2:
Pattern_2(weight);
break;
}
}
//+------------------------------------------------------------------+