forked from Princeec13/mql5
1265 lines
44 KiB
MQL5
1265 lines
44 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| EscapeEA_Enhanced.mq5 |
|
|
//| Copyright 2025, EscapeEA |
|
|
//| https://www.escapeea.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, EscapeEA"
|
|
#property link "https://www.escapeea.com"
|
|
#property version "3.01" // Updated version with integrated components
|
|
#property strict
|
|
|
|
// +------------------------------------------------------------------+
|
|
// | SecurityEnhancements.mqh inputs migrated to main EA |
|
|
// +------------------------------------------------------------------+
|
|
input group "=== News Filter Settings ==="
|
|
input bool InpEnableNewsFilter = true; // Enable news event filtering
|
|
input string InpAffectedSymbols = ""; // Comma-separated list of symbols affected by news (empty = all)
|
|
input datetime InpNewsStartTime = 0; // Start time of news blackout period
|
|
input datetime InpNewsEndTime = 0; // End time of news blackout period
|
|
|
|
input group "=== Rate Limiting ==="
|
|
input bool InpEnableRateLimiting = true; // Enable rate limiting
|
|
input int InpMaxTradesPerMinute = 5; // Maximum trades per minute
|
|
|
|
input group "=== Price Validation ==="
|
|
input bool InpValidatePrices = true; // Enable price validation
|
|
input int InpMaxPriceDeviation = 10; // Maximum price deviation in points
|
|
input int InpMaxSlippage = 3; // Maximum allowed slippage in points
|
|
|
|
input group "=== Anomaly Detection ==="
|
|
input bool InpEnableAnomalyDetection = true; // Enable anomaly detection
|
|
input int InpMaxAnomalyCount = 3; // Maximum allowed anomalies before blocking
|
|
|
|
/**
|
|
* @file EscapeEA_Enhanced.mq5
|
|
* @brief Advanced Expert Advisor with integrated Paper Trading and Security
|
|
*
|
|
* This EA implements a sophisticated trading strategy with the following features:
|
|
* - Multi-timeframe analysis using moving averages
|
|
* - Advanced paper trading simulation with win requirement for live trading
|
|
* - Comprehensive risk management with position sizing
|
|
* - Secure trade execution with circuit breaker protection
|
|
* - Real-time adaptive learning from trade outcomes
|
|
* - Visual feedback for paper and live trades
|
|
*
|
|
* @see PaperTrading.mqh For paper trading simulation
|
|
* @see TradeExecutor.mqh For trade execution details
|
|
* @see RiskManager.mqh For risk management
|
|
* @see EnhancedSecurity.mqh For security features
|
|
*/
|
|
|
|
//--- Required Includes
|
|
#include <Trade\PositionInfo.mqh>
|
|
#include <Trade\SymbolInfo.mqh>
|
|
#include <Trade\DealInfo.mqh>
|
|
#include <Trade\Trade.mqh>
|
|
#include <Arrays\ArrayObj.mqh>
|
|
|
|
// Include our custom security components
|
|
#include <Escape/SecureMemory.mqh>
|
|
#include <Escape/InputValidation.mqh>
|
|
#include <Escape/SecurityManager.mqh>
|
|
|
|
// News Impact Analysis System
|
|
#include <Escape/MarketAnalyzer.mqh>
|
|
#include <Escape/NewsFeedHandler.mqh>
|
|
#include <Escape/VolatilityManager.mqh>
|
|
|
|
// Forward declarations for our custom components
|
|
class CRiskManager;
|
|
class CTradeExecutor;
|
|
class CPaperTrading;
|
|
class CEnhancedSecurity;
|
|
class CSignalGenerator;
|
|
class CPositionManager;
|
|
class CSecurityManager;
|
|
class CConfigManager;
|
|
|
|
// Include our custom components from Include/Escape directory
|
|
#include <Escape/RiskManager.mqh>
|
|
#include <Escape/TradeExecutor.mqh>
|
|
#include <Escape/PaperTrading.mqh>
|
|
#include <Escape/EnhancedSecurity.mqh>
|
|
#include <Escape/SignalGenerator.mqh>
|
|
#include <Escape/PositionManager.mqh>
|
|
|
|
// Include security components
|
|
#include <Escape/RAII.mqh>
|
|
#include <Escape/ConfigManager.mqh>
|
|
|
|
//--- Constants
|
|
#define EXPERT_NAME "EscapeEA_Enhanced"
|
|
#define EXPERT_VERSION "3.01"
|
|
|
|
//--- Enums
|
|
enum ENUM_TRADE_MODE {
|
|
TRADE_MODE_PAPER, // Paper trading only
|
|
TRADE_MODE_LIVE, // Live trading only
|
|
TRADE_MODE_BOTH // Both paper and live
|
|
};
|
|
|
|
// Scaling profiles for position management
|
|
enum ENUM_SCALING_PROFILE {
|
|
SCALING_NONE, // No scaling
|
|
SCALING_CONSERVATIVE, // Conservative scaling
|
|
SCALING_MODERATE, // Moderate scaling
|
|
SCALING_AGGRESSIVE // Aggressive scaling
|
|
};
|
|
|
|
// Exit profiles for position management
|
|
enum ENUM_EXIT_PROFILE {
|
|
EXIT_AGGRESSIVE, // Aggressive exit (tighter stops)
|
|
EXIT_BALANCED, // Balanced exit
|
|
EXIT_CONSERVATIVE // Conservative exit (wider stops)
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Global Variables and Input Parameters |
|
|
//+------------------------------------------------------------------+
|
|
|
|
//--- Trading Components
|
|
CPositionInfo ExtPosition; // Position info object
|
|
CSymbolInfo ExtSymbol; // Symbol info object
|
|
CAccountInfo ExtAccount; // Account info object
|
|
CDealInfo ExtDeal; // Deal info object
|
|
CTrade* ExtTrade = NULL; // Trade object
|
|
CTradeExecutor* ExtTradeExecutor = NULL; // Trade executor
|
|
CRiskManager* ExtRiskManager = NULL; // Risk manager
|
|
CPositionManager* ExtPositionManager = NULL; // Position manager
|
|
CPaperTrading* ExtPaperTrading = NULL; // Paper trading system
|
|
CSignalGenerator* ExtSignalGenerator = NULL; // Signal generator
|
|
CEnhancedSecurity* ExtSecurity = NULL; // Security manager
|
|
CConfigManager* ExtConfig = NULL; // Configuration manager
|
|
|
|
//--- News Impact Analysis System
|
|
CVolatilityManager* ExtVolatilityManager = NULL; // Volatility manager
|
|
CNewsFeedHandler* ExtNewsHandler = NULL; // News feed handler
|
|
CMarketAnalyzer* ExtMarketAnalyzer = NULL; // Market analyzer
|
|
|
|
//--- Trading State
|
|
bool ExtPaperTradingActive = false; // Paper trading mode flag
|
|
PaperTradeStats ExtPaperStats; // Paper trading statistics
|
|
|
|
//--- Indicator Handles
|
|
int ExtHandleMA = INVALID_HANDLE; // MA indicator handle
|
|
int ExtHandleATR = INVALID_HANDLE; // ATR indicator handle
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Input Parameters |
|
|
//+------------------------------------------------------------------+
|
|
|
|
//--- Trade Settings
|
|
input group "=== Trade Settings ==="
|
|
input ENUM_TRADE_MODE InpTradeMode = TRADE_MODE_BOTH; // Trading mode
|
|
input double InpLotSize = 0.1; // Lot size
|
|
input int InpStopLoss = 200; // Stop Loss in points
|
|
input int InpTakeProfit = 400; // Take Profit in points
|
|
input int InpMagicNumber = 123456; // Magic Number
|
|
input double InpRiskPerTrade = 1.0; // Risk per trade (% of balance)
|
|
input bool InpUseFixedLot = false; // Use fixed lot size
|
|
|
|
//--- Paper Trading Settings
|
|
input group "=== Paper Trading ==="
|
|
input bool InpEnablePaperTrading = true; // Enable paper trading
|
|
input int InpPaperTradesRequired = 5; // Required paper trades
|
|
input int InpPaperWinsRequired = 3; // Required winning trades
|
|
input double InpPaperInitialBalance = 10000; // Initial paper balance
|
|
|
|
//--- Risk Management
|
|
input group "=== Risk Management ==="
|
|
input double InpMaxRiskPerTrade = 2.0; // Max risk per trade (%)
|
|
input double InpMaxDailyDrawdown = 5.0; // Max daily drawdown (%)
|
|
input int InpMaxOpenTrades = 5; // Max open trades
|
|
|
|
//--- Indicator Parameters
|
|
input group "=== Indicator Settings ==="
|
|
input int InpMAPeriod = 14; // MA Period
|
|
input int InpMAShift = 0; // MA Shift
|
|
input ENUM_MA_METHOD InpMAMethod = MODE_SMA; // MA Method
|
|
input ENUM_APPLIED_PRICE InpMAApplied = PRICE_CLOSE; // MA Applied Price
|
|
input int InpATRPeriod = 14; // ATR Period
|
|
|
|
//--- Trading Hours
|
|
input group "=== Trading Hours ==="
|
|
input bool InpUseTradingHours = false; // Use trading hours
|
|
input int InpStartHour = 8; // Trading start hour (server time)
|
|
input int InpEndHour = 20; // Trading end hour (server time)
|
|
|
|
//--- Advanced Settings
|
|
input group "=== Advanced Settings ==="
|
|
input int InpMaxSlippage = 30; // Max Slippage (points)
|
|
input bool InpUseTrailingStop = true; // Use Trailing Stop
|
|
input int InpTrailingStop = 100; // Trailing Stop (points)
|
|
input int InpTrailingStep = 10; // Trailing Step (points)
|
|
input bool InpUseBreakEven = true; // Use Break Even
|
|
input int InpBreakEven = 100; // Break Even (points)
|
|
input int InpBreakEvenProfit = 50; // Break Even Profit (points)
|
|
|
|
//--- Visual Settings
|
|
input group "=== Visual Settings ==="
|
|
color InpBuyColor = clrDodgerBlue; // Buy signal color
|
|
color InpSellColor = clrCrimson; // Sell signal color
|
|
int InpSignalWidth = 2; // Signal line width
|
|
ENUM_LINE_STYLE InpSignalStyle = STYLE_SOLID; // Signal line style
|
|
|
|
// Paper Trading Statistics
|
|
struct PaperTradeStats {
|
|
int totalTrades; // Total paper trades taken
|
|
int winningTrades; // Number of winning paper trades
|
|
int losingTrades; // Number of losing paper trades
|
|
double totalProfit; // Total profit from paper trades
|
|
double totalLoss; // Total loss from paper trades
|
|
double winRate; // Current win rate
|
|
double profitFactor; // Profit factor (gross profit / gross loss)
|
|
datetime lastTradeTime; // Time of last trade
|
|
|
|
// Adaptive learning parameters
|
|
double positionSizeMultiplier; // Adjusts position size based on performance
|
|
double riskMultiplier; // Adjusts risk based on performance
|
|
double stopLossMultiplier; // Adjusts stop loss based on performance
|
|
double takeProfitMultiplier; // Adjusts take profit based on performance
|
|
|
|
// Initialize with default values
|
|
PaperTradeStats() {
|
|
totalTrades = 0;
|
|
winningTrades = 0;
|
|
losingTrades = 0;
|
|
totalProfit = 0.0;
|
|
totalLoss = 0.0;
|
|
winRate = 0.0;
|
|
profitFactor = 0.0;
|
|
lastTradeTime = 0;
|
|
positionSizeMultiplier = 1.0;
|
|
riskMultiplier = 1.0;
|
|
stopLossMultiplier = 1.0;
|
|
takeProfitMultiplier = 1.0;
|
|
}
|
|
|
|
// Update statistics after a trade
|
|
void UpdateStats(bool isWin, double profit) {
|
|
totalTrades++;
|
|
if(isWin) {
|
|
winningTrades++;
|
|
totalProfit += MathAbs(profit);
|
|
} else {
|
|
losingTrades++;
|
|
totalLoss += MathAbs(profit);
|
|
}
|
|
winRate = (double)winningTrades / totalTrades * 100.0;
|
|
profitFactor = (totalLoss > 0) ? totalProfit / totalLoss : 0.0;
|
|
lastTradeTime = TimeCurrent();
|
|
}
|
|
|
|
// Check if live trading is allowed (3/5 win rule)
|
|
bool IsLiveTradingAllowed() {
|
|
if(totalTrades < InpPaperTradesRequired) return false;
|
|
return (winningTrades >= InpPaperWinsRequired);
|
|
}
|
|
|
|
// Adaptive learning - adjust parameters based on trade outcomes
|
|
void LearnFromTrade(bool isWin, double profit, double learningRate) {
|
|
if(!InpEnableAdaptiveLearning) return;
|
|
|
|
// Adjust position size multiplier based on win/loss
|
|
if(isWin) {
|
|
// Increase position size multiplier on wins, but cap it
|
|
positionSizeMultiplier = MathMin(2.0, positionSizeMultiplier * (1.0 + learningRate));
|
|
} else {
|
|
// Decrease position size multiplier on losses, but keep it above 0.1
|
|
positionSizeMultiplier = MathMax(0.1, positionSizeMultiplier * (1.0 - learningRate));
|
|
}
|
|
|
|
// Adjust risk multiplier based on recent performance
|
|
double recentWinRate = (winningTrades > 0) ? (double)winningTrades / totalTrades : 0.5;
|
|
riskMultiplier = 0.5 + recentWinRate; // Range: 0.5 to 1.5
|
|
|
|
// Adjust stop loss and take profit based on volatility
|
|
// (This is a simplified example - you can make this more sophisticated)
|
|
if(isWin) {
|
|
// On wins, we can be more aggressive with take profit
|
|
takeProfitMultiplier = MathMin(2.0, takeProfitMultiplier * (1.0 + learningRate * 0.5));
|
|
} else {
|
|
// On losses, tighten stop loss
|
|
stopLossMultiplier = MathMax(0.5, stopLossMultiplier * (1.0 - learningRate * 0.5));
|
|
}
|
|
|
|
// Ensure multipliers stay within reasonable bounds
|
|
positionSizeMultiplier = MathMax(0.1, MathMin(2.0, positionSizeMultiplier));
|
|
riskMultiplier = MathMax(0.5, MathMin(1.5, riskMultiplier));
|
|
stopLossMultiplier = MathMax(0.5, MathMin(1.5, stopLossMultiplier));
|
|
takeProfitMultiplier = MathMax(0.5, MathMin(2.0, takeProfitMultiplier));
|
|
}
|
|
};
|
|
|
|
PaperTradeStats ExtPaperStats; // Global instance of paper trading statistics
|
|
|
|
// Trading State
|
|
ENUM_TRADE_MODE ExtTradeMode = TRADE_MODE_PAPER; // Trading mode
|
|
bool ExtIsTradingAllowed = true; // Global trading flag
|
|
bool ExtIsFirstTick = true; // First tick flag
|
|
bool ExtPaperTradingActive = true; // Paper trading mode flag
|
|
datetime ExtLastTradeTime = 0; // Last trade time
|
|
datetime ExtLastOrderTime = 0; // Last order time
|
|
int ExtOrderCount = 0; // Order counter for rate limiting
|
|
datetime ExtLastOrderCountReset = 0; // Last order count reset time
|
|
int ExtTimerId = -1; // Timer ID
|
|
|
|
// Trading Statistics
|
|
double ExtTotalProfit = 0.0; // Total profit
|
|
int ExtTotalTrades = 0; // Total trades
|
|
int ExtWinningTrades = 0; // Winning trades
|
|
int ExtLosingTrades = 0; // Losing trades
|
|
#define OBJ_PREFIX "EscapeEA_" // Prefix for chart objects
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
// Initialize security components
|
|
if(!InitializeSecurity())
|
|
{
|
|
Print("Failed to initialize security components");
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
// Initialize indicators
|
|
if(!InitializeIndicators())
|
|
{
|
|
Print("Failed to initialize indicators");
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
// Initialize trading components
|
|
if(!InitializeTradingComponents())
|
|
{
|
|
Print("Failed to initialize trading components");
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
// Initialize News Impact Analysis System
|
|
if(!InitializeNewsImpactAnalysis())
|
|
{
|
|
Print("Warning: News Impact Analysis System initialization failed. Continuing without it.");
|
|
// Don't fail initialization if news system fails
|
|
}
|
|
|
|
// Initialize visualization
|
|
if(!InitializeVisualization())
|
|
{
|
|
Print("Warning: Failed to initialize visualization components");
|
|
// Don't fail initialization if visualization fails
|
|
}
|
|
|
|
// Set up timer for periodic updates
|
|
EventSetTimer(1);
|
|
|
|
Print(EXPERT_NAME " v" + EXPERT_VERSION + " initialized successfully");
|
|
return INIT_SUCCEEDED;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialize News Impact Analysis System |
|
|
//+------------------------------------------------------------------+
|
|
bool InitializeNewsImpactAnalysis()
|
|
{
|
|
// Initialize Volatility Manager
|
|
ExtVolatilityManager = new CVolatilityManager();
|
|
if(ExtVolatilityManager == NULL)
|
|
{
|
|
Print("Failed to create Volatility Manager");
|
|
return false;
|
|
}
|
|
|
|
// Initialize News Feed Handler
|
|
ExtNewsHandler = new CNewsFeedHandler();
|
|
if(ExtNewsHandler == NULL)
|
|
{
|
|
Print("Failed to create News Feed Handler");
|
|
delete ExtVolatilityManager;
|
|
ExtVolatilityManager = NULL;
|
|
return false;
|
|
}
|
|
|
|
// Initialize Market Analyzer with dependencies
|
|
ExtMarketAnalyzer = new CMarketAnalyzer(ExtNewsHandler, ExtVolatilityManager);
|
|
if(ExtMarketAnalyzer == NULL)
|
|
{
|
|
Print("Failed to create Market Analyzer");
|
|
delete ExtVolatilityManager;
|
|
delete ExtNewsHandler;
|
|
ExtVolatilityManager = NULL;
|
|
ExtNewsHandler = NULL;
|
|
return false;
|
|
}
|
|
|
|
// Configure news filter settings
|
|
if(InpEnableNewsFilter)
|
|
{
|
|
// Set up affected symbols
|
|
if(StringLen(InpAffectedSymbols) > 0)
|
|
{
|
|
string symbols[];
|
|
StringSplit(InpAffectedSymbols, ',', symbols);
|
|
for(int i = 0; i < ArraySize(symbols); i++)
|
|
{
|
|
string symbol = StringTrimRight(StringTrimLeft(symbols[i]));
|
|
if(symbol != "")
|
|
ExtMarketAnalyzer.AddAffectedSymbol(symbol);
|
|
}
|
|
}
|
|
|
|
// Set up news blackout period if specified
|
|
if(InpNewsStartTime > 0 && InpNewsEndTime > 0 && InpNewsStartTime < InpNewsEndTime)
|
|
{
|
|
ExtMarketAnalyzer.SetNewsBlackoutPeriod(InpNewsStartTime, InpNewsEndTime);
|
|
}
|
|
}
|
|
|
|
// Initialize components
|
|
if(!ExtVolatilityManager.Initialize())
|
|
{
|
|
Print("Failed to initialize Volatility Manager");
|
|
return false;
|
|
}
|
|
|
|
if(!ExtNewsHandler.Initialize())
|
|
{
|
|
Print("Failed to initialize News Feed Handler");
|
|
return false;
|
|
}
|
|
|
|
if(!ExtMarketAnalyzer.Initialize())
|
|
{
|
|
Print("Failed to initialize Market Analyzer");
|
|
return false;
|
|
}
|
|
|
|
Print("News Impact Analysis System initialized successfully");
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
// Stop the timer
|
|
EventKillTimer();
|
|
|
|
// Clean up trading components
|
|
if(ExtTrade != NULL)
|
|
{
|
|
delete ExtTrade;
|
|
ExtTrade = NULL;
|
|
}
|
|
|
|
if(ExtTradeExecutor != NULL)
|
|
{
|
|
delete ExtTradeExecutor;
|
|
ExtTradeExecutor = NULL;
|
|
}
|
|
|
|
if(ExtRiskManager != NULL)
|
|
{
|
|
delete ExtRiskManager;
|
|
ExtRiskManager = NULL;
|
|
}
|
|
|
|
if(ExtPositionManager != NULL)
|
|
{
|
|
delete ExtPositionManager;
|
|
ExtPositionManager = NULL;
|
|
}
|
|
|
|
if(ExtSignalGenerator != NULL)
|
|
{
|
|
delete ExtSignalGenerator;
|
|
ExtSignalGenerator = NULL;
|
|
}
|
|
|
|
if(ExtPaperTrading != NULL)
|
|
{
|
|
delete ExtPaperTrading;
|
|
ExtPaperTrading = NULL;
|
|
}
|
|
|
|
// Release indicator handles
|
|
if(ExtHandleMA != INVALID_HANDLE)
|
|
{
|
|
IndicatorRelease(ExtHandleMA);
|
|
ExtHandleMA = INVALID_HANDLE;
|
|
}
|
|
|
|
if(ExtHandleATR != INVALID_HANDLE)
|
|
{
|
|
IndicatorRelease(ExtHandleATR);
|
|
ExtHandleATR = INVALID_HANDLE;
|
|
}
|
|
|
|
// Clean up visualization objects
|
|
ObjectsDeleteAll(0, OBJ_PREFIX);
|
|
|
|
Print("EscapeEA successfully deinitialized");
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialize trading components |
|
|
//+------------------------------------------------------------------+
|
|
bool InitializeTradingComponents()
|
|
{
|
|
// Initialize trade object
|
|
ExtTrade = new CTrade();
|
|
if(ExtTrade == NULL)
|
|
{
|
|
Print("Failed to create trade object");
|
|
return false;
|
|
}
|
|
|
|
// Set trade parameters
|
|
ExtTrade.SetDeviationInPoints(InpMaxSlippage);
|
|
ExtTrade.SetTypeFilling(ORDER_FILLING_FOK);
|
|
ExtTrade.SetExpertMagicNumber(InpMagicNumber);
|
|
|
|
// Initialize trade executor
|
|
ExtTradeExecutor = new CTradeExecutor(ExtTrade);
|
|
if(ExtTradeExecutor == NULL)
|
|
{
|
|
Print("Failed to create trade executor");
|
|
return false;
|
|
}
|
|
|
|
// Initialize risk manager
|
|
ExtRiskManager = new CRiskManager(InpRiskPerTrade, InpMaxRiskPerTrade, InpMaxDailyDrawdown);
|
|
if(ExtRiskManager == NULL)
|
|
{
|
|
Print("Failed to create risk manager");
|
|
return false;
|
|
}
|
|
|
|
// Initialize position manager
|
|
ExtPositionManager = new CPositionManager(ExtTrade, InpMagicNumber);
|
|
if(ExtPositionManager == NULL)
|
|
{
|
|
Print("Failed to create position manager");
|
|
return false;
|
|
}
|
|
|
|
// Initialize signal generator
|
|
ExtSignalGenerator = new CSignalGenerator(ExtHandleMA, ExtHandleATR, InpMAPeriod);
|
|
if(ExtSignalGenerator == NULL)
|
|
{
|
|
Print("Failed to create signal generator");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialize technical indicators |
|
|
//+------------------------------------------------------------------+
|
|
bool InitializeIndicators()
|
|
{
|
|
// Initialize MA indicator
|
|
ExtHandleMA = iMA(_Symbol, PERIOD_CURRENT, InpMAPeriod, InpMAShift, InpMAMethod, InpMAApplied);
|
|
if(ExtHandleMA == INVALID_HANDLE)
|
|
{
|
|
Print("Failed to create MA indicator");
|
|
return false;
|
|
}
|
|
|
|
// Initialize ATR indicator
|
|
ExtHandleATR = iATR(_Symbol, PERIOD_CURRENT, InpATRPeriod);
|
|
if(ExtHandleATR == INVALID_HANDLE)
|
|
{
|
|
Print("Failed to create ATR indicator");
|
|
return false;
|
|
}
|
|
|
|
// All indicators initialized successfully
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialize paper trading system |
|
|
//+------------------------------------------------------------------+
|
|
bool InitializePaperTrading()
|
|
{
|
|
ExtPaperTrading = new CPaperTrading(InpPaperInitialBalance, InpMagicNumber);
|
|
if(ExtPaperTrading == NULL)
|
|
{
|
|
Print("Failed to create paper trading system");
|
|
return false;
|
|
}
|
|
|
|
// Set paper trading mode based on input parameters
|
|
ExtPaperTradingActive = (InpTradeMode == TRADE_MODE_PAPER ||
|
|
(InpTradeMode == TRADE_MODE_BOTH && !ExtPaperStats.IsLiveTradingAllowed()));
|
|
|
|
Print("Paper trading ", ExtPaperTradingActive ? "enabled" : "disabled");
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialize security components |
|
|
//+------------------------------------------------------------------+
|
|
bool InitializeSecurity()
|
|
{
|
|
// Initialize input validator first
|
|
ExtInputValidator = CInputValidator::Instance();
|
|
if(ExtInputValidator == NULL)
|
|
{
|
|
Print("Failed to create input validator");
|
|
return false;
|
|
}
|
|
|
|
// Create security manager instance
|
|
ExtSecurity = CSecurityManager::Instance();
|
|
if(ExtSecurity == NULL)
|
|
{
|
|
Print("Failed to create security manager");
|
|
return false;
|
|
}
|
|
|
|
// Initialize with current symbol and log path
|
|
string logPath = StringFormat("%s\\%s", TerminalInfoString(TERMINAL_DATA_PATH), "Logs\\EscapeEA_Security_Log.txt");
|
|
if(!ExtSecurity->Initialize(_Symbol, logPath))
|
|
{
|
|
Print("Failed to initialize security manager");
|
|
return false;
|
|
}
|
|
|
|
// Validate environment
|
|
if(!ExtSecurity->ValidateEnvironment())
|
|
{
|
|
Print("Security validation failed");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update trading statistics |
|
|
//+------------------------------------------------------------------+
|
|
void UpdateTradingStats()
|
|
{
|
|
// Update total trades count
|
|
int totalTrades = TradesTotal();
|
|
|
|
// If no trades, nothing to update
|
|
if(totalTrades == 0)
|
|
return;
|
|
|
|
// Loop through closed trades
|
|
for(int i = totalTrades - 1; i >= 0; i--)
|
|
{
|
|
if(ExtDeal.SelectByIndex(i))
|
|
{
|
|
// Check if this is our trade
|
|
if(ExtDeal.Magic() == InpMagicNumber &&
|
|
ExtDeal.Symbol() == _Symbol)
|
|
{
|
|
// Update statistics
|
|
ExtTotalTrades++;
|
|
double profit = ExtDeal.Profit();
|
|
|
|
if(profit > 0)
|
|
ExtWinningTrades++;
|
|
else
|
|
ExtLosingTrades++;
|
|
|
|
ExtTotalProfit += profit;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update account info panel |
|
|
//+------------------------------------------------------------------+
|
|
bool UpdateAccountInfoPanel()
|
|
{
|
|
string panelName = OBJ_PREFIX + "AccountInfo";
|
|
string text = "";
|
|
|
|
// Format account info
|
|
text += "Balance: " + DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2) + "\n";
|
|
text += "Equity: " + DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY), 2) + "\n";
|
|
text += "Margin: " + DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN), 2) + "\n";
|
|
text += "Free Margin: " + DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_FREE), 2) + "\n\n";
|
|
|
|
// Add trading statistics
|
|
text += "=== Trading Stats ===\n";
|
|
text += "Total Trades: " + IntegerToString(ExtTotalTrades) + "\n";
|
|
text += "Win Rate: " + (ExtTotalTrades > 0 ?
|
|
DoubleToString((double)ExtWinningTrades / ExtTotalTrades * 100, 2) + "%" : "N/A") + "\n";
|
|
text += "Total Profit: " + DoubleToString(ExtTotalProfit, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY) + "\n";
|
|
|
|
// Add paper trading info if enabled
|
|
if(InpEnablePaperTrading)
|
|
{
|
|
text += "\n=== Paper Trading ===\n";
|
|
text += "Mode: " + (ExtPaperTradingActive ? "ACTIVE" : "INACTIVE") + "\n";
|
|
text += "Trades: " + IntegerToString(ExtPaperStats.totalTrades) + "\n";
|
|
text += "Wins: " + IntegerToString(ExtPaperStats.winningTrades) + "\n";
|
|
text += "Win Rate: " + (ExtPaperStats.totalTrades > 0 ?
|
|
DoubleToString((double)ExtPaperStats.winningTrades / ExtPaperStats.totalTrades * 100, 2) + "%" : "N/A") + "\n";
|
|
}
|
|
|
|
// Create or update the panel
|
|
if(ObjectFind(0, panelName) < 0)
|
|
{
|
|
if(!ObjectCreate(0, panelName, OBJ_LABEL, 0, 0, 0))
|
|
{
|
|
Print("Failed to create account info panel");
|
|
return false;
|
|
}
|
|
|
|
// Set panel properties
|
|
ObjectSetInteger(0, panelName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
|
ObjectSetInteger(0, panelName, OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, panelName, OBJPROP_YDISTANCE, 20);
|
|
ObjectSetInteger(0, panelName, OBJPROP_COLOR, clrWhite);
|
|
ObjectSetInteger(0, panelName, OBJPROP_FONTSIZE, 8);
|
|
}
|
|
|
|
// Update panel text
|
|
ObjectSetString(0, panelName, OBJPROP_TEXT, text);
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Display current trading mode (Paper/Live) |
|
|
//+------------------------------------------------------------------+
|
|
bool DisplayMode()
|
|
{
|
|
string modeText = ExtPaperTradingActive ? "PAPER TRADING" : "LIVE TRADING";
|
|
string modeColor = ExtPaperTradingActive ? clrDodgerBlue : clrLime;
|
|
|
|
// Create or update mode label
|
|
string labelName = OBJ_PREFIX + "ModeLabel";
|
|
if(ObjectFind(0, labelName) < 0)
|
|
{
|
|
if(!ObjectCreate(0, labelName, OBJ_LABEL, 0, 0, 0))
|
|
{
|
|
Print("Failed to create mode label");
|
|
return false;
|
|
}
|
|
|
|
// Set label properties
|
|
ObjectSetInteger(0, labelName, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
|
|
ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, 20);
|
|
ObjectSetInteger(0, labelName, OBJPROP_COLOR, modeColor);
|
|
ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 10);
|
|
ObjectSetInteger(0, labelName, OBJPROP_FONT, "Arial Bold");
|
|
}
|
|
|
|
// Update label text and color
|
|
ObjectSetString(0, labelName, OBJPROP_TEXT, modeText);
|
|
ObjectSetInteger(0, labelName, OBJPROP_COLOR, modeColor);
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update signal visualization on the chart |
|
|
//+------------------------------------------------------------------+
|
|
bool UpdateSignalVisualization(bool buySignal, bool sellSignal, double price, double stopLoss, double takeProfit)
|
|
{
|
|
// Remove any existing signal objects
|
|
ObjectsDeleteAll(0, OBJ_PREFIX + "Signal_");
|
|
|
|
// If no signals, exit
|
|
if(!buySignal && !sellSignal)
|
|
return true;
|
|
|
|
// Calculate the current time and price for the signal arrow
|
|
datetime currentTime = TimeCurrent();
|
|
|
|
// Create signal arrow
|
|
string arrowName = OBJ_PREFIX + "Signal_Arrow";
|
|
if(!ObjectCreate(0, arrowName, OBJ_ARROW, 0, currentTime, price))
|
|
{
|
|
Print("Failed to create signal arrow");
|
|
return false;
|
|
}
|
|
|
|
// Set arrow properties based on signal type
|
|
if(buySignal)
|
|
{
|
|
ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 233); // Up arrow
|
|
ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrLime);
|
|
ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2);
|
|
}
|
|
else if(sellSignal)
|
|
{
|
|
ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 234); // Down arrow
|
|
ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrRed);
|
|
ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2);
|
|
}
|
|
|
|
// Add stop loss and take profit levels if provided
|
|
if(stopLoss > 0)
|
|
{
|
|
string slName = OBJ_PREFIX + "Signal_SL";
|
|
if(!ObjectCreate(0, slName, OBJ_HLINE, 0, 0, stopLoss))
|
|
{
|
|
Print("Failed to create stop loss line");
|
|
return false;
|
|
}
|
|
ObjectSetInteger(0, slName, OBJPROP_COLOR, clrRed);
|
|
ObjectSetInteger(0, slName, OBJPROP_STYLE, STYLE_DOT);
|
|
ObjectSetString(0, slName, OBJPROP_TEXT, "SL: " + DoubleToString(stopLoss, _Digits));
|
|
}
|
|
|
|
if(takeProfit > 0)
|
|
{
|
|
string tpName = OBJ_PREFIX + "Signal_TP";
|
|
if(!ObjectCreate(0, tpName, OBJ_HLINE, 0, 0, takeProfit))
|
|
{
|
|
Print("Failed to create take profit line");
|
|
return false;
|
|
}
|
|
ObjectSetInteger(0, tpName, OBJPROP_COLOR, clrLime);
|
|
ObjectSetInteger(0, tpName, OBJPROP_STYLE, STYLE_DOT);
|
|
ObjectSetString(0, tpName, OBJPROP_TEXT, "TP: " + DoubleToString(takeProfit, _Digits));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Timer function for periodic updates |
|
|
//+------------------------------------------------------------------+
|
|
void OnTimer()
|
|
{
|
|
// Update visualization periodically
|
|
UpdateVisualization();
|
|
|
|
// Check for news events if enabled
|
|
if(ExtSecurity != NULL)
|
|
{
|
|
ExtSecurity->CheckNewsEvents();
|
|
}
|
|
|
|
// Update trading statistics
|
|
UpdateTradingStats();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
// Check if we're properly initialized
|
|
if(!IsInitialized())
|
|
{
|
|
Print("EA not properly initialized");
|
|
return;
|
|
}
|
|
|
|
// Check if trading is allowed
|
|
if(!IsTradeAllowed())
|
|
{
|
|
Print("Trading is not allowed at this time");
|
|
return;
|
|
}
|
|
|
|
// Update account and symbol info
|
|
if(!ExtAccount.RefreshRates() || !ExtSymbol.RefreshRates())
|
|
{
|
|
Print("Failed to refresh rates");
|
|
return;
|
|
}
|
|
|
|
// Update indicators
|
|
if(!UpdateIndicators())
|
|
{
|
|
Print("Failed to update indicators");
|
|
return;
|
|
}
|
|
|
|
// Process trading signals based on current mode
|
|
ProcessTradingMode();
|
|
|
|
// Manage open positions
|
|
ManagePositions();
|
|
|
|
// Update visualization
|
|
UpdateVisualization();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check if trading is allowed |
|
|
//+------------------------------------------------------------------+
|
|
bool IsTradeAllowed()
|
|
{
|
|
// Check if trading is allowed by the expert
|
|
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
|
|
{
|
|
Print("Trading is not allowed in the terminal settings");
|
|
return false;
|
|
}
|
|
|
|
// Check if the expert is allowed to trade
|
|
if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
|
|
{
|
|
Print("Trading is not allowed for this expert");
|
|
return false;
|
|
}
|
|
|
|
// Check if we're in paper trading mode
|
|
if(ExtPaperTradingActive && !ExtPaperStats.IsLiveTradingAllowed())
|
|
{
|
|
Print("Paper trading: " + string(ExtPaperStats.winningTrades) +
|
|
" out of " + string(ExtPaperStats.totalTrades) + " required trades are winners");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check if the expert is properly initialized |
|
|
//+------------------------------------------------------------------+
|
|
bool IsInitialized()
|
|
{
|
|
if(ExtTrade == NULL || ExtTradeExecutor == NULL ||
|
|
ExtRiskManager == NULL || ExtPositionManager == NULL)
|
|
{
|
|
Print("One or more components are not initialized");
|
|
return false;
|
|
}
|
|
|
|
// Check if indicators are properly initialized
|
|
if(ExtHandleMA == INVALID_HANDLE || ExtHandleATR == INVALID_HANDLE)
|
|
{
|
|
Print("One or more indicators are not initialized");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update market indicators |
|
|
//+------------------------------------------------------------------+
|
|
bool UpdateIndicators()
|
|
{
|
|
// Update MA indicator
|
|
if(CopyBuffer(ExtHandleMA, 0, 0, 3, ExtMABuffer) != 3)
|
|
{
|
|
Print("Failed to copy MA buffer: ", GetLastError());
|
|
return false;
|
|
}
|
|
|
|
// Update ATR indicator
|
|
if(CopyBuffer(ExtHandleATR, 0, 0, 1, &ExtATRValue) != 1)
|
|
{
|
|
Print("Failed to copy ATR buffer: ", GetLastError());
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Process trading based on current mode |
|
|
//+------------------------------------------------------------------+
|
|
void ProcessTradingMode()
|
|
{
|
|
// Check if we have any open positions
|
|
if(PositionsTotal() > 0)
|
|
{
|
|
// Manage existing positions
|
|
return;
|
|
}
|
|
|
|
// Generate trading signals
|
|
bool buySignal = false, sellSignal = false;
|
|
double stopLoss = 0.0, takeProfit = 0.0;
|
|
|
|
if(ExtSignalGenerator != NULL &&
|
|
ExtSignalGenerator.GenerateSignals(buySignal, sellSignal, stopLoss, takeProfit))
|
|
{
|
|
// Execute trade based on signal
|
|
if(buySignal)
|
|
{
|
|
ExecuteTrade(ORDER_TYPE_BUY, stopLoss, takeProfit);
|
|
}
|
|
else if(sellSignal)
|
|
{
|
|
ExecuteTrade(ORDER_TYPE_SELL, stopLoss, takeProfit);
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Execute a trade with proper risk management |
|
|
//+------------------------------------------------------------------+
|
|
void ExecuteTrade(ENUM_ORDER_TYPE orderType, double stopLoss, double takeProfit)
|
|
{
|
|
// Calculate position size based on risk management
|
|
double lotSize = ExtRiskManager.CalculatePositionSize(stopLoss);
|
|
if(lotSize <= 0)
|
|
{
|
|
Print("Invalid position size calculated");
|
|
return;
|
|
}
|
|
|
|
// Execute the trade
|
|
if(ExtPaperTradingActive)
|
|
{
|
|
// Execute paper trade
|
|
if(ExtPaperTrading.ExecutePaperTrade(orderType, lotSize, stopLoss, takeProfit))
|
|
{
|
|
Print("Paper trade executed successfully");
|
|
}
|
|
else
|
|
{
|
|
Print("Failed to execute paper trade");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Execute live trade
|
|
if(ExtTradeExecutor.ExecuteTrade(orderType, lotSize, stopLoss, takeProfit))
|
|
{
|
|
Print("Live trade executed successfully");
|
|
}
|
|
else
|
|
{
|
|
Print("Failed to execute live trade: ", GetLastError());
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Manage open positions |
|
|
//+------------------------------------------------------------------+
|
|
void ManagePositions()
|
|
{
|
|
// Check if we have any open positions
|
|
if(PositionsTotal() == 0)
|
|
return;
|
|
|
|
// Loop through all open positions
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
|
{
|
|
if(ExtPosition.SelectByIndex(i))
|
|
{
|
|
// Check if this is our position
|
|
if(ExtPosition.Magic() == InpMagicNumber &&
|
|
ExtPosition.Symbol() == _Symbol)
|
|
{
|
|
// Update trailing stop if enabled
|
|
if(InpUseTrailingStop)
|
|
{
|
|
ExtPositionManager.UpdateTrailingStop(ExtPosition.Ticket(),
|
|
InpTrailingStop,
|
|
InpTrailingStep);
|
|
}
|
|
|
|
// Check for break even
|
|
if(InpUseBreakEven)
|
|
{
|
|
ExtPositionManager.CheckBreakEven(ExtPosition.Ticket(),
|
|
InpBreakEven,
|
|
InpBreakEvenProfit);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update visualization on the chart |
|
|
//+------------------------------------------------------------------+
|
|
void UpdateVisualization()
|
|
{
|
|
// Update account info panel
|
|
if(!UpdateAccountInfoPanel())
|
|
{
|
|
Print("Failed to update account info panel");
|
|
}
|
|
|
|
// Update mode display (Paper/Live)
|
|
if(!DisplayMode())
|
|
{
|
|
Print("Failed to update mode display");
|
|
}
|
|
|
|
// Update signal visualization if needed
|
|
if(ExtSignalGenerator != NULL)
|
|
{
|
|
bool buySignal = false, sellSignal = false;
|
|
double stopLoss = 0.0, takeProfit = 0.0;
|
|
|
|
if(ExtSignalGenerator.GenerateSignals(buySignal, sellSignal, stopLoss, takeProfit))
|
|
{
|
|
double price = SymbolInfoDouble(_Symbol, buySignal ? SYMBOL_ASK : SYMBOL_BID);
|
|
if(!UpdateSignalVisualization(buySignal, sellSignal, price, stopLoss, takeProfit))
|
|
{
|
|
Print("Failed to update signal visualization");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Force chart redraw
|
|
ChartRedraw(0);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update signal visualization on the chart |
|
|
//+------------------------------------------------------------------+
|
|
void UpdateSignalVisualization(bool buySignal, bool sellSignal, double currentPrice, double stopLoss, double takeProfit)
|
|
{
|
|
// Remove any existing signal objects
|
|
ObjectsDeleteAll(0, "EscapeEA_Signal_");
|
|
|
|
// If no signals, exit
|
|
if(!buySignal && !sellSignal) {
|
|
return;
|
|
}
|
|
|
|
// Calculate the current time and price for the signal arrow
|
|
datetime currentTime = TimeCurrent();
|
|
|
|
// Create signal arrow
|
|
string arrowName = "EscapeEA_Signal_Arrow";
|
|
if(!ObjectCreate(0, arrowName, OBJ_ARROW, 0, currentTime, currentPrice - stopLoss))
|
|
{
|
|
Print("Failed to create signal arrow");
|
|
return;
|
|
}
|
|
|
|
// Set arrow properties based on signal type
|
|
if(buySignal)
|
|
{
|
|
ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 233); // Up arrow
|
|
ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrLime);
|
|
ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2);
|
|
}
|
|
else if(sellSignal)
|
|
{
|
|
ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 234); // Down arrow
|
|
ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrRed);
|
|
ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2);
|
|
}
|
|
|
|
// Add stop loss and take profit levels if provided
|
|
if(stopLoss > 0)
|
|
{
|
|
string slName = "EscapeEA_SL";
|
|
if(!ObjectCreate(0, slName, OBJ_HLINE, 0, 0, currentPrice - stopLoss))
|
|
{
|
|
Print("Failed to create stop loss line");
|
|
return;
|
|
}
|
|
ObjectSetInteger(0, slName, OBJPROP_COLOR, clrRed);
|
|
ObjectSetInteger(0, slName, OBJPROP_STYLE, STYLE_DOT);
|
|
ObjectSetString(0, slName, OBJPROP_TEXT, "SL: " + DoubleToString(currentPrice - stopLoss, _Digits));
|
|
}
|
|
|
|
if(takeProfit > 0)
|
|
{
|
|
string tpName = "EscapeEA_TP";
|
|
if(!ObjectCreate(0, tpName, OBJ_HLINE, 0, 0, currentPrice + takeProfit))
|
|
{
|
|
Print("Failed to create take profit line");
|
|
return;
|
|
}
|
|
ObjectSetInteger(0, tpName, OBJPROP_COLOR, clrLime);
|
|
ObjectSetInteger(0, tpName, OBJPROP_STYLE, STYLE_DOT);
|
|
ObjectSetString(0, tpName, OBJPROP_TEXT, "TP: " + DoubleToString(currentPrice + takeProfit, _Digits));
|
|
}
|
|
|
|
// Force chart redraw
|
|
ChartRedraw();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Display current mode (Paper/Live) |
|
|
//+------------------------------------------------------------------+
|
|
void DisplayMode()
|
|
{
|
|
string modeText = ExtPaperTradingActive ? "PAPER TRADING" : "LIVE TRADING";
|
|
string modeColor = ExtPaperTradingActive ? clrDodgerBlue : clrLime;
|
|
|
|
// Create or update mode label
|
|
string modeLabel = "EscapeEA_Mode";
|
|
if(ObjectFind(0, modeLabel) < 0) {
|
|
ObjectCreate(0, modeLabel, OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, modeLabel, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
|
|
ObjectSetInteger(0, modeLabel, OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, modeLabel, OBJPROP_YDISTANCE, 10);
|
|
ObjectSetInteger(0, modeLabel, OBJPROP_COLOR, modeColor);
|
|
ObjectSetInteger(0, modeLabel, OBJPROP_FONTSIZE, 12);
|
|
ObjectSetString(0, modeLabel, OBJPROP_FONT, "Arial");
|
|
ObjectSetInteger(0, modeLabel, OBJPROP_BACK, false);
|
|
}
|
|
ObjectSetString(0, modeLabel, OBJPROP_TEXT, modeText);
|
|
ObjectSetInteger(0, modeLabel, OBJPROP_COLOR, modeColor);
|
|
|
|
// Display paper trading info if active
|
|
if(ExtPaperTradingActive && ExtPaperTrading != NULL) {
|
|
string infoText = StringFormat("Paper Balance: %.2f\n" +
|
|
"Equity: %.2f\n" +
|
|
"Trades: %d (%dW/%dL)\n" +
|
|
"Win Rate: %.1f%%",
|
|
ExtPaperTrading->GetBalance(),
|
|
ExtPaperTrading->GetEquity(),
|
|
ExtPaperTrading->GetTotalTrades(),
|
|
ExtPaperTrading->GetWinningTrades(),
|
|
ExtPaperTrading->GetLosingTrades(),
|
|
ExtPaperTrading->GetWinRate());
|
|
|
|
string infoLabel = "EscapeEA_PaperInfo";
|
|
if(ObjectFind(0, infoLabel) < 0) {
|
|
ObjectCreate(0, infoLabel, OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, infoLabel, OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
|
ObjectSetInteger(0, infoLabel, OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, infoLabel, OBJPROP_YDISTANCE, 30);
|
|
ObjectSetInteger(0, infoLabel, OBJPROP_COLOR, clrWhite);
|
|
ObjectSetInteger(0, infoLabel, OBJPROP_FONTSIZE, 10);
|
|
ObjectSetString(0, infoLabel, OBJPROP_FONT, "Arial");
|
|
ObjectSetInteger(0, infoLabel, OBJPROP_BACK, true);
|
|
}
|
|
ObjectSetString(0, infoLabel, OBJPROP_TEXT, infoText);
|
|
}
|
|
|
|
// Update account info
|
|
string accountInfo = StringFormat("Balance: %.2f %s\n" +
|
|
"Equity: %.2f %s\n" +
|
|
"Margin: %.2f %s\n" +
|
|
"Free Margin: %.2f %s",
|
|
AccountInfoDouble(ACCOUNT_BALANCE),
|
|
AccountInfoString(ACCOUNT_CURRENCY),
|
|
AccountInfoDouble(ACCOUNT_EQUITY),
|
|
AccountInfoString(ACCOUNT_CURRENCY),
|
|
AccountInfoDouble(ACCOUNT_MARGIN),
|
|
AccountInfoString(ACCOUNT_CURRENCY),
|
|
AccountInfoDouble(ACCOUNT_MARGIN_FREE),
|
|
AccountInfoString(ACCOUNT_CURRENCY));
|
|
|
|
string accountLabel = "EscapeEA_AccountInfo";
|
|
if(ObjectFind(0, accountLabel) < 0) {
|
|
ObjectCreate(0, accountLabel, OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, accountLabel, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
|
|
ObjectSetInteger(0, accountLabel, OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, accountLabel, OBJPROP_YDISTANCE, 30);
|
|
ObjectSetInteger(0, accountLabel, OBJPROP_COLOR, clrWhite);
|
|
ObjectSetInteger(0, accountLabel, OBJPROP_FONTSIZE, 10);
|
|
ObjectSetString(0, accountLabel, OBJPROP_FONT, "Arial");
|
|
ObjectSetInteger(0, accountLabel, OBJPROP_BACK, true);
|
|
}
|
|
ObjectSetString(0, accountLabel, OBJPROP_TEXT, accountInfo);
|
|
|
|
// Update chart
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|