PracticeCode/OpencandletehoryEA.mq5

243 lines
15 KiB
MQL5
Raw Permalink Normal View History

2025-11-20 10:14:26 +03:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| One Candle Theory EA.mq5 |
//| Copyright 2025, ElOportunista |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, ElOportunista"
#property link "https://www.mql5.com"
#property version "1.01"
#property link "usen con cuidado"
#include <Trade\Trade.mqh>
input group "Strategy Parameters"
input string InpIndicatorFileName = "OpenCandleTheory"; // Nombre del archivo del indicador (sin .ex5)
input int Maperiod = 20; // EMA Period
input bool Use_MediaMovil = false; // Use EMA Filter
input int MinCandleSize = 200; // Min Candle Size (points)
input double MinPurpleZone = 50; // Min Purple Zone (points)
input double MaxPurpleZonePercent = 80; // Max Purple Zone %
input group "Risk Management"
input double LotSize = 0.1; // Fixed Lot Size
input int ATR_Period = 14; // ATR Period for SL/TP
input double ATR_SL_Multiplier = 1.5; // ATR Multiplier for Stop Loss
input double ATR_TP_Multiplier = 2.0; // ATR Multiplier for Take Profit
input int MagicNumber = 123456; // Magic Number
input group "Trading Time Window"
input int HoraInit = 8; // Start hour
input int HoraEnd = 20; // End hour
//--- Global variables
CTrade trade;
int emaHandle;
int atrHandle;
int indicatorHandle = INVALID_HANDLE; // Handle for the visual indicator
datetime lastProcessedH4 = 0;
double mypoint;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize Point value (handle 3/5 digit brokers)
mypoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(SymbolInfoInteger(_Symbol, SYMBOL_DIGITS) % 2 == 1)
mypoint *= 10;
trade.SetExpertMagicNumber(MagicNumber);
trade.SetTypeFillingBySymbol(_Symbol);
trade.SetDeviationInPoints(10);
indicatorHandle = iCustom(_Symbol, PERIOD_CURRENT, InpIndicatorFileName,
Maperiod, Use_MediaMovil, MinCandleSize, MinPurpleZone, MaxPurpleZonePercent,
true, true, true, 2); // Extra params: ShowAlerts, DrawLevels, See_text, mult
if(indicatorHandle != INVALID_HANDLE)
{
if(!ChartIndicatorAdd(0, 0, indicatorHandle))
{
Print("Warning: Could not add indicator to chart. Error: ", GetLastError());
}
else
{
Print("Indicator added to chart successfully.");
}
}
else
{
Print("Warning: Could not find indicator file '", InpIndicatorFileName, "'. Visuals will not be shown.");
}
if(Use_MediaMovil)
{
emaHandle = iMA(_Symbol, PERIOD_H4, Maperiod, 0, MODE_EMA, PRICE_CLOSE);
if(emaHandle == INVALID_HANDLE)
{
Print("Error creating EMA handle");
return(INIT_FAILED);
}
}
// Initialize ATR for SL/TP (Using H4 to match strategy timeframe)
atrHandle = iATR(_Symbol, PERIOD_H4, ATR_Period);
if(atrHandle == INVALID_HANDLE)
{
Print("Error creating ATR handle");
return(INIT_FAILED);
}
Print("EA Initialized. Strategy: One Candle Theory on H4");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(emaHandle != INVALID_HANDLE) IndicatorRelease(emaHandle);
if(atrHandle != INVALID_HANDLE) IndicatorRelease(atrHandle);
if(indicatorHandle != INVALID_HANDLE)
{
IndicatorRelease(indicatorHandle);
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// --- Trading Time Filter --- //
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
int hour = dt.hour;
if(!(hour >= HoraInit && hour < HoraEnd))
{
return;
}
datetime currentH4Time = iTime(_Symbol, PERIOD_H4, 0);
if(currentH4Time == 0) return; // Data not ready
if(currentH4Time == lastProcessedH4) return;
CheckSignalAndTrade();
lastProcessedH4 = currentH4Time;
}
//+------------------------------------------------------------------+
//| Main Logic Function |
//+------------------------------------------------------------------+
void CheckSignalAndTrade()
{
int total = PositionsTotal();
for(int i = 0; i < total; i++)
{
string sym = PositionGetSymbol(i);
ulong mg = (ulong)PositionGetInteger(POSITION_MAGIC);
if(sym == _Symbol && mg == MagicNumber)
{
Print("Trade already open. No new trades allowed.");
return; //
}
}
double hi = iHigh(_Symbol, PERIOD_H4, 1);
double lo = iLow(_Symbol, PERIOD_H4, 1);
double op = iOpen(_Symbol, PERIOD_H4, 1);
double cl = iClose(_Symbol, PERIOD_H4, 1);
if(hi == 0 || lo == 0) return;
double candlesize = (hi - lo) / mypoint;
double purpleZoneUp = (cl - lo) / mypoint;
double purpleZoneDn = (hi - cl) / mypoint;
if(candlesize < MinCandleSize) return;
bool isBullish = (cl >= op);
double purpleZone = isBullish ? purpleZoneUp : purpleZoneDn;
double purplePercent = (candlesize > 0) ? (purpleZone / candlesize) * 100 : 0;
if(purpleZone < MinPurpleZone || purplePercent > MaxPurpleZonePercent) return;
if(Use_MediaMovil)
{
double ema[];
ArraySetAsSeries(ema, true);
if(CopyBuffer(emaHandle, 0, 1, 1, ema) > 0)
{
if(isBullish && cl < ema[0]) return;
if(!isBullish && cl > ema[0]) return;
}
else return;
}
double atr[];
ArraySetAsSeries(atr, true);
if(CopyBuffer(atrHandle, 0, 1, 1, atr) <= 0)
{
Print("Error copying ATR data");
return;
}
double currentATR = atr[0];
if(isBullish)
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = ask - (currentATR * ATR_SL_Multiplier);
double tp = ask + (currentATR * ATR_TP_Multiplier);
sl = NormalizeDouble(sl, _Digits);
tp = NormalizeDouble(tp, _Digits);
Print("BUY Signal Detected. Opening Trade...");
if(trade.Buy(LotSize, _Symbol, ask, sl, tp, "OCT Buy"))
{
Print("Buy Order Opened. SL: ", sl, " TP: ", tp);
}
else
{
Print("Error opening Buy: ", GetLastError());
}
}
else
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = bid + (currentATR * ATR_SL_Multiplier);
double tp = bid - (currentATR * ATR_TP_Multiplier);
sl = NormalizeDouble(sl, _Digits);
tp = NormalizeDouble(tp, _Digits);
Print("SELL Signal Detected. Opening Trade...");
if(trade.Sell(LotSize, _Symbol, bid, sl, tp, "OCT Sell"))
{
Print("Sell Order Opened. SL: ", sl, " TP: ", tp);
}
else
{
Print("Error opening Sell: ", GetLastError());
}
}
}