mql5/Include/Mql5Book/ExpertAdvisor.mqh

322 lines
25 KiB
MQL5

2026-03-15 02:48:52 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| ConcreteWebEa.mq5 |
//| Concrete Goonies - https://concrete-goonies.web.app |
//+------------------------------------------------------------------+
#property copyright "Concrete Goonies <00> 2025"
#property link "https://concrete-goonies.web.app"
#property version "1.00"
#include <Mql5Book\TradeHedge.mqh>
#include <Mql5Book\Price.mqh>
#include <Mql5Book\MoneyManagement.mqh>
#include <Mql5Book\TrailingStops.mqh>
#include <Mql5Book\Timer.mqh>
#include <Mql5Book\Indicators.mqh>
#include <WallPaper.mqh>
#include <Arrays\ArrayObj.mqh>
// Callback for notifications
typedef void (*TradeNotificationCallback)(const string &message);
//+------------------------------------------------------------------+
//| EA Config Structure |
//+------------------------------------------------------------------+
struct EAConfig {
string name;
bool enabled;
int tradeDuration;
int tradeCount;
double lotSize;
int stopLoss;
int takeProfit;
ulong magicNumber;
bool allowBuy;
bool allowSell;
bool useMM;
double riskPercent;
bool hidden;
ENUM_TIMEFRAMES timeframe;
};
//+------------------------------------------------------------------+
//| Expert Advisor Class |
//+------------------------------------------------------------------+
class ExpertAdvisor : public CObject {
protected:
EAConfig cfg;
CBars bar;
CTradeHedge trade;
CPositions positions;
CTrailing trail;
CNewBar newBar;
CTimer Timer;
Signal glSignal;
CWallPaper backgroundImage;
ulong glBuyTicket;
ulong glSellTicket;
void GetTickets(bool isBuy);
bool CanOpenPosition(bool isBuy);
void HandleTrade(bool isBuy, double volume, double sl = 0, double tp = 0, string comment = "Concrete Goonies");
public:
TradeNotificationCallback Notify;
ExpertAdvisor(const EAConfig &config) : cfg(config) {
trade.Deviation(0.3);
trade.MagicNumber(cfg.magicNumber);
glSignal = SIGNAL_NONE;
Notify = NULL;
}
~ExpertAdvisor() {}
string GetSymbol() const {
return cfg.name;
}
ulong GetMagic() const {
return cfg.magicNumber;
}
ENUM_TIMEFRAMES GetTimeframe() const {
return cfg.timeframe;
}
EAConfig Config() const {
return cfg;
}
void SetConfig(const EAConfig &newCfg) {
cfg = newCfg;
}
virtual void OnTick();
virtual int OnInit();
virtual void Release();
bool InitBackGround(const string path, const char visibility = 100);
void Resize();
double GetVolume();
void ClosePositions();
bool OnNewBar();
bool IsBullish(int index);
bool IsBearish(int index);
};
//+------------------------------------------------------------------+
//| OnTick implementation |
//+------------------------------------------------------------------+
void ExpertAdvisor::OnTick() {
bar.Update(GetSymbol(), cfg.timeframe);
double volume = GetVolume();
// Update tickets
GetTickets(true);
GetTickets(false);
// Signal execution
if(cfg.enabled) {
if(OnNewBar()) {
ClosePositions();
if(GetSymbol() == "Boom 1000 Index" || GetSymbol() == "Boom 500 Index" || GetSymbol() == "Boom 300 Index") {
if(cfg.allowSell) {
if(IsBullish(3) && IsBearish(2) && IsBearish(1)) {
glSignal = SIGNAL_SELL;
}
} else if(cfg.allowBuy) {
if(IsBullish(3) && IsBearish(2) && IsBearish(1)) {
glSignal = SIGNAL_BUY;
}
}
} else
if(GetSymbol() == "Crash 1000 Index" || GetSymbol() == "Crash 500 Index" || GetSymbol() == "Crash 300 Index") {
if(cfg.allowSell) {
if(IsBearish(3) && IsBullish(2) && IsBullish(1)) {
glSignal = SIGNAL_SELL;
}
} else if(cfg.allowBuy) {
if(IsBearish(3) && IsBullish(2) && IsBullish(1)) {
glSignal = SIGNAL_BUY;
}
}
}
else {
if(IsBearish(3) && IsBullish(2) && IsBullish(1)) {
glSignal = SIGNAL_BUY;
}
if(IsBullish(3) && IsBearish(2) && IsBearish(1)) {
glSignal = SIGNAL_SELL;
}
}
if(glSignal == SIGNAL_BUY && cfg.allowBuy && CanOpenPosition(true))
HandleTrade(true, volume);