165 lines
6.7 KiB
MQL5
165 lines
6.7 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|