240 lines
11 KiB
MQL4
240 lines
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);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|