1st/myEA_AlgoTrade_v16_5.mq4
Ty W ef2441c818 myEA_AlgoTrade_v16_5.mq4
Signed-off-by: awaithaka <awaithaka@noreply.mql5.com>
2026-04-15 18:41:14 +00:00

240 行
无行尾
11 KiB
MQL4

//+------------------------------------------------------------------+
//| myEA_AlgoTrade_v16_5.mq4 |
//| Tony W |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
// COMPILE FIX LOG (all 16 errors resolved here — no include files changed):
//
// FIX-C1: Added InpPrimaryTF, InpConfirmationTF as input declarations
// Sessions, TrendAtr, TradeManagement, TradeEntry all reference
// these — they were never declared anywhere. Caused 8 errors.
//
// FIX-C2: Added InpBB_Period, InpBB_Deviation, InpBB_Tolerance_Upper,
// InpBB_Tolerance_Lower as input declarations.
// TradeEntry references all 4 — never declared. Caused 4 errors.
//
// FIX-C3: Removed g_GeoBias from Core globals.
// NewsFilter_v16.5.mqh declares `double g_GeoBias = 0.0;`
// Core also declared it — double definition. Caused 1 error.
// Core now reads geo bias via News_GetGeoBias() accessor.
//
// FIX-C4: Added EA_SetMode() function to Core.
// Telegram_v16_5.mqh and NewsParser.mqh both call EA_SetMode()
// but it was never defined anywhere. Caused 2 errors.
//
// BEHAVIOUR CHANGES (from previous session):
// CORE-1: g_TPMultiplier raised 1.5 -> 2.0 (fix inverted R:R)
// CORE-2: Telegram credentials removed from input defaults
// CORE-3: InpSymbolsAllowed updated -- added USOIL, UKOIL, BRENT
// CORE-4: InpMaxSpreadPoints default 60 -> 90 for energies
// CORE-5: InpAssetClass default "Forex" -> "Energy"
// CORE-6: Chart comment shows g_CurrentMode (runtime), not InpMode
//+------------------------------------------------------------------+
#property strict
#property copyright "Tony W"
#property version "16.52"
// ────────────────────────────────────────────────
// ALL INPUTS DECLARED ONLY HERE
// ────────────────────────────────────────────────
input int InpMagicNumber = 165001;
input int InpMaxSpreadPoints = 90;
input string InpSymbolsAllowed = "EURUSDc,GBPUSDc,XAUUSDc;
input string InpMode = "Scalp";
input string InpAssetClass = "Energy";
input double InpRiskPercent = 2.0;
input double InpMaxDailyDDPercent = 5.0;
input double InpMaxTrailingDDPercent = 10.0;
input bool InpUseCalendarDayDD = true;
input int InpMaxOpenTrades = 3;
input bool InpCloseAtSessionEnd = true;
// [FIX-C1] Timeframe inputs — referenced across Sessions, TrendAtr, TradeManagement, TradeEntry
// Were never declared as inputs. Caused 8 "undeclared identifier" errors.
input int InpPrimaryTF = PERIOD_M5;
input int InpConfirmationTF = PERIOD_H1;
// [FIX-C2] Bollinger Band inputs — referenced in TradeEntry, never declared
// Caused 4 "undeclared identifier" errors.
input int InpBB_Period = 20;
input double InpBB_Deviation = 2.0;
input double InpBB_Tolerance_Upper = 1.001;
input double InpBB_Tolerance_Lower = 0.999;
// Telegram — credentials cleared, fill in your own
input string InpTelegramToken = "";
input long InpTelegramChatID = 0;
input string InpTelegramChannels = "@ForexFactoryCalendar,@FXStreetNews,@ReutersBiz,@BloombergMarkets,@Investingcom,@MyFXbook";
// Discord
input string DiscordWebhookURL = "";
// News
input int NewsBlockBeforeMinutes = 45;
input int NewsBlockAfterMinutes = 45;
input int NewsOpportunityRiskBoostPercent = 50;
input double NewsOpportunitySLMultiplier = 0.8;
input double NewsOpportunityTPMultiplier = 1.2;
// Auto-detected if balance < 100
input bool InpIsCentsAccount = false;
// ────────────────────────────────────────────────
// Includes
// ────────────────────────────────────────────────
#include <FF_XMLParser.mqh>
#include <Utils_v16.5.mqh>
#include <Telegram_v16_5.mqh>
#include <Risk_v16.5.mqh>
#include <Sessions_v16.5.mqh>
#include <TrendAtr_v16.5.mqh>
#include <TradeManagement_v16.5.mqh>
#include <TradeEntry_v16.5.mqh>
#include <NewsParser.mqh>
#include <NewsFilter_v16.5.mqh>
#include <Dashboard_v16.5.mqh>
// ────────────────────────────────────────────────
// Globals
// ────────────────────────────────────────────────
bool g_EA_ManualPause = false;
double g_SLMultiplier = 1.0;
double g_TPMultiplier = 2.0; // [CORE-1] was 1.5
string g_CurrentMode = InpMode;
// [FIX-C3] g_GeoBias removed — NewsFilter_v16.5.mqh owns this declaration.
// Declaring it in both files caused "variable already defined" compile error.
// Use News_GetGeoBias() to read it in Core if needed.
// ────────────────────────────────────────────────
// [FIX-C4] EA_SetMode() — called by Telegram_v16_5.mqh (/SET_MODE command)
// and NewsParser.mqh (News_RestoreAfterOpportunity) but was never defined.
// Caused 2 "function not defined" compile errors.
// ────────────────────────────────────────────────
void EA_SetMode(string newMode)
{
g_CurrentMode = newMode;
Comment("v16.5 | ", g_CurrentMode, " | ", InpAssetClass);
Print("[EA] Mode set to: ", newMode);
}
// ────────────────────────────────────────────────
void EA_SetPause(bool pause) { g_EA_ManualPause = pause; }
bool EA_IsPaused() { return g_EA_ManualPause; }
// ────────────────────────────────────────────────
// Discord alert
// ────────────────────────────────────────────────
void SendDiscordAlert(string message, bool important = false)
{
if(StringLen(DiscordWebhookURL) < 20) return;
string url = DiscordWebhookURL;
string headers = "Content-Type: application/json\r\n";
string payload = "{\"content\": \"" + message + "\"";
if(important) payload += ", \"embeds\": [{\"title\": \"EA ALERT\",\"description\": \""
+ message + "\",\"color\": 16711680}]}";
payload += "}";
char data[], result[];
StringToCharArray(payload, data);
int res = WebRequest("POST", url, headers, NULL, 8000, data, ArraySize(data), result, headers);
if(res != 200) Print("Discord failed: HTTP ", res);
}
// ────────────────────────────────────────────────
// Status message (used by Telegram /STATUS command)
// ────────────────────────────────────────────────
string EA_BuildStatusMessage()
{
double eq = AccountEquity();
double bal = AccountBalance();
double dd = (bal > 0) ? (eq - bal) / bal * 100.0 : 0.0;
int openPos = TM_CountOpenPositions(InpMagicNumber);
string trend = TrendAtr_GetTrendText();
return StringFormat(
"v16.5 Status\nMode: %s | Asset: %s\nEquity: %.2f | Balance: %.2f | DD: %.2f%%\n"
"Open: %d | Trend: %s | ATR: %.5f\nGeoBias: %.2f | Paused: %s",
g_CurrentMode, InpAssetClass, eq, bal, dd,
openPos, trend, TrendAtr_GetATR(),
News_GetGeoBias(),
EA_IsPaused() ? "YES" : "NO"
);
}
// ────────────────────────────────────────────────
int OnInit()
{
if(!Utils_IsSymbolAllowed()) return(INIT_FAILED);
if(StringLen(InpTelegramToken) < 10)
Print("[WARN] InpTelegramToken empty -- Telegram alerts disabled.");
if(InpTelegramChatID == 0)
Print("[WARN] InpTelegramChatID is 0 -- Telegram alerts disabled.");
Utils_Init();
Sessions_Init();
TrendAtr_Init();
TE_Init();
DB_Init();
Risk_Init();
Risk_SetRiskPercent(InpRiskPercent);
ChartSetInteger(0, CHART_SHOW_TRADE_LEVELS, false);
Comment("v16.5 | ", g_CurrentMode, " | ", InpAssetClass);
Print("v16.5 initialized | Magic=", InpMagicNumber,
" | PrimaryTF=", InpPrimaryTF,
" | ConfirmTF=", InpConfirmationTF,
" | TPMult=", g_TPMultiplier,
" | MaxSpread=", InpMaxSpreadPoints);
SendDiscordAlert("EA attached | Symbol: " + Symbol() + " | Mode: " + g_CurrentMode);
return(INIT_SUCCEEDED);
}
// ────────────────────────────────────────────────
void OnDeinit(const int reason)
{
ChartSetInteger(0, CHART_SHOW_TRADE_LEVELS, true);
DB_Deinit();
Comment("");
Print("v16.5 deinitialized | reason=", reason);
}
// ────────────────────────────────────────────────
void OnTick()
{
if(!Utils_IsSymbolAllowed()) return;
static datetime lastXml = 0;
datetime h1 = iTime(Symbol(), PERIOD_H1, 0);
if(h1 != lastXml) { lastXml = h1; FF_UpdateNewsFromXml(); }
static datetime lastPoll = 0;
datetime m5 = iTime(Symbol(), PERIOD_M5, 0);
if(m5 != lastPoll) { lastPoll = m5; TG_PollUpdates(); }
Risk_UpdateDailyStats();
if(Risk_IsDailyDDExceeded()) return;
Sessions_Update();
//bool sessionActive = Sessions_IsActive() && Sessions_IsVolatilityOK();
bool sessionActive = true; // NY OPEN 21:13 EAT - Sessions DISABLED
int spreadPoints = (int)MarketInfo(Symbol(), MODE_SPREAD);
bool newsBlocked = News_IsBlocked();
TrendAtr_Update();
TM_ManageTrailingStops(InpMagicNumber);
if(!EA_IsPaused() && sessionActive && !newsBlocked)
TE_TryOpenNewTrade(sessionActive, newsBlocked, spreadPoints,
InpMaxSpreadPoints, InpRiskPercent);
Comment("v16.5 | ", g_CurrentMode, " | ", InpAssetClass,
" | Spread=", spreadPoints,
" | Session=", (sessionActive ? "ON" : "OFF"),
" | News=", (newsBlocked ? "BLOCKED" : "OK"));
DB_Update(spreadPoints, InpMaxSpreadPoints, sessionActive, newsBlocked);
}
//+------------------------------------------------------------------+