135 lines
4.7 KiB
Plaintext
135 lines
4.7 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| MadTurtle_MTF.mqh - Multi-Timeframe confirmation filters |
|
|
//+------------------------------------------------------------------+
|
|
#ifndef MADTURTLE_MTF
|
|
#define MADTURTLE_MTF
|
|
|
|
struct MadTurtleMTFState {
|
|
double h4_sma_fast;
|
|
double h4_sma_slow;
|
|
double h4_rsi;
|
|
double h4_macd;
|
|
double h4_volume_ratio;
|
|
ENUM_ORDER_TYPE h4_bias;
|
|
|
|
double d1_sma_fast;
|
|
double d1_sma_slow;
|
|
double d1_rsi;
|
|
double d1_volume_ratio;
|
|
ENUM_ORDER_TYPE d1_bias;
|
|
|
|
datetime h4_updated;
|
|
datetime d1_updated;
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Indicator value helpers (MQL5 handle + CopyBuffer) |
|
|
//+------------------------------------------------------------------+
|
|
double MadTurtle_GetMA(ENUM_TIMEFRAMES tf, int period, int shift)
|
|
{
|
|
int h = iMA(_Symbol, tf, period, 0, MODE_SMA, PRICE_CLOSE);
|
|
if(h == INVALID_HANDLE) return 0;
|
|
double buf[];
|
|
if(CopyBuffer(h, 0, shift, 1, buf) != 1) { IndicatorRelease(h); return 0; }
|
|
IndicatorRelease(h);
|
|
return buf[0];
|
|
}
|
|
|
|
double MadTurtle_GetRSI(ENUM_TIMEFRAMES tf, int period, int shift)
|
|
{
|
|
int h = iRSI(_Symbol, tf, period, PRICE_CLOSE);
|
|
if(h == INVALID_HANDLE) return 0;
|
|
double buf[];
|
|
if(CopyBuffer(h, 0, shift, 1, buf) != 1) { IndicatorRelease(h); return 0; }
|
|
IndicatorRelease(h);
|
|
return buf[0];
|
|
}
|
|
|
|
double MadTurtle_GetATR(ENUM_TIMEFRAMES tf, int period, int shift)
|
|
{
|
|
int h = iATR(_Symbol, tf, period);
|
|
if(h == INVALID_HANDLE) return 0;
|
|
double buf[];
|
|
if(CopyBuffer(h, 0, shift, 1, buf) != 1) { IndicatorRelease(h); return 0; }
|
|
IndicatorRelease(h);
|
|
return buf[0];
|
|
}
|
|
|
|
double MadTurtle_GetMACD(ENUM_TIMEFRAMES tf, int fast, int slow, int signal, int shift)
|
|
{
|
|
int h = iMACD(_Symbol, tf, fast, slow, signal, PRICE_CLOSE);
|
|
if(h == INVALID_HANDLE) return 0;
|
|
double buf[];
|
|
if(CopyBuffer(h, 0, shift, 1, buf) != 1) { IndicatorRelease(h); return 0; }
|
|
IndicatorRelease(h);
|
|
return buf[0];
|
|
}
|
|
|
|
double MadTurtle_GetVolume(ENUM_TIMEFRAMES tf, int shift)
|
|
{
|
|
long vol = iVolume(_Symbol, tf, shift);
|
|
return (double)vol;
|
|
}
|
|
|
|
ENUM_ORDER_TYPE MadTurtle_MTF_BiasFromSMA(double sma_fast, double sma_slow)
|
|
{
|
|
if(sma_fast > sma_slow && sma_fast > 0 && sma_slow > 0) return ORDER_TYPE_BUY;
|
|
if(sma_fast < sma_slow && sma_fast > 0 && sma_slow > 0) return ORDER_TYPE_SELL;
|
|
return -1;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update multi-timeframe state |
|
|
//+------------------------------------------------------------------+
|
|
void MadTurtle_UpdateMTFState(MadTurtleMTFState &state)
|
|
{
|
|
datetime now = TimeCurrent();
|
|
|
|
if(now - state.h4_updated >= 60) {
|
|
state.h4_sma_fast = MadTurtle_GetMA(PERIOD_H4, 10, 1);
|
|
state.h4_sma_slow = MadTurtle_GetMA(PERIOD_H4, 50, 1);
|
|
state.h4_rsi = MadTurtle_GetRSI(PERIOD_H4, 14, 1);
|
|
state.h4_macd = MadTurtle_GetMACD(PERIOD_H4, 12, 26, 9, 1);
|
|
state.h4_volume_ratio = MadTurtle_GetVolume(PERIOD_H4, 1);
|
|
state.h4_bias = MadTurtle_MTF_BiasFromSMA(state.h4_sma_fast, state.h4_sma_slow);
|
|
state.h4_updated = now;
|
|
}
|
|
|
|
if(now - state.d1_updated >= 60) {
|
|
state.d1_sma_fast = MadTurtle_GetMA(PERIOD_D1, 10, 1);
|
|
state.d1_sma_slow = MadTurtle_GetMA(PERIOD_D1, 50, 1);
|
|
state.d1_rsi = MadTurtle_GetRSI(PERIOD_D1, 14, 1);
|
|
state.d1_volume_ratio = MadTurtle_GetVolume(PERIOD_D1, 1);
|
|
state.d1_bias = MadTurtle_MTF_BiasFromSMA(state.d1_sma_fast, state.d1_sma_slow);
|
|
state.d1_updated = now;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check if MTF confirmation allows a BUY |
|
|
//+------------------------------------------------------------------+
|
|
bool MadTurtle_MTF_ConfirmBuy(const MadTurtleMTFState &state)
|
|
{
|
|
if(state.h4_bias != ORDER_TYPE_BUY) return false;
|
|
if(state.d1_bias == ORDER_TYPE_SELL) return false;
|
|
if(state.h4_rsi > 75.0) return false;
|
|
if(state.d1_rsi > 75.0) return false;
|
|
if(state.h4_macd < 0 && state.d1_sma_fast < state.d1_sma_slow) return false;
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check if MTF confirmation allows a SELL |
|
|
//+------------------------------------------------------------------+
|
|
bool MadTurtle_MTF_ConfirmSell(const MadTurtleMTFState &state)
|
|
{
|
|
if(state.h4_bias != ORDER_TYPE_SELL) return false;
|
|
if(state.d1_bias == ORDER_TYPE_BUY) return false;
|
|
if(state.h4_rsi < 25.0) return false;
|
|
if(state.d1_rsi < 25.0) return false;
|
|
if(state.h4_macd > 0 && state.d1_sma_fast > state.d1_sma_slow) return false;
|
|
return true;
|
|
}
|
|
|
|
#endif // MADTURTLE_MTF
|