619 lines
12 KiB
Plaintext
619 lines
12 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center XSAMPLE MQL5 Expert Advisor
|
|
// -------------------------------------------------
|
|
// Name: XSAMPLE
|
|
// Description: an Exper Advisor which used RSI and MA
|
|
// to Analyse Market ...
|
|
//
|
|
// 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 XSAMPLE"
|
|
#property strict
|
|
|
|
//
|
|
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
|
#include "../Classes/x-saherelm.xalert.class.mq5"
|
|
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
|
|
|
//
|
|
#define ShortName "XSAMPLE"
|
|
|
|
//
|
|
int pivotLifeTime = 20;
|
|
int pivotBreakoutsLifeTime = 10;
|
|
ENUM_TIMEFRAMES destPEriod = PERIOD_H4;
|
|
|
|
//
|
|
int xAge = 0;
|
|
|
|
//
|
|
double lastHH = 0;
|
|
double lastUpper = 0;
|
|
double lastDestHH = 0;
|
|
|
|
//
|
|
double lastLL = 0;
|
|
double lastLower = 0;
|
|
double lastDestLL = 0;
|
|
|
|
//
|
|
datetime lastTime = NULL;
|
|
datetime lastDestTime = NULL;
|
|
|
|
//
|
|
XSCAlert *mAlert;
|
|
XSCTrade *mTrader;
|
|
|
|
//
|
|
XBarTracker xBarTracker;
|
|
XMarketCycle xDestCycle;
|
|
|
|
//
|
|
// Initialization ...
|
|
int OnInit()
|
|
{
|
|
//
|
|
drawPrefix = ShortName;
|
|
|
|
//
|
|
if (!InitialEA())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// De Initialize XSampleEA Providers ...
|
|
}
|
|
|
|
//
|
|
// On Tick Handler ...
|
|
void OnTick()
|
|
{
|
|
//
|
|
if (!xBarTracker.IsNewBar())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
xDestCycle.Update(0);
|
|
|
|
//
|
|
Analyze();
|
|
|
|
//
|
|
ManxAge();
|
|
}
|
|
|
|
//
|
|
//
|
|
|
|
//
|
|
bool InitialEA()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
mAlert = new XSCAlert();
|
|
mAlert.SetLogAlerts(true);
|
|
mAlert.SetPrefix(ShortName);
|
|
mAlert.SetEnableAlerts(true);
|
|
mAlert.SetPushAlerts(false);
|
|
mAlert.SetMailAlerts(false);
|
|
mAlert.SetTerminalAlerts(false);
|
|
|
|
//
|
|
mTrader = new XSCTrade(
|
|
10,
|
|
78692110,
|
|
0,
|
|
0,
|
|
0 //
|
|
);
|
|
|
|
//
|
|
result = xBarTracker.Init(
|
|
_Symbol,
|
|
_Period //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = xDestCycle.Init(
|
|
_Symbol,
|
|
_Period,
|
|
X_MARKET_CYCLE_MEDIUM,
|
|
X_PERIOD_MANUALLY,
|
|
destPEriod,
|
|
"DEST" //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = true;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void Analyze()
|
|
{
|
|
//
|
|
XOHCL cBar;
|
|
cBar.Init(
|
|
_Symbol,
|
|
_Period,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
if (IsLookingForBoundary())
|
|
{
|
|
FindBoundary();
|
|
return;
|
|
}
|
|
|
|
//
|
|
double longSLPrice = 0;
|
|
double shortSLPrice = 0;
|
|
|
|
// //
|
|
// xAge = 0;
|
|
// if (IsValid(lastTime))
|
|
// {
|
|
// //
|
|
// xAge = iBarShift(
|
|
// _Symbol,
|
|
// _Period,
|
|
// lastTime //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// if (xAge > pivotBreakoutsLifeTime)
|
|
// {
|
|
// //
|
|
// lastHH = cBar.FindHighest(
|
|
// xAge - 1,
|
|
// MODE_HIGH //
|
|
// );
|
|
|
|
// //
|
|
// lastLL = cBar.FindLowest(
|
|
// xAge - 1,
|
|
// MODE_LOW //
|
|
// );
|
|
|
|
// //
|
|
// DrawPivot(lastLL, clrAqua, "PVB_L_", true);
|
|
// DrawPivot(lastHH, clrMagenta, "PVB_H_", true);
|
|
// }
|
|
|
|
//
|
|
// Detect Breakouts for Long ...
|
|
// - Upper Must Breaked as Resistance ...
|
|
// - Lower Must Rejects as Support ...
|
|
|
|
// //
|
|
// bool isSupRejected = cBar.IsSupportRejected(lastLower);
|
|
// bool isResBreaked = cBar.IsResistanceBreaked(lastUpper);
|
|
// bool isLastLLRejectedAsSupport = cBar.IsSupportRejected(lastDestLL);
|
|
// bool isLastHHBreakedAsResistance = cBar.IsResistanceBreaked(lastDestHH);
|
|
|
|
// //
|
|
// bool hasLong =
|
|
// //
|
|
// cBar.HasStrongBody() &&
|
|
// (
|
|
// //
|
|
// (isLastLLRejectedAsSupport
|
|
// //
|
|
// ||
|
|
// //
|
|
// isLastHHBreakedAsResistance)
|
|
// //
|
|
// ||
|
|
// //
|
|
// (cBar.GetMid() > MathMax(lastLower, lastUpper) &&
|
|
// (isResBreaked
|
|
// //
|
|
// ||
|
|
// //
|
|
// isSupRejected))
|
|
// //
|
|
// )
|
|
// //
|
|
// ;
|
|
|
|
// //
|
|
// if (hasLong)
|
|
// {
|
|
// //
|
|
// longSLPrice = isResBreaked
|
|
// ? lastUpper
|
|
// : isLastHHBreakedAsResistance
|
|
// ? lastDestHH
|
|
// : isSupRejected
|
|
// ? lastLower
|
|
// : lastDestLL;
|
|
// }
|
|
|
|
//
|
|
// Detect Breakouts for Long ...
|
|
// - Upper Must Rejects as Resistance ...
|
|
// - Lower Must Breaked as Support ...
|
|
|
|
// //
|
|
// bool isResRejected = cBar.IsResistanceRejected(lastUpper);
|
|
// bool isSupBreaked = cBar.IsSupportBreaked(lastLower);
|
|
// bool isLastLLBreadedAsSupport = cBar.IsSupportBreaked(lastDestLL);
|
|
// bool isLastHHRejectedAsResistance = cBar.IsResistanceRejected(lastDestHH);
|
|
|
|
// //
|
|
// bool hasShort =
|
|
// //
|
|
// cBar.HasStrongBody() &&
|
|
// (
|
|
// //
|
|
// (isLastLLBreadedAsSupport
|
|
// //
|
|
// ||
|
|
// //
|
|
// isLastHHRejectedAsResistance)
|
|
// //
|
|
// ||
|
|
// //
|
|
// (cBar.GetMid() < MathMin(lastLower, lastUpper) &&
|
|
// (isSupBreaked
|
|
// //
|
|
// ||
|
|
// //
|
|
// isResRejected))
|
|
// //
|
|
// )
|
|
// //
|
|
// ;
|
|
|
|
// //
|
|
// if (hasShort)
|
|
// {
|
|
// //
|
|
// shortSLPrice = isSupBreaked
|
|
// ? lastLower
|
|
// : isLastLLBreadedAsSupport
|
|
// ? lastDestLL
|
|
// : isResRejected
|
|
// ? lastUpper
|
|
// : lastDestHH;
|
|
// }
|
|
|
|
//
|
|
//
|
|
bool hasLong = false;
|
|
bool hasShort = false;
|
|
|
|
//
|
|
bool hasSignal = hasLong || hasShort;
|
|
if (hasSignal)
|
|
{
|
|
//
|
|
double slPrice =
|
|
hasLong
|
|
? longSLPrice
|
|
: shortSLPrice;
|
|
// double slPrice =
|
|
// hasLong
|
|
// ? shortSLPrice
|
|
// : longSLPrice;
|
|
|
|
//
|
|
ENUM_POSITION_TYPE mType =
|
|
hasLong
|
|
? POSITION_TYPE_BUY
|
|
: POSITION_TYPE_SELL
|
|
//
|
|
;
|
|
// ENUM_POSITION_TYPE mType =
|
|
// hasLong
|
|
// ? POSITION_TYPE_BUY
|
|
// : POSITION_TYPE_SELL
|
|
// //
|
|
// ;
|
|
|
|
//
|
|
double mEntry = GetEntry(
|
|
_Symbol,
|
|
mType //
|
|
);
|
|
|
|
//
|
|
double priceToRisk = PointToPrice(30, _Symbol);
|
|
double priceToReward = PointToPrice(30, _Symbol);
|
|
|
|
//
|
|
double mSL = 0;
|
|
double mTP = 0;
|
|
CalculateTPSL(
|
|
mSL,
|
|
mTP,
|
|
mType,
|
|
mEntry,
|
|
1,
|
|
slPrice,
|
|
0,
|
|
priceToRisk,
|
|
priceToReward //
|
|
);
|
|
|
|
//
|
|
// Ignore Zero TP SL ...
|
|
if (mTP > 0 && mSL > 0)
|
|
{
|
|
//
|
|
XSignal signal;
|
|
bool isPrepared = signal.Prepare(
|
|
_Symbol,
|
|
"X92",
|
|
_Period,
|
|
mType,
|
|
X_ORDER_MODE_MARKET,
|
|
mEntry,
|
|
0.01,
|
|
mSL,
|
|
mTP //
|
|
);
|
|
|
|
//
|
|
if (isPrepared)
|
|
{
|
|
//
|
|
ENUM_X_SIGNAL_EXECUTION_RESULT state;
|
|
bool isExecuted = mTrader.ExecuteSignal(
|
|
signal,
|
|
state //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
bool resetLast =
|
|
xAge > pivotLifeTime || hasSignal;
|
|
|
|
//
|
|
if (resetLast)
|
|
{
|
|
//
|
|
lastUpper = 0;
|
|
lastLower = 0;
|
|
|
|
//
|
|
RemoveDraws();
|
|
}
|
|
}
|
|
|
|
//
|
|
void ManxAge()
|
|
{
|
|
//
|
|
return;
|
|
double profit = mTrader.Profit();
|
|
if (profit > 50 || profit < -100)
|
|
{
|
|
//
|
|
string comment = "EQM Hedge: " + ToString(profit);
|
|
|
|
//
|
|
int numberOfClosed = mTrader.Close(comment);
|
|
if (numberOfClosed > 0)
|
|
{
|
|
mAlert.Alert(comment);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
bool IsLookingForBoundary()
|
|
{
|
|
//
|
|
bool result = lastUpper == 0 && lastLower == 0;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void FindBoundary()
|
|
{
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = 1;
|
|
int pIndex = 2;
|
|
int ppIndex = 3;
|
|
|
|
//
|
|
// Detect Inside Bar ...
|
|
XOHCL cBar;
|
|
cBar.Init(
|
|
_Symbol,
|
|
_Period,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
XOHCL cDestBar = xDestCycle.GetBar(1);
|
|
|
|
//
|
|
if (cDestBar.time != lastDestTime) {
|
|
//
|
|
lastDestLL = cDestBar.low;
|
|
lastDestHH = cDestBar.high;
|
|
|
|
//
|
|
lastDestTime = cDestBar.time;
|
|
|
|
//
|
|
DrawPivot(lastUpper, clrOrangeRed, "Pvt_");
|
|
DrawPivot(lastLower, clrLimeGreen, "Pvt_");
|
|
}
|
|
|
|
//
|
|
// if (cDestBar.IsInsideBar())
|
|
// {
|
|
// //
|
|
// lastUpper = cDestBar.high;
|
|
// lastLower = cDestBar.low;
|
|
|
|
// //
|
|
// lastTime = TimeCurrent();
|
|
|
|
// //
|
|
// DrawPivot(lastUpper, clrOrangeRed, "Pvt_");
|
|
// DrawPivot(lastLower, clrLimeGreen, "Pvt_");
|
|
// }
|
|
|
|
// //
|
|
// if (lastUpper != cDestBar.high && lastLower != cDestBar.low)
|
|
// {
|
|
// //
|
|
// lastDestHH = cDestBar.high;
|
|
// lastDestLL = cDestBar.low;
|
|
|
|
// //
|
|
// DrawPivot(lastDestLL, clrYellow, "LDST_LL_", true);
|
|
// DrawPivot(lastDestHH, clrYellow, "LDST_HH_", true);
|
|
|
|
// //
|
|
// lastDestTime = TimeCurrent();
|
|
// }
|
|
|
|
//
|
|
DrawFibo();
|
|
}
|
|
|
|
//
|
|
void DrawPivot(
|
|
double price,
|
|
color clr,
|
|
string prefix,
|
|
bool forceRemove = false //
|
|
)
|
|
{
|
|
//
|
|
long chartID = ChartID();
|
|
datetime time1 = iTime(
|
|
_Symbol,
|
|
_Period,
|
|
2 //
|
|
);
|
|
datetime time = iTime(
|
|
_Symbol,
|
|
_Period,
|
|
0 //
|
|
);
|
|
|
|
//
|
|
string pPrefix = prefix + "P_" +
|
|
ToString(price);
|
|
|
|
//
|
|
if (IsDrawExists(prefix) && forceRemove)
|
|
{
|
|
RemoveDraws(prefix);
|
|
}
|
|
|
|
//
|
|
if (IsDrawExists(pPrefix))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
DrawTrendLine(
|
|
chartID,
|
|
pPrefix,
|
|
0,
|
|
time1,
|
|
price,
|
|
time,
|
|
price,
|
|
clr,
|
|
STYLE_SOLID,
|
|
2,
|
|
false,
|
|
false,
|
|
true //
|
|
);
|
|
}
|
|
|
|
//
|
|
void DrawFibo()
|
|
{
|
|
//
|
|
if (!IsValid(lastDestTime) || lastDestHH == 0 || lastDestLL == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = "LDST_FIb";
|
|
|
|
//
|
|
datetime time1 = TimeCurrent();
|
|
datetime time0 = lastDestTime;
|
|
|
|
//
|
|
RemoveDraw(name);
|
|
|
|
//
|
|
DrawFibonacci(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
time0,
|
|
lastDestHH,
|
|
time1,
|
|
lastDestLL,
|
|
clrAquamarine,
|
|
STYLE_DOT //
|
|
);
|
|
}
|
|
|
|
// |