feat: Fimathe Trend EA v1.00 — Expert Advisor MQL5

EA profissional baseado na Técnica Fimathe de Marcelo Ferreira.
Inclui identificação de tendência (EMA + estrutura), detecção de
pullback em zona Fibonacci (0.618/0.786), gestão de capital por
risco percentual, breakeven e trailing stop automáticos.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
adalbertodasilva2580asf-collab
2026-05-30 08:14:36 -03:00
commit bc6f403b28
3 changed files with 956 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
# MetaTrader 5 compilado
*.ex5
# Arquivos de log e temporários
*.log
*.tmp
Thumbs.db
.DS_Store
+761
View File
@@ -0,0 +1,761 @@
//+------------------------------------------------------------------+
//| Fimathe_Trend_EA.mq5 |
//| Baseado na Técnica Fimathe de Marcelo Ferreira |
//| Expert Advisor para MetaTrader 5 |
//+------------------------------------------------------------------+
#property copyright "Fimathe Trend EA"
#property link ""
#property version "1.00"
#property description "EA profissional baseado na técnica Fimathe de Marcelo Ferreira"
#property strict
/*
================================================================================
CABEÇALHO — REGRAS DA TÉCNICA FIMATHE (Marcelo Ferreira)
================================================================================
FUNDAMENTOS:
┌──────────────────────────────────────────────────────────────────┐
│ 1. TENDÊNCIA É SOBERANA │
│ - Opere SEMPRE a favor da tendência principal (TF superior) │
│ - Alta : sequência de topos e fundos ASCENDENTES │
│ - Baixa : sequência de topos e fundos DESCENDENTES │
│ - Jamais entre contra a tendência principal identificada │
├──────────────────────────────────────────────────────────────────┤
│ 2. ESTRUTURA DE MERCADO (Canais / Zonas) │
│ - Máximas e mínimas recentes formam suportes e resistências │
│ - O preço respeita e reage a estruturas formadas anteriormente │
│ - Breakout confirma novo movimento direcional │
├──────────────────────────────────────────────────────────────────┤
│ 3. CORREÇÕES FIBONACCI │
│ - Após o impulso, aguardar a correção (pullback) │
│ - Níveis principais de entrada: 0.618 e 0.786 │
│ - A correção deve respeitar a estrutura anterior │
│ - Não entrar antes do preço atingir a zona Fibonacci │
├──────────────────────────────────────────────────────────────────┤
│ 4. CONFIRMAÇÃO DE ENTRADA (corpo da vela) │
│ - Aguardar FECHAMENTO do corpo da vela na direção da tendência │
│ - Compra : vela de alta com corpo relevante │
│ - Venda : vela de baixa com corpo relevante │
│ - Evitar doji e velas de indecisão │
├──────────────────────────────────────────────────────────────────┤
│ 5. GESTÃO DE RISCO │
│ - Stop Loss ABAIXO da mínima do pullback (compra) │
│ - Stop Loss ACIMA da máxima do pullback (venda) │
│ - Take Profit em próxima estrutura ou % do capital │
│ - Risco fixo por operação (% do saldo) │
├──────────────────────────────────────────────────────────────────┤
│ 6. HORÁRIO E LIQUIDEZ │
│ - Priorizar horários de maior volume │
│ - Londres : 08h12h | Nova York : 13h17h (hora servidor) │
│ - Evitar entrada em horários de baixo volume │
├──────────────────────────────────────────────────────────────────┤
│ 7. DISCIPLINA OPERACIONAL │
│ - Máximo 1 posição aberta por vez │
│ - Não reentrar em sequência imediata após stop │
│ - Aguardar novo setup completo antes de reentrar │
└──────────────────────────────────────────────────────────────────┘
FLUXO DE DECISÃO:
Tendência TF Superior → Impulso Identificado → Aguardar Pullback
→ Zona Fibonacci (0.618 / 0.786) → Confirmação de Vela → Entrada
→ Gestão com SL estrutural + TP percentual + Trailing/Breakeven
================================================================================
*/
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
//=============================================================================
// INPUTS
//=============================================================================
sinput string sep_cap = "════ GESTÃO DE CAPITAL ════";
input bool UseMoneyMgmt = true; // Usar gestão de capital por risco
input double RiskPercent = 1.0; // % do saldo a arriscar por operação
input double TargetPct = 2.0; // % de lucro alvo por operação
input double LotSize = 0.01; // Lote fixo (se gestão desativada)
sinput string sep_tf = "════ TIMEFRAMES ════";
input ENUM_TIMEFRAMES TrendTF = PERIOD_H1; // Timeframe de identificação da tendência
input ENUM_TIMEFRAMES OperTF = PERIOD_M5; // Timeframe operacional de entrada
sinput string sep_fib = "════ FIBONACCI ════";
input double FibLvl1 = 0.618; // Nível Fibonacci 1 (entrada principal)
input double FibLvl2 = 0.786; // Nível Fibonacci 2 (entrada secundária)
input double FibTolerance = 0.015; // Tolerância da zona Fib (fração do range)
sinput string sep_struct = "════ ESTRUTURA / SETUP ════";
input int StructBars = 35; // Barras para detectar estrutura de swing
input int MinBodyPts = 60; // Pontos mínimos no corpo da vela de conf.
input bool NeedBodyClose = true; // Exigir corpo mínimo na vela de confirmação
sinput string sep_sl = "════ STOP LOSS ════";
input bool UseATR = true; // Calcular SL via ATR
input int ATRPeriod = 14; // Período do ATR
input double ATRMult = 2.0; // Multiplicador do ATR para o SL
input double SLBuffer = 150.0; // Buffer além da estrutura em pontos (sem ATR)
sinput string sep_be = "════ BREAKEVEN / TRAILING ════";
input bool UseBreakEven = true; // Ativar breakeven automático
input double BEPct = 0.5; // % de lucro no saldo para ativar BE
input bool UseTrailing = true; // Ativar trailing stop automático
input double TSPct = 1.0; // % de lucro no saldo para ativar trailing
input double TSPoints = 250.0; // Distância do trailing em pontos
sinput string sep_time = "════ HORÁRIO ════";
input bool UseTimeFilter = true; // Filtrar horário de operação
input int StartHour = 9; // Hora de início (servidor)
input int StartMin = 0; // Minuto de início
input int EndHour = 18; // Hora de fim (servidor)
input int EndMin = 0; // Minuto de fim
input bool CloseAtEnd = false; // Fechar posições ao atingir hora fim
sinput string sep_id = "════ IDENTIFICAÇÃO ════";
input int MagicNumber = 202536; // Número mágico
input string EAComment = "Fimathe Trend EA"; // Comentário nas ordens
//=============================================================================
// ENUMERAÇÕES
//=============================================================================
enum ENUM_FTREND
{
FT_UP = 1, // Tendência de Alta
FT_DOWN = -1, // Tendência de Baixa
FT_NEUTRAL = 0 // Sem tendência definida
};
//=============================================================================
// ESTRUTURA DO SETUP FIMATHE
//=============================================================================
struct SSetup
{
bool valid;
bool isBuy;
double entry;
double sl;
double tp;
double lots;
double swHigh;
double swLow;
double fib618;
double fib786;
};
//=============================================================================
// CLASSE: GERENCIADOR DE TRADES
//=============================================================================
class CManager
{
private:
CTrade m_trade;
CPositionInfo m_pos;
CAccountInfo m_acc;
int m_magic;
string m_sym;
string m_comment;
public:
CManager(int magic, string sym, string comment)
{
m_magic = magic;
m_sym = sym;
m_comment = comment;
m_trade.SetExpertMagicNumber(magic);
m_trade.SetDeviationInPoints(30);
m_trade.SetTypeFilling(ORDER_FILLING_FOK);
m_trade.LogLevel(LOG_LEVEL_ERRORS);
}
bool HasPos(ENUM_POSITION_TYPE type)
{
for(int i = PositionsTotal()-1; i >= 0; i--)
{
if(!m_pos.SelectByIndex(i)) continue;
if(m_pos.Symbol() == m_sym && m_pos.Magic() == m_magic &&
m_pos.PositionType() == type) return true;
}
return false;
}
bool HasAny() { return HasPos(POSITION_TYPE_BUY) || HasPos(POSITION_TYPE_SELL); }
bool Buy(double lots, double sl, double tp)
{
int d = (int)SymbolInfoInteger(m_sym, SYMBOL_DIGITS);
double ask = SymbolInfoDouble(m_sym, SYMBOL_ASK);
bool ok = m_trade.Buy(lots, m_sym, ask, NormalizeDouble(sl,d), NormalizeDouble(tp,d), m_comment);
if(!ok) Print("[Fimathe] BUY falhou: ", m_trade.ResultRetcode(), " - ", m_trade.ResultRetcodeDescription());
else Print("[Fimathe] BUY aberto | Lots=",lots," SL=",NormalizeDouble(sl,d)," TP=",NormalizeDouble(tp,d));
return ok;
}
bool Sell(double lots, double sl, double tp)
{
int d = (int)SymbolInfoInteger(m_sym, SYMBOL_DIGITS);
double bid = SymbolInfoDouble(m_sym, SYMBOL_BID);
bool ok = m_trade.Sell(lots, m_sym, bid, NormalizeDouble(sl,d), NormalizeDouble(tp,d), m_comment);
if(!ok) Print("[Fimathe] SELL falhou: ", m_trade.ResultRetcode(), " - ", m_trade.ResultRetcodeDescription());
else Print("[Fimathe] SELL aberto | Lots=",lots," SL=",NormalizeDouble(sl,d)," TP=",NormalizeDouble(tp,d));
return ok;
}
// Breakeven: move SL para o preço de entrada após X% de lucro no saldo
void DoBreakEven(double actPct)
{
double bal = m_acc.Balance();
if(bal <= 0) return;
int d = (int)SymbolInfoInteger(m_sym, SYMBOL_DIGITS);
double spread = (double)SymbolInfoInteger(m_sym, SYMBOL_SPREAD) * SymbolInfoDouble(m_sym, SYMBOL_POINT);
for(int i = PositionsTotal()-1; i >= 0; i--)
{
if(!m_pos.SelectByIndex(i)) continue;
if(m_pos.Symbol() != m_sym || m_pos.Magic() != m_magic) continue;
if((m_pos.Profit() / bal) * 100.0 < actPct) continue;
double op = m_pos.PriceOpen();
double csl = m_pos.StopLoss();
if(m_pos.PositionType() == POSITION_TYPE_BUY)
{
double nsl = NormalizeDouble(op + spread, d);
if(nsl > csl)
{
if(m_trade.PositionModify(m_pos.Ticket(), nsl, m_pos.TakeProfit()))
Print("[Fimathe] Breakeven BUY ativado | SL=", nsl);
}
}
else
{
double nsl = NormalizeDouble(op - spread, d);
if(csl == 0.0 || nsl < csl)
{
if(m_trade.PositionModify(m_pos.Ticket(), nsl, m_pos.TakeProfit()))
Print("[Fimathe] Breakeven SELL ativado | SL=", nsl);
}
}
}
}
// Trailing stop: segue o preço após X% de lucro no saldo
void DoTrailing(double actPct, double stepPts)
{
double bal = m_acc.Balance();
if(bal <= 0) return;
double pt = SymbolInfoDouble(m_sym, SYMBOL_POINT);
int d = (int)SymbolInfoInteger(m_sym, SYMBOL_DIGITS);
double step = stepPts * pt;
for(int i = PositionsTotal()-1; i >= 0; i--)
{
if(!m_pos.SelectByIndex(i)) continue;
if(m_pos.Symbol() != m_sym || m_pos.Magic() != m_magic) continue;
if((m_pos.Profit() / bal) * 100.0 < actPct) continue;
double csl = m_pos.StopLoss();
if(m_pos.PositionType() == POSITION_TYPE_BUY)
{
double bid = SymbolInfoDouble(m_sym, SYMBOL_BID);
double nsl = NormalizeDouble(bid - step, d);
if(nsl > csl) m_trade.PositionModify(m_pos.Ticket(), nsl, m_pos.TakeProfit());
}
else
{
double ask = SymbolInfoDouble(m_sym, SYMBOL_ASK);
double nsl = NormalizeDouble(ask + step, d);
if(csl == 0.0 || nsl < csl) m_trade.PositionModify(m_pos.Ticket(), nsl, m_pos.TakeProfit());
}
}
}
void CloseAll()
{
for(int i = PositionsTotal()-1; i >= 0; i--)
{
if(!m_pos.SelectByIndex(i)) continue;
if(m_pos.Symbol() == m_sym && m_pos.Magic() == m_magic)
m_trade.PositionClose(m_pos.Ticket());
}
}
};
//=============================================================================
// VARIÁVEIS GLOBAIS
//=============================================================================
CManager* g_mgr = NULL;
CAccountInfo g_acc;
int g_hATR = INVALID_HANDLE;
int g_hEMA20T = INVALID_HANDLE; // EMA 20 no TF de tendência
int g_hEMA50T = INVALID_HANDLE; // EMA 50 no TF de tendência
int g_hEMA200T = INVALID_HANDLE; // EMA 200 no TF de tendência
datetime g_lastBar = 0;
int g_digits = 5;
double g_point = 0.00001;
//=============================================================================
// UTILITÁRIOS
//=============================================================================
bool IsNewBar()
{
datetime t[];
ArraySetAsSeries(t, true);
if(CopyTime(_Symbol, OperTF, 0, 1, t) < 1) return false;
if(t[0] == g_lastBar) return false;
g_lastBar = t[0];
return true;
}
bool InTradingHours()
{
if(!UseTimeFilter) return true;
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
int now = dt.hour * 60 + dt.min;
int start = StartHour * 60 + StartMin;
int end = EndHour * 60 + EndMin;
if(start <= end) return (now >= start && now < end);
return (now >= start || now < end);
}
bool PastEndTime()
{
if(!CloseAtEnd) return false;
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
int now = dt.hour * 60 + dt.min;
int end = EndHour * 60 + EndMin;
return (now >= end);
}
double NormLots(double lots)
{
double mn = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double mx = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double st = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
if(st <= 0) st = 0.01;
lots = MathFloor(lots / st) * st;
return NormalizeDouble(MathMax(mn, MathMin(mx, lots)), 2);
}
// Calcula lote por risco percentual sobre o saldo
double CalcLots(double slDist)
{
if(!UseMoneyMgmt) return NormLots(LotSize);
if(slDist <= 0) return NormLots(LotSize);
double bal = g_acc.Balance();
double risk = bal * (RiskPercent / 100.0);
double ts = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double tv = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
if(ts <= 0 || tv <= 0) return NormLots(LotSize);
double lpl = (slDist / ts) * tv; // perda por lote
if(lpl <= 0) return NormLots(LotSize);
return NormLots(risk / lpl);
}
// Calcula Take Profit baseado em % do saldo para o lote especificado
double CalcTP(double entry, bool buy, double lots)
{
if(lots <= 0) return 0;
double bal = g_acc.Balance();
double target = bal * (TargetPct / 100.0);
double ts = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double tv = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
if(ts <= 0 || tv <= 0) return 0;
double tpDist = (target / (lots * tv)) * ts;
return NormalizeDouble(buy ? entry + tpDist : entry - tpDist, g_digits);
}
double GetATR()
{
double buf[];
ArraySetAsSeries(buf, true);
if(CopyBuffer(g_hATR, 0, 1, 1, buf) < 1) return 0;
return buf[0];
}
//=============================================================================
// IDENTIFICAÇÃO DE TENDÊNCIA (TF Superior)
//=============================================================================
/*
Critérios combinados:
1. Estrutura de topos/fundos (Higher High + Higher Low = alta; Lower High + Lower Low = baixa)
2. Alinhamento das EMAs 20/50/200
Tendência confirmada quando ambos os critérios concordam.
Se apenas estrutura ou apenas EMAs disponíveis, usa o que está disponível.
*/
ENUM_FTREND IdentifyTrend()
{
// --- EMAs ---
double ema20[], ema50[], ema200[];
ArraySetAsSeries(ema20, true);
ArraySetAsSeries(ema50, true);
ArraySetAsSeries(ema200, true);
bool emasOk = (CopyBuffer(g_hEMA20T, 0, 0, 3, ema20) >= 3 &&
CopyBuffer(g_hEMA50T, 0, 0, 3, ema50) >= 3 &&
CopyBuffer(g_hEMA200T, 0, 0, 3, ema200) >= 3);
// --- Dados OHLC do TF de tendência ---
MqlRates tr[];
ArraySetAsSeries(tr, true);
int needed = StructBars + 10;
bool ratesOk = (CopyRates(_Symbol, TrendTF, 0, needed, tr) >= needed);
// --- Análise de estrutura (topos e fundos locais) ---
double h1 = 0, h2 = 0, l1 = DBL_MAX, l2 = DBL_MAX;
int hc = 0, lc = 0;
if(ratesOk)
{
for(int i = 2; i < StructBars - 2; i++)
{
if(hc < 2)
{
if(tr[i].high > tr[i-1].high && tr[i].high > tr[i+1].high &&
tr[i].high > tr[i-2].high && tr[i].high > tr[i+2].high)
{
if(hc == 0) h1 = tr[i].high;
else h2 = tr[i].high;
hc++;
}
}
if(lc < 2)
{
if(tr[i].low < tr[i-1].low && tr[i].low < tr[i+1].low &&
tr[i].low < tr[i-2].low && tr[i].low < tr[i+2].low)
{
if(lc == 0) l1 = tr[i].low;
else l2 = tr[i].low;
lc++;
}
}
if(hc >= 2 && lc >= 2) break;
}
}
bool structUp = (hc >= 2 && lc >= 2 && h1 > h2 && l1 > l2);
bool structDown = (hc >= 2 && lc >= 2 && h1 < h2 && l1 < l2);
bool emaUp = emasOk && (ema20[0] > ema50[0] && ema50[0] > ema200[0]);
bool emaDown = emasOk && (ema20[0] < ema50[0] && ema50[0] < ema200[0]);
// Confirmação forte (estrutura + EMA)
if(structUp && emaUp) return FT_UP;
if(structDown && emaDown) return FT_DOWN;
// Confirmação parcial
if(structUp && !structDown) return FT_UP;
if(structDown && !structUp) return FT_DOWN;
if(emaUp && !emaDown) return FT_UP;
if(emaDown && !emaUp) return FT_DOWN;
return FT_NEUTRAL;
}
//=============================================================================
// DETECÇÃO DO SETUP FIMATHE (Pullback → Fibonacci → Confirmação)
//=============================================================================
/*
COMPRA (uptrend):
- Localizar swing high e swing low recentes no TF operacional
- O swing high deve ser MAIS RECENTE que o swing low (impulso de alta concluído)
- Preço recuou do topo e está na zona Fibonacci (0.6180.786 do range)
- Vela confirmação: bullish, corpo >= MinBodyPts, fechando acima da mínima da zona
- SL: abaixo do swing low + buffer | TP: % do saldo
VENDA (downtrend):
- O swing low deve ser MAIS RECENTE que o swing high (impulso de baixa concluído)
- Preço recuperou do fundo e está na zona Fibonacci (0.6180.786 do range)
- Vela confirmação: bearish, corpo >= MinBodyPts, fechando abaixo do máximo da zona
- SL: acima do swing high + buffer | TP: % do saldo
*/
SSetup DetectSetup(ENUM_FTREND trend)
{
SSetup s;
ZeroMemory(s);
s.valid = false;
if(trend == FT_NEUTRAL) return s;
// Barras do TF operacional (índice 0 = barra em formação, excluída)
MqlRates r[];
ArraySetAsSeries(r, true);
if(CopyRates(_Symbol, OperTF, 0, StructBars + 5, r) < StructBars + 5) return s;
// Localizar swing high e swing low no lookback (barras 1..StructBars)
double swH = 0, swL = DBL_MAX;
int iH = 0, iL = 0;
for(int i = 1; i <= StructBars; i++)
{
if(r[i].high > swH) { swH = r[i].high; iH = i; }
if(r[i].low < swL) { swL = r[i].low; iL = i; }
}
if(swH <= 0 || swL >= DBL_MAX || swH <= swL) return s;
double range = swH - swL;
// Exigir range mínimo de 50 pontos para evitar noise
if(range < 50.0 * g_point) return s;
// Níveis Fibonacci
double fib618_buy = swH - range * FibLvl1; // zona suporte Fib para compra
double fib786_buy = swH - range * FibLvl2;
double fib618_sel = swL + range * FibLvl1; // zona resistência Fib para venda
double fib786_sel = swL + range * FibLvl2;
double tol = range * FibTolerance;
// Vela de confirmação = barra 1 (último candle fechado)
double cClose = r[1].close;
double cOpen = r[1].open;
double body = MathAbs(cClose - cOpen);
bool okBody = (!NeedBodyClose || body >= (double)MinBodyPts * g_point);
double atr = GetATR();
//--- SETUP DE COMPRA ---
// iH < iL: swing high mais recente → impulso de alta concluído, agora em correção
if(trend == FT_UP && iH < iL && iH >= 2)
{
bool inZone = (cClose >= fib786_buy - tol && cClose <= fib618_buy + tol);
bool bullish = (cClose > cOpen); // vela bullish
bool turning = (cClose > r[2].close); // preço retomando a subida
if(inZone && bullish && okBody && turning)
{
s.valid = true;
s.isBuy = true;
s.swHigh = swH;
s.swLow = swL;
s.fib618 = fib618_buy;
s.fib786 = fib786_buy;
s.entry = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
s.sl = UseATR && atr > 0
? s.entry - atr * ATRMult
: swL - SLBuffer * g_point;
s.sl = NormalizeDouble(s.sl, g_digits);
s.lots = CalcLots(s.entry - s.sl);
s.tp = CalcTP(s.entry, true, s.lots);
}
}
//--- SETUP DE VENDA ---
// iL < iH: swing low mais recente → impulso de baixa concluído, agora em correção
if(trend == FT_DOWN && iL < iH && iL >= 2)
{
bool inZone = (cClose <= fib786_sel + tol && cClose >= fib618_sel - tol);
bool bearish = (cClose < cOpen);
bool turning = (cClose < r[2].close);
if(inZone && bearish && okBody && turning)
{
s.valid = true;
s.isBuy = false;
s.swHigh = swH;
s.swLow = swL;
s.fib618 = fib618_sel;
s.fib786 = fib786_sel;
s.entry = SymbolInfoDouble(_Symbol, SYMBOL_BID);
s.sl = UseATR && atr > 0
? s.entry + atr * ATRMult
: swH + SLBuffer * g_point;
s.sl = NormalizeDouble(s.sl, g_digits);
s.lots = CalcLots(s.sl - s.entry);
s.tp = CalcTP(s.entry, false, s.lots);
}
}
return s;
}
//=============================================================================
// EXECUÇÃO DO SETUP
//=============================================================================
void ExecuteSetup(SSetup &s)
{
if(!s.valid || s.lots <= 0) return;
// Verificar distância mínima de stop exigida pelo broker
double minStop = (double)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL)
* SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(s.isBuy)
{
if(g_mgr.HasPos(POSITION_TYPE_BUY))
{ Print("[Fimathe] Já existe BUY aberto. Ignorando."); return; }
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
if(ask - s.sl < minStop)
{ Print("[Fimathe] SL BUY muito próximo. Ignorando."); return; }
s.entry = ask;
s.tp = CalcTP(ask, true, s.lots);
g_mgr.Buy(s.lots, s.sl, s.tp);
}
else
{
if(g_mgr.HasPos(POSITION_TYPE_SELL))
{ Print("[Fimathe] Já existe SELL aberto. Ignorando."); return; }
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(s.sl - bid < minStop)
{ Print("[Fimathe] SL SELL muito próximo. Ignorando."); return; }
s.entry = bid;
s.tp = CalcTP(bid, false, s.lots);
g_mgr.Sell(s.lots, s.sl, s.tp);
}
}
//=============================================================================
// OnInit
//=============================================================================
int OnInit()
{
if(StructBars < 10)
{ Alert("[Fimathe] StructBars deve ser >= 10!"); return INIT_PARAMETERS_INCORRECT; }
if(RiskPercent <= 0 || RiskPercent > 20)
{ Alert("[Fimathe] RiskPercent deve estar entre 0.1 e 20!"); return INIT_PARAMETERS_INCORRECT; }
if(TargetPct <= 0)
{ Alert("[Fimathe] TargetPct deve ser > 0!"); return INIT_PARAMETERS_INCORRECT; }
g_digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
g_point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
g_mgr = new CManager(MagicNumber, _Symbol, EAComment);
if(g_mgr == NULL) { Print("[Fimathe] Falha ao criar CManager!"); return INIT_FAILED; }
g_hEMA20T = iMA(_Symbol, TrendTF, 20, 0, MODE_EMA, PRICE_CLOSE);
g_hEMA50T = iMA(_Symbol, TrendTF, 50, 0, MODE_EMA, PRICE_CLOSE);
g_hEMA200T = iMA(_Symbol, TrendTF, 200, 0, MODE_EMA, PRICE_CLOSE);
g_hATR = iATR(_Symbol, OperTF, ATRPeriod);
if(g_hEMA20T == INVALID_HANDLE || g_hEMA50T == INVALID_HANDLE ||
g_hEMA200T == INVALID_HANDLE || g_hATR == INVALID_HANDLE)
{ Print("[Fimathe] Falha ao criar indicadores!"); return INIT_FAILED; }
Print("════════════════════════════════════════════════");
Print(" Fimathe Trend EA — Iniciado com sucesso!");
Print(" Símbolo : ", _Symbol);
Print(" TF Tendência : ", EnumToString(TrendTF));
Print(" TF Operac. : ", EnumToString(OperTF));
Print(" Gestão Cap. : ", UseMoneyMgmt
? "Sim — Risco=" + DoubleToString(RiskPercent,1) + "% / Alvo=" + DoubleToString(TargetPct,1) + "%"
: "Não — Lote fixo=" + DoubleToString(LotSize,2));
Print(" Fib Levels : ", FibLvl1, " / ", FibLvl2);
Print(" Magic : ", MagicNumber);
Print("════════════════════════════════════════════════");
return INIT_SUCCEEDED;
}
//=============================================================================
// OnDeinit
//=============================================================================
void OnDeinit(const int reason)
{
if(CloseAtEnd && g_mgr != NULL) g_mgr.CloseAll();
if(g_hEMA20T != INVALID_HANDLE) IndicatorRelease(g_hEMA20T);
if(g_hEMA50T != INVALID_HANDLE) IndicatorRelease(g_hEMA50T);
if(g_hEMA200T != INVALID_HANDLE) IndicatorRelease(g_hEMA200T);
if(g_hATR != INVALID_HANDLE) IndicatorRelease(g_hATR);
if(g_mgr != NULL) { delete g_mgr; g_mgr = NULL; }
Comment("");
Print("[Fimathe] EA desativado. Razão: ", reason);
}
//=============================================================================
// OnTick — Lógica principal
//=============================================================================
void OnTick()
{
if(g_mgr == NULL) return;
// Gestão contínua a cada tick (trailing e breakeven)
if(UseBreakEven) g_mgr.DoBreakEven(BEPct);
if(UseTrailing) g_mgr.DoTrailing(TSPct, TSPoints);
// Fechar ao atingir hora fim
if(PastEndTime())
{
g_mgr.CloseAll();
Comment("Fimathe Trend EA | Horário encerrado — posições fechadas");
return;
}
// Processar apenas no fechamento de cada nova barra
if(!IsNewBar()) return;
// Verificar janela de horário
if(!InTradingHours())
{
Comment("Fimathe Trend EA | Fora do horário | ",
StartHour, ":", StringFormat("%02d", StartMin),
" — ", EndHour, ":", StringFormat("%02d", EndMin));
return;
}
// 1) Identificar tendência principal no TF superior
ENUM_FTREND trend = IdentifyTrend();
string tStr = (trend == FT_UP) ? "ALTA ▲" :
(trend == FT_DOWN) ? "BAIXA ▼" : "NEUTRA ●";
if(trend == FT_NEUTRAL)
{
Comment("Fimathe Trend EA | Tendência: NEUTRA — aguardando definição");
return;
}
// 2) Se há posição aberta, apenas gerir (trailing/BE já aplicados acima)
if(g_mgr.HasAny())
{
Comment("Fimathe Trend EA | Tendência: ", tStr, " | Posição aberta — gerenciando");
return;
}
// 3) Detectar setup Fimathe (pullback para zona Fibonacci + confirmação)
SSetup setup = DetectSetup(trend);
if(setup.valid)
{
string dir = setup.isBuy ? "COMPRA ▲" : "VENDA ▼";
Print("[Fimathe] Setup ", dir, " | SwH=", setup.swHigh, " SwL=", setup.swLow,
" | Fib618=", setup.fib618, " Fib786=", setup.fib786,
" | Lots=", setup.lots, " SL=", setup.sl, " TP=", setup.tp);
Comment("Fimathe Trend EA | Tendência: ", tStr, " | Setup ", dir,
" | Lots=", DoubleToString(setup.lots,2),
" SL=", DoubleToString(setup.sl, g_digits),
" TP=", DoubleToString(setup.tp, g_digits));
ExecuteSetup(setup);
}
else
{
Comment("Fimathe Trend EA | Tendência: ", tStr,
" | Aguardando pullback para zona Fibonacci (",
DoubleToString(FibLvl1,3), " / ", DoubleToString(FibLvl2,3), ")...");
}
}
//+------------------------------------------------------------------+
//| FIM — Fimathe Trend EA v1.00 |
//+------------------------------------------------------------------+
+187
View File
@@ -0,0 +1,187 @@
# Fimathe Trend EA
Expert Advisor profissional para MetaTrader 5 baseado na **Técnica Fimathe** de Marcelo Ferreira.
O EA automatiza integralmente o método: identifica a tendência no timeframe superior, aguarda o pullback para a zona de Fibonacci e entra após confirmação de candle — tudo com gestão de capital integrada.
---
## Sumário
- [Como Funciona](#como-funciona)
- [Fluxo de Decisão](#fluxo-de-decisão)
- [Parâmetros de Configuração](#parâmetros-de-configuração)
- [Instalação](#instalação)
- [Requisitos](#requisitos)
- [Aviso Legal](#aviso-legal)
---
## Como Funciona
### Os 7 Pilares da Técnica Fimathe
| # | Pilar | Descrição |
|---|-------|-----------|
| 1 | **Tendência é Soberana** | Opera sempre a favor da tendência principal identificada no TF superior |
| 2 | **Estrutura de Mercado** | Máximas e mínimas recentes formam suportes e resistências que o preço respeita |
| 3 | **Correções Fibonacci** | Após o impulso, aguarda o pullback nas zonas de 61,8% e 78,6% |
| 4 | **Confirmação de Entrada** | Aguarda o fechamento de uma vela na direção da tendência com corpo relevante |
| 5 | **Gestão de Risco** | SL estrutural abaixo/acima do pullback; TP percentual sobre o saldo |
| 6 | **Horário e Liquidez** | Prioriza sessões de Londres (08h12h) e Nova York (13h17h) |
| 7 | **Disciplina Operacional** | Máximo 1 posição aberta; sem reentrada imediata após stop |
### Identificação de Tendência
A tendência é confirmada por dois critérios combinados:
- **Estrutura de mercado**: sequência de topos e fundos ascendentes (alta) ou descendentes (baixa)
- **Alinhamento de EMAs**: EMA 20 > EMA 50 > EMA 200 (alta) ou inverso (baixa)
A confirmação é forte quando ambos concordam; parcial quando apenas um está presente.
### Detecção do Setup
**Compra (uptrend):**
1. Localiza o swing high e swing low recentes no TF operacional
2. O swing high deve ser mais recente que o swing low (impulso de alta concluído)
3. Preço recuou para a zona Fibonacci (entre 61,8% e 78,6% do range)
4. Vela de confirmação: bullish, corpo >= mínimo configurado, fechando acima do mínimo da zona
**Venda (downtrend):**
1. O swing low deve ser mais recente que o swing high (impulso de baixa concluído)
2. Preço recuperou para a zona Fibonacci (61,8%78,6% do range)
3. Vela de confirmação: bearish, corpo >= mínimo configurado, fechando abaixo do máximo da zona
---
## Fluxo de Decisão
```
Tendência TF Superior
Impulso Identificado (Swing High / Swing Low)
Aguardar Pullback para Zona Fibonacci (0.618 / 0.786)
Confirmação de Vela (corpo relevante na direção da tendência)
Abertura da Posição
Gestão: SL estrutural + TP percentual + Trailing + Breakeven
```
---
## Parâmetros de Configuração
### Gestão de Capital
| Parâmetro | Padrão | Descrição |
|-----------|--------|-----------|
| `UseMoneyMgmt` | `true` | Ativa gestão de capital por risco percentual |
| `RiskPercent` | `1.0` | % do saldo a arriscar por operação |
| `TargetPct` | `2.0` | % de lucro alvo por operação |
| `LotSize` | `0.01` | Lote fixo (usado quando `UseMoneyMgmt = false`) |
### Timeframes
| Parâmetro | Padrão | Descrição |
|-----------|--------|-----------|
| `TrendTF` | `H1` | Timeframe para identificação da tendência |
| `OperTF` | `M5` | Timeframe operacional de entrada |
### Fibonacci
| Parâmetro | Padrão | Descrição |
|-----------|--------|-----------|
| `FibLvl1` | `0.618` | Nível Fibonacci principal (61,8%) |
| `FibLvl2` | `0.786` | Nível Fibonacci secundário (78,6%) |
| `FibTolerance` | `0.015` | Tolerância da zona como fração do range |
### Estrutura e Setup
| Parâmetro | Padrão | Descrição |
|-----------|--------|-----------|
| `StructBars` | `35` | Barras para detectar swing high/low |
| `MinBodyPts` | `60` | Pontos mínimos no corpo da vela de confirmação |
| `NeedBodyClose` | `true` | Exige corpo mínimo na vela de confirmação |
### Stop Loss
| Parâmetro | Padrão | Descrição |
|-----------|--------|-----------|
| `UseATR` | `true` | Calcula SL via ATR |
| `ATRPeriod` | `14` | Período do ATR |
| `ATRMult` | `2.0` | Multiplicador do ATR para o SL |
| `SLBuffer` | `150` | Buffer além da estrutura em pontos (sem ATR) |
### Breakeven e Trailing Stop
| Parâmetro | Padrão | Descrição |
|-----------|--------|-----------|
| `UseBreakEven` | `true` | Ativa breakeven automático |
| `BEPct` | `0.5` | % de lucro no saldo para ativar o breakeven |
| `UseTrailing` | `true` | Ativa trailing stop automático |
| `TSPct` | `1.0` | % de lucro no saldo para ativar o trailing |
| `TSPoints` | `250` | Distância do trailing stop em pontos |
### Horário de Operação
| Parâmetro | Padrão | Descrição |
|-----------|--------|-----------|
| `UseTimeFilter` | `true` | Filtra o horário de operação |
| `StartHour` | `9` | Hora de início (horário do servidor) |
| `StartMin` | `0` | Minuto de início |
| `EndHour` | `18` | Hora de fim (horário do servidor) |
| `EndMin` | `0` | Minuto de fim |
| `CloseAtEnd` | `false` | Fecha posições ao atingir a hora de fim |
### Identificação
| Parâmetro | Padrão | Descrição |
|-----------|--------|-----------|
| `MagicNumber` | `202536` | Número mágico para identificar as ordens do EA |
| `EAComment` | `Fimathe Trend EA` | Comentário nas ordens abertas |
---
## Instalação
1. Abra o **MetaEditor** (atalho `F4` no MetaTrader 5)
2. Copie o arquivo `Fimathe_Trend_EA.mq5` para a pasta:
```
[Dados MT5]\MQL5\Experts\
```
Por padrão em Windows:
```
C:\Users\[SeuUsuário]\AppData\Roaming\MetaQuotes\Terminal\[ID]\MQL5\Experts\
```
3. No MetaEditor, abra o arquivo e clique em **Compilar** (`F7`) — o arquivo `.ex5` será gerado automaticamente
4. No MetaTrader 5, vá em **Exibir → Navegador → Expert Advisors**
5. Arraste o `Fimathe_Trend_EA` para o gráfico do ativo desejado
6. Na janela de configuração, ajuste os parâmetros conforme sua estratégia
7. Certifique-se de que o **AutoTrading** está habilitado (botão verde na barra de ferramentas)
---
## Requisitos
- **Plataforma**: MetaTrader 5 (build 3000+)
- **Linguagem**: MQL5
- **Conta**: Real ou Demo com execução automática de ordens habilitada
- **Ativos sugeridos**: Forex, Índices, Commodities com liquidez nas sessões de Londres e Nova York
---
## Aviso Legal
> **Este software é fornecido para fins educacionais e de estudo da Técnica Fimathe.**
>
> Trading automatizado envolve riscos significativos de perda de capital. Resultados passados não garantem resultados futuros. Teste sempre em conta demo antes de operar com capital real. O autor não se responsabiliza por perdas financeiras decorrentes do uso deste software.
>
> A Técnica Fimathe é de autoria de **Marcelo Ferreira**. Este EA é uma implementação técnica independente e não tem vínculo oficial com o autor da técnica.
---
*Fimathe Trend EA v1.00 — MQL5 / MetaTrader 5*