223 lines
No EOL
14 KiB
MQL5
223 lines
No EOL
14 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| AbsorbingFinder.mqh |
|
|
//| Copyright 2024, Competent Dilettante |
|
|
//| https://www.youtube.com/@competentdilettante |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2024, Competent Dilettante"
|
|
#property link "https://www.youtube.com/@competentdilettante"
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
int DistPrices(double priceA, double priceB, string symbol = NULL)
|
|
{
|
|
return (int)(::MathAbs(priceA - priceB) / SymbolInfoDouble(symbol,SYMBOL_POINT));
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
bool IsValidData(const int begin,const int end,const int formation)
|
|
{
|
|
|
|
if(begin <= 0) {
|
|
::Print("Все свечи паттерна должны быть полностью сформированы\nТекущая незакрытая свеча не допускается");
|
|
return false;
|
|
}
|
|
if(begin >= end) {
|
|
::Print("Указанные индексы не соответсвуют логике");
|
|
return false;
|
|
}
|
|
if(::MathAbs(end - begin) + 1 < formation) {
|
|
//::Print(end," - ",begin," = ",end - begin);
|
|
::Print("Нехватает свечей для анализа");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
bool IsAbsorbingUp(const string symbol,const ENUM_TIMEFRAMES tf,const int index,double &start,double &stop)
|
|
{
|
|
|
|
int end = index + 1;
|
|
|
|
if(!IsValidData(index,end,2))
|
|
return false;
|
|
|
|
double open,close,preOpen,preClose;
|
|
open = ::iOpen(symbol,tf,index);
|
|
close = ::iClose(symbol,tf,index);
|
|
preOpen = ::iOpen(symbol,tf,end);
|
|
preClose = ::iClose(symbol,tf,end);
|
|
|
|
if(preOpen > preClose && open < close) {
|
|
if(DistPrices(open,close,symbol) > DistPrices(preOpen,preClose,symbol)) {
|
|
if(preOpen <= close && preClose >= open) {
|
|
start = ::iLow(symbol,tf,end);
|
|
stop = ::iHigh(symbol,tf,index);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
bool IsAbsorbingDn(const string symbol,const ENUM_TIMEFRAMES tf,const int index,double &start,double &stop)
|
|
{
|
|
|
|
int end = index + 1;
|
|
|
|
if(!IsValidData(index,end,2))
|
|
return false;
|
|
|
|
double open,close,preOpen,preClose;
|
|
open = ::iOpen(symbol,tf,index);
|
|
close = ::iClose(symbol,tf,index);
|
|
preOpen = ::iOpen(symbol,tf,end);
|
|
preClose = ::iClose(symbol,tf,end);
|
|
|
|
if(preOpen < preClose && open > close) {
|
|
if(DistPrices(open,close,symbol) > DistPrices(preOpen,preClose,symbol)) {
|
|
if(preOpen >= close && preClose <= open) {
|
|
start = ::iHigh(symbol,tf,end);
|
|
stop = ::iLow(symbol,tf,index);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
bool IsDoubleAbsorbingUp(const string symbol,const ENUM_TIMEFRAMES tf,const int index,double &start,double &stop)
|
|
{
|
|
|
|
int end = index + 2;
|
|
|
|
if(!IsValidData(index,end,3))
|
|
return false;
|
|
|
|
double open,close,preOpen,preClose,signalOpen,signalClose;
|
|
open = ::iOpen(symbol,tf,index);
|
|
close = ::iClose(symbol,tf,index);
|
|
preOpen = ::iOpen(symbol,tf,index + 1);
|
|
preClose = ::iClose(symbol,tf,index + 1);
|
|
signalOpen = ::iOpen(symbol,tf,end);
|
|
signalClose = ::iClose(symbol,tf,end);
|
|
|
|
if(signalOpen > signalClose && preOpen < preClose && open < close && preClose < signalOpen) {
|
|
if(DistPrices(preOpen,close,symbol) > DistPrices(signalOpen,signalClose,symbol)) {
|
|
if(signalOpen <= close && signalClose >= preOpen) {
|
|
start = ::iLow(symbol,tf,end);
|
|
stop = ::iHigh(symbol,tf,index);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
bool IsTripleAbsorbingUp(const string symbol,const ENUM_TIMEFRAMES tf,const int index,double &start,double &stop)
|
|
{
|
|
|
|
int end = index + 3;
|
|
|
|
if(!IsValidData(index,end,4))
|
|
return false;
|
|
|
|
double open,close,preOpen,preClose,signalOpen,signalClose,prePreOpen,prePreClose;
|
|
open = ::iOpen(symbol,tf,index);
|
|
close = ::iClose(symbol,tf,index);
|
|
preOpen = ::iOpen(symbol,tf,index + 1);
|
|
preClose = ::iClose(symbol,tf,index + 1);
|
|
prePreOpen = ::iOpen(symbol,tf,index + 2);
|
|
prePreClose = ::iClose(symbol,tf,index + 2);
|
|
signalOpen = ::iOpen(symbol,tf,end);
|
|
signalClose = ::iClose(symbol,tf,end);
|
|
|
|
if(signalOpen > signalClose && preOpen < preClose && prePreOpen < prePreClose && open < close
|
|
&& preClose < signalOpen && prePreClose < signalOpen) {
|
|
if(DistPrices(prePreOpen,close,symbol) > DistPrices(signalOpen,signalClose,symbol)) {
|
|
if(signalOpen <= close && signalClose >= preOpen) {
|
|
start = ::iLow(symbol,tf,end);
|
|
stop = ::iHigh(symbol,tf,index);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
bool IsDoubleAbsorbingDn(const string symbol,const ENUM_TIMEFRAMES tf,const int index,double &start,double &stop)
|
|
{
|
|
|
|
int end = index + 2;
|
|
|
|
if(!IsValidData(index,end,3))
|
|
return false;
|
|
|
|
double open,close,preOpen,preClose,signalOpen,signalClose;
|
|
open = ::iOpen(symbol,tf,index);
|
|
close = ::iClose(symbol,tf,index);
|
|
preOpen = ::iOpen(symbol,tf,index + 1);
|
|
preClose = ::iClose(symbol,tf,index + 1);
|
|
signalOpen = ::iOpen(symbol,tf,end);
|
|
signalClose = ::iClose(symbol,tf,end);
|
|
|
|
if(signalOpen < signalClose && preOpen > preClose && open > close && preClose > signalOpen) {
|
|
if(DistPrices(preOpen,close,symbol) > DistPrices(signalOpen,signalClose,symbol)) {
|
|
if(signalOpen >= close && signalClose <= preOpen) {
|
|
start = ::iHigh(symbol,tf,end);
|
|
stop = ::iLow(symbol,tf,index);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
bool IsTripleAbsorbingDn(const string symbol,const ENUM_TIMEFRAMES tf,const int index,double &start,double &stop)
|
|
{
|
|
|
|
int end = index + 3;
|
|
|
|
if(!IsValidData(index,end,4))
|
|
return false;
|
|
|
|
double open,close,preOpen,preClose,signalOpen,signalClose,prePreOpen,prePreClose;
|
|
open = ::iOpen(symbol,tf,index);
|
|
close = ::iClose(symbol,tf,index);
|
|
preOpen = ::iOpen(symbol,tf,index + 1);
|
|
preClose = ::iClose(symbol,tf,index + 1);
|
|
prePreOpen = ::iOpen(symbol,tf,index + 2);
|
|
prePreClose = ::iClose(symbol,tf,index + 2);
|
|
signalOpen = ::iOpen(symbol,tf,end);
|
|
signalClose = ::iClose(symbol,tf,end);
|
|
|
|
if(signalOpen < signalClose && preOpen > preClose && prePreOpen > prePreClose && open > close
|
|
&& preClose > signalOpen && prePreClose > preOpen) {
|
|
if(DistPrices(prePreOpen,close,symbol) > DistPrices(signalOpen,signalClose,symbol)) {
|
|
if(signalOpen >= close && signalClose <= preOpen) {
|
|
start = ::iLow(symbol,tf,end);
|
|
stop = ::iHigh(symbol,tf,index);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
} |