bb_trader2/AbsorbingFinder.mqh
super.admin 82800f3c49 convert
2025-05-30 14:43:19 +02:00

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;
}