last backup XCAEA
This commit is contained in:
@@ -0,0 +1,816 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| X121_Strategy_EA.mq5 |
|
||||
//| Copyright 2023, SaherElm IT |
|
||||
//| https://saherelm.ir/ |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "EA based on X121 XCA and X3MA indicators"
|
||||
#property strict
|
||||
|
||||
// Include Common Library
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include <Trade/Trade.mqh>
|
||||
|
||||
// Indicator handles
|
||||
int xcaHandle = INVALID_HANDLE;
|
||||
int x3maHandle = INVALID_HANDLE;
|
||||
|
||||
// Indicator buffers for XCA
|
||||
double xcaTrendBuffer[];
|
||||
double xcaTrendColorBuffer[];
|
||||
double xcaKIBuffer[];
|
||||
double xcaKIColorBuffer[];
|
||||
double xcaVidyaBuffer[];
|
||||
double xcaVidyaColorBuffer[];
|
||||
double xcaSwingLowBuffer[];
|
||||
double xcaSwingHighBuffer[];
|
||||
double xcaSupportBuffer[];
|
||||
double xcaResistanceBuffer[];
|
||||
double xcaSLBuffer[]; // Short Cycle Low
|
||||
double xcaSHBuffer[]; // Short Cycle High
|
||||
double xcaMLBuffer[]; // Medium Cycle Low
|
||||
double xcaMHBuffer[]; // Medium Cycle High
|
||||
double xcaFiboLevel2Buffer[]; // 50% Fibo level
|
||||
|
||||
// Indicator buffers for X3MA
|
||||
double x3maFastBuffer[];
|
||||
double x3maFastColorBuffer[];
|
||||
double x3maMediumBuffer[];
|
||||
double x3maMediumColorBuffer[];
|
||||
double x3maSlowBuffer[];
|
||||
double x3maSlowColorBuffer[];
|
||||
|
||||
// Trade parameters
|
||||
input group "Trade Settings" input double LotSize = 0.1; // Fixed Lot Size
|
||||
input bool UseAutoLotSize = false; // Use Auto Lot Size
|
||||
input double RiskPercent = 1.0; // Risk Percent (for Auto Lot)
|
||||
input int StopLoss = 100; // Stop Loss in points
|
||||
input int TakeProfit = 200; // Take Profit in points
|
||||
input bool UseTrailingStop = true; // Use Trailing Stop
|
||||
input int TrailingStop = 50; // Trailing Stop in points
|
||||
input int TrailingStep = 10; // Trailing Step in points
|
||||
|
||||
input group "Strategy Parameters" input bool UseSwingPoints = true; // Use Swing Points for Entry
|
||||
input bool UseFiboLevels = true; // Use Fibonacci Levels
|
||||
input bool UseMAAlignment = true; // Require All MAs Alignment
|
||||
input bool UseKIConfirmation = true; // Require KI Confirmation
|
||||
input bool UseVidyaConfirmation = true; // Require VIDYA Confirmation
|
||||
input bool UseTrendConfirmation = true; // Require Trend Confirmation
|
||||
|
||||
input group "Money Management" input bool UseMultipleTargets = true; // Use Multiple Profit Targets
|
||||
input double Target1Percent = 33.0; // First Target Percentage
|
||||
input double Target2Percent = 33.0; // Second Target Percentage
|
||||
input double Target3Percent = 34.0; // Third Target Percentage
|
||||
|
||||
input group "Time Filter" input bool UseTimeFilter = false; // Use Time Filter
|
||||
input string StartTradeTime = "08:00"; // Start Trading Time (Server Time)
|
||||
input string EndTradeTime = "16:00"; // End Trading Time (Server Time)
|
||||
|
||||
// Global variables
|
||||
int magicNumber = 12121;
|
||||
bool isTradingAllowed = true;
|
||||
datetime lastBarTime = 0;
|
||||
int barsTotalPrev = 0;
|
||||
|
||||
// Trade objects
|
||||
CTrade trade;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
// Initialize trade object
|
||||
trade.SetExpertMagicNumber(magicNumber);
|
||||
|
||||
// Initialize XCA indicator
|
||||
xcaHandle = iCustom(_Symbol, _Period, "x-saherelm.x121.xca");
|
||||
if (xcaHandle == INVALID_HANDLE)
|
||||
{
|
||||
Print("Failed to create handle of the XCA indicator");
|
||||
return (INIT_FAILED);
|
||||
}
|
||||
|
||||
// Initialize X3MA indicator
|
||||
x3maHandle = iCustom(_Symbol, _Period, "x-saherelm.x121.x3ma");
|
||||
if (x3maHandle == INVALID_HANDLE)
|
||||
{
|
||||
Print("Failed to create handle of the X3MA indicator");
|
||||
return (INIT_FAILED);
|
||||
}
|
||||
|
||||
// Set up arrays as series
|
||||
ArraySetAsSeries(xcaTrendBuffer, true);
|
||||
ArraySetAsSeries(xcaTrendColorBuffer, true);
|
||||
ArraySetAsSeries(xcaKIBuffer, true);
|
||||
ArraySetAsSeries(xcaKIColorBuffer, true);
|
||||
ArraySetAsSeries(xcaVidyaBuffer, true);
|
||||
ArraySetAsSeries(xcaVidyaColorBuffer, true);
|
||||
ArraySetAsSeries(xcaSwingLowBuffer, true);
|
||||
ArraySetAsSeries(xcaSwingHighBuffer, true);
|
||||
ArraySetAsSeries(xcaSupportBuffer, true);
|
||||
ArraySetAsSeries(xcaResistanceBuffer, true);
|
||||
ArraySetAsSeries(xcaSLBuffer, true);
|
||||
ArraySetAsSeries(xcaSHBuffer, true);
|
||||
ArraySetAsSeries(xcaMLBuffer, true);
|
||||
ArraySetAsSeries(xcaMHBuffer, true);
|
||||
ArraySetAsSeries(xcaFiboLevel2Buffer, true);
|
||||
|
||||
ArraySetAsSeries(x3maFastBuffer, true);
|
||||
ArraySetAsSeries(x3maFastColorBuffer, true);
|
||||
ArraySetAsSeries(x3maMediumBuffer, true);
|
||||
ArraySetAsSeries(x3maMediumColorBuffer, true);
|
||||
ArraySetAsSeries(x3maSlowBuffer, true);
|
||||
ArraySetAsSeries(x3maSlowColorBuffer, true);
|
||||
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
// Release indicator handles
|
||||
if (xcaHandle != INVALID_HANDLE)
|
||||
IndicatorRelease(xcaHandle);
|
||||
|
||||
if (x3maHandle != INVALID_HANDLE)
|
||||
IndicatorRelease(x3maHandle);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
// Check if we're allowed to trade based on time filter
|
||||
if (UseTimeFilter && !IsTradeTimeAllowed())
|
||||
return;
|
||||
|
||||
// Get current bar time
|
||||
datetime currentBarTime = iTime(_Symbol, _Period, 0);
|
||||
|
||||
// Only process on new bar
|
||||
if (currentBarTime == lastBarTime)
|
||||
return;
|
||||
|
||||
lastBarTime = currentBarTime;
|
||||
|
||||
// Update indicator buffers
|
||||
if (!UpdateIndicatorBuffers())
|
||||
return;
|
||||
|
||||
// Check for open positions and manage them
|
||||
ManageOpenPositions();
|
||||
|
||||
// Check for new trade signals
|
||||
CheckForTradeSignals();
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Update all indicator buffers |
|
||||
//+------------------------------------------------------------------+
|
||||
bool UpdateIndicatorBuffers()
|
||||
{
|
||||
// Copy XCA indicator buffers
|
||||
if (CopyBuffer(xcaHandle, 18, 0, 3, xcaTrendBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 19, 0, 3, xcaTrendColorBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 20, 0, 3, xcaKIBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 21, 0, 3, xcaKIColorBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 26, 0, 3, xcaVidyaBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 27, 0, 3, xcaVidyaColorBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 22, 0, 3, xcaSwingLowBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 23, 0, 3, xcaSwingHighBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 8, 0, 3, xcaSupportBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 9, 0, 3, xcaResistanceBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 0, 0, 3, xcaSHBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 1, 0, 3, xcaSLBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 2, 0, 3, xcaMHBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 3, 0, 3, xcaMLBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(xcaHandle, 15, 0, 3, xcaFiboLevel2Buffer) < 3)
|
||||
return false;
|
||||
|
||||
// Copy X3MA indicator buffers
|
||||
if (CopyBuffer(x3maHandle, 0, 0, 3, x3maFastBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(x3maHandle, 1, 0, 3, x3maFastColorBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(x3maHandle, 2, 0, 3, x3maMediumBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(x3maHandle, 3, 0, 3, x3maMediumColorBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(x3maHandle, 4, 0, 3, x3maSlowBuffer) < 3)
|
||||
return false;
|
||||
if (CopyBuffer(x3maHandle, 5, 0, 3, x3maSlowColorBuffer) < 3)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check if current time is within allowed trading hours |
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsTradeTimeAllowed()
|
||||
{
|
||||
// If time filter is not enabled, always allow trading
|
||||
if (!UseTimeFilter)
|
||||
return true;
|
||||
|
||||
// Get current server time
|
||||
datetime serverTime = TimeCurrent();
|
||||
MqlDateTime currentTime;
|
||||
TimeToStruct(serverTime, currentTime);
|
||||
|
||||
// Convert start and end time strings to hours and minutes
|
||||
int startHour = 0, startMinute = 0;
|
||||
int endHour = 0, endMinute = 0;
|
||||
|
||||
// Parse start time
|
||||
string startTimeParts[];
|
||||
if (StringSplit(StartTradeTime, ':', startTimeParts) == 2)
|
||||
{
|
||||
startHour = (int)StringToInteger(startTimeParts[0]);
|
||||
startMinute = (int)StringToInteger(startTimeParts[1]);
|
||||
}
|
||||
|
||||
// Parse end time
|
||||
string endTimeParts[];
|
||||
if (StringSplit(EndTradeTime, ':', endTimeParts) == 2)
|
||||
{
|
||||
endHour = (int)StringToInteger(endTimeParts[0]);
|
||||
endMinute = (int)StringToInteger(endTimeParts[1]);
|
||||
}
|
||||
|
||||
// Convert current time, start time and end time to minutes for easy comparison
|
||||
int currentTimeInMinutes = currentTime.hour * 60 + currentTime.min;
|
||||
int startTimeInMinutes = startHour * 60 + startMinute;
|
||||
int endTimeInMinutes = endHour * 60 + endMinute;
|
||||
|
||||
// Check if current time is within trading hours
|
||||
bool isAllowed = false;
|
||||
|
||||
// If end time is greater than start time (same day trading session)
|
||||
if (endTimeInMinutes > startTimeInMinutes)
|
||||
{
|
||||
isAllowed = (currentTimeInMinutes >= startTimeInMinutes &&
|
||||
currentTimeInMinutes <= endTimeInMinutes);
|
||||
}
|
||||
// If end time is less than start time (overnight trading session)
|
||||
else if (endTimeInMinutes < startTimeInMinutes)
|
||||
{
|
||||
isAllowed = (currentTimeInMinutes >= startTimeInMinutes ||
|
||||
currentTimeInMinutes <= endTimeInMinutes);
|
||||
}
|
||||
// If start time equals end time (24-hour trading)
|
||||
else
|
||||
{
|
||||
isAllowed = true;
|
||||
}
|
||||
|
||||
return isAllowed;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check for new trade signals |
|
||||
//+------------------------------------------------------------------+
|
||||
void CheckForTradeSignals()
|
||||
{
|
||||
// Don't open new trades if we already have open positions
|
||||
if (CountOpenPositions() > 0)
|
||||
return;
|
||||
|
||||
// Check for buy signal
|
||||
if (IsBuySignal())
|
||||
{
|
||||
OpenBuyPosition();
|
||||
}
|
||||
// Check for sell signal
|
||||
else if (IsSellSignal())
|
||||
{
|
||||
OpenSellPosition();
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check if we have a valid buy signal |
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsBuySignal()
|
||||
{
|
||||
// 1. Trend Confirmation
|
||||
bool trendConfirmation = true;
|
||||
if (UseTrendConfirmation)
|
||||
{
|
||||
// X3MA: Fast MA crosses above Medium MA
|
||||
bool fastCrossingAboveMedium = x3maFastBuffer[1] <= x3maMediumBuffer[1] &&
|
||||
x3maFastBuffer[0] > x3maMediumBuffer[0];
|
||||
|
||||
// X3MA: All three MAs are in bullish alignment
|
||||
bool maAlignment = true;
|
||||
if (UseMAAlignment)
|
||||
{
|
||||
maAlignment = x3maFastBuffer[0] > x3maMediumBuffer[0] &&
|
||||
x3maMediumBuffer[0] > x3maSlowBuffer[0];
|
||||
}
|
||||
|
||||
// XCA: VIDYA line shows bullish color
|
||||
bool vidyaBullish = true;
|
||||
if (UseVidyaConfirmation)
|
||||
{
|
||||
vidyaBullish = xcaVidyaColorBuffer[0] == 1; // 1 is bullish color index
|
||||
}
|
||||
|
||||
// XCA: Trend line shows bullish color
|
||||
bool trendBullish = xcaTrendColorBuffer[0] == 1; // 1 is bullish color index
|
||||
|
||||
trendConfirmation = (fastCrossingAboveMedium || maAlignment) &&
|
||||
(vidyaBullish || !UseVidyaConfirmation) &&
|
||||
trendBullish;
|
||||
}
|
||||
|
||||
// 2. Cycle Analysis
|
||||
bool cycleAnalysis = true;
|
||||
{
|
||||
// XCA: Price is above the Short Cycle low
|
||||
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||
bool priceAboveSL = currentPrice > xcaSLBuffer[0];
|
||||
|
||||
// XCA: Medium Cycle is in uptrend phase
|
||||
bool mediumCycleUptrend = xcaMLBuffer[0] > xcaMLBuffer[1];
|
||||
|
||||
// XCA: Support level is established and holding
|
||||
bool supportHolding = currentPrice > xcaSupportBuffer[0];
|
||||
|
||||
cycleAnalysis = priceAboveSL && mediumCycleUptrend && supportHolding;
|
||||
}
|
||||
|
||||
// 3. Entry Timing
|
||||
bool entryTiming = true;
|
||||
{
|
||||
// XCA: A swing low is identified
|
||||
bool swingLowFound = UseSwingPoints ? xcaSwingLowBuffer[0] != 0 : true;
|
||||
|
||||
// XCA: Price is near but above the Fibonacci level 2 (50% retracement)
|
||||
bool nearFiboLevel = true;
|
||||
if (UseFiboLevels)
|
||||
{
|
||||
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||
double fiboLevel = xcaFiboLevel2Buffer[0];
|
||||
double priceDiff = MathAbs(currentPrice - fiboLevel);
|
||||
double priceRange = xcaResistanceBuffer[0] - xcaSupportBuffer[0];
|
||||
nearFiboLevel = priceDiff < priceRange * 0.1 && currentPrice > fiboLevel;
|
||||
}
|
||||
|
||||
// XCA: KI line shows bullish color
|
||||
bool kiBullish = true;
|
||||
if (UseKIConfirmation)
|
||||
{
|
||||
kiBullish = xcaKIColorBuffer[0] == 1; // 1 is bullish color index
|
||||
}
|
||||
|
||||
entryTiming = swingLowFound && (nearFiboLevel || !UseFiboLevels) &&
|
||||
(kiBullish || !UseKIConfirmation);
|
||||
}
|
||||
|
||||
return trendConfirmation && cycleAnalysis && entryTiming;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check if we have a valid sell signal |
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsSellSignal()
|
||||
{
|
||||
// 1. Trend Confirmation
|
||||
bool trendConfirmation = true;
|
||||
if (UseTrendConfirmation)
|
||||
{
|
||||
// X3MA: Fast MA crosses below Medium MA
|
||||
bool fastCrossingBelowMedium = x3maFastBuffer[1] >= x3maMediumBuffer[1] &&
|
||||
x3maFastBuffer[0] < x3maMediumBuffer[0];
|
||||
|
||||
// X3MA: All three MAs are in bearish alignment
|
||||
bool maAlignment = true;
|
||||
if (UseMAAlignment)
|
||||
{
|
||||
maAlignment = x3maFastBuffer[0] < x3maMediumBuffer[0] &&
|
||||
x3maMediumBuffer[0] < x3maSlowBuffer[0];
|
||||
}
|
||||
|
||||
// XCA: VIDYA line shows bearish color
|
||||
bool vidyaBearish = true;
|
||||
if (UseVidyaConfirmation)
|
||||
{
|
||||
vidyaBearish = xcaVidyaColorBuffer[0] == 2; // 2 is bearish color index
|
||||
}
|
||||
|
||||
// XCA: Trend line shows bearish color
|
||||
bool trendBearish = xcaTrendColorBuffer[0] == 2; // 2 is bearish color index
|
||||
|
||||
trendConfirmation = (fastCrossingBelowMedium || maAlignment) &&
|
||||
(vidyaBearish || !UseVidyaConfirmation) &&
|
||||
trendBearish;
|
||||
}
|
||||
|
||||
// 2. Cycle Analysis
|
||||
bool cycleAnalysis = true;
|
||||
{
|
||||
// XCA: Price is below the Short Cycle high
|
||||
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||
bool priceBelowSH = currentPrice < xcaSHBuffer[0];
|
||||
|
||||
// XCA: Medium Cycle is in downtrend phase
|
||||
bool mediumCycleDowntrend = xcaMHBuffer[0] < xcaMHBuffer[1];
|
||||
|
||||
// XCA: Resistance level is established and holding
|
||||
bool resistanceHolding = currentPrice < xcaResistanceBuffer[0];
|
||||
|
||||
cycleAnalysis = priceBelowSH && mediumCycleDowntrend && resistanceHolding;
|
||||
}
|
||||
|
||||
// 3. Entry Timing
|
||||
bool entryTiming = true;
|
||||
{
|
||||
// XCA: A swing high is identified
|
||||
bool swingHighFound = UseSwingPoints ? xcaSwingHighBuffer[0] != 0 : true;
|
||||
|
||||
// XCA: Price is near but below the Fibonacci level 2 (50% retracement)
|
||||
bool nearFiboLevel = true;
|
||||
if (UseFiboLevels)
|
||||
{
|
||||
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||
double fiboLevel = xcaFiboLevel2Buffer[0];
|
||||
double priceDiff = MathAbs(currentPrice - fiboLevel);
|
||||
double priceRange = xcaResistanceBuffer[0] - xcaSupportBuffer[0];
|
||||
nearFiboLevel = priceDiff < priceRange * 0.1 && currentPrice < fiboLevel;
|
||||
}
|
||||
|
||||
// XCA: KI line shows bearish color
|
||||
bool kiBearish = true;
|
||||
if (UseKIConfirmation)
|
||||
{
|
||||
kiBearish = xcaKIColorBuffer[0] == 2; // 2 is bearish color index
|
||||
}
|
||||
|
||||
entryTiming = swingHighFound && (nearFiboLevel || !UseFiboLevels) &&
|
||||
(kiBearish || !UseKIConfirmation);
|
||||
}
|
||||
|
||||
return trendConfirmation && cycleAnalysis && entryTiming;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Count open positions with our magic number |
|
||||
//+------------------------------------------------------------------+
|
||||
int CountOpenPositions()
|
||||
{
|
||||
int count = 0;
|
||||
int total = PositionsTotal();
|
||||
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if (ticket <= 0)
|
||||
continue;
|
||||
|
||||
// Check if position belongs to current symbol and our EA
|
||||
if (PositionGetString(POSITION_SYMBOL) == _Symbol &&
|
||||
PositionGetInteger(POSITION_MAGIC) == magicNumber)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Manage open positions (trailing stops, partial closes) |
|
||||
//+------------------------------------------------------------------+
|
||||
void ManageOpenPositions()
|
||||
{
|
||||
int total = PositionsTotal();
|
||||
|
||||
// Loop through all open positions
|
||||
for (int i = total - 1; i >= 0; i--)
|
||||
{
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if (ticket <= 0)
|
||||
continue;
|
||||
|
||||
// Check if position belongs to current symbol and our EA
|
||||
if (PositionGetString(POSITION_SYMBOL) != _Symbol ||
|
||||
PositionGetInteger(POSITION_MAGIC) != magicNumber)
|
||||
continue;
|
||||
|
||||
// Get position details
|
||||
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||
double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
|
||||
double stopLoss = PositionGetDouble(POSITION_SL);
|
||||
double takeProfit = PositionGetDouble(POSITION_TP);
|
||||
double positionVolume = PositionGetDouble(POSITION_VOLUME);
|
||||
ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
||||
|
||||
// Check for exit signals
|
||||
bool exitSignal = false;
|
||||
|
||||
// For BUY positions
|
||||
if (positionType == POSITION_TYPE_BUY)
|
||||
{
|
||||
// Exit if Fast MA crosses below Medium MA
|
||||
if (x3maFastBuffer[1] > x3maMediumBuffer[1] && x3maFastBuffer[0] <= x3maMediumBuffer[0])
|
||||
exitSignal = true;
|
||||
|
||||
// Apply trailing stop if enabled
|
||||
if (UseTrailingStop && !exitSignal)
|
||||
{
|
||||
// Calculate new stop loss level
|
||||
double newStopLoss = 0;
|
||||
|
||||
// Use the most recent swing low as trailing stop if available
|
||||
if (xcaSwingLowBuffer[0] > 0 && xcaSwingLowBuffer[0] < currentPrice)
|
||||
{
|
||||
newStopLoss = xcaSwingLowBuffer[0] - 5 * _Point;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Traditional trailing stop
|
||||
double trailingLevel = currentPrice - TrailingStop * _Point;
|
||||
if (trailingLevel > stopLoss + TrailingStep * _Point)
|
||||
newStopLoss = trailingLevel;
|
||||
}
|
||||
|
||||
// Update stop loss if we have a better level
|
||||
if (newStopLoss > stopLoss && newStopLoss > 0)
|
||||
{
|
||||
trade.PositionModify(ticket, newStopLoss, takeProfit);
|
||||
Print("Updated BUY trailing stop to: ", newStopLoss);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle multiple targets
|
||||
if (UseMultipleTargets && positionVolume > LotSize * 0.5)
|
||||
{
|
||||
// First target: When price reaches resistance or initial TP
|
||||
if (currentPrice >= xcaResistanceBuffer[0] && xcaResistanceBuffer[0] > openPrice)
|
||||
{
|
||||
double closeVolume = NormalizeDouble(positionVolume * Target1Percent / 100, 2);
|
||||
if (closeVolume > 0)
|
||||
{
|
||||
trade.PositionClosePartial(ticket, closeVolume);
|
||||
Print("First target reached for BUY position. Partially closed: ", closeVolume);
|
||||
}
|
||||
}
|
||||
|
||||
// Second target: When price reaches Fibonacci level 3 (76.4%)
|
||||
double fiboLevel3Buffer[];
|
||||
ArraySetAsSeries(fiboLevel3Buffer, true);
|
||||
if (CopyBuffer(xcaHandle, 16, 0, 1, fiboLevel3Buffer) > 0)
|
||||
{
|
||||
double fiboLevel3 = fiboLevel3Buffer[0];
|
||||
if (fiboLevel3 > 0 && currentPrice >= fiboLevel3 && fiboLevel3 > openPrice)
|
||||
{
|
||||
double closeVolume = NormalizeDouble(positionVolume * Target2Percent / 100, 2);
|
||||
if (closeVolume > 0)
|
||||
{
|
||||
trade.PositionClosePartial(ticket, closeVolume);
|
||||
Print("Second target reached for BUY position. Partially closed: ", closeVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// For SELL positions
|
||||
else if (positionType == POSITION_TYPE_SELL)
|
||||
{
|
||||
// Exit if Fast MA crosses above Medium MA
|
||||
if (x3maFastBuffer[1] < x3maMediumBuffer[1] && x3maFastBuffer[0] >= x3maMediumBuffer[0])
|
||||
exitSignal = true;
|
||||
|
||||
// Apply trailing stop if enabled
|
||||
if (UseTrailingStop && !exitSignal)
|
||||
{
|
||||
// Calculate new stop loss level
|
||||
double newStopLoss = 0;
|
||||
|
||||
// Use the most recent swing high as trailing stop if available
|
||||
if (xcaSwingHighBuffer[0] > 0 && xcaSwingHighBuffer[0] > currentPrice)
|
||||
{
|
||||
newStopLoss = xcaSwingHighBuffer[0] + 5 * _Point;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Traditional trailing stop
|
||||
double trailingLevel = currentPrice + TrailingStop * _Point;
|
||||
if (trailingLevel < stopLoss - TrailingStep * _Point || stopLoss == 0)
|
||||
newStopLoss = trailingLevel;
|
||||
}
|
||||
|
||||
// Update stop loss if we have a better level
|
||||
if ((newStopLoss < stopLoss || stopLoss == 0) && newStopLoss > 0)
|
||||
{
|
||||
trade.PositionModify(ticket, newStopLoss, takeProfit);
|
||||
Print("Updated SELL trailing stop to: ", newStopLoss);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle multiple targets
|
||||
if (UseMultipleTargets && positionVolume > LotSize * 0.5)
|
||||
{
|
||||
// First target: When price reaches support or initial TP
|
||||
if (currentPrice <= xcaSupportBuffer[0] && xcaSupportBuffer[0] < openPrice)
|
||||
{
|
||||
double closeVolume = NormalizeDouble(positionVolume * Target1Percent / 100, 2);
|
||||
if (closeVolume > 0)
|
||||
{
|
||||
trade.PositionClosePartial(ticket, closeVolume);
|
||||
Print("First target reached for SELL position. Partially closed: ", closeVolume);
|
||||
}
|
||||
}
|
||||
|
||||
// Second target: When price reaches Fibonacci level 3 (76.4%)
|
||||
double fiboLevel3Buffer[];
|
||||
ArraySetAsSeries(fiboLevel3Buffer, true);
|
||||
if (CopyBuffer(xcaHandle, 16, 0, 1, fiboLevel3Buffer) > 0)
|
||||
{
|
||||
double fiboLevel3 = fiboLevel3Buffer[0];
|
||||
if (fiboLevel3 > 0 && currentPrice <= fiboLevel3 && fiboLevel3 < openPrice)
|
||||
{
|
||||
double closeVolume = NormalizeDouble(positionVolume * Target2Percent / 100, 2);
|
||||
if (closeVolume > 0)
|
||||
{
|
||||
trade.PositionClosePartial(ticket, closeVolume);
|
||||
Print("Second target reached for SELL position. Partially closed: ", closeVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close position if exit signal is triggered
|
||||
if (exitSignal)
|
||||
{
|
||||
trade.PositionClose(ticket);
|
||||
Print("Exit signal triggered. Position closed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Open a buy position with proper risk management |
|
||||
//+------------------------------------------------------------------+
|
||||
void OpenBuyPosition()
|
||||
{
|
||||
double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||
double stopLossPrice = 0;
|
||||
double takeProfitPrice = 0;
|
||||
|
||||
// Calculate stop loss price
|
||||
if (StopLoss > 0)
|
||||
{
|
||||
// Use either the specified stop loss or the swing low, whichever is closer
|
||||
double swingLowPrice = xcaSwingLowBuffer[0];
|
||||
double slByPoints = entryPrice - StopLoss * _Point;
|
||||
|
||||
// If we have a valid swing low and it's not too far
|
||||
if (swingLowPrice > 0 && entryPrice - swingLowPrice < StopLoss * 2 * _Point)
|
||||
stopLossPrice = swingLowPrice - 5 * _Point; // Place SL slightly below swing low
|
||||
else
|
||||
stopLossPrice = slByPoints;
|
||||
}
|
||||
|
||||
// Calculate take profit price
|
||||
if (TakeProfit > 0)
|
||||
{
|
||||
// If using multiple targets, we'll set the first one here and manage the rest in position management
|
||||
if (UseMultipleTargets)
|
||||
{
|
||||
// Use resistance level as first target if available
|
||||
if (xcaResistanceBuffer[0] > entryPrice)
|
||||
takeProfitPrice = xcaResistanceBuffer[0];
|
||||
else
|
||||
takeProfitPrice = entryPrice + TakeProfit * _Point;
|
||||
}
|
||||
else
|
||||
{
|
||||
takeProfitPrice = entryPrice + TakeProfit * _Point;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate position size
|
||||
double volume = LotSize;
|
||||
if (UseAutoLotSize && stopLossPrice > 0)
|
||||
{
|
||||
double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100;
|
||||
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) *
|
||||
(SymbolInfoDouble(_Symbol, SYMBOL_POINT) / SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
|
||||
double pipDistance = MathAbs(entryPrice - stopLossPrice) / SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
||||
|
||||
if (pipDistance > 0 && pipValue > 0)
|
||||
volume = NormalizeDouble(riskAmount / (pipDistance * pipValue), 2);
|
||||
|
||||
// Ensure volume is within allowed limits
|
||||
double minVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
double maxVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double volumeStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
||||
|
||||
volume = MathMax(minVolume, MathMin(maxVolume, volume));
|
||||
volume = NormalizeDouble(volume / volumeStep, 0) * volumeStep;
|
||||
}
|
||||
|
||||
// Execute the trade
|
||||
trade.Buy(volume, _Symbol, 0, stopLossPrice, takeProfitPrice, "X121 Strategy Buy");
|
||||
|
||||
// Log the trade
|
||||
Print("BUY Signal: Opening position at ", entryPrice,
|
||||
", SL: ", stopLossPrice,
|
||||
", TP: ", takeProfitPrice,
|
||||
", Volume: ", volume);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Open a sell position with proper risk management |
|
||||
//+------------------------------------------------------------------+
|
||||
void OpenSellPosition()
|
||||
{
|
||||
double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||
double stopLossPrice = 0;
|
||||
double takeProfitPrice = 0;
|
||||
|
||||
// Calculate stop loss price
|
||||
if (StopLoss > 0)
|
||||
{
|
||||
// Use either the specified stop loss or the swing high, whichever is closer
|
||||
double swingHighPrice = xcaSwingHighBuffer[0];
|
||||
double slByPoints = entryPrice + StopLoss * _Point;
|
||||
|
||||
// If we have a valid swing high and it's not too far
|
||||
if (swingHighPrice > 0 && swingHighPrice - entryPrice < StopLoss * 2 * _Point)
|
||||
stopLossPrice = swingHighPrice + 5 * _Point; // Place SL slightly above swing high
|
||||
else
|
||||
stopLossPrice = slByPoints;
|
||||
}
|
||||
|
||||
// Calculate take profit price
|
||||
if (TakeProfit > 0)
|
||||
{
|
||||
// If using multiple targets, we'll set the first one here and manage the rest in position management
|
||||
if (UseMultipleTargets)
|
||||
{
|
||||
// Use support level as first target if available
|
||||
if (xcaSupportBuffer[0] > 0 && xcaSupportBuffer[0] < entryPrice)
|
||||
takeProfitPrice = xcaSupportBuffer[0];
|
||||
else
|
||||
takeProfitPrice = entryPrice - TakeProfit * _Point;
|
||||
}
|
||||
else
|
||||
{
|
||||
takeProfitPrice = entryPrice - TakeProfit * _Point;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate position size
|
||||
double volume = LotSize;
|
||||
if (UseAutoLotSize && stopLossPrice > 0)
|
||||
{
|
||||
double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100;
|
||||
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) *
|
||||
(SymbolInfoDouble(_Symbol, SYMBOL_POINT) / SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
|
||||
double pipDistance = MathAbs(entryPrice - stopLossPrice) / SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
||||
|
||||
if (pipDistance > 0 && pipValue > 0)
|
||||
volume = NormalizeDouble(riskAmount / (pipDistance * pipValue), 2);
|
||||
|
||||
// Ensure volume is within allowed limits
|
||||
double minVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
double maxVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double volumeStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
||||
|
||||
volume = MathMax(minVolume, MathMin(maxVolume, volume));
|
||||
volume = NormalizeDouble(volume / volumeStep, 0) * volumeStep;
|
||||
}
|
||||
|
||||
// Execute the trade
|
||||
trade.Sell(volume, _Symbol, 0, stopLossPrice, takeProfitPrice, "X121 Strategy Sell");
|
||||
|
||||
// Log the trade
|
||||
Print("SELL Signal: Opening position at ", entryPrice,
|
||||
", SL: ", stopLossPrice,
|
||||
", TP: ", takeProfitPrice,
|
||||
", Volume: ", volume);
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XTest MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XRRToolsEA
|
||||
// Description: a Template For Exper Advisors
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////x
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XRRToolsEA"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#define ShortName "XRRTools"
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
||||
#include "../Classes/x-saherelm.x-rm.panel.class.mq5"
|
||||
#include "../Classes/x-saherelm.x-trade.class.mq5"
|
||||
#include "../Helpers/x-saherelm.x121.xcc.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.x121.xct.helper.mq5"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
|
||||
//
|
||||
// Common ...
|
||||
input group "Common";
|
||||
input long eaMagicNumber = 78692110; // Magic Number
|
||||
input int eaSlippage = 10; // Slippgae
|
||||
input string eaLogSuffix = ""; // Log Suffix
|
||||
|
||||
//
|
||||
// Alert ...
|
||||
// Here we Provider All Requirements for
|
||||
// Configuring Alert Provider ...
|
||||
input group "Alert";
|
||||
input bool eAEnableAlerts = true; // Enable Alerts
|
||||
input bool eALogAlerts = true; // Log Alerts
|
||||
input bool eAMailAlerts = false; // Mail Alerts
|
||||
input bool eAPushAlerts = false; // Push Alerts
|
||||
input bool eATerminalAlerts = false; // Terminal Alerts
|
||||
|
||||
//
|
||||
// Define Local Variables ...
|
||||
|
||||
//
|
||||
string eaLogTag; // EA Log Prefix ...
|
||||
XCAlert *eaAlert; // Alert Provider for Expert Adviser ...
|
||||
XCTrade *eaTrader; // Trader of Expert Adviser ...
|
||||
XCRMPanel eaMainWindow; // Main Window ...
|
||||
XCX121XCTHelper *eaCTHelper; // Bar Timer Indicator Helper class ...
|
||||
XCX121XCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs and Required Parameters
|
||||
// for EA to Works fine ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize Timer ...
|
||||
if (!InitTimer())
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize all Requirements ...
|
||||
if (!InitEA())
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize all GUI Objects and Classes ...
|
||||
if (!InitGUI())
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Alert Initialization ...
|
||||
string msg = "Initialized Successfully ...";
|
||||
eaAlert.Alert(msg);
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Destroy Timer ...
|
||||
DestroyTimer();
|
||||
|
||||
//
|
||||
// Destroy all GUI Requirements ...
|
||||
DestroyGUI();
|
||||
|
||||
//
|
||||
// Alert De Initialization Succeeded ...
|
||||
string msg = "De Initialized Successfully ...";
|
||||
eaAlert.Alert(msg);
|
||||
|
||||
//
|
||||
// Destroy all EA Requirements ...
|
||||
DestroyEA();
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle On Trade Event ...
|
||||
void OnTrade()
|
||||
{
|
||||
eaTrader.HandleOnTrade();
|
||||
}
|
||||
|
||||
//
|
||||
// On Timer ...
|
||||
void OnTimer()
|
||||
{
|
||||
//
|
||||
// TODO: Implement Time Based Functionalities ...
|
||||
}
|
||||
|
||||
//
|
||||
// Chart Event Handler ...
|
||||
void OnChartEvent(
|
||||
const int id,
|
||||
const long &lparam,
|
||||
const double &dparam,
|
||||
const string &sparam //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Apply Chart Event on Main Window ...
|
||||
eaMainWindow.ChartEvent(id, lparam, dparam, sparam);
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Event Handlers ...
|
||||
|
||||
/**
|
||||
* Handle StopLoss Triggered Positions ...
|
||||
*
|
||||
* @param deal: XDeal ...
|
||||
*/
|
||||
void OnStopLossTriggered(const XDeal &deal)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Take Profit Triggered Positions ...
|
||||
*
|
||||
* @param deal: XDeal ...
|
||||
*/
|
||||
void OnTakeProfitTriggered(const XDeal &deal)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Force Close a Position ...
|
||||
*
|
||||
* @param ticket: Position Ticket ...
|
||||
* @param position: XPosition ...
|
||||
* @param comment: Closing Comment ...
|
||||
*/
|
||||
void OnPositionForceClosed(
|
||||
const ulong ticket,
|
||||
const XPosition &position,
|
||||
const string comment //
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Functions ...
|
||||
|
||||
/**
|
||||
* Validate all Inputs of Expert Adviser ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
string errMessage = "";
|
||||
|
||||
//
|
||||
bool isCommonValid = (
|
||||
//
|
||||
eaSlippage > 0 &&
|
||||
eaMagicNumber > 0
|
||||
//
|
||||
);
|
||||
if (!isCommonValid)
|
||||
{
|
||||
//
|
||||
errMessage += "common configurations error;" + "\n";
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// Common ...
|
||||
isCommonValid &&
|
||||
//
|
||||
// Otere ...
|
||||
true
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
||||
Print(ShortName + " Errors: \n", errMessage);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Timer ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool InitTimer()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Initialize Timer if necessary ...
|
||||
// result = EventSetTimer(1);
|
||||
// result = EventSetMillisecondTimer(100);
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy Timer ...
|
||||
*/
|
||||
void DestroyTimer()
|
||||
{
|
||||
//
|
||||
// TODO: Use This ...
|
||||
// EventKillTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all Requirements for Working Fine ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool InitEA()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Locally Apply Changes on Prefix ...
|
||||
eaLogTag = ShortName + ">" + eaLogSuffix;
|
||||
|
||||
//
|
||||
// Bar Timer ...
|
||||
X121XCTInputs ctInputs;
|
||||
ctInputs.Default(); // Default Configurations ...
|
||||
eaCTHelper = new XCX121XCTHelper();
|
||||
result = eaCTHelper.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
ctInputs //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Bar Styles ...
|
||||
X121XCCInputs ccInputs;
|
||||
ccInputs.Default(); // Default Configurations ...
|
||||
eaCCHelper = new XCX121XCCHelper();
|
||||
result = eaCCHelper.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
ccInputs //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Create Instance of Alert Class and Configure it ...
|
||||
eaAlert = new XCAlert();
|
||||
eaAlert.SetPrefix(eaLogTag);
|
||||
eaAlert.SetLogAlerts(eALogAlerts);
|
||||
eaAlert.SetMailAlerts(eAMailAlerts);
|
||||
eaAlert.SetPushAlerts(eAPushAlerts);
|
||||
eaAlert.SetEnableAlerts(eAEnableAlerts);
|
||||
eaAlert.SetTerminalAlerts(eATerminalAlerts);
|
||||
|
||||
//
|
||||
// Create Trader Instance and Configure it ...
|
||||
eaTrader = new XCTrade(
|
||||
eaSlippage,
|
||||
eaMagicNumber //
|
||||
);
|
||||
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
|
||||
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
||||
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all Initialized EA Requirements ...
|
||||
*/
|
||||
void DestroyEA()
|
||||
{
|
||||
//
|
||||
delete eaCTHelper;
|
||||
delete eaCCHelper;
|
||||
|
||||
//
|
||||
delete eaAlert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all GUI Requirements for EA ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool InitGUI()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Initialize Application Main Window ...
|
||||
result = eaMainWindow.Create(
|
||||
ChartID(),
|
||||
ShortName, // Dialog Name ...
|
||||
0, // SubWindow ...
|
||||
10, // X1 ...
|
||||
35, // Y1 ...
|
||||
300, // X2 ...
|
||||
200 // Y2 ...
|
||||
);
|
||||
|
||||
//
|
||||
// Try To Run Main Window ...
|
||||
if (result)
|
||||
{
|
||||
eaMainWindow.Run();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update GUI based on Each Ticks ...
|
||||
*/
|
||||
void UpdateGUI()
|
||||
{
|
||||
//
|
||||
eaMainWindow.UpdateState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all Initialized GUi Requirements ...
|
||||
*/
|
||||
void DestroyGUI()
|
||||
{
|
||||
//
|
||||
eaMainWindow.Destroy();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -0,0 +1,745 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XCAEA MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XCAEA
|
||||
// Description: an Exper Advisor which used Panels
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XCAEA EA"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
||||
#include "../Classes/x-saherelm.x-trade.class.mq5"
|
||||
#include "../Classes/x-saherelm.x-volume.class.mq5"
|
||||
#include "../XCAEA/Classes/xcaea.x-trade.manager.class.mq5"
|
||||
#include "../XCAEA/Signals/xcaea.signaller.class.mq5"
|
||||
|
||||
//
|
||||
#define ShortName "XCAEAEA"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
|
||||
//
|
||||
// Common ...
|
||||
input group "Common";
|
||||
input long eaMagicNumber = 78692110; // Magic Number
|
||||
input int eaSlippage = 10; // Slippgae
|
||||
input string eaLogSuffix = ""; // Log Suffix
|
||||
|
||||
//
|
||||
// Volume ...
|
||||
input group "Volume";
|
||||
input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_EQUITY; // Volume Applying Type
|
||||
input double eaStaticVoluem = 0.0; // Static Volume
|
||||
input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume
|
||||
input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing
|
||||
input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade
|
||||
input double eaConstantPercent = 0.5; // Constant Percent of Balance Per Trade
|
||||
input double eaConstantBalance = 0.0; // Constant Balance for Calculations
|
||||
|
||||
//
|
||||
// Management ...
|
||||
input group "Management";
|
||||
input bool eaAllowTrade = true; // Allow Trade on Signals
|
||||
input bool eaAllowLongs = true; // Allow Long Trades
|
||||
input bool eaAllowShorts = true; // Allow Short Trades
|
||||
input int eaMaxAllowedTradesPerDay = 3; // Max Allowed Trades per Day
|
||||
input int eaMaxAllowedSLsPerDay = 2; // Max Allowed SL(s) per Day
|
||||
input string eaSessionStartTime = ""; // Trade Start Time
|
||||
input string eaSessionEndTime = ""; // Trade End Time
|
||||
input int eaMaxAllowedPositions = 5; // Max Allowed Same Time Trades
|
||||
input double eaMaxAllowedSpread = 25; // Max Allowed Spread For Trade
|
||||
input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade
|
||||
input string eaCloseAllOpenTradesAt = ""; // Close All Open Trades per Day At Specified Time
|
||||
|
||||
//
|
||||
// Alert ...
|
||||
// Here we Provider All Requirements for
|
||||
// Configuring Alert Provider ...
|
||||
input group "Alert";
|
||||
input bool eaEnableAlerts = true; // Enable Alerts
|
||||
input bool eaLogAlerts = true; // Log Alerts
|
||||
input bool eaMailAlerts = false; // Mail Alerts
|
||||
input bool eaPushAlerts = false; // Push Alerts
|
||||
input bool eaTerminalAlerts = false; // Terminal Alerts
|
||||
|
||||
//
|
||||
// Time Report ...
|
||||
input group "Reports";
|
||||
input bool eaReportNewMonths = false; // Report New Month
|
||||
input bool eaReportNewWeeks = false; // Report New Weeks
|
||||
input bool eaReportNewDays = true; // Report New Days
|
||||
input bool eaReportNewHours = false; // Report New Hours
|
||||
input bool eaReportTrades = true; // Report Trades
|
||||
input bool eaReportSignals = true; // Report Signals
|
||||
input bool eaReportProtector = true; // Report Protector Actions
|
||||
input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished
|
||||
|
||||
//
|
||||
// Variables, Instances ...
|
||||
XCAlert *eaAlert;
|
||||
XCTrade *eaTrade;
|
||||
XSignal eaSignal;
|
||||
XCVolume *eaVolume;
|
||||
XTimeTracker eaTimeTracker;
|
||||
XCXCAEASignaller *eaSignaller;
|
||||
XCXCAEATradeManager *eaTradeManager;
|
||||
XCAEAStrategyConditions eaConditions;
|
||||
|
||||
//
|
||||
string eaTag = "";
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs and Required Parameters
|
||||
// for EA to Works fine ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize Timer ...
|
||||
if (!InitTimer())
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Initial Requirements ...
|
||||
InitRequirements();
|
||||
|
||||
//
|
||||
// Initialize Volume Manger ...
|
||||
if (!InitVolume())
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// eaSignaller.DeInit();
|
||||
|
||||
//
|
||||
ZeroMemory(eaAlert);
|
||||
ZeroMemory(eaTrade);
|
||||
ZeroMemory(eaVolume);
|
||||
ZeroMemory(eaSignaller);
|
||||
|
||||
//
|
||||
eaSignal.Clean();
|
||||
eaConditions.Clean();
|
||||
eaTimeTracker.Clean();
|
||||
|
||||
//
|
||||
DestroyTimer();
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
int idx = -1;
|
||||
int count = 0;
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
HandleTimeReport();
|
||||
|
||||
//
|
||||
// Handle Position Management / Protections ...
|
||||
eaTradeManager.Manage();
|
||||
|
||||
//
|
||||
eaSignal.Clean();
|
||||
eaConditions.Clean();
|
||||
|
||||
//
|
||||
double r2r = 4;
|
||||
string provider = "XCAEA";
|
||||
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
||||
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
bool hasLong = false;
|
||||
bool hasShort = false;
|
||||
|
||||
//
|
||||
// Start Calculations ...
|
||||
|
||||
//
|
||||
// Retrieve Common Data ...
|
||||
string symbol = eaSignaller.GetSymbol();
|
||||
ENUM_TIMEFRAMES period = eaSignaller.GetPeriod();
|
||||
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
|
||||
//
|
||||
// Required Value For SL/TP Calculations ...
|
||||
double points = GetPoints(symbol);
|
||||
double pip = GetPipPrice(symbol);
|
||||
double pip2 = 2 * pip;
|
||||
|
||||
//
|
||||
has = eaSignaller.DetectSignalSetup(
|
||||
r2r,
|
||||
300 // Max Allowed SL Distance ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
count = eaSignaller
|
||||
.AddConditionsIfNotExists();
|
||||
|
||||
//
|
||||
eaSignaller.mConditions.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Check Setuped Conditions Exists ...
|
||||
count = ArraySize(eaSignaller.mConditionsCollection);
|
||||
has = IsValidSize(count);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
has = eaSignaller
|
||||
.DetectSignalTrigger(eaSignaller
|
||||
.mConditionsCollection[i]);
|
||||
|
||||
//
|
||||
// If Triggered ...
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
idx = i;
|
||||
eaConditions = eaSignaller.mConditionsCollection[i];
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Condition Validation ...
|
||||
has = eaSignaller.mConditionsCollection[i].IsValid() &&
|
||||
eaSignaller.mConditionsCollection[i].IsSetuped();
|
||||
if (!has)
|
||||
{
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Remove Setuped Condition if provided IDX ...
|
||||
has = IsValidIndex(idx);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
ArrayRemove(
|
||||
eaSignaller.mConditionsCollection,
|
||||
idx,
|
||||
1 //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Check EA Conditions is Valid or not ...
|
||||
has = eaConditions.IsSetuped() &&
|
||||
eaConditions.CanTrigger();
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
eaConditions.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Setting Time to Conditions ...
|
||||
eaConditions.time = cTime;
|
||||
has = ToPositionType(
|
||||
type,
|
||||
eaConditions.type //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
eaSignal.Clean();
|
||||
eaConditions.Clean();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Trigger Direction ...
|
||||
hasLong = eaConditions.HasBullishSignal();
|
||||
hasShort = eaConditions.HasBearishSignal();
|
||||
has = hasLong ||
|
||||
hasShort;
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
eaSignal.Clean();
|
||||
eaConditions.Clean();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Preparing Signal ...
|
||||
//
|
||||
eaSignal.mode = mode;
|
||||
eaSignal.type = type;
|
||||
eaSignal.entry = GetEntry(
|
||||
eaConditions.symbol,
|
||||
eaConditions.dir //
|
||||
);
|
||||
eaSignal.provider = provider;
|
||||
eaSignal.sl = eaConditions.sl;
|
||||
eaSignal.tp = eaConditions.tp;
|
||||
eaSignal.volume = X_MIN_VOLUME;
|
||||
eaSignal.time = eaConditions.time;
|
||||
eaSignal.symbol = eaConditions.symbol;
|
||||
eaSignal.period = eaConditions.period;
|
||||
eaSignal.partialCloseOnTPLevel = eaConditions.partialCloseOnTPLevel;
|
||||
eaSignal.partialCloseMultiplier = eaConditions.partialCloseMultiplier;
|
||||
|
||||
//
|
||||
Copy(
|
||||
eaConditions.targets,
|
||||
eaSignal.targets //
|
||||
);
|
||||
|
||||
//
|
||||
has = eaSignal.IsValid();
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
eaSignal.Clean();
|
||||
eaConditions.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Volume Management ...
|
||||
double iVolume = eaVolume.CalculateVolume(eaSignal);
|
||||
if (iVolume > X_MIN_VOLUME &&
|
||||
iVolume != eaSignal.volume)
|
||||
{
|
||||
eaSignal.volume = iVolume;
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Signal ...
|
||||
|
||||
//
|
||||
// Execute Signal ...
|
||||
|
||||
//
|
||||
has = eaTradeManager.Execute(
|
||||
eaSignal,
|
||||
eaConditions //
|
||||
);
|
||||
|
||||
//
|
||||
eaSignal.Clean();
|
||||
eaConditions.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle On Trade Event ...
|
||||
void OnTrade()
|
||||
{
|
||||
eaTrade.HandleOnTrade();
|
||||
}
|
||||
|
||||
//
|
||||
// On Timer ...
|
||||
void OnTimer()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Chart Event Handler ...
|
||||
void OnChartEvent(
|
||||
const int id,
|
||||
const long &lparam,
|
||||
const double &dparam,
|
||||
const string &sparam //
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Event Listeners ...
|
||||
|
||||
/**
|
||||
* Handle StopLoss Triggered Positions ...
|
||||
*
|
||||
* @param deal: XDeal instance ...
|
||||
*/
|
||||
void OnStopLossTriggered(const XDeal &deal)
|
||||
{
|
||||
eaTradeManager.HandleSL(deal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Take Profit Triggered Positions ...
|
||||
*
|
||||
* @param deal: XDeal instance ...
|
||||
*/
|
||||
void OnTakeProfitTriggered(const XDeal &deal)
|
||||
{
|
||||
eaTradeManager.HandleTP(deal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Force Close a Position ...
|
||||
*
|
||||
* @param ticket: ULONG ...
|
||||
* @param position: XPosition instance ...
|
||||
* @param comment: String ...
|
||||
*/
|
||||
void OnPositionForceClosed(
|
||||
const ulong ticket,
|
||||
const XPosition &position,
|
||||
const string comment //
|
||||
)
|
||||
{
|
||||
eaTradeManager.HandleForceClose(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Deals Changes ...
|
||||
*
|
||||
* @param count: Integer, Number of Changes ...
|
||||
*/
|
||||
void OnDealsChanged(int count)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Orders Changes ...
|
||||
*
|
||||
* @param count: Integer, Number of Changes ...
|
||||
*/
|
||||
void OnOrdersChanged(int count)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Positions Changes ...
|
||||
*
|
||||
* @param count: Integer, Number of Changes ...
|
||||
*/
|
||||
void OnPositionsChanged(int count)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Functions ...
|
||||
|
||||
/**
|
||||
* Validate all Inputs of Expert Adviser ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
string errMessage = "";
|
||||
|
||||
//
|
||||
bool isCommonValid = (
|
||||
//
|
||||
eaSlippage > 0 &&
|
||||
eaMagicNumber > 0
|
||||
//
|
||||
);
|
||||
if (!isCommonValid)
|
||||
{
|
||||
//
|
||||
errMessage += "common configurations error;" + "\n";
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// Common ...
|
||||
isCommonValid &&
|
||||
//
|
||||
// Otere ...
|
||||
true
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
||||
Print(ShortName + " Errors: \n", errMessage);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Timer ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool InitTimer()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Initialize Timer if necessary ...
|
||||
// result = EventSetTimer(1);
|
||||
// result = EventSetMillisecondTimer(100);
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy Timer ...
|
||||
*/
|
||||
void DestroyTimer()
|
||||
{
|
||||
//
|
||||
// TODO: Use This ...
|
||||
// EventKillTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial Volume Manager Class Based on Given Configuration ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool InitVolume()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
eaVolume = new XCVolume();
|
||||
|
||||
//
|
||||
result = eaVolume.Init(
|
||||
eaVolumeSelect,
|
||||
eaStaticVoluem,
|
||||
eaDynamicVolumeStepBalance,
|
||||
eaDynamicVolumeStepVolume,
|
||||
eaConstantRiskBalance,
|
||||
eaConstantPercent,
|
||||
eaConstantBalance //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial Requirements of EA ...
|
||||
*/
|
||||
void InitRequirements()
|
||||
{
|
||||
//
|
||||
// Preparing Tags ...
|
||||
eaTag =
|
||||
(IsValid(eaLogSuffix)
|
||||
? eaLogSuffix + "_"
|
||||
: "") +
|
||||
ShortName;
|
||||
|
||||
//
|
||||
// EA Alert ...
|
||||
eaAlert = new XCAlert(
|
||||
eaTag,
|
||||
eaEnableAlerts,
|
||||
eaLogAlerts,
|
||||
eaTerminalAlerts,
|
||||
eaMailAlerts,
|
||||
eaPushAlerts //
|
||||
);
|
||||
|
||||
//
|
||||
// EA Trade ...
|
||||
eaTrade = new XCTrade(
|
||||
eaSlippage,
|
||||
eaMagicNumber,
|
||||
eaMaxAllowedSpread,
|
||||
eaMaxAllowedPositions,
|
||||
eaMaxAllowedDrawdownFactor //
|
||||
);
|
||||
eaTrade.AddOnStopLossEventHandler(OnStopLossTriggered);
|
||||
eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
||||
eaTrade.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
||||
|
||||
//
|
||||
// EA Trae Manager ...
|
||||
eaTradeManager = new XCXCAEATradeManager(
|
||||
eaTrade //
|
||||
);
|
||||
eaTradeManager.SaveTrades(true);
|
||||
eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts);
|
||||
eaTradeManager.SetAlertPrefix(eaTag);
|
||||
eaTradeManager.SetAlertLogAlerts(eaLogAlerts);
|
||||
eaTradeManager.SetAlertMailAlerts(eaMailAlerts);
|
||||
eaTradeManager.SetAlertPushAlerts(eaPushAlerts);
|
||||
eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts);
|
||||
|
||||
//
|
||||
// Setting Trade Reports ...
|
||||
eaTradeManager
|
||||
.SetTradeReports(
|
||||
eaReportTrades,
|
||||
eaReportSignals,
|
||||
eaReportProtector,
|
||||
eaReportAfterTradesBalance //
|
||||
);
|
||||
|
||||
//
|
||||
// Setting Trade Permissions ...
|
||||
eaTradeManager
|
||||
.SetTradePermissions(
|
||||
eaAllowTrade,
|
||||
eaAllowLongs,
|
||||
eaAllowShorts //
|
||||
);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// eaMaxAllowedTradesPerDay
|
||||
// eaMaxAllowedSLsPerDay
|
||||
// eaSessionStartTime
|
||||
// eaSessionEndTime
|
||||
|
||||
//
|
||||
// EA Signaller ...
|
||||
eaSignaller = new XCXCAEASignaller(
|
||||
_Symbol,
|
||||
_Period //
|
||||
);
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handling Time Reporting ...
|
||||
*/
|
||||
void HandleTimeReport()
|
||||
{
|
||||
//
|
||||
// Monthly Report ....
|
||||
if (eaReportNewMonths &&
|
||||
eaTimeTracker.IsNewMonth())
|
||||
{
|
||||
//
|
||||
string msg = "New Month ...";
|
||||
|
||||
//
|
||||
eaAlert.Alert(msg);
|
||||
}
|
||||
|
||||
//
|
||||
// Weekly Report ....
|
||||
if (eaReportNewWeeks &&
|
||||
eaTimeTracker.IsNewWeek())
|
||||
{
|
||||
//
|
||||
string msg = "New Week ...";
|
||||
|
||||
//
|
||||
eaAlert.Alert(msg);
|
||||
}
|
||||
|
||||
//
|
||||
// Daily Report ....
|
||||
bool isNewDay = eaTimeTracker.IsNewDay();
|
||||
if (isNewDay)
|
||||
{
|
||||
//
|
||||
// Handle New Day on Trade Manager ...
|
||||
eaTradeManager.HandleNewDay();
|
||||
|
||||
//
|
||||
// Reporting New Day if Reuired ...
|
||||
if (eaReportNewDays)
|
||||
{
|
||||
//
|
||||
string msg = "New Day ...";
|
||||
|
||||
//
|
||||
eaAlert.Alert(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Hourly Report ....
|
||||
if (eaReportNewHours &&
|
||||
eaTimeTracker.IsNewHour())
|
||||
{
|
||||
//
|
||||
string msg = "New Hour ...";
|
||||
|
||||
//
|
||||
eaAlert.Alert(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
Reference in New Issue
Block a user