ICTLibraryEasy/Examples/Benchmark/OtherCode/Code1.mq5
2026-01-14 07:41:55 -05:00

252 lines
No EOL
8.4 KiB
MQL5

//+------------------------------------------------------------------+
//| Fvg.mq5 |
//| Copyright 2024, rpanchyk |
//| https://github.com/rpanchyk |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, rpanchyk"
#property link "https://github.com/rpanchyk"
#property version "1.03"
#property description "Expert Advisor shows fair value gaps"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "..\\Utils\\MetricSaver.mqh"
// https://github.com/rpanchyk/mt5-fvg-ind/blob/main/MQL5/Indicators/Fvg.mq5 (convertido a EA)
// types
enum ENUM_BORDER_STYLE
{
BORDER_STYLE_SOLID = STYLE_SOLID, // Solid
BORDER_STYLE_DASH = STYLE_DASH // Dash
};
// config
input group "Section :: Main";
input bool InpContinueToMitigation = true; // Continue to mitigation
input group "Section :: Style";
input color InpDownTrendColor = clrLightPink; // Down trend color
input color InpUpTrendColor = clrLightGreen; // Up trend color
input bool InpFill = true; // Fill solid (true) or transparent (false)
input ENUM_BORDER_STYLE InpBoderStyle = BORDER_STYLE_SOLID; // Border line style
input int InpBorderWidth = 2; // Border line width
input group "Section :: Dev";
input bool InpDebugEnabled = false; // Enable debug (verbose logging)
// constants
const string OBJECT_PREFIX = "FVG";
const string OBJECT_PREFIX_CONTINUATED = OBJECT_PREFIX + "CNT";
const string OBJECT_SEP = "#";
// global variables
datetime lastBarTime = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
CMetricsSave::Start(FILE_CODE1);
if(InpDebugEnabled)
{
Print("Fvg expert advisor initialization started");
}
lastBarTime = 0;
if(InpDebugEnabled)
{
Print("Fvg expert advisor initialization finished");
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(InpDebugEnabled)
{
Print("Fvg expert advisor deinitialization started");
}
if(!MQLInfoInteger(MQL_TESTER))
{
ObjectsDeleteAll(0, OBJECT_PREFIX);
}
if(InpDebugEnabled)
{
Print("Fvg expert advisor deinitialization finished");
}
CMetricsSave::Destroy();
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if(lastBarTime == currentBarTime)
{
return;
}
lastBarTime = currentBarTime;
MqlRates rates[];
ArraySetAsSeries(rates, true);
int copied = CopyRates(_Symbol, PERIOD_CURRENT, 0, 100, rates);
if(copied < 3)
{
return;
}
if(InpContinueToMitigation)
{
int total = ObjectsTotal(0, 0, OBJ_RECTANGLE);
for(int i = 0; i < total; i++)
{
string objName = ObjectName(0, i, 0, OBJ_RECTANGLE);
if(StringFind(objName, OBJECT_PREFIX_CONTINUATED) == 0)
{
string result[];
StringSplit(objName, StringGetCharacter(OBJECT_SEP, 0), result);
datetime leftTime = StringToTime(result[1]);
double leftPrice = StringToDouble(result[2]);
datetime rightTime = rates[0].time;
double rightPrice = StringToDouble(result[4]);
if(rightPrice < rates[1].high && rightPrice > rates[1].low)
{
rightTime = rates[1].time;
if(ObjectDelete(0, objName))
{
DrawBox(leftTime, leftPrice, rightTime, rightPrice, false);
}
}
else
{
ObjectMove(0, objName, 1, rightTime, rightPrice);
if(InpDebugEnabled)
{
PrintFormat("Expand box %s", objName);
}
}
}
}
}
int limit = copied - 3;
if(InpDebugEnabled)
{
PrintFormat("Copied: %i, Limit: %i", copied, limit);
}
for(int i = 1; i < limit; i++)
{
double rightHighPrice = rates[i].high;
double rightLowPrice = rates[i].low;
double midHighPrice = rates[i + 1].high;
double midLowPrice = rates[i + 1].low;
double leftHighPrice = rates[i + 2].high;
double leftLowPrice = rates[i + 2].low;
datetime rightTime = rates[i].time;
datetime leftTime = rates[i + 2].time;
// Up trend
bool upLeft = midLowPrice <= leftHighPrice && midLowPrice > leftLowPrice;
bool upRight = midHighPrice >= rightLowPrice && midHighPrice < rightHighPrice;
bool upGap = leftHighPrice < rightLowPrice;
if(upLeft && upRight && upGap)
{
if(InpContinueToMitigation)
{
rightTime = rates[0].time;
for(int j = i - 1; j > 0; j--) // Search mitigation bar
{
if((rightLowPrice < rates[j].high && rightLowPrice >= rates[j].low) || (leftHighPrice > rates[j].low && leftHighPrice <= rates[j].high))
{
rightTime = rates[j].time;
break;
}
}
}
DrawBox(leftTime, leftHighPrice, rightTime, rightLowPrice, InpContinueToMitigation && rightTime == rates[0].time);
continue;
}
// Down trend
bool downLeft = midHighPrice >= leftLowPrice && midHighPrice < leftHighPrice;
bool downRight = midLowPrice <= rightHighPrice && midLowPrice > rightLowPrice;
bool downGap = leftLowPrice > rightHighPrice;
if(downLeft && downRight && downGap)
{
if(InpContinueToMitigation)
{
rightTime = rates[0].time;
for(int j = i - 1; j > 0; j--) // Search mitigation bar
{
if((rightHighPrice <= rates[j].high && rightHighPrice > rates[j].low) || (leftLowPrice >= rates[j].low && leftLowPrice < rates[j].high))
{
rightTime = rates[j].time;
break;
}
}
}
DrawBox(leftTime, leftLowPrice, rightTime, rightHighPrice, InpContinueToMitigation && rightTime == rates[0].time);
continue;
}
}
}
//+------------------------------------------------------------------+
//| Draws FVG box |
//+------------------------------------------------------------------+
void DrawBox(datetime leftDt, double leftPrice, datetime rightDt, double rightPrice, bool continuated)
{
string objName = (continuated ? OBJECT_PREFIX_CONTINUATED : OBJECT_PREFIX)
+ OBJECT_SEP
+ TimeToString(leftDt)
+ OBJECT_SEP
+ DoubleToString(leftPrice)
+ OBJECT_SEP
+ TimeToString(rightDt)
+ OBJECT_SEP
+ DoubleToString(rightPrice);
if(ObjectFind(0, objName) < 0)
{
ObjectCreate(0, objName, OBJ_RECTANGLE, 0, leftDt, leftPrice, rightDt, rightPrice);
ObjectSetInteger(0, objName, OBJPROP_COLOR, leftPrice < rightPrice ? InpUpTrendColor : InpDownTrendColor);
ObjectSetInteger(0, objName, OBJPROP_FILL, InpFill);
ObjectSetInteger(0, objName, OBJPROP_STYLE, InpBoderStyle);
ObjectSetInteger(0, objName, OBJPROP_WIDTH, InpBorderWidth);
ObjectSetInteger(0, objName, OBJPROP_BACK, true);
ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, objName, OBJPROP_SELECTED, false);
ObjectSetInteger(0, objName, OBJPROP_HIDDEN, false);
ObjectSetInteger(0, objName, OBJPROP_ZORDER, 0);
if(InpDebugEnabled)
{
PrintFormat("Draw box: %s", objName);
}
}
}
//+------------------------------------------------------------------+