148 lines
4.9 KiB
Plaintext
148 lines
4.9 KiB
Plaintext
//+------------------------------------------------------------------+
|
||||
|
|
//| Trend.mqh – Step 1: Trend detection via EMA34 & EMA89 |
|
|||
|
|
//| |
|
|||
|
|
//| Logic: |
|
|||
|
|
//| BULLISH: EMA_fast > EMA_slow AND close > EMA_fast |
|
|||
|
|
//| BEARISH: EMA_fast < EMA_slow AND close < EMA_fast |
|
|||
|
|
//| NEUTRAL: otherwise (EMA crossing or price between EMAs) |
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
#ifndef __SIMPLE_FVG_TREND_MQH__
|
|||
|
|
#define __SIMPLE_FVG_TREND_MQH__
|
|||
|
|
|
|||
|
|
#include "Config.mqh"
|
|||
|
|
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
//| Module state |
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
int g_HandleEMAFast = INVALID_HANDLE;
|
|||
|
|
int g_HandleEMASlow = INVALID_HANDLE;
|
|||
|
|
string g_NameEMAFast = "";
|
|||
|
|
string g_NameEMASlow = "";
|
|||
|
|
|
|||
|
|
double g_EMAFastValue = 0.0;
|
|||
|
|
double g_EMASlowValue = 0.0;
|
|||
|
|
ENUM_TREND_DIRECTION g_CurrentTrend = TREND_NEUTRAL;
|
|||
|
|
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
//| Init: create EMA indicator handles and add to chart |
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
bool TrendInit()
|
|||
|
|
{
|
|||
|
|
string symbol = GetTradeSymbol();
|
|||
|
|
|
|||
|
|
g_HandleEMAFast = iMA(symbol, InpTimeframe, InpEMAFastPeriod, 0, MODE_EMA, PRICE_CLOSE);
|
|||
|
|
if(g_HandleEMAFast == INVALID_HANDLE)
|
|||
|
|
{
|
|||
|
|
PrintFormat("[Trend] FAILED to create EMA%d handle", InpEMAFastPeriod);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
g_HandleEMASlow = iMA(symbol, InpTimeframe, InpEMASlowPeriod, 0, MODE_EMA, PRICE_CLOSE);
|
|||
|
|
if(g_HandleEMASlow == INVALID_HANDLE)
|
|||
|
|
{
|
|||
|
|
PrintFormat("[Trend] FAILED to create EMA%d handle", InpEMASlowPeriod);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ChartIndicatorAdd(0, 0, g_HandleEMAFast);
|
|||
|
|
int countAfterFast = ChartIndicatorsTotal(0, 0);
|
|||
|
|
if(countAfterFast > 0)
|
|||
|
|
g_NameEMAFast = ChartIndicatorName(0, 0, countAfterFast - 1);
|
|||
|
|
|
|||
|
|
ChartIndicatorAdd(0, 0, g_HandleEMASlow);
|
|||
|
|
int countAfterSlow = ChartIndicatorsTotal(0, 0);
|
|||
|
|
if(countAfterSlow > 0)
|
|||
|
|
g_NameEMASlow = ChartIndicatorName(0, 0, countAfterSlow - 1);
|
|||
|
|
|
|||
|
|
if(InpDebugLog)
|
|||
|
|
PrintFormat("[Trend] OK – EMA%d + EMA%d on %s %s",
|
|||
|
|
InpEMAFastPeriod, InpEMASlowPeriod,
|
|||
|
|
symbol, EnumToString(InpTimeframe));
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
//| Deinit: release handles and remove from chart |
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
void TrendDeinit()
|
|||
|
|
{
|
|||
|
|
if(g_NameEMAFast != "")
|
|||
|
|
ChartIndicatorDelete(0, 0, g_NameEMAFast);
|
|||
|
|
if(g_NameEMASlow != "")
|
|||
|
|
ChartIndicatorDelete(0, 0, g_NameEMASlow);
|
|||
|
|
|
|||
|
|
if(g_HandleEMAFast != INVALID_HANDLE)
|
|||
|
|
{
|
|||
|
|
IndicatorRelease(g_HandleEMAFast);
|
|||
|
|
g_HandleEMAFast = INVALID_HANDLE;
|
|||
|
|
}
|
|||
|
|
if(g_HandleEMASlow != INVALID_HANDLE)
|
|||
|
|
{
|
|||
|
|
IndicatorRelease(g_HandleEMASlow);
|
|||
|
|
g_HandleEMASlow = INVALID_HANDLE;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
//| Read one EMA value at a given bar shift |
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
double ReadEMA(int handle, int shift)
|
|||
|
|
{
|
|||
|
|
double buffer[1];
|
|||
|
|
if(handle == INVALID_HANDLE) return 0.0;
|
|||
|
|
if(CopyBuffer(handle, 0, shift, 1, buffer) < 1) return 0.0;
|
|||
|
|
return buffer[0];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
//| Update trend direction (call once per new bar) |
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
ENUM_TREND_DIRECTION TrendUpdate()
|
|||
|
|
{
|
|||
|
|
g_EMAFastValue = ReadEMA(g_HandleEMAFast, 1);
|
|||
|
|
g_EMASlowValue = ReadEMA(g_HandleEMASlow, 1);
|
|||
|
|
|
|||
|
|
if(g_EMAFastValue == 0.0 || g_EMASlowValue == 0.0)
|
|||
|
|
{
|
|||
|
|
g_CurrentTrend = TREND_NEUTRAL;
|
|||
|
|
return g_CurrentTrend;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double closePrice = iClose(GetTradeSymbol(), InpTimeframe, 1);
|
|||
|
|
|
|||
|
|
if(g_EMAFastValue > g_EMASlowValue && closePrice > g_EMAFastValue)
|
|||
|
|
g_CurrentTrend = TREND_BULLISH;
|
|||
|
|
else if(g_EMAFastValue < g_EMASlowValue && closePrice < g_EMAFastValue)
|
|||
|
|
g_CurrentTrend = TREND_BEARISH;
|
|||
|
|
else
|
|||
|
|
g_CurrentTrend = TREND_NEUTRAL;
|
|||
|
|
|
|||
|
|
return g_CurrentTrend;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
//| Utility: convert trend enum to readable string |
|
|||
|
|
//+------------------------------------------------------------------+
|
|||
|
|
string TrendToString(ENUM_TREND_DIRECTION trend)
|
|||
|
|
{
|
|||
|
|
switch(trend)
|
|||
|
|
{
|
|||
|
|
case TREND_BULLISH: return "BULLISH";
|
|||
|
|
case TREND_BEARISH: return "BEARISH";
|
|||
|
|
default: return "NEUTRAL";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
color TrendToColor(ENUM_TREND_DIRECTION trend)
|
|||
|
|
{
|
|||
|
|
switch(trend)
|
|||
|
|
{
|
|||
|
|
case TREND_BULLISH: return clrLime;
|
|||
|
|
case TREND_BEARISH: return clrTomato;
|
|||
|
|
default: return clrGray;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif
|