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();
| |||
}
| |||
//+------------------------------------------------------------------+
|