last ...
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SaherElm IT Center MQL5 Expert Advisor |
|
||||
//| |
|
||||
//| Name: X121 XPV EA |
|
||||
//| Description: Multi-Timeframe Peak & Vale Breakout Strategy |
|
||||
//| Maintainer: Hadi Khazaee Asl |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#include "../Helpers/x-saherelm.x121.xpv.helper.mq5"
|
||||
|
||||
// Input Parameters
|
||||
input double RiskPercent = 1.0; // Risk per trade in percentage
|
||||
input int StopLossPips = 50; // Stop Loss in pips
|
||||
input int TakeProfitPips = 100; // Take Profit in pips
|
||||
input bool UseTrailingStop = true; // Enable trailing stop
|
||||
input int TrailingStopPips = 30; // Trailing stop distance in pips
|
||||
input int MagicNumber = 123456; // Unique identifier for trades
|
||||
input bool DebugMode = true; // Enable debug messages
|
||||
|
||||
//
|
||||
// Global Variables ...
|
||||
X121XPVInputs mXPVInputs;
|
||||
XCX121XPVHelper *mXPVHelper;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert Initialization Function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Attach the X121 XPV indicator ...
|
||||
mXPVInputs.Default();
|
||||
mXPVHelper = new XCX121XPVHelper();
|
||||
bool isInited = mXPVHelper.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mXPVInputs //
|
||||
);
|
||||
if (!isInited)
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
Print("X121 XPV EA Initialized.");
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert Deinitialization Function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
mXPVInputs.Clean();
|
||||
ZeroMemory(mXPVHelper);
|
||||
Print("X121 XPV EA Deinitialized.");
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert Tick Function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
// Check if there are open positions for this symbol
|
||||
if (PositionSelect(_Symbol))
|
||||
{
|
||||
ManageOpenPosition();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
X121XPVConditions pvConditions;
|
||||
bool isRetrieved = mXPVHelper.GetConditions(
|
||||
pvConditions,
|
||||
1 //
|
||||
);
|
||||
if (!isRetrieved)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Get indicator values
|
||||
double peak = pvConditions.peaksBuffer[0];
|
||||
double vale = pvConditions.valesBuffer[0];
|
||||
double peakGoldenZone = pvConditions.peaksGoldenBuffer[0];
|
||||
double valeGoldenZone = pvConditions.valesGoldenBuffer[0];
|
||||
|
||||
//
|
||||
// Validate indicator values
|
||||
if (peak == EMPTY_VALUE || vale == EMPTY_VALUE || peakGoldenZone == EMPTY_VALUE || valeGoldenZone == EMPTY_VALUE)
|
||||
{
|
||||
//
|
||||
if (DebugMode)
|
||||
Print("Invalid indicator values. Skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Entry Conditions
|
||||
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||
|
||||
//
|
||||
// Long Entry
|
||||
if (bid > peak && bid > peakGoldenZone)
|
||||
{
|
||||
OpenTrade(ORDER_TYPE_BUY, peak, valeGoldenZone);
|
||||
}
|
||||
|
||||
//
|
||||
// Short Entry
|
||||
if (ask < vale && ask < valeGoldenZone)
|
||||
{
|
||||
OpenTrade(ORDER_TYPE_SELL, vale, peakGoldenZone);
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Open a Trade |
|
||||
//+------------------------------------------------------------------+
|
||||
void OpenTrade(int orderType, double entryLevel, double targetLevel)
|
||||
{
|
||||
//
|
||||
double lotSize = CalculateLotSize(entryLevel, targetLevel);
|
||||
double sl = (orderType == ORDER_TYPE_BUY) ? entryLevel - StopLossPips * Point() : entryLevel + StopLossPips * Point();
|
||||
double tp = (orderType == ORDER_TYPE_BUY) ? entryLevel + TakeProfitPips * Point() : entryLevel - TakeProfitPips * Point();
|
||||
|
||||
//
|
||||
// Prepare trade request
|
||||
MqlTradeRequest request = {};
|
||||
MqlTradeResult result = {};
|
||||
|
||||
//
|
||||
request.action = TRADE_ACTION_DEAL;
|
||||
request.symbol = _Symbol;
|
||||
request.volume = lotSize;
|
||||
request.type = (ENUM_ORDER_TYPE)orderType;
|
||||
request.price = (orderType == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||
request.sl = sl;
|
||||
request.tp = tp;
|
||||
request.deviation = 10;
|
||||
request.magic = MagicNumber;
|
||||
|
||||
//
|
||||
// Send trade request
|
||||
if (!OrderSend(request, result))
|
||||
{
|
||||
Print("Trade failed: ", result.retcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Print("Trade opened successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Manage Open Position |
|
||||
//+------------------------------------------------------------------+
|
||||
void ManageOpenPosition()
|
||||
{
|
||||
ulong ticket = PositionGetInteger(POSITION_TICKET);
|
||||
double currentPrice = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||
double sl = PositionGetDouble(POSITION_SL);
|
||||
double tp = PositionGetDouble(POSITION_TP);
|
||||
|
||||
// Trailing Stop Logic
|
||||
if (UseTrailingStop)
|
||||
{
|
||||
double newSL = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
|
||||
? currentPrice - TrailingStopPips * Point()
|
||||
: currentPrice + TrailingStopPips * Point();
|
||||
|
||||
if ((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && newSL > sl) ||
|
||||
(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && newSL < sl))
|
||||
{
|
||||
ModifyPosition(ticket, newSL, tp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Modify Position |
|
||||
//+------------------------------------------------------------------+
|
||||
void ModifyPosition(ulong ticket, double newSL, double newTP)
|
||||
{
|
||||
MqlTradeRequest request = {};
|
||||
MqlTradeResult result = {};
|
||||
|
||||
request.action = TRADE_ACTION_SLTP;
|
||||
request.position = ticket;
|
||||
request.sl = newSL;
|
||||
request.tp = newTP;
|
||||
|
||||
if (!OrderSend(request, result))
|
||||
{
|
||||
Print("Failed to modify position: ", result.retcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Print("Position modified successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate Lot Size |
|
||||
//+------------------------------------------------------------------+
|
||||
double CalculateLotSize(double entryLevel, double targetLevel)
|
||||
{
|
||||
double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100;
|
||||
double stopLossDistance = MathAbs(entryLevel - targetLevel) / Point();
|
||||
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
||||
double lotSize = riskAmount / (stopLossDistance * tickValue);
|
||||
|
||||
// Normalize lot size
|
||||
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double stepLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
||||
|
||||
lotSize = MathFloor(lotSize / stepLot) * stepLot;
|
||||
lotSize = MathMax(minLot, MathMin(maxLot, lotSize));
|
||||
|
||||
return lotSize;
|
||||
}
|
||||
Reference in New Issue
Block a user