Backup ...

This commit is contained in:
2025-02-24 19:20:10 +03:30
parent a0307177a0
commit 8b79f5c87e
373 changed files with 175584 additions and 0 deletions
Binary file not shown.
@@ -0,0 +1,101 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XBaseClass
// Description: provides all based classes for use ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// XBase Class ...
class XCBase
{
//
// Public ...
public:
//
// Protected ...
//
// Represent Basic Unique Tag ...
virtual string GetTag() {
return NULL;
}
//
// Retrieve Class Token ...
virtual string GetToken() {
return NULL;
}
//
// Protected
protected:
//
// Private ...
private:
};
//
template <typename T>
string GenerateSpecifiedCommonSummary(
T &mItem,
string separator = "\n",
bool includeScores = true,
bool setLabel = false //
)
{
//
string result = NULL;
//
double bullishScore = 0;
double bearishScore = 0;
mItem.GenerateScore(
bullishScore,
bearishScore //
);
//
result =
//
(!setLabel
? ""
: "Commons:" + separator) +
"---------------" + separator +
"Symbol: " + mItem.symbol + separator +
"Period: " + ToString(mItem.period) + separator +
"Time: " + ToString(mItem.time) + separator +
(includeScores
? "---------------" + separator +
"Scores:" + separator +
"---------------" + separator +
"Bullish: " + ToString(bullishScore) + separator +
"Bearish: " + ToString(bearishScore) + separator +
"---------------" + separator
: "") +
""
//
;
//
return result;
}
//
Binary file not shown.
@@ -0,0 +1,398 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCAccount
// Description: provides all Account requirements ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// START Definitions ...
//
//
// END Definitions ...
//
//
// START Import and Inclused requirements ...
//
//
// Includes ...
#include "../Classes/x-saherelm.base.class.mq5"
#include <Trade/AccountInfo.mqh>
//
// END Import and Inclused requirements ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Class for Manage Account ...
class XCAccount : public XCBase
{
//
// Public ...
public:
//
// Constructor ...
void XCAccount()
{
//
mAccountInfo = new CAccountInfo();
}
//
// Deconstructor ...
void ~XCAccount()
{
}
//
// START Provided Functions ...
//
//
// User Account ...
long GetUserAccount()
{
return mAccountInfo.Login();
}
//
// Account Leverage ...
long GetLeverage()
{
return mAccountInfo.Leverage();
}
//
// Get Trade Expert State ...
bool CanExpertTrade()
{
return mAccountInfo.TradeExpert();
}
//
// User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ...
// --------------------------
// ACCOUNT_TRADE_MODE_DEMO
// ACCOUNT_TRADE_MODE_CONTEST
// ACCOUNT_TRADE_MODE_REAL
ENUM_ACCOUNT_TRADE_MODE GetTradeMode()
{
return mAccountInfo.TradeMode();
}
//
// Get Account Balance ...
double GetBalance()
{
return mAccountInfo.Balance();
}
//
// Get the amount of give Credit ...
double GetCredit()
{
return mAccountInfo.Credit();
}
//
// Get the amount of current Profit on account ...
double GetProfit()
{
return mAccountInfo.Profit();
}
//
// Get the amount of current Equity on account ...
double GetEquity()
{
return mAccountInfo.Equity();
}
//
// Get the amount of reserved Margin ...
double GetMargin()
{
return mAccountInfo.Margin();
}
//
// Get the amount of free Margin ...
double GetFreeMargin()
{
return mAccountInfo.FreeMargin();
}
//
// Get the Level of Margin ...
double GetMarginLevel()
{
return mAccountInfo.MarginLevel();
}
//
// Get the Level Of Margin for a Deposit ...
double GetMarginCall()
{
return mAccountInfo.MarginCall();
}
//
// Get the Level of Margin for Stop out ...
double GetMarginStopOut()
{
return mAccountInfo.MarginStopOut();
}
//
// Get the Client Name ...
string GetName()
{
return mAccountInfo.Name();
}
//
// Get the Trade Server Name ...
string GetServerName()
{
return mAccountInfo.Server();
}
//
// Get deposit Currency Name ...
string GetCurrency()
{
return mAccountInfo.Currency();
}
//
// Get the Company Name that serves an Account ...
string GetCompany()
{
return mAccountInfo.Company();
}
//
// Calculate Profits for the current account based on passed parameters ...
double CalculateTradeProfit(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry, // open price
double exit // close price
)
{
//
double result = mAccountInfo.OrderProfitCheck(
symbol,
type,
volume,
entry,
exit);
//
return result;
}
//
// Calculate amount of margin which required for trade operation ...
double CalculateMarging(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry // open price
)
{
//
double result = mAccountInfo.MarginCheck(
symbol,
type,
volume,
entry);
//
return result;
}
//
// Calculate amount of free margin left after trade operation ...
double CalculateFreeMarging(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry // open price
)
{
//
double result = mAccountInfo.FreeMarginCheck(
symbol,
type,
volume,
entry);
//
return result;
}
//
// Calculate the Maximum possible volume of trade operation ...
double CalculateMaxVolume(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double entry, // open price
double percent = 100 // percent of available margin
)
{
//
double result = mAccountInfo.MaxLotCheck(
symbol,
type,
entry,
percent);
//
return result;
}
//
// Calculate Point Value for Given Symbol based on Account ...
double GetPointValue(
string symbol // trading symbol
)
{
//
double result = 0;
//
double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
//
double ticksPerPoint = tickSize / point;
//
result = tickValue / ticksPerPoint;
//
return result;
}
//
// Calculate Risk Amount based on account Currency by Providing:
// Points and Volume ...
double CalculateRiskAmount(
string symbol, // trading symbol
double points, // amount of Risk Points
double volume // position Volume
)
{
//
double result = 0;
//
double pointValue = GetPointValue(symbol);
//
result = pointValue * volume * points;
//
return result;
}
//
// Calculate Risk Points based on account Currency by Providing:
// Volume and Amount ...
double CalculateRiskPoints(
string symbol, // trading symbol
double volume, // position Volume
double amount // amount of Risk based on Account Currency
)
{
//
double result = 0;
//
double pointValue = GetPointValue(symbol);
//
result = amount / (pointValue * volume);
//
return result;
}
//
// Calculate Volume based on account Currency by Providing:
// Amount and Risk Points ...
double CalculateVolume(
string symbol, // trading symbol
double amount, // amount of Risk based on Account Currency
double points // amount of Risk Points
)
{
//
double result = 0;
//
points =
points <= 0
? 10
: points;
//
double pointValue = GetPointValue(symbol);
//
result = amount / (pointValue * points);
//
return result;
}
//
// END Provided Functions ...
//
//
// Protected ...
protected:
//
// Private ...
private:
//
// Account Info ...
CAccountInfo mAccountInfo;
};
//
// START Usefull Functions ...
//
//
// END Usefull Functions ...
//
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,275 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCPanel
// Description: provides all based classes for use ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
//
#include <Controls/Dialog.mqh>
//
#include "../Classes/x-saherelm.base.class.mq5"
//
// Extentions ...
/**
* Check a Qery Contains in a Content or not ...
*
* @param mQuery: String ...
* @param mContent: String ...
* @param ignoreCase: Boolean ...
*
* @return ( bool )
*/
bool XContains(
string mQuery, // Search String
string mContent, // Search Content
bool ignoreCase = true // Ignore Case
)
{
return Contains(
mQuery,
mContent,
ignoreCase //
);
}
//
// Implementation ...
//
// a Base App Dialog Class ...
class XCAppDialog : public CAppDialog
{
public:
//
// Action ...
//
// Virual ...
/**
* Override Close Button Click Action ...
*/
void OnClickButtonClose()
{
//
bool isClosed = ConfirmDialog("Close EA ?");
//
if (isClosed)
{
Destroy();
}
}
//
// Configuration Actions ...
/**
* Show or Hide Minimize Button ...
*
* @param show: boolean
*/
void MinimizeButton(bool show)
{
//
int controlIDX = ControlFind("MinMax");
if (!IsValidIndex(controlIDX))
{
return;
}
//
if (show)
{
Control(controlIDX).Show();
}
else
{
Control(controlIDX).Hide();
}
}
/**
* Show or Hide Close Button ...
*
* @param show: boolean
*/
void CloseButton(bool show)
{
//
int controlIDX = ControlFind("Close");
if (!IsValidIndex(controlIDX))
{
return;
}
//
if (show)
{
Control(controlIDX).Show();
}
else
{
Control(controlIDX).Hide();
}
}
/**
* Minimize Functionality Implementation ...
*/
void Minimize()
{
//
m_minimized = true;
Rebound(m_min_rect);
ClientAreaVisible(false);
}
/**
* Set Background Color ...
*
* @param clr: Color ...
*/
void BackgroundColor(color clr)
{
//
int controlIDX = ControlFind("Client");
if (!IsValidIndex(controlIDX))
{
return;
}
//
CWnd *obj = Control(controlIDX);
CWndClient *wndclient = (CWndClient *)obj;
//
wndclient.ColorBackground(clr);
}
//
protected:
//
/**
* Find Specific Control in Dialog ...
*
* @param name: String to Search
*
* @return ( int )
*/
int ControlFind(string name)
{
//
int result = -1;
//
if (!IsValid(name))
{
return result;
}
//
int count = ControlsTotal();
if (!IsValidSize(count))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
string iName = Control(i).Name();
//
bool isContains = XContains(
name,
iName,
true // Ignore Case ...
);
if (isContains)
{
//
result = i;
break;
}
}
//
return result;
}
/**
* Create and Run Confirm Dialog ...
*
* @param message: message for Message Box ...
*
* @return ( bool )
*/
bool ConfirmDialog(string message = NULL)
{
//
bool result = false;
//
if (!IsValid(message))
{
message = "Confirm ?";
}
//
int dialogResult = MessageBox(message, NULL, MB_YESNO);
//
// use 'switch' or 'if' as needed
switch (dialogResult)
{
//
// Yes ...
case IDYES:
result = true;
break;
//
// No ...
case IDNO:
result = false;
break;
//
// Cancel ...
case IDCANCEL:
result = false;
break;
}
//
return result;
}
//
private:
//
//
};
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
@@ -0,0 +1,967 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCBaseExpert
// Description: provides all based classes for use ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../Classes/x-saherelm.x-alert.class.mq5"
#include "../Classes/x-saherelm.x-trade.class.mq5"
//
// Definitions ...
string XCBaseExpertToken = "XCBaseEA";
//
// Inputs ...
//
// Implementations ...
class XCBaseExpert : public XCBaseAlert
{
//
public:
//
//
XCTrade *mTrader; // Trader of Expert Adviser ...
//
// Constructur(s) ...
void XCBaseExpert()
{
}
//
// Deconstructor ...
void ~XCBaseExpert()
{
//
delete mTrader;
//
ZeroMemory(mTrader);
}
//
// Getter(s) / Setter(s) ...
//
// Common ...
/**
* Get Magic Number ...
*
* @return ( long )
*/
long MagicNumber()
{
return mMagicNumber;
}
/**
* Set Magic Number ...
*
* @param value: Long ...
*/
void MagicNumber(long value)
{
//
mMagicNumber = value;
ReConfigure();
}
/**
* Get Slippage ...
*
* @return ( int )
*/
int Slippage()
{
return mSlippage;
}
/**
* Set Slippage ...
*
* @param value: Integer ...
*/
void Slippage(int value)
{
//
mSlippage = value;
ReConfigure();
}
/**
* Get Tag Prefix ...
*
* @return ( string )
*/
string TagPrefix()
{
return mTagPrefix;
}
/**
* Set Tag Prefix ...
*
* @param value: String ...
*/
void TagPrefix(string value)
{
//
mTagPrefix = value;
ReConfigure();
}
//
// Symbol ...
/**
* Get Period ...
*
* @return ( ENUM_TIMEFRAMES )
*/
ENUM_TIMEFRAMES GetPeriod()
{
return mPeriod;
}
/**
* Set Period ...
*
* @param value: ENUM_TIMEFRAMES member ...
*/
void SetPeriod(ENUM_TIMEFRAMES value)
{
//
mPeriod = value;
ReConfigure();
}
/**
* Get Symbol ...
*
* @return ( string )
*/
string GetSymbol()
{
return mSymbol;
}
/**
* Set Symbol ...
*
* @param value: String ...
*/
void SetSymbol(string value)
{
//
mSymbol = value;
ReConfigure();
}
/**
* Get Multi Symbol is Enable or Not ...
*
* @return ( bool )
*/
bool MultiSymbol()
{
return mMultiSymbol;
}
/**
* Set Multi Symbol is Enable or Not ...
*
* @param value: Boolean ...
*/
void MultiSymbol(bool value)
{
//
mMultiSymbol = value;
ReConfigure();
}
/**
* Get Multi Provided Symbols ...
*
* @return ( string )
*/
string Symbols()
{
return mSymbols;
}
/**
* Set Multi Provided Symbols ...
*
* @param value: String ...
*/
void Symbols(string value)
{
//
mSymbols = value;
ReConfigure();
}
//
// Signalling ...
/**
* Get Force Disable Signalling ...
*
* @return ( bool )
*/
bool Disabled()
{
return mDisabled;
}
/**
* Set Force Disable Signalling ...
*
* @param value: Boolean ...
*/
void Disabled(bool value)
{
//
mDisabled = value;
ReConfigure();
}
/**
* Get Allow Long Signals ...
*
* @return ( bool )
*/
bool AllowLong()
{
return mAllowLong;
}
/**
* Set Allow Long Signals ...
*
* @param value: Boolean ...
*/
void AllowLong(bool value)
{
//
mAllowLong = value;
ReConfigure();
}
/**
* Get Allow Short Signalling ...
*
* @return ( bool )
*/
bool AllowShort()
{
return mAllowShort;
}
/**
* Set Allow Short Signalling ...
*
* @param value: Boolean ...
*/
void AllowShort(bool value)
{
//
mAllowShort = value;
ReConfigure();
}
//
// Reports ...
/**
* Get Report New Month State ...
*
* @return ( bool )
*/
bool ReportNewMonths()
{
return mReportNewMonths;
}
/**
* Set Report New Month State ...
*
* @param value: Boolean ...
*/
void ReportNewMonths(bool value)
{
//
mReportNewMonths = value;
ReConfigure();
}
/**
* Get Report New Weeks State ...
*
* @return ( bool )
*/
bool ReportNewWeeks()
{
return mReportNewWeeks;
}
/**
* Set Report New Weeks State ...
*
* @param value: Boolean ...
*/
void ReportNewWeeks(bool value)
{
//
mReportNewWeeks = value;
ReConfigure();
}
/**
* Get Report New Days State ...
*
* @return ( bool )
*/
bool ReportNewDays()
{
return mReportNewDays;
}
/**
* Set Report New Days State ...
*
* @param value: Boolean ...
*/
void ReportNewDays(bool value)
{
//
mReportNewDays = value;
ReConfigure();
}
/**
* Get Report New Hours State ...
*
* @return ( bool )
*/
bool ReportNewHours()
{
return mReportNewHours;
}
/**
* Set Report New Hours State ...
*
* @param value: Boolean ...
*/
void ReportNewHours(bool value)
{
//
mReportNewHours = value;
ReConfigure();
}
//
// Actions ...
/**
* Handle Expert OnInit Event ...
*
* @return ( bool )
*/
bool HandleOnInit()
{
//
bool result = false;
//
string message = "";
//
// Validate Input ...
result = ValidateInputs();
if (!result)
{
//
message = "Invalid Inputs ....";
//
Alert(message);
}
//
// Initial All Requirements ...
result = InitEA();
if (!result)
{
return result;
}
//
// Initial All GUI Requirements ...
result = InitGUI();
if (!result)
{
return result;
}
//
message = "Initialized Successfully ...";
Alert(message);
//
return result;
}
/**
* Handle Expert OnDeInit Event ...
*/
void HandleOnDeInit()
{
//
// Destroy all GUI Requirements ...
DestroyGUI();
//
// Alert De Initialization Succeeded ...
string msg = "De Initialized Successfully ...";
Alert(msg);
//
// Destroy all EA Requirements ...
DestroyEA();
}
/**
* Handle Expert OnTick Event ...
*/
void HandleOnTick()
{
//
UpdateGUI();
HandleReportTime();
HandleStrategiesOnTick();
HandleStrategiesGuard();
}
/**
* Handle Expert OnTrade Event ...
*/
void HandleOnTrade()
{
mTrader.HandleOnTrade();
}
/**
* Handle Expert OnTimer Event ...
*/
void HandleOnTimer()
{
}
/**
* Handle Expert OnChart Event ...
*/
void HandleOnChartEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
}
//
// Virtual Actions ...
/**
* Apply Default Configurations ...
*/
virtual void DefaultConfigure()
{
//
// Commons ...
Slippage(10);
TagPrefix("");
MagicNumber(1694056);
//
// Symbol ...
SetSymbol(_Symbol);
SetPeriod(_Period);
MultiSymbol(false);
Symbols("EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb");
//
// Signalling ...
Disabled(false);
AllowLong(true);
AllowShort(true);
//
string tag = GetTag();
//
// Alert ...
SetAlertPrefix(tag);
SetAlertLogAlerts(true);
SetAlertPushAlerts(true);
SetAlertMailAlerts(false);
SetAlertEnableAlerts(true);
SetAlertTerminalAlerts(false);
//
// Reports ...
ReportNewDays(true);
ReportNewWeeks(false);
ReportNewHours(false);
ReportNewMonths(false);
}
/**
* Vaslidate Inputs ...
*
* @return ( virtual bool )
*/
virtual bool ValidateInputs()
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
mSlippage > 0 &&
mMagicNumber > 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 ...
errMessage = " Errors: \n" + errMessage;
Alert(errMessage);
}
//
return result;
}
//
// Initializers and DeInitializers ...
/**
* Initial EA Requirements ...
*
* @return ( virtual bool )
*/
virtual bool InitEA()
{
//
bool result = false;
//
// Initialize Indicator Helpers ...
//
// Create Trader Instance and Configure it ...
mTrader = new XCTrade(
mSlippage,
mMagicNumber //
);
//
return result;
}
/**
* Destroy Initialized Requirements ...
*/
virtual void DestroyEA()
{
//
delete mTrader;
//
ZeroMemory(mTrader);
}
/**
* GUI Initialize if required ...
*
* @return ( virtual bool )
*/
virtual bool InitGUI()
{
//
bool result = false;
//
result = true;
//
return result;
}
/**
* Update All GUI Contents ...
*/
virtual void UpdateGUI()
{
}
/**
* Destroy all Initialized GUi Elements ...
*/
virtual void DestroyGUI()
{
}
//
// Event Handlers ...
/**
* Calls When a Position's SL Triggered ...
*
* @param deal: XDeal instance ...
*/
virtual void HandleOnStopLossTriggered(const XDeal &deal)
{
HandleReportBalance();
}
/**
* Calls When a Position's TP Triggered ...
*
* @param deal: XDeal instance ...
*/
virtual void HandleOnTakeProfitTriggered(const XDeal &deal)
{
HandleReportBalance();
}
/**
* Handle Force Close a Position ...
*
* @param ticket: Position Ticket ...
* @param position: XPosition ...
* @param comment: Closing Comment ...
*/
virtual void HandleOnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
HandleReportBalance();
}
/**
* Handle Position Modified ...
*
* @param ticket: ULONG ...
* @param profit: Double ...
* @param comment: String ...
*/
virtual void HandleOnPositionModified(
const ulong ticket,
const double profit,
const string comment //
)
{
}
/**
* Handle Position Partially Closed ...
*
* @param ticket: ULONG ...
* @param profit: Double ...
* @param comment: String ...
*/
virtual void HandleOnPositionPartialClosed(
const ulong ticket,
const double profit,
const string comment //
)
{
}
/**
* Handle Deals Changed ...
*
* @param count: Integer, Number of Changes ...
*/
virtual void HandleOnDealsChanged(int count)
{
}
/**
* Handle Orders Changed ...
*
* @param count: Integer, Number of Changes ...
*/
virtual void HandleOnOrdersChanged(int count)
{
}
/**
* Handle Positions Changed ...
*
* @param count: Integer, Number of Changes ...
*/
virtual void HandleOnPositionsChanged(int count)
{
}
/**
* Do All Signalling Processing Here ...
*/
virtual void HandleStrategiesOnTick()
{
}
/**
* Check Strategies for Guards and then Apply Them ...
*/
virtual void HandleStrategiesGuard()
{
}
//
// Time Handlers ...
virtual void HandleOnNewMonth()
{
}
virtual void HandleOnNewWeek()
{
}
virtual void HandleOnNewDay()
{
}
virtual void HandleOnNewHour()
{
}
virtual void ReConfigure()
{
}
/**
* Generate Identifier Tag ...
*
* @return ( virtual string )
*/
virtual string GetTag()
{
//
string result = NULL;
//
string tagPrefix = TagPrefix();
if (IsValid(tagPrefix))
{
result = tagPrefix;
}
else
{
result = "";
}
//
result =
XCBaseExpertToken + result;
//
return result;
}
//
protected:
//
//
// Props ...
//
XTimeTracker mTimeTracker; // Time Tracker for Providing Reports ...
//
// Actions ...
/**
* Report Account Balance ...
*/
void HandleReportBalance()
{
//
if (!IsRunningOnTestMode())
{
return;
}
//
string msg = "Balance: " + ToString(mTrader.mAccount.GetBalance());
Log(msg);
}
/**
* Time Reporting based on Inputs ...
*/
void HandleReportTime()
{
//
// Monthly Report ....
if (mTimeTracker.IsNewMonth())
{
//
HandleOnNewMonth();
//
if (mReportNewMonths)
{
//
string msg = "New Month ...";
//
Alert(msg);
}
}
//
// Weekly Report ....
if (mTimeTracker.IsNewWeek())
{
//
HandleOnNewWeek();
//
if (mReportNewWeeks)
{
//
string msg = "New Week ...";
//
Alert(msg);
}
}
//
// Daily Report ....
if (mTimeTracker.IsNewDay())
{
//
HandleOnNewDay();
//
if (mReportNewDays)
{
//
string msg = "New Day ...";
//
Alert(msg);
}
}
//
// Hourly Report ....
if (mTimeTracker.IsNewHour())
{
//
HandleOnNewHour();
//
if (mReportNewHours)
{
//
string msg = "New Hour ...";
//
Alert(msg);
}
}
}
//
private:
//
//
// Props ...
//
// Common ...
long mMagicNumber; // Magic Number ...
int mSlippage; // Slippage ...
string mTagPrefix; // Tag Prefix ...
//
// Symbol ...
ENUM_TIMEFRAMES mPeriod; // Period ...
string mSymbol; // Symbol ...
bool mMultiSymbol; // Multi Symbol is Enable or Not ...
string mSymbols; // Multi Provided Symbols ...
//
// Signalling ...
bool mDisabled; // Force Disable Signalling ...
bool mAllowLong; // Allow Long Signals ...
bool mAllowShort; // Allow Short Signals ...
//
// Reports ...
bool mReportNewMonths; // Report New Month ...
bool mReportNewWeeks; // Report New Weeks ...
bool mReportNewDays; // Report New Days ...
bool mReportNewHours; // Report New Hours ...
//
};
//
Binary file not shown.
@@ -0,0 +1,151 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCBaseHelper
// Description: provides all Base Indicator
// Helper requirements ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes ...
#include "../Classes/x-saherelm.base.class.mq5"
//
// Definitions ...
//
// a Class for Handle base requirements ...
// for indicators ...
class XCBaseHelper : public XCBase
{
//
// Public ...
public:
//
// Constructor ...
void XCBaseHelper(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period // Trading Time Frame
)
{
//
mSymbol = symbol;
mPeriod = period;
}
//
// Deconstructor ...
void ~XCBaseHelper()
{
//
IndicatorRelease(mHandler);
}
//
// Setter(s) / Getter(s) ...
//
// Symbol ...
string GetSymbol()
{
return mSymbol;
}
//
// Period ...
ENUM_TIMEFRAMES GetPeriod()
{
return mPeriod;
}
//
// Retrieve Bars ...
int CountBars()
{
//
int result =
Bars(
mSymbol,
mPeriod
//
);
//
return result;
}
//
// Retrieve Indicator Calculated Bars ...
int CountCalculatedBars()
{
return BarsCalculated(mHandler);
}
//
virtual void Free() {}
//
// Generate Tag ...
virtual string GetTag()
{
//
string result = NULL;
//
result =
//
GetToken() +
"[" +
GetSymbol() + "|" +
ToString(GetPeriod()) +
"]"
//
;
//
return result;
}
//
// Functions ...
//
// Protected ...
protected:
//
// Props ...
//
// Symbol ...
string mSymbol;
//
// Period ...
ENUM_TIMEFRAMES mPeriod;
//
// Indicator Handler ...
int mHandler;
//
// Private ...
private:
//
};
//
// Tools ....
Binary file not shown.
@@ -0,0 +1,373 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCHttp
// Description: provides all HTTP requirements ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Definitions ...
//
enum X_HTTP_METHOD
{
X_HTTP_GET,
X_HTTP_POST
};
//
// Imports ...
//
// Includes ...
#include "../Classes/x-saherelm.base.class.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// a Class for Manage Account ...
class XCHttp : public XCBase
{
//
// Public ...
public:
//
// Constructor ...
void XCHttp()
{
XCHttp("", 10000);
}
void XCHttp(
string path, // Base Folder to Store Data
int timeout // base timeout for Requests
)
{
//
Path(path);
Timeout(timeout);
}
//
// Deconstructor ...
void ~XCHttp()
{
}
//
// Properties Getter(s) / Setter(s) ...
//
// Path ...
void Path(string value)
{
//
mPath = value;
//
if (!IsValid(mPath))
{
mPath = GetTag();
}
}
string Path()
{
return mPath;
}
//
// Timeout ...
void Timeout(int value)
{
mTimeout = value;
}
//
int Timeout()
{
return mTimeout;
}
//
// Error ...
int Error()
{
return mError;
}
//
// Response ...
string Response()
{
return mResponse;
}
//
// Overrides ...
string GetTag() override
{
return GetSpecificToken(this);
}
//
// Tools ...
//
// Send Global Request ...
int SendRequest(
X_HTTP_METHOD method, // Httm Request Method
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
)
{
//
int result = -1;
//
string strMethod = ToString(method);
if (StringLen(strMethod) == 0)
{
return result;
}
//
// Reset State ...
ResetState();
//
result = WebRequest(
strMethod,
url,
headers,
timeout,
payload,
response,
responseHeaders);
//
if (result < 0)
{
mError = GetLastError();
}
else
{
mResponse = CharArrayToString(response);
}
//
return result;
}
//
// Get Request ...
int GetRequest(
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
)
{
//
int result = SendRequest(
X_HTTP_GET,
url,
headers,
payload,
response,
responseHeaders,
timeout);
//
return result;
}
//
// Post Request ...
int PostRequest(
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
)
{
//
int result = SendRequest(
X_HTTP_POST,
url,
headers,
payload,
response,
responseHeaders,
timeout);
//
return result;
}
//
// Handle Download Specific URL Content to Specific Path and File Name ...
bool Download(
string url, // the URL address which going to download
string fileName // Specify Destination file name to Store Response
)
{
//
bool result = false;
//
string filePath = GetFilePath(fileName);
string cookie = NULL;
string referer = NULL;
int timeout = Timeout();
//
char payload[];
string headers;
char response[];
string responseHeaders;
//
// Send Request ...
int requestResult = GetRequest(
url,
headers,
payload,
response,
responseHeaders,
timeout);
//
// Define File Handler ...
int mFileHandler = FileOpen(
filePath,
FILE_WRITE | FILE_BIN);
if (mFileHandler == INVALID_HANDLE)
{
//
mError = GetLastError();
return result;
}
//
// Write Response to File ...
uint writed = FileWriteArray(
mFileHandler,
response,
0,
ArraySize(response));
FileFlush(mFileHandler);
FileClose(mFileHandler);
//
result = writed > 0;
//
return result;
}
//
// END Provided Functions ...
//
//
// Protected ...
protected:
//
// Destintion Folder Path ...
string mPath;
//
// WEB Request Timeout Value ...
int mTimeout;
//
// WEB Request's Response ...
string mResponse;
//
// Error Value ...
int mError;
//
// Private ...
private:
//
// Reset Errors State ...
void ResetState()
{
//
// Reset Errors ...
mError = -1;
mResponse = "";
ResetLastError();
}
//
// Generate Full File Path ...
string GetFilePath(string fileName)
{
//
string result = "";
//
result =
//
Path() + "\\" + fileName
//
;
//
return result;
}
};
//
// Tools ...
//
// Convert enum to String ...
string ToString(X_HTTP_METHOD method)
{
//
string result = "";
//
switch (method)
{
//
case X_HTTP_GET:
result = "GET";
break;
//
case X_HTTP_POST:
result = "POST";
break;
}
//
return result;
}
//
Binary file not shown.
@@ -0,0 +1,445 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCMD5
// Description: Provides MD5 Hashing Requirements ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// START Definitions ...
//
//
static uchar _md5_PADDING[64] =
{
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//
#define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define _md5_H(x, y, z) ((x) ^ (y) ^ (z))
#define _md5_I(x, y, z) ((y) ^ ((x) | (~z)))
#define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
//
#define _md5_FF(a, b, c, d, x, s, ac) \
{ \
(a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \
(a) = _md5_ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
//
#define _md5_GG(a, b, c, d, x, s, ac) \
{ \
(a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \
(a) = _md5_ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
//
#define _md5_HH(a, b, c, d, x, s, ac) \
{ \
(a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \
(a) = _md5_ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
//
#define _md5_II(a, b, c, d, x, s, ac) \
{ \
(a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \
(a) = _md5_ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
//
#define _md5_INIT_STATE_0 0x67452301
#define _md5_INIT_STATE_1 0xefcdab89
#define _md5_INIT_STATE_2 0x98badcfe
#define _md5_INIT_STATE_3 0x10325476
//
#define _md5_S11 7
#define _md5_S12 12
#define _md5_S13 17
#define _md5_S14 22
//
#define _md5_S21 5
#define _md5_S22 9
#define _md5_S23 14
#define _md5_S24 20
//
#define _md5_S31 4
#define _md5_S32 11
#define _md5_S33 16
#define _md5_S34 23
//
#define _md5_S41 6
#define _md5_S42 10
#define _md5_S43 15
#define _md5_S44 21
//
// END Definitions ...
//
//
// XCMD5 a library for Hashing ...
class XCMD5
{
//
// Public Provides ...
public:
//
// Protected Provides ...
//
// Constructor ...
XCMD5(void)
{
}
//
// Deconstructor ...
~XCMD5(void)
{
}
//
// Hash Specified Char Array ...
string Hash(
uchar &mSource[], // Specify Char Array to Hash
int mLength = 0 // Specify Length of Char Array which required to hash
)
{
//
string result = "";
//
int sourceCount = ArraySize(mSource);
//
// Validate Args ...
if (
sourceCount <= 0 ||
(sourceCount > 0 && mLength > sourceCount))
{
return result;
}
//
// Normalize Args ...
if (mLength == 0)
{
mLength = sourceCount;
}
//
// Init MD5 ...
MD5Init();
//
// Update Buffer ...
MD5Update(mSource, mLength);
//
// Calculate Result ...
result = MD5Final();
//
return result;
}
//
// Hash Specified String ...
string Hash(
string mSource // Specified String
)
{
//
string result = "";
//
// Converts String to Char Array ...
uchar bytes[];
StringToCharArray(
mSource,
bytes,
0,
StringLen(mSource));
//
result = Hash(
bytes,
ArraySize(bytes));
//
return result;
}
protected:
//
// Private Provides ...
private:
//
uint m_lMD5[4];
uint m_nCount[2];
uchar m_lpszBuffer[64];
//
// Convert Byte to DWord ...
void ByteToDWord(int &out[], uint &in[], uint len)
{
//
uint i = 0;
uint j = 0;
//
for (; j < len; i++, j += 4)
{
out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24;
}
}
//
// Convert DWord to Byte ...
void DWordToByte(uchar &out[], int &in[], uint len)
{
//
uint i = 0;
uint j = 0;
//
for (; j < len; i++, j += 4)
{
//
out[j] = (uchar)(in[i] & 0xff);
out[j + 1] = (uchar)((in[i] >> 8) & 0xff);
out[j + 2] = (uchar)((in[i] >> 16) & 0xff);
out[j + 3] = (uchar)((in[i] >> 24) & 0xff);
}
}
//
// Init MD5 Array ...
void MD5Init()
{
//
ArrayInitialize(m_lpszBuffer, 64);
//
m_nCount[0] = m_nCount[1] = 0;
m_lMD5[0] = _md5_INIT_STATE_0;
m_lMD5[1] = _md5_INIT_STATE_1;
m_lMD5[2] = _md5_INIT_STATE_2;
m_lMD5[3] = _md5_INIT_STATE_3;
}
//
// Update MD5 ...
void MD5Update(uchar &inBuf[], uint inLen)
{
//
int i, ii;
int mdi;
//
uint in[16];
int i0 = 0;
//
mdi = (int)((m_nCount[0] >> 3) & 0x3F);
//
if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0])
{
m_nCount[1]++;
}
//
m_nCount[0] += ((uint)inLen << 3);
m_nCount[1] += ((uint)inLen >> 29);
//
while ((inLen--) > 0)
{
//
m_lpszBuffer[mdi++] = inBuf[i0++];
if (mdi == 0x40)
{
//
for (i = 0, ii = 0; i < 16; i++, ii += 4)
{
in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]);
}
//
Transform(m_lMD5, in);
//
mdi = 0;
}
}
}
//
// Finalize an MD5 Expression ...
string MD5Final()
{
//
uchar bits[8];
int nIndex;
uint nPadLen;
const int nMD5Size = 16;
uchar lpszMD5[16];
string temp;
string out = "";
int i;
//
DWordToByte(bits, m_nCount, 8);
nIndex = (int)((m_nCount[0] >> 3) & 0x3f);
nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex);
MD5Update(_md5_PADDING, nPadLen);
MD5Update(bits, 8);
DWordToByte(lpszMD5, m_lMD5, nMD5Size);
//
for (i = 0; i < nMD5Size; i++)
{
//
if (lpszMD5[i] == 0)
{
temp = "00";
}
else if (lpszMD5[i] <= 15)
{
temp = StringFormat("0%x", lpszMD5[i]);
}
else
{
temp = StringFormat("%x", lpszMD5[i]);
}
//
out += temp;
}
//
lpszMD5[0] = '\0';
//
return (out);
}
//
// Transform Buffers ...
void Transform(uint &buf[], uint &in[])
{
//
uint a = buf[0], b = buf[1], c = buf[2], d = buf[3];
//
_md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478);
_md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756);
_md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB);
_md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE);
_md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF);
_md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A);
_md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613);
_md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501);
_md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8);
_md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF);
_md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1);
_md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE);
_md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122);
_md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193);
_md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E);
_md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821);
//
_md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562);
_md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340);
_md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51);
_md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA);
_md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D);
_md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453);
_md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681);
_md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8);
_md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6);
_md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6);
_md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87);
_md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED);
_md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905);
_md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8);
_md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9);
_md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A);
//
_md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942);
_md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681);
_md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122);
_md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C);
_md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44);
_md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9);
_md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60);
_md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70);
_md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6);
_md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA);
_md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085);
_md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05);
_md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039);
_md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5);
_md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8);
_md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665);
//
_md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244);
_md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97);
_md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7);
_md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039);
_md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3);
_md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92);
_md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D);
_md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1);
_md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F);
_md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0);
_md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314);
_md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1);
_md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82);
_md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235);
_md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB);
_md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391);
//
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
};
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
+346
View File
@@ -0,0 +1,346 @@
//
// Detect Inside Zones ...
//
XCFVG *insideFVG;
bool hasInsideFVG = false;
//
XCOrderBlock *insideOB;
bool hasInsideOB = false;
//
XCSupplyZone *insideSupply;
bool hasInsideSupply = false;
//
XCDemandZone *insideDemand;
bool hasInsideDemand = false;
//
XCSupportZone *insideSupport;
bool hasInsideSupport = false;
//
XCResistanceZone *insideResistnce;
bool hasInsideResistance = false;
//
// Detect PullBack ...
//
ENUM_X_DIRECTION pullbackDir;
bool hasPullBack = mXWZBarAnalyser.HasPullBack(
pullbackDir,
iBar //
);
bool hasBullishPullBack =
hasPullBack &&
IsBullish(pullbackDir);
bool hasBearishPullBack =
hasPullBack &&
IsBearish(pullbackDir);
//
// Detect PinBar ...
//
ENUM_X_DIRECTION pinBarDir;
bool hasPinBar = mXWZBarAnalyser.IsPinBar(
iBar,
pinBarDir,
0 //
);
bool hasBullishPinBar =
hasPinBar &&
IsBullish(pinBarDir);
bool hasBearishPinBar =
hasPinBar &&
IsBearish(pinBarDir);
//
// Detect Order Block ...
//
XOHCL obBar;
XCOrderBlock *ob;
ENUM_X_DIRECTION obDir;
bool hasOB = mXWZBarAnalyser.HasOrderBlock(
iBar,
obBar,
obDir //
);
bool hasBullishOB =
hasOB &&
IsBullish(obDir);
bool hasBearishOB =
hasOB &&
IsBearish(obDir);
if (hasOB)
{
//
ob = new XCOrderBlock();
bool isInited = ob.Init(obBar, obDir);
if (isInited)
{
//
ENUM_X_DIRECTION forDir = ob.GetDirection();
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isObActivationBarBodyIn = false;
bool isActivated = ob.IsActivated(
forDir,
activationBar,
isObActivationBarBodyIn,
false,
_Period //
);
//
if (isActivated)
{
//
hasOB = false;
obBar.Clean();
ZeroMemory(ob);
hasBullishOB = false;
hasBearishOB = false;
}
}
}
//
if (hasBullishPinBar)
{
//
XCBarArrowObject *iObj;
bool isCreated = mXWZPOIDrawer
.CreateBarArrow(
iBar,
iObj,
X_PRICE_LOW,
159,
clrAqua,
3,
ANCHOR_BOTTOM,
"BULLPULL" //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
//
if (hasBearishPinBar)
{
//
XCBarArrowObject *iObj;
bool isCreated = mXWZPOIDrawer
.CreateBarArrow(
iBar,
iObj,
X_PRICE_HIGH,
159,
clrMagenta,
3,
ANCHOR_TOP,
"BEARPULL" //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
//
if (hasOB)
{
//
XCBaseObject *iObj;
bool isCreated = mXWZPOIDrawer.CreateOrderBlock(
ob,
iObj //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
//
int idx = -1;
int count = 0;
bool has = false;
//
ENUM_X_DIRECTION trend =
IsValid(lastBullishTrend) &&
lastBullishTrend > lastBearishTrend
? X_DIRECTION_BULLISH
: IsValid(lastBearishTrend) &&
lastBearishTrend > lastBullishTrend
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
bool hasTrend = HasDirection(trend);
bool hasBullishTrend = hasTrend &&
IsBullish(trend);
bool hasBearishTrend = hasTrend &&
IsBearish(trend);
//
// Order Block ...
has = hasBullishTrend;
if (has)
{
}
has = hasBearishTrend;
if (has)
{
}
//
// Fair Value Gap ...
has = hasBullishTrend;
if (has)
{
}
has = hasBearishTrend;
if (has)
{
}
//
// Supply Zone ...
has = hasBearishTrend;
if (has)
{
}
//
// Resistance Zone ...
has = hasBearishTrend;
if (has)
{
}
//
// Demand Zone ...
has = hasBullishTrend;
if (has)
{
}
//
// Support Zone ...
has = hasBullishTrend;
if (has)
{
}
//
// Draw Inside Zones ...
//
if (hasInsideOB)
{
//
XCBaseObject *iObj;
bool isCreated = mXWZPOIDrawer
.CreateOrderBlock(
insideOB,
iObj //
);
//
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
//
if (hasInsideFVG)
{
//
XCBaseObject *iObj;
bool isCreated = mXWZPOIDrawer
.CreateFairValueGap(
insideFVG,
iObj //
);
//
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
//
if (hasInsideSupply)
{
//
XCSupplyZoneObject *iObj;
bool isCreated = mXWZPOIDrawer
.CreateSupplyZone(
insideSupply,
iObj //
);
//
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
//
if (hasInsideDemand)
{
//
XCDemandZoneObject *iObj;
bool isCreated = mXWZPOIDrawer
.CreateDemandZone(
insideDemand,
iObj //
);
//
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
//
if (hasInsideSupport)
{
//
XCSupportZoneObject *iObj;
bool isCreated = mXWZPOIDrawer
.CreateSupportZone(
insideSupport,
iObj //
);
//
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
//
if (hasInsideResistance)
{
//
XCResistanceZoneObject *iObj;
bool isCreated = mXWZPOIDrawer
.CreateResistanceZone(
insideResistnce,
iObj //
);
//
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,464 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XTest MQL5 Expert Advisor
// -------------------------------------------------
// Name: X121SMCEA
// 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 X121SMCEA"
#property strict
//
#define ShortName "X121SMCEA"
//
// Imports ...
#include "../X121SMCEA/Experts/x-121.smc.expert.alert.class.mq5"
//
// Inputs ...
//
// Common ...
input group "Common";
input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
//
// Symbols ...
input group "Symbols";
input bool eaMultiSymbol = false; // Use Multi Symbol
input string eaSymbols = "EURUSDb"; // Trading Symbols
//
// Signalling ...
input group "Signalling";
input bool eaAllowLong = true; // Allow Long Signals
input bool eaAllowShort = true; // Allow Short Signals
input int eaMaxAllowedLongs = 5; // Max Allowed Long Signals
input int eaMaxAllowedShorts = 5; // Max Allowed Short Signals
input bool eaUseMaxAllowedSignalsPerSymbol = true; // Use Max Allowed Signal Types Per Symbol
input double eaLastPositionProfitForAcceptNextInPoint = 0; // Last Position Profit In Points for Accept new Signal
input int eaDelaysBetweenTwoSignalsInBar = 0; // Delay between two Signals in Bars
input double eaMaxAllowedSpread = 25; // Max Allowed Spread for Signalling
input int eaMinRequiredVerificationForSpreadPass = 20; // Minimum Spread Verification for Signalling
//
// Trade ...
input group "Trade";
input bool eaAllowTrade = false; // Allow Open Trade On Signals
input string eaStartTradeAt = ""; // Enable Trade on Signals on Time
input string eaStopTradeAt = ""; // Enable Trade on Signals on Time
input string eaCloseAllTradesAt = ""; // Enable Close All Trades on Signals on Time
//
// Risk Management ...
input group "Risk Management";
input double eaR2R = 4; // Signallers Risk to Reward Ratio
input double eaVolume = 0; // Static Volume
input double eaStaticBalance = 1000; // Static Balance
input double eaBalancePerTrade = 10; // Balance Used in Each Trade
input double eaRiskPercentPerBalance = 0; // Risk Percent Per Balance in Each Trade
input bool eaDynamicRiskManagement = false; // Dynamic Risk Management
input bool eaUseDynamicVolume = false; // Use Dynamic Volume
input double eaDynamicVolumeStep = 0.01; // Increase Volume Step
input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume
input double eaMaxAllowedDrawdownToOpenTrades = 3; // Max Allowed Drawdown for Open Trades
input int eaMaxAllowedSLToPauseSignallingPerSymbol = 2; // Max Allowed SL for Pause Signalling Per Symbol
input int eaPauseSignallingAfterReachesMaxAllowedSLInSecconds = 7200; // Pause Signalling Per Symbol afte Max Allowed SL Reached In Seconds
//
// Protection ...
input group "Protection";
input bool eaAllowHedging = false; // Allow Hedge Positions
input int eaMinOpenTradesFroHedging = 4; // Minimum Open Positions for Hedging
input double eaHedgingMinVolumeStep = 0.01; // Minimum Volume Step for Hedging
input double eaHedgeingMinRequiredProfitPerVolumeStep = 2.0; // Minimum Required Profit Per Volume Step for Hedging
//
// 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 = true; // 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
//
// Define Local Variables ...
XC121SMCExpert *eaExpert;
//
// 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;
}
//
// Configure EA Expert Class ...
eaExpert = new XC121SMCExpert();
//
// Event Handlers ...
eaExpert.OnSignalEventListener = OnSignalRecieved;
eaExpert.OnDealsChangedEventListener = OnDealsChanged;
eaExpert.OnOrdersChangedEventListener = OnOrdersChanged;
eaExpert.OnPositionSLEventListener = OnStopLossTriggered;
eaExpert.OnPositionTPEventListener = OnTakeProfitTriggered;
eaExpert.OnPositionsChangedEventListener = OnPositionsChanged;
eaExpert.OnPositionForceCloseEventListener = OnPositionForceClosed;
//
// Common ...
eaExpert.MagicNumber(eaMagicNumber);
eaExpert.Slippage(eaSlippage);
eaExpert.TagPrefix(eaLogSuffix);
//
// Symbol ...
eaExpert.SetSymbol(_Symbol);
eaExpert.SetPeriod(_Period);
eaExpert.Symbols(eaSymbols);
eaExpert.MultiSymbol(eaMultiSymbol);
//
// Signalling ...
eaExpert.AllowLong(eaAllowLong);
eaExpert.AllowShort(eaAllowShort);
eaExpert.MaxAllowedLongs(eaMaxAllowedLongs);
eaExpert.MaxAllowedShorts(eaMaxAllowedShorts);
eaExpert.UseMaxAllowedSignalsPerSymbol(eaUseMaxAllowedSignalsPerSymbol);
eaExpert.LastPositionProfitForAcceptNextInPoint(eaLastPositionProfitForAcceptNextInPoint);
eaExpert.DelaysBetweenTwoSignalsInBar(eaDelaysBetweenTwoSignalsInBar);
eaExpert.MaxAllowedSpread(eaMaxAllowedSpread);
eaExpert.MinRequiredVerificationForSpreadPass(eaMinRequiredVerificationForSpreadPass);
//
// Trade ...
eaExpert.AllowTrade(eaAllowTrade);
eaExpert.StartTradeAt(eaStartTradeAt);
eaExpert.StopTradeAt(eaStopTradeAt);
eaExpert.CloseAllTradesAt(eaCloseAllTradesAt);
//
// Risk Management ...
eaExpert.R2R(eaR2R);
eaExpert.Volume(eaVolume);
eaExpert.StaticBalance(eaStaticBalance);
eaExpert.BalancePerTrade(eaBalancePerTrade);
eaExpert.RiskPercentPerBalance(eaRiskPercentPerBalance);
eaExpert.DynamicRiskManagement(eaDynamicRiskManagement);
eaExpert.UseDynamicVolume(eaUseDynamicVolume);
eaExpert.DynamicVolumeStep(eaDynamicVolumeStep);
eaExpert.DynamicVolumeBalanceFactor(eaDynamicVolumeBalanceFactor);
eaExpert.MaxAllowedDrawdownToOpenTrades(eaMaxAllowedDrawdownToOpenTrades);
eaExpert.MaxAllowedSLToPauseSignallingPerSymbol(eaMaxAllowedSLToPauseSignallingPerSymbol);
eaExpert.PauseSignallingAfterReachesMaxAllowedSLInSecconds(eaPauseSignallingAfterReachesMaxAllowedSLInSecconds);
//
// Protection ...
eaExpert.AllowHedging(eaAllowHedging);
eaExpert.MinOpenTradesFroHedging(eaMinOpenTradesFroHedging);
eaExpert.HedgingMinVolumeStep(eaHedgingMinVolumeStep);
eaExpert.HedgeingMinRequiredProfitPerVolumeStep(eaHedgeingMinRequiredProfitPerVolumeStep);
//
// Alert ...
eaExpert.SetAlertEnableAlerts(eaEnableAlerts);
eaExpert.SetAlertLogAlerts(eaLogAlerts);
eaExpert.SetAlertMailAlerts(eaMailAlerts);
eaExpert.SetAlertPushAlerts(eaPushAlerts);
eaExpert.SetAlertTerminalAlerts(eaTerminalAlerts);
//
// Reports ...
eaExpert.ReportNewMonths(eaReportNewMonths);
eaExpert.ReportNewWeeks(eaReportNewWeeks);
eaExpert.ReportNewDays(eaReportNewDays);
eaExpert.ReportNewHours(eaReportNewHours);
//
bool isInited = eaExpert.HandleOnInit();
if (!isInited)
{
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
//
// Destroy Timer ...
eaExpert.HandleOnDeInit();
//
delete eaExpert;
//
ZeroMemory(eaExpert);
}
//
// On Tick Handler ...
void OnTick()
{
eaExpert.HandleOnTick();
}
//
// Handle On Trade Event ...
void OnTrade()
{
eaExpert.HandleOnTrade();
}
//
// On Timer ...
void OnTimer()
{
eaExpert.HandleOnTimer();
}
//
// Chart Event Handler ...
void OnChartEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
eaExpert.HandleOnChartEvent(id, lparam, dparam, sparam);
}
//
// Event Listeners ...
/**
* Do What we Want by Specific Signal ...
*
* @param signal: XSignal instance ...
* @param conditions: XStrategyConditions instance ...
*/
void OnSignalRecieved(
XSignal &signal,
X121SMCStrategyConditions &conditions //
)
{
//
eaExpert.HandleOnSignalRecieved(
signal,
conditions //
);
}
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal instance ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
eaExpert.HandleOnStopLossTriggered(deal);
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal instance ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
eaExpert.HandleOnTakeProfitTriggered(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 //
)
{
//
eaExpert.HandleOnPositionForceClosed(
ticket,
position,
comment //
);
}
/**
* Handle Deals Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnDealsChanged(int count)
{
eaExpert.HandleOnDealsChanged(count);
}
/**
* Handle Orders Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnOrdersChanged(int count)
{
eaExpert.HandleOnOrdersChanged(count);
}
/**
* Handle Positions Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnPositionsChanged(int count)
{
eaExpert.HandleOnPositionsChanged(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();
}
//
@@ -0,0 +1,279 @@
<mxfile host="65bd71144e">
<diagram id="QReEEfusIJtThQdlE9lK" name="Page-1">
<mxGraphModel dx="1382" dy="987" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="15" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="3">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="420" y="100"/>
<mxPoint x="100" y="100"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="16" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="6">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="420" y="100"/>
<mxPoint x="780" y="100"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="2" value="Position" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="360" y="40" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="17" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="4">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="100" y="340"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="18" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="5">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="100" y="620"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="3" value="States" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="40" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="27" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="420"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="28" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="500"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="4" value="InDrawdown" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="320" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="29" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="700"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="30" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="780"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="5" value="InProfit" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="600" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="19" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="8">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="20" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="9">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="21" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="11">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="22" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="10">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="460"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="6" value="Events" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="720" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="31" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="38" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="220"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="39" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="220"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="43" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="220"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8" value="Bullish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="200" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="32" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="37" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="300"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="40" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="300"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="44" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="300"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9" value="Bearish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="280" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="34" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="400" as="targetPoint"/>
<Array as="points">
<mxPoint x="520" y="460"/>
<mxPoint x="520" y="360"/>
<mxPoint x="260" y="360"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="35" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="460"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="42" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="680" as="targetPoint"/>
<Array as="points">
<mxPoint x="560" y="460"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="46" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="24">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="810" as="targetPoint"/>
<Array as="points">
<mxPoint x="560" y="460"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="10" value="Bearish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="440" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="33" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="380"/>
<mxPoint x="520" y="360"/>
<mxPoint x="260" y="360"/>
<mxPoint x="260" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="36" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="380"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="41" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="380"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="45" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="380"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="11" value="Bullish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="360" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="23" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="680" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="24" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="760" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="25" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="400" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="26" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="480" width="120" height="40" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@@ -0,0 +1,506 @@
/**
* XColor Tools Module ...
* a module for handle colorify text contents in node js ...
*
* Maintainer
*
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
*/
//
//#region Module Imports ...
const XValueTools = require("./x-value.tools");
//#endregion
//
//#region Constants ...
/**
* these are available style which can applied to an string ...
*/
const AVAILABLE_STYLES = {
//
Bold: "\x1b[1m",
Dim: "\x1b[2m",
Underlined: "\x1b[4m",
Blink: "\x1b[5m",
ReverseFandB: "\x1b[7m",
Hidden: "\x1b[8m",
//
// Commonly used for reset all Styles ...
Reset: "\x1b[0m"
};
/**
* these are available foreground colors which can applied to an string ...
*/
const AVAILABLE_FOREGROUND_COLORS = {
Default: "\x1b[39m",
Black: "\x1b[30m",
Red: "\x1b[31m",
Green: "\x1b[32m",
Yellow: "\x1b[33m",
Blue: "\x1b[34m",
Magenta: "\x1b[35m",
Cyan: "\x1b[36m",
LightGray: "\x1b[37m",
DarkGray: "\x1b[90m",
LightRed: "\x1b[91m",
LightGreen: "\x1b[92m",
LightYellow: "\x1b[93m",
LightBlue: "\x1b[94m",
LightMagenta: "\x1b[95m",
LightCyan: "\x1b[96m",
White: "\x1b[97m",
};
/**
* these are available background colors which can applied to an string ...
*/
const AVAILABLE_BACKGROUND_COLORS = {
Default: "\x1b[49m",
Black: "\x1b[40m",
Red: "\x1b[41m",
Green: "\x1b[42m",
Yellow: "\x1b[43m",
Blue: "\x1b[44m",
Magenta: "\x1b[45m",
Cyan: "\x1b[46m",
LightGray: "\x1b[47m",
DarkGray: "\x1b[100m",
LightRed: "\x1b[101m",
LightGreen: "\x1b[102m",
LightYellow: "\x1b[103m",
LightBlue: "\x1b[104m",
LightMagenta: "\x1b[105m",
LightCyan: "\x1b[106m",
White: "\x1b[107m",
};
/**
* these are available style names, which exports from module and
* users can use them ...
*/
const STYLE_NAMES = {
Bold: "Bold",
Dim: "Dim",
Underlined: "Underlined",
Blink: "Blink",
ReverseFandB: "ReverseFandB",
Hidden: "Hidden",
Reset: "Reset",
};
/**
* these are available color names, which exports from module and
* users can use them ...
*/
const COLOR_NAMES = {
Default: "Default",
Black: "Black",
Red: "Red",
Green: "Green",
Yellow: "Yellow",
Blue: "Blue",
Magenta: "Magenta",
Cyan: "Cyan",
LightGray: "LightGray",
DarkGray: "DarkGray",
LightRed: "LightRed",
LightGreen: "LightGreen",
LightYellow: "LightYellow",
LightBlue: "LightBlue",
LightMagenta: "LightMagenta",
LightCyan: "LightCyan",
White: "White",
};
//#endregion
//
//#region Actions ...
/**
* apply specified style and color on a content ...
*
* @param {string} content specified content for styling ...
* @param {string} color specific color name for using to styling ...
* @param {string} style soecufic style name to use ...
* @param {boolean} toForeground apply specified color as foreground ...
* @param {boolean} toBackground apply specified color as background ...
* @returns {string} styled content ...
*/
function apply(
content,
color,
style,
toForeground = true,
toBackground = false
) {
//
let result = content;
//
// Validate Arg ...
if (!XValueTools.isValidArg(content)) {
return result;
}
//
// Detect and Validate Style and Apply it ...
let eStyle = AVAILABLE_STYLES[style];
if (XValueTools.isValidArg(eStyle)) {
result = `${eStyle}${result}${AVAILABLE_STYLES.Reset}`;
}
//
// Detect and Validate Foreground Color and Apply it ...
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
if (
!!toForeground
&& XValueTools.isValidArg(eFColor)
) {
result = `${eFColor}${result}${AVAILABLE_STYLES.Reset}`;
}
//
// Detect and Validate Background Color and Apply it ...
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
if (
!!toBackground
&& XValueTools.isValidArg(eBColor)
) {
result = `${eBColor}${result}${AVAILABLE_STYLES.Reset}`;
}
}
/**
* apply specific style on a content ...
*
* @param {string} content specific content which going to styled ...
* @param {string} style a member of STYLE_NAMES which specified that which style going to applied to content ...
* @returns {string} styled content ...
*/
function applyStyle(content, style) {
//
// Validate Arg ...
if (!XValueTools.isValidArg(content)) {
return content;
}
//
let eStyle = AVAILABLE_STYLES[style];
if (eStyle === undefined) {
return content;
}
//
return `${eStyle}${content}${AVAILABLE_STYLES.Reset}`;
}
/**
* apply specific foreground color on a content ...
*
* @param {string} content specific content which going to colorified ...
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
* @returns {string} colorified content ...
*/
function applyForegroundColor(content, color) {
//
// Validate Arg ...
if (!XValueTools.isValidArg(content)) {
return content;
}
//
let eColor = AVAILABLE_FOREGROUND_COLORS[color];
if (eColor === undefined) {
return content;
}
//
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
}
/**
* apply specific background color on a content ...
*
* @param {string} content specific content which going to colorified ...
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
* @returns {string} colorified content ...
*/
function applyBackgroundColor(content, color) {
//
// Validate Arg ...
if (!XValueTools.isValidArg(content)) {
return content;
}
//
let eColor = AVAILABLE_BACKGROUND_COLORS[color];
if (eColor === undefined) {
return content;
}
//
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
}
/**
* generate style and color applier expression ...
*
* @param {string} color specific color name for using to styling ...
* @param {string} style soecufic style name to use ...
* @param {boolean} reset close applier string by reset styles ...
* @param {boolean} toForeground apply specified color as foreground ...
* @param {boolean} toBackground apply specified color as background ...
* @returns {string} style and color applier string ...
*/
function getApplier(
style = "",
color = "",
reset = false,
toForeground = true,
toBackground = false
) {
//
let result = "";
//
// Detect and Validate Style and Apply it ...
let eStyle = AVAILABLE_STYLES[style];
if (XValueTools.isValidArg(eStyle)) {
result = `${eStyle}`;
}
//
// Detect and Validate Foreground Color and Apply it ...
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
if (
!!toForeground
&& XValueTools.isValidArg(eFColor)
) {
result = `${eFColor}`;
}
//
// Detect and Validate Background Color and Apply it ...
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
if (
!!toBackground
&& XValueTools.isValidArg(eBColor)
) {
result = `${eBColor}`;
}
//
if (
!!reset &&
result.length > 0
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
/**
* generate style applier expression ...
*
* @param {string} style soecufic style name to use ...
* @param {boolean} reset close applier string by reset styles ...
* @returns {string} style applier string ...
*/
function getStyleApplier(
style = "",
reset = false
) {
//
let result = "";
//
// Detect and Validate Style and Apply it ...
let eStyle = AVAILABLE_STYLES[style];
if (XValueTools.isValidArg(eStyle)) {
result = `${eStyle}`;
}
//
if (
!!reset &&
result.length > 0
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
/**
* generate color applier expression ...
*
* @param {string} color specific color name for using to styling ...
* @param {boolean} reset close applier string by reset styles ...
* @param {boolean} toForeground apply specified color as foreground ...
* @param {boolean} toBackground apply specified color as background ...
* @returns {string} color applier string ...
*/
function getColorApplier(
color = "",
reset = false,
toForeground = true,
toBackground = false
) {
//
let result = "";
//
// Detect and Validate Foreground Color and Apply it ...
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
if (
!!toForeground
&& XValueTools.isValidArg(eFColor)
) {
result = `${eFColor}`;
}
//
// Detect and Validate Background Color and Apply it ...
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
if (
!!toBackground
&& XValueTools.isValidArg(eBColor)
) {
result = `${eBColor}`;
}
//
if (
!!reset &&
result.length > 0
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
/**
* colorified specific content ...
*
* @param {string} content specified content for styling ...
* @param {string} color specific color name for using to styling ...
* @param {boolean} toForeground apply specified color as foreground ...
* @param {boolean} toBackground apply specified color as background ...
* @returns {string}
*/
function colorifyContent(
content = "",
color = "",
toForeground = true,
toBackground = false
) {
//
let result = content;
//
if (!XValueTools.isValidArg(content)) {
return result;
}
//
// Finde Colors ...
//
// Detect and Validate Foreground Color and Apply it ...
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
if (
!!toForeground
&& XValueTools.isValidArg(eFColor)
) {
result = `${eFColor}${result}`;
}
//
// Detect and Validate Background Color and Apply it ...
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
if (
!!toBackground
&& XValueTools.isValidArg(eBColor)
) {
result = `${eBColor}${result}`;
}
//
if (
result.length > 0
&& (
XValueTools.isValidArg(eFColor) ||
XValueTools.isValidArg(eBColor)
)
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
/**
* apply style on specific content ...
*
* @param {string} content specified content for styling ...
* @param {string} style soecufic style name to use ...
* @returns {string}
*/
function stylifiyContent(
content = "",
style = "",
) {
//
let result = content;
//
if (!XValueTools.isValidArg(content)) {
return result;
}
//
// Detect and Validate Style and Apply it ...
let eStyle = AVAILABLE_STYLES[style];
if (XValueTools.isValidArg(eStyle)) {
result = `${eStyle}${result}`;
}
//
if (
result.length > 0
&& XValueTools.isValidArg(eStyle)
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
//#endregion
//
//#region Module Exports ...
module.exports = {
//
STYLE_NAMES,
COLOR_NAMES,
//
apply,
applyStyle,
getApplier,
getColorApplier,
getStyleApplier,
colorifyContent,
stylifiyContent,
applyForegroundColor,
applyBackgroundColor,
}
//#endregion
@@ -0,0 +1,887 @@
/**
* XFile Tools Module ...
* a module for handle all file/folder manipulating task in node js ...
*
* Maintainer
*
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
*/
//
//#region Module Imports ...
const fs = require('fs');
const os = require('os');
const Path = require('path');
const http = require('http');
const https = require('https');
const XValueTools = require('./x-value.tools');
//#endregion
//
//#region Constants ...
/**
* current os path separators ...
*/
const PathSeparator = Path.sep;
/**
* current directory ...
*/
const CurrentDir = __dirname;
//#endregion
//
//#region Actions ...
//
//#region Global ...
/**
* retrieve a path status ...
*
* @param {string} path a path value to check ...
* @returns an stat object ...
*/
function getStatus(path = '') {
//
if (!XValueTools.isValidArg(path)) {
return undefined;
}
//
return fs.statSync(path);
}
/**
* retrieve user's Home path ...
*
* @returns {string} a path ...
*/
function getHomePath() {
return os.homedir();
}
//#endregion
//
//#region Path ...
/**
* retrieve the base name of specific address path ...
*
* @param {string} path address of file or folder ...
* @returns string ...
*/
function basename(path = '') {
//
if (!XValueTools.isValidArg(path)) {
return '';
}
//
const result = Path.basename(path);
return result;
}
/**
* join several path segments together ...
*
* @param {...string} path path params ...
* @returns a joined paths ...
*/
function joinPath(...path) {
return Path.join(...path);
}
/**
* resolve a relative path to absolute ...
*
* @param {string[]} path a path value to check ...
* @returns {string}
*/
function resolvePath(...path) {
return Path.resolve(...path);
}
//#endregion
//
//#region File ...
/**
* determines a path destination is a file or not ...
*
* @param {string} path a path value to check ...
* @returns a boolean value ...
*/
function isFileExists(path = '') {
//
if (!XValueTools.isValidArg(path)) {
return false;
}
//
try {
const stat = getStatus(path);
if (!stat) {
return false;
}
//
return stat.isFile();
} catch {
return false;
}
}
/**
* remove a file ...
*
* @param {string} path a file path ...
* @returns {Promise<boolean>} action done or not ...
*/
function removeFile(path = '') {
return new Promise((resolve) => {
//
if (!isFileExists(path)) {
resolve(false);
}
//
fs.unlink(path, (err) => {
//
if (err) {
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* copy a file to destination path ...
*
* @param {string} source source file path ...
* @param {string} dest dest folder path ...
* @returns {Promise<boolean>} action done or not ...
*/
function copyFile(
source = '',
dest = ''
) {
return new Promise((resolve) => {
//
if (
!isFileExists(source) ||
!isDirectoryExists(dest)
) {
resolve(false);
return;
}
//
const destFilePath = Path.join(dest, Path.basename(source));
fs.copyFile(source, destFilePath, (err) => {
//
if (err) {
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* reading specified file content ...
*
* @param {string} path a file path ...
* @returns {Promise<string>} file content ...
*/
function readFile(path = '') {
return new Promise((resolve) => {
//
if (!isFileExists(path)) {
resolve('');
return;
}
//
fs.readFile(path, 'utf8', (err, content) => {
//
if (err) {
resolve(undefined);
return;
}
//
resolve(content);
});
});
}
/**
* write content to a file ...
*
* @param {string} path a file path ...
* @param {string} content the content which going to write to the file ...
* @param {bool} overwrite determines file overwrite if exists ...
* @returns {Promise<boolean>} action done or not ...
*/
function writeFile(
path = '',
content = '',
overwrite = true
) {
return new Promise((resolve) => {
//
if (isFileExists(path) && !overwrite) {
//
resolve(false);
return;
}
//
// Normalize Content ...
content = XValueTools.isValidArg(content) ?
content :
'';
//
fs.writeFile(path, content, (err) => {
//
if (err) {
//
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* create a file ...
*
* @param {string} path file path ...
* @param {string} fileName file name ...
* @returns {Promise<boolean>} action done or not ...
*/
function createFile(
path = '',
fileName = ''
) {
return new Promise((resolve) => {
//
const filePath = Path.join(path, fileName);
if (
isFileExists(filePath) ||
!XValueTools.isValidArg(path) ||
!XValueTools.isValidArg(fileName)
) {
//
resolve(false);
return;
}
//
fs.writeFile(filePath, '', (err) => {
//
if (err) {
//
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* remove a file name extension ...
*
* @param {string} name
* @returns {string} name without extension ...
*/
function removeFileExtension(name = '') {
return name.substring(0, name.lastIndexOf('.')) || name;
}
/**
* retrieve a file extension ...
*
* @param {string} path a path which locate a file ...
* @returns {string}
*/
function getFileExtension(path = '') {
//
let result = "";
//
// Validate Arg ...
if (
!XValueTools.isValidArg(path)
|| !isFileExists(path)
) {
return result;
}
//
// Retrieve just file name ...
const fileName = basename(path);
result = fileName.replace(
removeFileExtension(fileName),
""
);
//
return result;
}
/**
* retrieve all files list recursively from specific path ...
*
* @param {string} path a source folder path ...
* @param {string[]} extensions which file extensions need to be listed, live empty for all files ...
* @returns {Promise<string[]>}
*/
async function getRecursiveFilesList(
path = "",
extensions = []
) {
//
let result = [];
//
// Validate Args ...
if (
!XValueTools.isValidArg(path)
|| !isDirectoryExists(path)
) {
return result;
}
//
const contents = await getDirectoryContents(path);
for (const item of contents) {
//
const itemPath = joinPath(
path,
item
);
//
const isItemFile = isFileExists(itemPath);
if (isItemFile) {
//
const itemFileExtension = getFileExtension(itemPath);
const isFileInSupportedExtensions =
extensions === undefined || extensions.length === 0
? true
: extensions.includes(itemFileExtension)
;
if (isFileInSupportedExtensions) {
result.push(itemPath);
}
} else if (isDirectoryExists(itemPath)) {
//
const itemPathFiles = await getRecursiveFilesList(itemPath, extensions);
result.push(...itemPathFiles);
}
}
//
return result;
}
/**
* Extract Specific files from a folder and it's content ...
*
* @param {string} path Folder Path ...
* @returns
*/
async function extractFiles(path = "", ext = [], excludeWorkspaceFolders = []) {
//
const result = [];
//
if (!ext || ext.length == 0) {
return result;
}
//
const pathContent = await getDirectoryContents(path);
if (!pathContent || pathContent.length == 0) {
return result;
}
//
// Loop through Content ...
for (const c of pathContent) {
//
// Prepare full path ...
const cPath = joinPath(path, c);
//
// check content path is file or not ...
const isCFile = isFileExists(cPath);
const isCDirectory = isDirectoryExists(cPath);
if (isCFile) {
//
// Check it is MQL file or not ...
const cExt = getFileExtension(cPath);
if (ext.includes(cExt)) {
result.push(cPath);
}
} else if (isCDirectory) {
//
const destFolderName = basename(cPath);
const isExcluded = excludeWorkspaceFolders.includes(destFolderName);
if (isExcluded) {
continue;
}
//
const cFiles = await extractFiles(cPath, ext);
if (cFiles && cFiles.length > 0) {
result.push(...cFiles);
}
}
}
//
return result;
}
//#endregion
//
//#region Directory ...
/**
* create a directory ...
*
* @param {string} path destination path including dir name ...
* @param {boolean} recursive create directories recursively ...
* @returns action done or not ...
*/
function createDirectory(
path = '',
recursive = true
) {
//
let result = false;
//
if (
isDirectoryExists(path) ||
!XValueTools.isValidArg(path)
) {
return false;
}
//
try {
//
fs.mkdirSync(path, { recursive: recursive });
result = true;
return result;
} catch {
return false;
}
}
/**
* remove a directory ...
*
* @param {string} path destination path including dir name ...
* @param {boolean} recursive removes directories recursively ...
* @returns {Promise<boolean>} action done or not ...
*/
function removeDirectory(
path = '',
recursive = false
) {
return new Promise((resolve) => {
//
if (!isDirectoryExists(path)) {
resolve(false);
return;
}
//
fs.rm(path, {
recursive
}, (err) => {
//
if (err) {
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* determines a path destination is a directory or not ...
*
* @param {string} path a folder path ...
* @returns represent destnation path is Directory or not ...
*/
function isDirectoryExists(path = '') {
//
if (!XValueTools.isValidArg(path)) {
return false;
}
//
try {
//
const isExists = fs.existsSync(path);
if (!isExists) {
return false;
}
//
const stat = getStatus(path);
if (!stat) {
return false;
}
//
const result = stat.isDirectory();
return result;
} catch {
return false;
}
}
/**
* retrieve a directory content ...
*
* @param {string} path a folder path ...
* @returns {Promise<string[]>} a collection of folder files ...
*/
function getDirectoryContents(path = '') {
return new Promise((resolve) => {
//
if (!isDirectoryExists(path)) {
resolve([]);
return;
}
//
fs.readdir(path, (err, content) => {
//
if (err) {
resolve([]);
return;
}
//
resolve(content);
});
});
}
/**
* retrieve a directory files ...
*
* @param {string} path a folder path ...
* @returns {Promise<string[]>} a collection of folder files ...
*/
function getDirectoryFiles(
path = '',
containsHiddenFiles = false
) {
return new Promise((resolve) => {
//
if (!isDirectoryExists(path)) {
resolve([]);
return;
}
//
fs.readdir(path, (err, content) => {
//
if (err) {
resolve([]);
return;
}
//
if (!containsHiddenFiles) {
content = content.filter(c => !c.startsWith('.'));
}
//
const result = [];
content
.forEach(c => {
//
const cPath = Path.join(path, c);
if (isFileExists(cPath)) {
result.push(c);
}
});
//
resolve(result);
});
});
}
/**
* retrieve a directory folders ...
*
* @param {string} path a folder path ...
* @returns {Promise<string[]>} a collection of folder names ...
*/
function getDirectoryFolders(path = '') {
return new Promise((resolve) => {
//
if (!isDirectoryExists(path)) {
resolve([]);
return;
}
//
fs.readdir(path, (err, content) => {
//
if (err) {
resolve([]);
return;
}
//
const result = [];
content.forEach(c => {
//
const cPath = Path.join(path, c);
if (isDirectoryExists(cPath)) {
result.push(c);
}
});
//
resolve(result);
});
});
}
/**
* copy a folder with all of it's content to dest ...
*
* @param {string} source source folder path ...
* @param {string} dest dest folder path ...
* @returns {Promise<boolean>} action done or not ...
*/
async function copyFolder(
source = '',
dest = ''
) {
//
if (
!isDirectoryExists(source) ||
!XValueTools.isValidArg(dest) ||
!XValueTools.isValidArg(source)
) {
return false;
}
//
const folderName = Path.basename(source);
const destPath = Path.join(dest, folderName);
//
// Create Dest Path folder if not exists ...
if (!isDirectoryExists(destPath)) {
//
let result = createDirectory(destPath, true);
if (!result) {
return false;
}
}
//
// Files ...
const files = await getDirectoryFiles(source);
if (files && files.constructor === Array && files.length > 0) {
//
const filesPromises = files.map(file => copyFile(Path.join(source, file), destPath));
const filesResult = (await Promise.all(filesPromises)).every(r => !!r);
if (!filesResult) {
return false;
}
}
//
// Folders ...
const folders = await getDirectoryFolders(source);
if (folders && folders.constructor === Array && folders.length > 0) {
//
const folderPromises = folders.map(folder => copyFolder(Path.join(source, folder), destPath));
const filesResult = (await Promise.all(folderPromises)).every(r => !!r);
if (!filesResult) {
return false;
}
}
//
return true;
}
//#endregion
//
//#region Downloader ...
/**
* download a file from specific url and store it ...
*
* @param {string} filepath the file name and path which required to put download file on it ...
* @param {string} url the web url for downloading ...
*/
function download(filepath, url) {
//
// Validate Args ...
if (
!XValueTools.isValidArg(url)
|| !XValueTools.isValidURL(url)
|| !XValueTools.isValidArg(filepath)
) {
return;
}
//
var file = fs.createWriteStream(filepath);
//
if (url.startsWith('https:')) {
https.get(url, function (response) {
response.pipe(file);
});
} else if (url.startsWith('http:')) {
http.get(url, function (response) {
response.pipe(file);
});
}
}
//#endregion
//
//#region JSON ...
/**
* read and parse a JSON content from a file ...
*
* @param {string} path source file path ...
* @returns {any}
*/
function readJSON(path = "") {
//
// Validate Args ...
if (!isFileExists(path)) {
return undefined;
}
//
let result = undefined;
try {
result = require(path);
} catch {
result = undefined;
}
//
return result;
}
/**
* write a JSON Object content into a file ...
*
* @param {string} path dest file path ...
* @param {any} content an object which required to write to file ...
* @returns {Promise<boolean>}
*/
async function writeJSON(
path = "",
content = undefined
) {
//
let result = false;
//
// Validate Args ...
if (!XValueTools.isValidArg(path)) {
return result;
}
//
// Normallize Content ...
if (content === undefined) {
content = {};
}
//
const contentString = XValueTools.beautifyJSON(content);
//
result = await writeFile(
path,
contentString,
true
);
//
return result;
}
//#endregion
//#endregion
//
//#region Module Exports ...
module.exports = {
//
CurrentDir,
PathSeparator,
//
getStatus,
getHomePath,
//
basename,
joinPath,
resolvePath,
//
download,
//
readJSON,
writeJSON,
//
copyFile,
readFile,
writeFile,
createFile,
removeFile,
isFileExists,
getFileExtension,
removeFileExtension,
getRecursiveFilesList,
extractFiles,
//
copyFolder,
createDirectory,
removeDirectory,
isDirectoryExists,
getDirectoryFiles,
getDirectoryFolders,
getDirectoryContents,
};
//#endregion
@@ -0,0 +1,219 @@
/**
* XShell Tools Module ...
* a module for handling shell actions and retrieve OS Info in node js ...
*
* Maintainer
*
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
*/
//
//#region Imports ...
const os = require('os');
const process = require('process');
const { exec } = require("child_process");
const XFileTools = require('./x-file.tools');
//#endregion
//
//#region Constants ...
//
const OS = {
Aix: 'aix',
Darwin: 'darwin',
FreeBSD: 'freebsd',
Linux: 'linux',
OpenBSD: 'openbsd',
SnOS: 'sunos',
Windows: 'win32'
};
//
const isWindows = process.platform === OS.Windows;
//#endregion
//
//#region Actions ...
//
//#region Pure shell commands ...
/**
* execute a command using NodeJS on shell ...
*
* @param {string} cmd command to execute ...
* @param {string} cwd working directory ...
*
* @returns Promise<any, errr> instance ...
*/
function execute(cmd, cwd) {
return new Promise((resolve, reject) => {
//
if (!cmd || cmd.toString().length === 0 || (cwd && !XFileTools.isDirectoryExists(cwd))) {
reject('invalid args ...');
return;
}
//
exec(cmd, { cwd }, (err, result, stdError) => {
//
if (err) {
reject(err);
return;
}
//
if (stdError) {
//
// reject(stdError);
// return;
}
//
resolve(result);
});
});
};
/**
* determines a command exists on host or not ...
*
* @param {string} name specific command name ...
*
* @returns boolean Promise ...
*/
function checkCommandExists(name) {
return new Promise(resolve => {
//
if (!name) {
resolve(false);
return;
}
//
const cmd = isWindows ? `${name} >nul 2>&1` : `type ${name} >/dev/null 2>&1`;
execute(cmd).then(result => {
resolve(true);
})
.catch(err => {
resolve(false);
});
});
}
//#endregion
//
//#region required commands state ...
/**
* check al required commands exists or not ...
*
* @returns
*/
async function isRequiredCommandsExists() {
//
let result = false;
//
// const isTarExists = await isTarCommandExists();
// const isCatExists = await isCatCommandExists();
// const isGrepExists = await isGrepCommandExists();
// const isSedExists = await isSedCommandExists();
const isNpmExists = await isNpmCommandExists();
const isNgExists = await isNgCommandExists();
const isIonicExists = await isIonicCommandExists();
const isCordovaExists = await isCordovaCommandExists();
//
result = isNpmExists
&& isNgExists
&& isIonicExists
&& isCordovaExists
;
//
return result;
}
/**
* retrieve required commands state object ...
*
* @returns
*/
async function getRequiredCommandsStates() {
//
const result = {};
//
// const isTarExists = await isTarCommandExists();
// const isCatExists = await isCatCommandExists();
// const isGrepExists = await isGrepCommandExists();
// const isSedExists = await isSedCommandExists();
const isNpmExists = await isNpmCommandExists();
const isNgExists = await isNgCommandExists();
const isIonicExists = await isIonicCommandExists();
const isCordovaExists = await isCordovaCommandExists();
//
result['npm'] = isNpmExists;
result['ng'] = isNgExists;
result['ionic'] = isIonicExists;
result['cordova'] = isCordovaExists;
//
return result;
}
//#endregion
//
//#region Commonly used Command Checkers ...
/**
* determines npm command exists or not ...
*
* @returns
*/
function isNpmCommandExists() {
return checkCommandExists('npm');
}
/**
* determines ng command exists or not ...
*
* @returns
*/
function isNgCommandExists() {
return checkCommandExists('ng');
}
/**
* determines ionic command exists or not ...
*
* @returns
*/
function isIonicCommandExists() {
return checkCommandExists('ionic');
}
/**
* determines cordova command exists or not ...
*
* @returns
*/
function isCordovaCommandExists() {
return checkCommandExists('cordova');
}
//#endregion
//#endregion
//
//#region Module Exports ...
module.exports = {
//
execute,
checkCommandExists,
isRequiredCommandsExists,
getRequiredCommandsStates,
//
isNgCommandExists,
isIonicCommandExists,
isCordovaCommandExists,
}
//#endregion
@@ -0,0 +1,268 @@
/**
* DataType Tools Module ...
* a module for manipulate and detect supported data types in node js ...
*
* Maintainer
*
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
*/
//
//#region Constants ...
/**
* all supported data types ...
*/
const DataTypes = {
Null: 'null',
Date: 'date',
Array: 'array',
Object: 'object',
String: 'string',
Number: 'number',
Unknown: 'unknown',
Boolean: 'boolean',
Function: 'function',
Undefined: 'undefined',
};
//#endregion
//
//#region Actions ...
/**
* detect type of a content ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function getType(value) {
//
const type = typeof value;
//
let result = DataTypes.Unknown;
let dateIdentifier = '[object Date]';
let constructor = value && value.constructor ?
value.constructor.toString() :
'';
//
switch (type) {
//
case 'undefined':
result = DataTypes.Undefined;
break;
//
case 'boolean':
result = DataTypes.Boolean;
break;
//
case 'string':
result = DataTypes.String;
break;
//
case 'number':
result = DataTypes.Number;
break;
//
case 'function':
result = DataTypes.Function;
break;
//
case 'object':
//
// Null ...
if (value === null) {
result = DataTypes.Null;
} else
//
// Array ...
if (Array.isArray(value)) {
result = DataTypes.Array;
} else
//
// Data ...
if (
value instanceof Date ||
isFunction(value.getMonth) ||
constructor.includes(dateIdentifier) ||
Object.prototype.toString.call(value) === dateIdentifier
) {
result = DataTypes.Date;
} else
//
// Object ...
{
result = DataTypes.Object;
}
break;
//
default:
result = DataTypes.Unknown;
break;
}
//
return result;
}
/**
* retrieve an object constructor ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function getConstructor(value) {
//
const result = value && value.constructor ?
value.constructor.toString() :
'';
//
return result;
}
/**
* retrieve an object prototype ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function getPrototype(value) {
//
const result = value ?
Object.prototype.toString.call(value) :
'';
//
return result;
}
/**
* check an object is null or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isNull(value) {
return getType(value) === DataTypes.Null;
}
/**
* check an object is undefined or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isUndefined(value) {
return getType(value) === DataTypes.Undefined;
}
/**
* check an object is null or undefined or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isNullOrUndefined(value) {
return isNull(value) || isUndefined(value);
}
/**
* check an object is a date or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isDate(value) {
return getType(value) === DataTypes.Date;
}
/**
* check an object is number or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isNumber(value) {
return getType(value) === DataTypes.Number;
}
/**
* check an object is string or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isString(value) {
return getType(value) === DataTypes.String;
}
/**
* check an object is boolean or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isBoolean(value) {
return getType(value) === DataTypes.Boolean;
}
/**
* check an object is an Array or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isArray(value) {
return getType(value) === DataTypes.Array;
}
/**
* check an object is and Object or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isObject(value) {
return getType(value) === DataTypes.Object;
}
/**
* check an object is a Function or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isFunction(value) {
return getType(value) === DataTypes.Function;
}
//#endregion
//
//#region Module Exports ...
module.exports = {
//
DataTypes,
//
getType,
getConstructor,
getPrototype,
isNull,
isUndefined,
isNullOrUndefined,
isDate,
isNumber,
isString,
isBoolean,
isArray,
isObject,
isFunction,
}
//#endregion
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,542 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XTest MQL5 Expert Advisor
// -------------------------------------------------
// Name: XEATemplate
// 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 XEATemplate"
#property strict
//
#define ShortName "XEATemplate"
//
// Imports ...
#include "../Classes/x-saherelm.xalert.class.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
#include "../Helpers/x-saherelm.xcc.helper.mq5"
#include "../Helpers/x-saherelm.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
//
// Time Report ...
input group "Reports";
input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = false; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
//
// Define Local Variables ...
//
string eaLogTag; // EA Log Prefix ...
XSCAlert *eaAlert; // Alert Provider for Expert Adviser ...
XSCTrade *eaTrader; // Trader of Expert Adviser ...
XTimeTracker eaTimeTracker; // Time Tracker for Providing Reports ...
XSCXCTHelper *eaCHelper; // Bar Timer Indicator Helper class ...
XSCXCCHelper *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();
HandleReportTime();
UpdatePositionsState();
//
// TODO: Implemetn Tick Processors Algorithm ...
}
//
// 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 //
)
{
//
// Handle OnClick Event ...
if (id == CHARTEVENT_OBJECT_CLICK)
{
HandleOnClickEvent(sparam);
}
}
//
// Custom Event Handlers ...
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* 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 //
)
{
//
HandleReportBalance();
}
//
// 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 ...
XCTInputs ctInputs;
ctInputs.Default(); // Default Configurations ...
eaCHelper = new XSCXCTHelper();
result = eaCHelper.Init(
_Symbol,
_Period,
ctInputs //
);
if (!result)
{
return result;
}
//
// Bar Styles ...
XCCInputs ccInputs;
ccInputs.Default(); // Default Configurations ...
eaCCHelper = new XSCXCCHelper();
result = eaCCHelper.Init(
_Symbol,
_Period,
ccInputs //
);
if (!result)
{
return result;
}
//
// Create Instance of Alert Class and Configure it ...
eaAlert = new XSCAlert();
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 XSCTrade(
eaSlippage,
eaMagicNumber //
);
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
//
return result;
}
/**
* Destroy all Initialized EA Requirements ...
*/
void DestroyEA()
{
//
delete eaCHelper;
delete eaCCHelper;
//
delete eaAlert;
}
/**
* Initialize all GUI Requirements for EA ...
*
* @return ( bool )
*/
bool InitGUI()
{
//
bool result = false;
//
// TODO: Fix This ...
result = true;
//
return result;
}
/**
* Update GUI based on Each Ticks ...
*/
void UpdateGUI()
{
//
// TODO: Implement this ...
}
/**
* Destroy all Initialized GUi Requirements ...
*/
void DestroyGUI()
{
//
// TODO: Complete this ...
}
//
// Others ...
/**
* Update Positions States ...
*/
void UpdatePositionsState()
{
//
// TODO: Implement this ...
}
/**
* Handle On Click Event for GUI Components ...
*
* @param name: Object Name ...
*/
void HandleOnClickEvent(string name)
{
//
if (!IsValid(name))
{
return;
}
//
bool isClicked = false;
//
// TODO: Implement Chart Objects On Click ...
//
if (isClicked)
{
UpdateGUI();
}
}
/**
* Report Account Balance ...
*/
void HandleReportBalance()
{
//
if (!IsRunningOnTestMode())
{
return;
}
//
string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance());
eaAlert.Log(msg);
}
/**
* Time Reporting based on Inputs ...
*/
void HandleReportTime()
{
//
// 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 ....
if (eaReportNewDays &&
eaTimeTracker.IsNewDay())
{
//
string msg = "New Day ...";
//
eaAlert.Alert(msg);
}
//
// Hourly Report ....
if (eaReportNewHours &&
eaTimeTracker.IsNewHour())
{
//
string msg = "New Hour ...";
//
eaAlert.Alert(msg);
}
}
//
@@ -0,0 +1,575 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XTest MQL5 Expert Advisor
// -------------------------------------------------
// Name: XPanelEA
// Description: an Exper Advisor which used Panels
//
// 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 XPanelEA"
#property strict
//
#define ShortName "XPANELEA"
//
// Imports ...
#include "../Classes/x-saherelm.x-app-dialog.class.mq5"
#include "../Classes/x-saherelm.xalert.class.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
#include "../Helpers/x-saherelm.xcc.helper.mq5"
#include "../Helpers/x-saherelm.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
//
// Time Report ...
input group "Reports";
input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = false; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
//
// Define Local Variables ...
//
string eaLogTag; // EA Log Prefix ...
XSCAlert *eaAlert; // Alert Provider for Expert Adviser ...
XSCTrade *eaTrader; // Trader of Expert Adviser ...
XTimeTracker eaTimeTracker; // Time Tracker for Providing Reports ...
XSCXCTHelper *eaCTHelper; // Bar Timer Indicator Helper class ...
XSCXCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
//
XCAppDialog eaMainWindow; // EA Main Dialog ...
//
// 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();
HandleReportTime();
UpdatePositionsState();
//
// TODO: Implemetn Tick Processors Algorithm ...
}
//
// 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);
//
// Handle OnClick Event ...
if (id == CHARTEVENT_OBJECT_CLICK)
{
HandleOnClickEvent(sparam);
}
}
//
// Custom Event Handlers ...
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* 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 //
)
{
//
HandleReportBalance();
}
//
// 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 ...
XCTInputs ctInputs;
ctInputs.Default(); // Default Configurations ...
eaCTHelper = new XSCXCTHelper();
result = eaCTHelper.Init(
_Symbol,
_Period,
ctInputs //
);
if (!result)
{
return result;
}
//
// Bar Styles ...
XCCInputs ccInputs;
ccInputs.Default(); // Default Configurations ...
eaCCHelper = new XSCXCCHelper();
result = eaCCHelper.Init(
_Symbol,
_Period,
ccInputs //
);
if (!result)
{
return result;
}
//
// Create Instance of Alert Class and Configure it ...
eaAlert = new XSCAlert();
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 XSCTrade(
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 ...
);
//
// Configuring Dialog ...
// eaMainWindow.MinimizeButton(false); // Hide Minimize Button ...
// eaMainWindow.CloseButton(false); // Hide Close Button ...
eaMainWindow.BackgroundColor(clrBlack);
// result = true;
//
// Try To Run Main Window ...
if (result)
{
eaMainWindow.Run();
}
//
return result;
}
/**
* Update GUI based on Each Ticks ...
*/
void UpdateGUI()
{
//
// TODO: Implement this ...
}
/**
* Destroy all Initialized GUi Requirements ...
*/
void DestroyGUI()
{
//
eaMainWindow.Destroy();
}
//
// Others ...
/**
* Update Positions States ...
*/
void UpdatePositionsState()
{
//
// TODO: Implement this ...
}
/**
* Handle On Click Event for GUI Components ...
*
* @param name: Object Name ...
*/
void HandleOnClickEvent(string name)
{
//
if (!IsValid(name))
{
return;
}
//
bool isClicked = false;
//
// TODO: Implement Chart Objects On Click ...
//
if (isClicked)
{
UpdateGUI();
}
}
/**
* Report Account Balance ...
*/
void HandleReportBalance()
{
//
if (!IsRunningOnTestMode())
{
return;
}
//
string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance());
eaAlert.Log(msg);
}
/**
* Time Reporting based on Inputs ...
*/
void HandleReportTime()
{
//
// 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 ....
if (eaReportNewDays &&
eaTimeTracker.IsNewDay())
{
//
string msg = "New Day ...";
//
eaAlert.Alert(msg);
}
//
// Hourly Report ....
if (eaReportNewHours &&
eaTimeTracker.IsNewHour())
{
//
string msg = "New Hour ...";
//
eaAlert.Alert(msg);
}
}
//
Binary file not shown.
@@ -0,0 +1,168 @@
//+------------------------------------------------------------------+
//| ExpertMACD.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMACD.mqh>
#include <Expert\Trailing\TrailingNone.mqh>
#include <Expert\Money\MoneyNone.mqh>
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
//--- inputs for expert
input string Inp_Expert_Title ="ExpertMACD";
int Expert_MagicNumber =10981;
bool Expert_EveryTick =false;
//--- inputs for signal
input int Inp_Signal_MACD_PeriodFast =12;
input int Inp_Signal_MACD_PeriodSlow =24;
input int Inp_Signal_MACD_PeriodSignal=9;
input int Inp_Signal_MACD_TakeProfit =50;
input int Inp_Signal_MACD_StopLoss =20;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- Initializing expert
if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
{
//--- failed
printf(__FUNCTION__+": error initializing expert");
ExtExpert.Deinit();
return(-1);
}
//--- Creation of signal object
CSignalMACD *signal=new CSignalMACD;
if(signal==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating signal");
ExtExpert.Deinit();
return(-2);
}
//--- Add signal to expert (will be deleted automatically))
if(!ExtExpert.InitSignal(signal))
{
//--- failed
printf(__FUNCTION__+": error initializing signal");
ExtExpert.Deinit();
return(-3);
}
//--- Set signal parameters
signal.PeriodFast(Inp_Signal_MACD_PeriodFast);
signal.PeriodSlow(Inp_Signal_MACD_PeriodSlow);
signal.PeriodSignal(Inp_Signal_MACD_PeriodSignal);
signal.TakeLevel(Inp_Signal_MACD_TakeProfit);
signal.StopLevel(Inp_Signal_MACD_StopLoss);
//--- Check signal parameters
if(!signal.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error signal parameters");
ExtExpert.Deinit();
return(-4);
}
//--- Creation of trailing object
CTrailingNone *trailing=new CTrailingNone;
if(trailing==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating trailing");
ExtExpert.Deinit();
return(-5);
}
//--- Add trailing to expert (will be deleted automatically))
if(!ExtExpert.InitTrailing(trailing))
{
//--- failed
printf(__FUNCTION__+": error initializing trailing");
ExtExpert.Deinit();
return(-6);
}
//--- Set trailing parameters
//--- Check trailing parameters
if(!trailing.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error trailing parameters");
ExtExpert.Deinit();
return(-7);
}
//--- Creation of money object
CMoneyNone *money=new CMoneyNone;
if(money==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating money");
ExtExpert.Deinit();
return(-8);
}
//--- Add money to expert (will be deleted automatically))
if(!ExtExpert.InitMoney(money))
{
//--- failed
printf(__FUNCTION__+": error initializing money");
ExtExpert.Deinit();
return(-9);
}
//--- Set money parameters
//--- Check money parameters
if(!money.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error money parameters");
ExtExpert.Deinit();
return(-10);
}
//--- Tuning of all necessary indicators
if(!ExtExpert.InitIndicators())
{
//--- failed
printf(__FUNCTION__+": error initializing indicators");
ExtExpert.Deinit();
return(-11);
}
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ExtExpert.Deinit();
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
ExtExpert.OnTick();
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
ExtExpert.OnTrade();
}
//+------------------------------------------------------------------+
//| Function-event handler "timer" |
//+------------------------------------------------------------------+
void OnTimer(void)
{
ExtExpert.OnTimer();
}
//+------------------------------------------------------------------+
Binary file not shown.
@@ -0,0 +1,175 @@
//+------------------------------------------------------------------+
//| ExpertMAMA.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMA.mqh>
#include <Expert\Trailing\TrailingMA.mqh>
#include <Expert\Money\MoneyNone.mqh>
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
//--- inputs for expert
input string Inp_Expert_Title ="ExpertMAMA";
int Expert_MagicNumber =12003;
bool Expert_EveryTick =false;
//--- inputs for signal
input int Inp_Signal_MA_Period =12;
input int Inp_Signal_MA_Shift =6;
input ENUM_MA_METHOD Inp_Signal_MA_Method =MODE_SMA;
input ENUM_APPLIED_PRICE Inp_Signal_MA_Applied =PRICE_CLOSE;
//--- inputs for trailing
input int Inp_Trailing_MA_Period =12;
input int Inp_Trailing_MA_Shift =0;
input ENUM_MA_METHOD Inp_Trailing_MA_Method =MODE_SMA;
input ENUM_APPLIED_PRICE Inp_Trailing_MA_Applied=PRICE_CLOSE;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- Initializing expert
if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
{
//--- failed
printf(__FUNCTION__+": error initializing expert");
ExtExpert.Deinit();
return(-1);
}
//--- Creation of signal object
CSignalMA *signal=new CSignalMA;
if(signal==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating signal");
ExtExpert.Deinit();
return(-2);
}
//--- Add signal to expert (will be deleted automatically))
if(!ExtExpert.InitSignal(signal))
{
//--- failed
printf(__FUNCTION__+": error initializing signal");
ExtExpert.Deinit();
return(-3);
}
//--- Set signal parameters
signal.PeriodMA(Inp_Signal_MA_Period);
signal.Shift(Inp_Signal_MA_Shift);
signal.Method(Inp_Signal_MA_Method);
signal.Applied(Inp_Signal_MA_Applied);
//--- Check signal parameters
if(!signal.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error signal parameters");
ExtExpert.Deinit();
return(-4);
}
//--- Creation of trailing object
CTrailingMA *trailing=new CTrailingMA;
if(trailing==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating trailing");
ExtExpert.Deinit();
return(-5);
}
//--- Add trailing to expert (will be deleted automatically))
if(!ExtExpert.InitTrailing(trailing))
{
//--- failed
printf(__FUNCTION__+": error initializing trailing");
ExtExpert.Deinit();
return(-6);
}
//--- Set trailing parameters
trailing.Period(Inp_Trailing_MA_Period);
trailing.Shift(Inp_Trailing_MA_Shift);
trailing.Method(Inp_Trailing_MA_Method);
trailing.Applied(Inp_Trailing_MA_Applied);
//--- Check trailing parameters
if(!trailing.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error trailing parameters");
ExtExpert.Deinit();
return(-7);
}
//--- Creation of money object
CMoneyNone *money=new CMoneyNone;
if(money==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating money");
ExtExpert.Deinit();
return(-8);
}
//--- Add money to expert (will be deleted automatically))
if(!ExtExpert.InitMoney(money))
{
//--- failed
printf(__FUNCTION__+": error initializing money");
ExtExpert.Deinit();
return(-9);
}
//--- Set money parameters
//--- Check money parameters
if(!money.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error money parameters");
ExtExpert.Deinit();
return(-10);
}
//--- Tuning of all necessary indicators
if(!ExtExpert.InitIndicators())
{
//--- failed
printf(__FUNCTION__+": error initializing indicators");
ExtExpert.Deinit();
return(-11);
}
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ExtExpert.Deinit();
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
ExtExpert.OnTick();
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
ExtExpert.OnTrade();
}
//+------------------------------------------------------------------+
//| Function-event handler "timer" |
//+------------------------------------------------------------------+
void OnTimer(void)
{
ExtExpert.OnTimer();
}
//+------------------------------------------------------------------+
Binary file not shown.
@@ -0,0 +1,171 @@
//+------------------------------------------------------------------+
//| ExpertMAPSAR.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMA.mqh>
#include <Expert\Trailing\TrailingParabolicSAR.mqh>
#include <Expert\Money\MoneyNone.mqh>
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
//--- inputs for expert
input string Inp_Expert_Title ="ExpertMAPSAR";
int Expert_MagicNumber =14598;
bool Expert_EveryTick =false;
//--- inputs for signal
input int Inp_Signal_MA_Period =12;
input int Inp_Signal_MA_Shift =6;
input ENUM_MA_METHOD Inp_Signal_MA_Method =MODE_SMA;
input ENUM_APPLIED_PRICE Inp_Signal_MA_Applied =PRICE_CLOSE;
//--- inputs for trailing
input double Inp_Trailing_ParabolicSAR_Step =0.02;
input double Inp_Trailing_ParabolicSAR_Maximum=0.2;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- Initializing expert
if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
{
//--- failed
printf(__FUNCTION__+": error initializing expert");
ExtExpert.Deinit();
return(-1);
}
//--- Creation of signal object
CSignalMA *signal=new CSignalMA;
if(signal==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating signal");
ExtExpert.Deinit();
return(-2);
}
//--- Add signal to expert (will be deleted automatically))
if(!ExtExpert.InitSignal(signal))
{
//--- failed
printf(__FUNCTION__+": error initializing signal");
ExtExpert.Deinit();
return(-3);
}
//--- Set signal parameters
signal.PeriodMA(Inp_Signal_MA_Period);
signal.Shift(Inp_Signal_MA_Shift);
signal.Method(Inp_Signal_MA_Method);
signal.Applied(Inp_Signal_MA_Applied);
//--- Check signal parameters
if(!signal.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error signal parameters");
ExtExpert.Deinit();
return(-4);
}
//--- Creation of trailing object
CTrailingPSAR *trailing=new CTrailingPSAR;
if(trailing==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating trailing");
ExtExpert.Deinit();
return(-5);
}
//--- Add trailing to expert (will be deleted automatically))
if(!ExtExpert.InitTrailing(trailing))
{
//--- failed
printf(__FUNCTION__+": error initializing trailing");
ExtExpert.Deinit();
return(-6);
}
//--- Set trailing parameters
trailing.Step(Inp_Trailing_ParabolicSAR_Step);
trailing.Maximum(Inp_Trailing_ParabolicSAR_Maximum);
//--- Check trailing parameters
if(!trailing.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error trailing parameters");
ExtExpert.Deinit();
return(-7);
}
//--- Creation of money object
CMoneyNone *money=new CMoneyNone;
if(money==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating money");
ExtExpert.Deinit();
return(-8);
}
//--- Add money to expert (will be deleted automatically))
if(!ExtExpert.InitMoney(money))
{
//--- failed
printf(__FUNCTION__+": error initializing money");
ExtExpert.Deinit();
return(-9);
}
//--- Set money parameters
//--- Check money parameters
if(!money.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error money parameters");
ExtExpert.Deinit();
return(-10);
}
//--- Tuning of all necessary indicators
if(!ExtExpert.InitIndicators())
{
//--- failed
printf(__FUNCTION__+": error initializing indicators");
ExtExpert.Deinit();
return(-11);
}
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ExtExpert.Deinit();
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
ExtExpert.OnTick();
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
ExtExpert.OnTrade();
}
//+------------------------------------------------------------------+
//| Function-event handler "timer" |
//+------------------------------------------------------------------+
void OnTimer(void)
{
ExtExpert.OnTimer();
}
//+------------------------------------------------------------------+
@@ -0,0 +1,176 @@
//+------------------------------------------------------------------+
//| ExpertMAPSARSizeOptimized.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMA.mqh>
#include <Expert\Trailing\TrailingParabolicSAR.mqh>
#include <Expert\Money\MoneySizeOptimized.mqh>
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
//--- inputs for expert
input string Inp_Expert_Title ="ExpertMAPSARSizeOptimized";
int Expert_MagicNumber =27893;
bool Expert_EveryTick =false;
//--- inputs for signal
input int Inp_Signal_MA_Period =12;
input int Inp_Signal_MA_Shift =6;
input ENUM_MA_METHOD Inp_Signal_MA_Method =MODE_SMA;
input ENUM_APPLIED_PRICE Inp_Signal_MA_Applied =PRICE_CLOSE;
//--- inputs for trailing
input double Inp_Trailing_ParabolicSAR_Step =0.02;
input double Inp_Trailing_ParabolicSAR_Maximum =0.2;
//--- inputs for money
input double Inp_Money_SizeOptimized_DecreaseFactor=3.0;
input double Inp_Money_SizeOptimized_Percent =10.0;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- Initializing expert
if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
{
//--- failed
printf(__FUNCTION__+": error initializing expert");
ExtExpert.Deinit();
return(-1);
}
//--- Creation of signal object
CSignalMA *signal=new CSignalMA;
if(signal==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating signal");
ExtExpert.Deinit();
return(-2);
}
//--- Add signal to expert (will be deleted automatically))
if(!ExtExpert.InitSignal(signal))
{
//--- failed
printf(__FUNCTION__+": error initializing signal");
ExtExpert.Deinit();
return(-3);
}
//--- Set signal parameters
signal.PeriodMA(Inp_Signal_MA_Period);
signal.Shift(Inp_Signal_MA_Shift);
signal.Method(Inp_Signal_MA_Method);
signal.Applied(Inp_Signal_MA_Applied);
//--- Check signal parameters
if(!signal.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error signal parameters");
ExtExpert.Deinit();
return(-4);
}
//--- Creation of trailing object
CTrailingPSAR *trailing=new CTrailingPSAR;
if(trailing==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating trailing");
ExtExpert.Deinit();
return(-5);
}
//--- Add trailing to expert (will be deleted automatically))
if(!ExtExpert.InitTrailing(trailing))
{
//--- failed
printf(__FUNCTION__+": error initializing trailing");
ExtExpert.Deinit();
return(-6);
}
//--- Set trailing parameters
trailing.Step(Inp_Trailing_ParabolicSAR_Step);
trailing.Maximum(Inp_Trailing_ParabolicSAR_Maximum);
//--- Check trailing parameters
if(!trailing.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error trailing parameters");
ExtExpert.Deinit();
return(-7);
}
//--- Creation of money object
CMoneySizeOptimized *money=new CMoneySizeOptimized;
if(money==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating money");
ExtExpert.Deinit();
return(-8);
}
//--- Add money to expert (will be deleted automatically))
if(!ExtExpert.InitMoney(money))
{
//--- failed
printf(__FUNCTION__+": error initializing money");
ExtExpert.Deinit();
return(-9);
}
//--- Set money parameters
money.DecreaseFactor(Inp_Money_SizeOptimized_DecreaseFactor);
money.Percent(Inp_Money_SizeOptimized_Percent);
//--- Check money parameters
if(!money.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error money parameters");
ExtExpert.Deinit();
return(-10);
}
//--- Tuning of all necessary indicators
if(!ExtExpert.InitIndicators())
{
//--- failed
printf(__FUNCTION__+": error initializing indicators");
ExtExpert.Deinit();
return(-11);
}
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ExtExpert.Deinit();
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
ExtExpert.OnTick();
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
ExtExpert.OnTrade();
}
//+------------------------------------------------------------------+
//| Function-event handler "timer" |
//+------------------------------------------------------------------+
void OnTimer(void)
{
ExtExpert.OnTimer();
}
//+------------------------------------------------------------------+
Binary file not shown.
@@ -0,0 +1,45 @@
//+------------------------------------------------------------------+
//| Controls.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include "ControlsDialog.mqh"
//+------------------------------------------------------------------+
//| Global Variables |
//+------------------------------------------------------------------+
CControlsDialog ExtDialog;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create application dialog
if(!ExtDialog.Create(0,"Controls",0,20,20,360,324))
return(INIT_FAILED);
//--- run application
ExtDialog.Run();
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy dialog
ExtDialog.Destroy(reason);
}
//+------------------------------------------------------------------+
//| Expert chart event function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, // event ID
const long& lparam, // event parameter of the long type
const double& dparam, // event parameter of the double type
const string& sparam) // event parameter of the string type
{
ExtDialog.ChartEvent(id,lparam,dparam,sparam);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,427 @@
//+------------------------------------------------------------------+
//| ControlsDialog.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Edit.mqh>
#include <Controls\DatePicker.mqh>
#include <Controls\ListView.mqh>
#include <Controls\ComboBox.mqh>
#include <Controls\SpinEdit.mqh>
#include <Controls\RadioGroup.mqh>
#include <Controls\CheckGroup.mqh>
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
//--- indents and gaps
#define INDENT_LEFT (11) // indent from left (with allowance for border width)
#define INDENT_TOP (11) // indent from top (with allowance for border width)
#define INDENT_RIGHT (11) // indent from right (with allowance for border width)
#define INDENT_BOTTOM (11) // indent from bottom (with allowance for border width)
#define CONTROLS_GAP_X (5) // gap by X coordinate
#define CONTROLS_GAP_Y (5) // gap by Y coordinate
//--- for buttons
#define BUTTON_WIDTH (100) // size by X coordinate
#define BUTTON_HEIGHT (20) // size by Y coordinate
//--- for the indication area
#define EDIT_HEIGHT (20) // size by Y coordinate
//--- for group controls
#define GROUP_WIDTH (150) // size by X coordinate
#define LIST_HEIGHT (179) // size by Y coordinate
#define RADIO_HEIGHT (56) // size by Y coordinate
#define CHECK_HEIGHT (93) // size by Y coordinate
//+------------------------------------------------------------------+
//| Class CControlsDialog |
//| Usage: main dialog of the Controls application |
//+------------------------------------------------------------------+
class CControlsDialog : public CAppDialog
{
private:
CEdit m_edit; // the display field object
CButton m_button1; // the button object
CButton m_button2; // the button object
CButton m_button3; // the fixed button object
CSpinEdit m_spin_edit; // the up-down object
CDatePicker m_date; // the datepicker object
CListView m_list_view; // the list object
CComboBox m_combo_box; // the dropdown list object
CRadioGroup m_radio_group; // the radio buttons group object
CCheckGroup m_check_group; // the check box group object
public:
CControlsDialog(void);
~CControlsDialog(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
protected:
//--- create dependent controls
bool CreateEdit(void);
bool CreateButton1(void);
bool CreateButton2(void);
bool CreateButton3(void);
bool CreateSpinEdit(void);
bool CreateDate(void);
bool CreateListView(void);
bool CreateComboBox(void);
bool CreateRadioGroup(void);
bool CreateCheckGroup(void);
//--- handlers of the dependent controls events
void OnClickButton1(void);
void OnClickButton2(void);
void OnClickButton3(void);
void OnChangeSpinEdit(void);
void OnChangeDate(void);
void OnChangeListView(void);
void OnChangeComboBox(void);
void OnChangeRadioGroup(void);
void OnChangeCheckGroup(void);
};
//+------------------------------------------------------------------+
//| Event Handling |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CControlsDialog)
ON_EVENT(ON_CLICK,m_button1,OnClickButton1)
ON_EVENT(ON_CLICK,m_button2,OnClickButton2)
ON_EVENT(ON_CLICK,m_button3,OnClickButton3)
ON_EVENT(ON_CHANGE,m_spin_edit,OnChangeSpinEdit)
ON_EVENT(ON_CHANGE,m_date,OnChangeDate)
ON_EVENT(ON_CHANGE,m_list_view,OnChangeListView)
ON_EVENT(ON_CHANGE,m_combo_box,OnChangeComboBox)
ON_EVENT(ON_CHANGE,m_radio_group,OnChangeRadioGroup)
ON_EVENT(ON_CHANGE,m_check_group,OnChangeCheckGroup)
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CControlsDialog::CControlsDialog(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CControlsDialog::~CControlsDialog(void)
{
}
//+------------------------------------------------------------------+
//| Create |
//+------------------------------------------------------------------+
bool CControlsDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateEdit())
return(false);
if(!CreateButton1())
return(false);
if(!CreateButton2())
return(false);
if(!CreateButton3())
return(false);
if(!CreateSpinEdit())
return(false);
if(!CreateListView())
return(false);
if(!CreateDate())
return(false);
if(!CreateRadioGroup())
return(false);
if(!CreateCheckGroup())
return(false);
if(!CreateComboBox())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the display field |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateEdit(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP;
int x2=ClientAreaWidth()-INDENT_RIGHT;
int y2=y1+EDIT_HEIGHT;
//--- create
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_edit.ReadOnly(true))
return(false);
if(!Add(m_edit))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Button1" button |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton1(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+BUTTON_WIDTH;
int y2=y1+BUTTON_HEIGHT;
//--- create
if(!m_button1.Create(m_chart_id,m_name+"Button1",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button1.Text("Button1"))
return(false);
if(!Add(m_button1))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Button2" button |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton2(void)
{
//--- coordinates
int x1=INDENT_LEFT+(BUTTON_WIDTH+CONTROLS_GAP_X);
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+BUTTON_WIDTH;
int y2=y1+BUTTON_HEIGHT;
//--- create
if(!m_button2.Create(m_chart_id,m_name+"Button2",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button2.Text("Button2"))
return(false);
if(!Add(m_button2))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Button3" fixed button |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton3(void)
{
//--- coordinates
int x1=INDENT_LEFT+2*(BUTTON_WIDTH+CONTROLS_GAP_X);
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+BUTTON_WIDTH;
int y2=y1+BUTTON_HEIGHT;
//--- create
if(!m_button3.Create(m_chart_id,m_name+"Button3",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button3.Text("Locked"))
return(false);
if(!Add(m_button3))
return(false);
m_button3.Locking(true);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "SpinEdit" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateSpinEdit(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+(BUTTON_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+EDIT_HEIGHT;
//--- create
if(!m_spin_edit.Create(m_chart_id,m_name+"SpinEdit",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_spin_edit))
return(false);
m_spin_edit.MinValue(10);
m_spin_edit.MaxValue(1000);
m_spin_edit.Value(100);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "DatePicker" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateDate(void)
{
//--- coordinates
int x1=INDENT_LEFT+GROUP_WIDTH+2*CONTROLS_GAP_X;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+(BUTTON_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+EDIT_HEIGHT;
//--- create
if(!m_date.Create(m_chart_id,m_name+"Date",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_date))
return(false);
m_date.Value(TimeCurrent());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "ListView" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateListView(void)
{
//--- coordinates
int x1=INDENT_LEFT+GROUP_WIDTH+2*CONTROLS_GAP_X;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(BUTTON_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+2*CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+LIST_HEIGHT-CONTROLS_GAP_Y;
//--- create
if(!m_list_view.Create(m_chart_id,m_name+"ListView",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_list_view))
return(false);
//--- fill out with strings
for(int i=0;i<16;i++)
if(!m_list_view.AddItem("Item "+IntegerToString(i)))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "ComboBox" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateComboBox(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(BUTTON_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+EDIT_HEIGHT;
//--- create
if(!m_combo_box.Create(m_chart_id,m_name+"ComboBox",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_combo_box))
return(false);
//--- fill out with strings
for(int i=0;i<16;i++)
if(!m_combo_box.ItemAdd("Item "+IntegerToString(i)))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "RadioGroup" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateRadioGroup(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(BUTTON_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+RADIO_HEIGHT;
//--- create
if(!m_radio_group.Create(m_chart_id,m_name+"RadioGroup",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_radio_group))
return(false);
//--- fill out with strings
for(int i=0;i<3;i++)
if(!m_radio_group.AddItem("Item "+IntegerToString(i),1<<i))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "CheckGroup" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateCheckGroup(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(BUTTON_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(RADIO_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+CHECK_HEIGHT;
//--- create
if(!m_check_group.Create(m_chart_id,m_name+"CheckGroup",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_check_group))
return(false);
//--- fill out with strings
for(int i=0;i<5;i++)
if(!m_check_group.AddItem("Item "+IntegerToString(i),1<<i))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton1(void)
{
m_edit.Text(__FUNCTION__);
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton2(void)
{
m_edit.Text(__FUNCTION__);
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton3(void)
{
if(m_button3.Pressed())
m_edit.Text(__FUNCTION__+"On");
else
m_edit.Text(__FUNCTION__+"Off");
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeSpinEdit()
{
m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_spin_edit.Value()));
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeDate(void)
{
m_edit.Text(__FUNCTION__+" \""+TimeToString(m_date.Value(),TIME_DATE)+"\"");
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeListView(void)
{
m_edit.Text(__FUNCTION__+" \""+m_list_view.Select()+"\"");
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeComboBox(void)
{
m_edit.Text(__FUNCTION__+" \""+m_combo_box.Select()+"\"");
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeRadioGroup(void)
{
m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_radio_group.Value()));
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeCheckGroup(void)
{
m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_check_group.Value()));
}
//+------------------------------------------------------------------+
Binary file not shown.
@@ -0,0 +1,451 @@
//+------------------------------------------------------------------+
//| MACD Sample.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "5.50"
#property description "It is important to make sure that the expert works with a normal"
#property description "chart and the user did not make any mistakes setting input"
#property description "variables (Lots, TakeProfit, TrailingStop) in our case,"
#property description "we check TakeProfit on a chart of more than 2*trend_period bars"
#define MACD_MAGIC 1234502
//---
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
//---
input double InpLots =0.1; // Lots
input int InpTakeProfit =50; // Take Profit (in pips)
input int InpTrailingStop =30; // Trailing Stop Level (in pips)
input int InpMACDOpenLevel =3; // MACD open level (in pips)
input int InpMACDCloseLevel=2; // MACD close level (in pips)
input int InpMATrendPeriod =26; // MA trend period
//---
int ExtTimeOut=10; // time out in seconds between trade operations
//+------------------------------------------------------------------+
//| MACD Sample expert class |
//+------------------------------------------------------------------+
class CSampleExpert
{
protected:
double m_adjusted_point; // point value adjusted for 3 or 5 points
CTrade m_trade; // trading object
CSymbolInfo m_symbol; // symbol info object
CPositionInfo m_position; // trade position object
CAccountInfo m_account; // account info wrapper
//--- indicators
int m_handle_macd; // MACD indicator handle
int m_handle_ema; // moving average indicator handle
//--- indicator buffers
double m_buff_MACD_main[]; // MACD indicator main buffer
double m_buff_MACD_signal[]; // MACD indicator signal buffer
double m_buff_EMA[]; // EMA indicator buffer
//--- indicator data for processing
double m_macd_current;
double m_macd_previous;
double m_signal_current;
double m_signal_previous;
double m_ema_current;
double m_ema_previous;
//---
double m_macd_open_level;
double m_macd_close_level;
double m_traling_stop;
double m_take_profit;
public:
CSampleExpert(void);
~CSampleExpert(void);
bool Init(void);
void Deinit(void);
bool Processing(void);
protected:
bool InitCheckParameters(const int digits_adjust);
bool InitIndicators(void);
bool LongClosed(void);
bool ShortClosed(void);
bool LongModified(void);
bool ShortModified(void);
bool LongOpened(void);
bool ShortOpened(void);
};
//--- global expert
CSampleExpert ExtExpert;
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),
m_handle_macd(INVALID_HANDLE),
m_handle_ema(INVALID_HANDLE),
m_macd_current(0),
m_macd_previous(0),
m_signal_current(0),
m_signal_previous(0),
m_ema_current(0),
m_ema_previous(0),
m_macd_open_level(0),
m_macd_close_level(0),
m_traling_stop(0),
m_take_profit(0)
{
ArraySetAsSeries(m_buff_MACD_main,true);
ArraySetAsSeries(m_buff_MACD_signal,true);
ArraySetAsSeries(m_buff_EMA,true);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CSampleExpert::~CSampleExpert(void)
{
}
//+------------------------------------------------------------------+
//| Initialization and checking for input parameters |
//+------------------------------------------------------------------+
bool CSampleExpert::Init(void)
{
//--- initialize common information
m_symbol.Name(Symbol()); // symbol
m_trade.SetExpertMagicNumber(MACD_MAGIC); // magic
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(Symbol());
//--- tuning for 3 or 5 digits
int digits_adjust=1;
if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
digits_adjust=10;
m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- set default deviation for trading in adjusted points
m_macd_open_level =InpMACDOpenLevel*m_adjusted_point;
m_macd_close_level=InpMACDCloseLevel*m_adjusted_point;
m_traling_stop =InpTrailingStop*m_adjusted_point;
m_take_profit =InpTakeProfit*m_adjusted_point;
//--- set default deviation for trading in adjusted points
m_trade.SetDeviationInPoints(3*digits_adjust);
//---
if(!InitCheckParameters(digits_adjust))
return(false);
if(!InitIndicators())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Checking for input parameters |
//+------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters(const int digits_adjust)
{
//--- initial data checks
if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
{
printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
return(false);
}
if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
{
printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());
return(false);
}
//--- check for right lots amount
if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
{
printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
return(false);
}
if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10)
{
printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
return(false);
}
//--- warning
if(InpTakeProfit<=InpTrailingStop)
printf("Warning: Trailing Stop must be less than Take Profit");
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the indicators |
//+------------------------------------------------------------------+
bool CSampleExpert::InitIndicators(void)
{
//--- create MACD indicator
if(m_handle_macd==INVALID_HANDLE)
if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
{
printf("Error creating MACD indicator");
return(false);
}
//--- create EMA indicator and add it to collection
if(m_handle_ema==INVALID_HANDLE)
if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE)
{
printf("Error creating EMA indicator");
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Check for long position closing |
//+------------------------------------------------------------------+
bool CSampleExpert::LongClosed(void)
{
bool res=false;
//--- should it be closed?
if(m_macd_current>0)
if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
if(m_macd_current>m_macd_close_level)
{
//--- close position
if(m_trade.PositionClose(Symbol()))
printf("Long position by %s to be closed",Symbol());
else
printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
//--- processed and cannot be modified
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for short position closing |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortClosed(void)
{
bool res=false;
//--- should it be closed?
if(m_macd_current<0)
if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
if(MathAbs(m_macd_current)>m_macd_close_level)
{
//--- close position
if(m_trade.PositionClose(Symbol()))
printf("Short position by %s to be closed",Symbol());
else
printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
//--- processed and cannot be modified
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for long position modifying |
//+------------------------------------------------------------------+
bool CSampleExpert::LongModified(void)
{
bool res=false;
//--- check for trailing stop
if(InpTrailingStop>0)
{
if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
{
double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());
double tp=m_position.TakeProfit();
if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)
{
//--- modify position
if(m_trade.PositionModify(Symbol(),sl,tp))
printf("Long position by %s to be modified",Symbol());
else
{
printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Modify parameters : SL=%f,TP=%f",sl,tp);
}
//--- modified and must exit from expert
res=true;
}
}
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for short position modifying |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortModified(void)
{
bool res=false;
//--- check for trailing stop
if(InpTrailingStop>0)
{
if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
{
double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());
double tp=m_position.TakeProfit();
if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)
{
//--- modify position
if(m_trade.PositionModify(Symbol(),sl,tp))
printf("Short position by %s to be modified",Symbol());
else
{
printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Modify parameters : SL=%f,TP=%f",sl,tp);
}
//--- modified and must exit from expert
res=true;
}
}
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for long position opening |
//+------------------------------------------------------------------+
bool CSampleExpert::LongOpened(void)
{
bool res=false;
//--- check for long position (BUY) possibility
if(m_macd_current<0)
if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous)
{
double price=m_symbol.Ask();
double tp =m_symbol.Bid()+m_take_profit;
//--- check for free money
if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
printf("We have no money. Free Margin = %f",m_account.FreeMargin());
else
{
//--- open position
if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp))
printf("Position by %s to be opened",Symbol());
else
{
printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Open parameters : price=%f,TP=%f",price,tp);
}
}
//--- in any case we must exit from expert
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for short position opening |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
{
bool res=false;
//--- check for short position (SELL) possibility
if(m_macd_current>0)
if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous)
{
double price=m_symbol.Bid();
double tp =m_symbol.Ask()-m_take_profit;
//--- check for free money
if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
printf("We have no money. Free Margin = %f",m_account.FreeMargin());
else
{
//--- open position
if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp))
printf("Position by %s to be opened",Symbol());
else
{
printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Open parameters : price=%f,TP=%f",price,tp);
}
}
//--- in any case we must exit from expert
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| main function returns true if any position processed |
//+------------------------------------------------------------------+
bool CSampleExpert::Processing(void)
{
//--- refresh rates
if(!m_symbol.RefreshRates())
return(false);
//--- refresh indicators
if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2)
return(false);
if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main) !=2 ||
CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 ||
CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA) !=2)
return(false);
// m_indicators.Refresh();
//--- to simplify the coding and speed up access
//--- data are put into internal variables
m_macd_current =m_buff_MACD_main[0];
m_macd_previous =m_buff_MACD_main[1];
m_signal_current =m_buff_MACD_signal[0];
m_signal_previous=m_buff_MACD_signal[1];
m_ema_current =m_buff_EMA[0];
m_ema_previous =m_buff_EMA[1];
//--- it is important to enter the market correctly,
//--- but it is more important to exit it correctly...
//--- first check if position exists - try to select it
if(m_position.Select(Symbol()))
{
if(m_position.PositionType()==POSITION_TYPE_BUY)
{
//--- try to close or modify long position
if(LongClosed())
return(true);
if(LongModified())
return(true);
}
else
{
//--- try to close or modify short position
if(ShortClosed())
return(true);
if(ShortModified())
return(true);
}
}
//--- no opened position identified
else
{
//--- check for long position (BUY) possibility
if(LongOpened())
return(true);
//--- check for short position (SELL) possibility
if(ShortOpened())
return(true);
}
//--- exit without position processing
return(false);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- create all necessary objects
if(!ExtExpert.Init())
return(INIT_FAILED);
//--- secceed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert new tick handling function |
//+------------------------------------------------------------------+
void OnTick(void)
{
static datetime limit_time=0; // last trade processing time + timeout
//--- don't process if timeout
if(TimeCurrent()>=limit_time)
{
//--- check for data
if(Bars(Symbol(),Period())>2*InpMATrendPeriod)
{
//--- change limit time by timeout in seconds if processed
if(ExtExpert.Processing())
limit_time=TimeCurrent()+ExtTimeOut;
}
}
}
//+------------------------------------------------------------------+
@@ -0,0 +1,372 @@
//+------------------------------------------------------------------+
//| Functions.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//--- custom function y=f(x,y)
typedef double(*MathFunction)(double,double);
//+------------------------------------------------------------------+
//| math functions |
//+------------------------------------------------------------------+
enum EnMathFunction
{
Peaks=0,
Chomolungma=1,
ClimberDream=2,
Granite=3,
Hedgehog=4,
Hill=5,
Josephine=6,
Screw=7,
DoubleScrew=8,
MultiExtremalScrew=9,
Sink=10,
Skin=11,
Trapfall=12,
};
//+------------------------------------------------------------------+
//| Names of the math functions |
//+------------------------------------------------------------------+
const string ExtFunctionsNames[]=
{
"Peaks",
"Chomolungma",
"Climber Dream",
"Granite",
"Hedgehog",
"Hill",
"Josephine",
"Screw",
"Double Screw",
"Multi Extremal Screw",
"Sinc",
"Skin",
"Trapfall"
};
//+------------------------------------------------------------------+
//| Function Peaks |
//+------------------------------------------------------------------+
double PeaksFunction(double x,double y)
{
double res = 3*MathPow((1-x),2)*MathExp(-x*x-(y+1)*(y+1))-10*(0.2*x-MathPow(x,3)-MathPow(y,5))*MathExp(-x*x-y*y)-1/3*MathExp(-(x+1)*(x+1)-y*y);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Chomolungma |
//+------------------------------------------------------------------+
double ChomolungmaFunction(double x,double y)
{
double a= MathCos(x*x)+MathCos(y*y);
double b= MathPow(MathCos(5*x*y),5);
double c=1.0/MathPow(2,b);
//--- calculate result
double res=a-c;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function ClimberDream |
//+------------------------------------------------------------------+
double ClimberDreamFunction(double x,double y)
{
double a= MathSin(MathSqrt(MathAbs(x - 1.3) + MathAbs(y)));
double b= MathCos(MathSqrt(MathAbs(MathSin(x))) + MathSqrt(MathAbs(MathSin(y))));
double f=a+b;
//--- calculate result
double res=MathPow(f,4);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Granite |
//+------------------------------------------------------------------+
double GraniteFunction(double x,double y)
{
double a= MathPow(MathSin(MathSqrt(MathAbs(x)+MathAbs(y))),2);
double b= MathPow(MathCos(MathSqrt(MathAbs(x)+MathAbs(y))),2);
//--- calculate result
double res=a*b;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Hedgehog |
//+------------------------------------------------------------------+
double HedgehogFunction(double x,double y)
{
double a1=MathSin(MathSqrt(MathAbs(x-2)+MathAbs(y)));
double a2=MathCos(MathSqrt(MathAbs(MathSin(x)))+MathSqrt(MathAbs(MathSin(y))));
//--- calculate result
double res=a1+a2;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Hill |
//+------------------------------------------------------------------+
double HillFunction(double x,double y)
{
//--- calculate result
double res=MathExp(-x*x-y*y);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Josephine |
//+------------------------------------------------------------------+
double JosephineFunction(double x,double y)
{
double a= MathSin(MathPow(MathAbs(x)+MathAbs(y),0.5));
double b= MathCos(MathPow(MathAbs(x),0.5)+MathPow(MathAbs(y),0.5));
//--- calculate function
double res=a+b;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Screw |
//+------------------------------------------------------------------+
double ScrewFunction(double x,double y)
{
double a=(y==0)?0:((x*y<0)?MathArctan(x/y):MathArctan(x/y)+M_PI);
double b=x*x+y*y;
double f=MathSin(b+a);
//--- calculate result
double res=(f*f);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function DoubleScrew |
//+------------------------------------------------------------------+
double DoubleScrewFunction(double x,double y)
{
double a=(y==0)?0:((x*y<0)?MathArctan(x/y):MathArctan(x/y)+M_PI);
double b=x*x+y*y;
double res1=MathCos(b/2+a*3);
res1=((res1*res1)/sqrt(b+1)-0.2);
double res2=MathCos(b/2-a*3);
res2=((res2*res2)/sqrt(b+1)-0.2);
double f=fmax(res1,res2);
//--- calculate result
double res=(f>0)?f:0;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function MultiExtremalScrew |
//+------------------------------------------------------------------+
double MultiExtremalScrewFunction(double x,double y)
{
double a=(y==0)?0:((x*y<0)?MathArctan(x/y):MathArctan(x/y)+M_PI);
double b=x*x+y*y;
double res1=MathCos(b/2+a*3);
res1=((res1*res1)/sqrt(b+1)-0.2);
double res2=MathCos(b/2-a*3);
res2=((res2*res2)/sqrt(b+1)-0.2);
//--- calculate function
double res=fmin(res1,res2);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Sink |
//+------------------------------------------------------------------+
double SinkFunction(double x,double y)
{
static double k=5.0;
static double p=6.0;
//--- calculate result
double res=MathSin(x*x+y*y)+k*MathExp(-p*x*x-p*y*y);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Skin |
//+------------------------------------------------------------------+
double SkinFunction(double x,double y)
{
double a1=2*x*x;
double a2=2*y*y;
double b1=MathCos(a1)-1.1;
b1=b1*b1;
double c1=MathSin(0.5*x)-1.2;
c1=c1*c1;
double d1=MathCos(a2)-1.1;
d1=d1*d1;
double e1=MathSin(0.5*y)-1.2;
e1=e1*e1;
//--- calculate result
double res=b1+c1-d1+e1;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Trapfall |
//+------------------------------------------------------------------+
double TrapfallFunction(double x,double y)
{
double a1=MathSqrt(MathAbs(MathSin(x-1.0)));
double b1=MathSqrt(MathAbs(MathSin(y+2.0)));
//--- calculate result
double res=-MathSqrt(MathAbs(MathSin(MathSin(a1+b1))));
//---
return(res);
}
//+------------------------------------------------------------------+
//| GenerateFunctionData |
//+------------------------------------------------------------------+
void GenerateFunctionData(double &data[],int &x_size,int &y_size,double x_min,double x_max,double y_min,double y_max,MathFunction function)
{
double dx = 0.1;
double dy = 0.1;
//---
x_size = (int)((x_max - x_min)/dx) + 1;
y_size = (int)((y_max - y_min)/dy) + 1;
ArrayResize(data,x_size*y_size);
//---
for(int j = 0; j < y_size; j++)
{
for(int i = 0; i < x_size; i++)
{
double x = x_min + i*dx;
double y = y_min + j*dy;
data[j*x_size + i] = function(x,y);
}
}
}
//+------------------------------------------------------------------+
//| GenerateData |
//+------------------------------------------------------------------+
void GenerateData(EnMathFunction function_id,double &data[],int &x_size,int &y_size)
{
//---
switch(function_id)
{
case Peaks:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,PeaksFunction);
break;
case Chomolungma:
GenerateFunctionData(data,x_size,y_size,-2.0,+2.0,-2.0,+2.0,ChomolungmaFunction);
break;
case ClimberDream:
GenerateFunctionData(data,x_size,y_size,-10.0,+10.0,-10.0,+10.0,ClimberDreamFunction);
break;
case Granite:
GenerateFunctionData(data,x_size,y_size,-4.0,+4.0,-4.0,+4.0,GraniteFunction);
break;
case Hedgehog:
GenerateFunctionData(data,x_size,y_size,-10.0,+10.0,-10.0,+10.0,HedgehogFunction);
break;
case Hill:
GenerateFunctionData(data,x_size,y_size,-1.5,+1.5,-1.5,+1.5,HillFunction);
break;
case Josephine:
GenerateFunctionData(data,x_size,y_size,-200.0,+200.0,-200.0,+200.0,JosephineFunction);
break;
case Screw:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,ScrewFunction);
break;
case DoubleScrew:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,DoubleScrewFunction);
break;
case MultiExtremalScrew:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,MultiExtremalScrewFunction);
break;
case Sink:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,SinkFunction);
break;
case Skin:
GenerateFunctionData(data,x_size,y_size,-5.0,+5.0,-5.0,+5.0,SkinFunction);
break;
case Trapfall:
GenerateFunctionData(data,x_size,y_size,-5.0,+5.0,-5.0,+5.0,TrapfallFunction);
break;
}
}
//+------------------------------------------------------------------+
//| GenerateFunctionDataFixedSize |
//+------------------------------------------------------------------+
bool GenerateFunctionDataFixedSize(int x_size,int y_size,double &data[],double x_min,double x_max,double y_min,double y_max,MathFunction function)
{
if(x_size<2 || y_size<2)
{
PrintFormat("Error in data sizes: x_size=%d,y_size=%d",x_size,y_size);
return(false);
}
double dx = (x_max - x_min)/(x_size-1);
double dy = (y_max - y_min)/(y_size-1);
ArrayResize(data,x_size*y_size);
//---
for(int j = 0; j < y_size; j++)
{
for(int i = 0; i < x_size; i++)
{
double x = x_min + i*dx;
double y = y_min + j*dy;
data[j*x_size + i] = function(x,y);
}
}
return(true);
}
//+------------------------------------------------------------------+
//| GenerateDataFixedSize |
//+------------------------------------------------------------------+
bool GenerateDataFixedSize(int x_size,int y_size,EnMathFunction function_id,double &data[])
{
if(x_size<2 || y_size<2)
{
PrintFormat("Error in data sizes: x_size=%d,y_size=%d",x_size,y_size);
return(false);
}
bool result=false;
//---
switch(function_id)
{
case Peaks:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,PeaksFunction);
break;
case Chomolungma:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-2.0,+2.0,-2.0,+2.0,ChomolungmaFunction);
break;
case ClimberDream:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-10.0,+10.0,-10.0,+10.0,ClimberDreamFunction);
break;
case Granite:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-4.0,+4.0,-4.0,+4.0,GraniteFunction);
break;
case Hedgehog:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-10.0,+10.0,-10.0,+10.0,HedgehogFunction);
break;
case Hill:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-1.5,+1.5,-1.5,+1.5,HillFunction);
break;
case Josephine:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-200.0,+200.0,-200.0,+200.0,JosephineFunction);
break;
case Screw:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,ScrewFunction);
break;
case DoubleScrew:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,DoubleScrewFunction);
break;
case MultiExtremalScrew:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,MultiExtremalScrewFunction);
break;
case Sink:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,SinkFunction);
break;
case Skin:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-5.0,+5.0,-5.0,+5.0,SkinFunction);
break;
case Trapfall:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-5.0,+5.0,-5.0,+5.0,TrapfallFunction);
break;
}
//---
return(result);
}
//+------------------------------------------------------------------+
Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,233 @@
//+------------------------------------------------------------------+
//| Moving Averages.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
input double MaximumRisk = 0.02; // Maximum Risk in percentage
input double DecreaseFactor = 3; // Descrease factor
input int MovingPeriod = 12; // Moving Average period
input int MovingShift = 6; // Moving Average shift
//---
int ExtHandle=0;
bool ExtHedging=false;
CTrade ExtTrade;
#define MA_MAGIC 1234501
//+------------------------------------------------------------------+
//| Calculate optimal lot size |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
{
double price=0.0;
double margin=0.0;
//--- select lot size
if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
return(0.0);
if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
return(0.0);
if(margin<=0.0)
return(0.0);
double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
//--- calculate number of losses orders without a break
if(DecreaseFactor>0)
{
//--- select history for access
HistorySelect(0,TimeCurrent());
//---
int orders=HistoryDealsTotal(); // total history deals
int losses=0; // number of losses orders without a break
for(int i=orders-1;i>=0;i--)
{
ulong ticket=HistoryDealGetTicket(i);
if(ticket==0)
{
Print("HistoryDealGetTicket failed, no trade history");
break;
}
//--- check symbol
if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
continue;
//--- check Expert Magic number
if(HistoryDealGetInteger(ticket,DEAL_MAGIC)!=MA_MAGIC)
continue;
//--- check profit
double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
if(profit>0.0)
break;
if(profit<0.0)
losses++;
}
//---
if(losses>1)
lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
//--- normalize and check limits
double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
lot=stepvol*NormalizeDouble(lot/stepvol,0);
double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
if(lot<minvol)
lot=minvol;
double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
if(lot>maxvol)
lot=maxvol;
//--- return trading volume
return(lot);
}
//+------------------------------------------------------------------+
//| Check for open position conditions |
//+------------------------------------------------------------------+
void CheckForOpen(void)
{
MqlRates rt[2];
//--- go trading only for first ticks of new bar
if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
{
Print("CopyRates of ",_Symbol," failed, no history");
return;
}
if(rt[1].tick_volume>1)
return;
//--- get current Moving Average
double ma[1];
if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
{
Print("CopyBuffer from iMA failed, no data");
return;
}
//--- check signals
ENUM_ORDER_TYPE signal=WRONG_VALUE;
if(rt[0].open>ma[0] && rt[0].close<ma[0])
signal=ORDER_TYPE_SELL; // sell conditions
else
{
if(rt[0].open<ma[0] && rt[0].close>ma[0])
signal=ORDER_TYPE_BUY; // buy conditions
}
//--- additional checking
if(signal!=WRONG_VALUE)
{
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
ExtTrade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
0,0);
}
//---
}
//+------------------------------------------------------------------+
//| Check for close position conditions |
//+------------------------------------------------------------------+
void CheckForClose(void)
{
MqlRates rt[2];
//--- go trading only for first ticks of new bar
if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
{
Print("CopyRates of ",_Symbol," failed, no history");
return;
}
if(rt[1].tick_volume>1)
return;
//--- get current Moving Average
double ma[1];
if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
{
Print("CopyBuffer from iMA failed, no data");
return;
}
//--- positions already selected before
bool signal=false;
long type=PositionGetInteger(POSITION_TYPE);
if(type==(long)POSITION_TYPE_BUY && rt[0].open>ma[0] && rt[0].close<ma[0])
signal=true;
if(type==(long)POSITION_TYPE_SELL && rt[0].open<ma[0] && rt[0].close>ma[0])
signal=true;
//--- additional checking
if(signal)
{
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
ExtTrade.PositionClose(_Symbol,3);
}
//---
}
//+------------------------------------------------------------------+
//| Position select depending on netting or hedging |
//+------------------------------------------------------------------+
bool SelectPosition()
{
bool res=false;
//--- check position in Hedging mode
if(ExtHedging)
{
uint total=PositionsTotal();
for(uint i=0; i<total; i++)
{
string position_symbol=PositionGetSymbol(i);
if(_Symbol==position_symbol && MA_MAGIC==PositionGetInteger(POSITION_MAGIC))
{
res=true;
break;
}
}
}
//--- check position in Netting mode
else
{
if(!PositionSelect(_Symbol))
return(false);
else
return(PositionGetInteger(POSITION_MAGIC)==MA_MAGIC); //---check Magic number
}
//--- result for Hedging mode
return(res);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- prepare trade class to control positions if hedging mode is active
ExtHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
ExtTrade.SetExpertMagicNumber(MA_MAGIC);
ExtTrade.SetMarginMode();
ExtTrade.SetTypeFillingBySymbol(Symbol());
//--- Moving Average indicator
ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
if(ExtHandle==INVALID_HANDLE)
{
printf("Error creating MA indicator");
return(INIT_FAILED);
}
//--- ok
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick(void)
{
//---
if(SelectPosition())
CheckForClose();
else
CheckForOpen();
//---
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
@@ -0,0 +1,657 @@
//+------------------------------------------------------------------+
//| BlackCrows WhiteSoldiers CCI.mq5 |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#define SIGNAL_BUY 1 // Buy signal
#define SIGNAL_NOT 0 // no trading signal
#define SIGNAL_SELL -1 // Sell signal
#define CLOSE_LONG 2 // signal to close Long
#define CLOSE_SHORT -2 // signal to close Short
//--- Input parameters
input int InpAverBodyPeriod=12; // period for calculating average candlestick size
input int InpPeriodCCI =37; // CCI period
input ENUM_APPLIED_PRICE InpPrice=PRICE_CLOSE; // price type
//--- trade parameters
input uint InpDuration=10; // position holding time in bars
input uint InpSL =200; // Stop Loss in points
input uint InpTP =200; // Take Profit in points
input uint InpSlippage=10; // slippage in points
//--- money management parameters
input double InpLot =0.1; // lot
//--- Expert ID
input long InpMagicNumber=120100; // Magic Number
//--- global variables
int ExtAvgBodyPeriod; // average candlestick calculation period
int ExtSignalOpen =0; // Buy/Sell signal
int ExtSignalClose =0; // signal to close a position
string ExtPatternInfo =""; // current pattern information
string ExtDirection =""; // position opening direction
bool ExtPatternDetected=false; // pattern detected
bool ExtConfirmed =false; // pattern confirmed
bool ExtCloseByTime =true; // requires closing by time
bool ExtCheckPassed =true; // status checking error
//--- indicator handle
int ExtIndicatorHandle=INVALID_HANDLE;
//--- service objects
CTrade ExtTrade;
CSymbolInfo ExtSymbolInfo;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
Print("InpSL=", InpSL);
Print("InpTP=", InpTP);
//--- set parameters for trading operations
ExtTrade.SetDeviationInPoints(InpSlippage); // slippage
ExtTrade.SetExpertMagicNumber(InpMagicNumber); // Expert Advisor ID
ExtTrade.LogLevel(LOG_LEVEL_ERRORS); // logging level
ExtAvgBodyPeriod=InpAverBodyPeriod;
//--- indicator initialization
ExtIndicatorHandle=iCCI(_Symbol, _Period, InpPeriodCCI, InpPrice);
if(ExtIndicatorHandle==INVALID_HANDLE)
{
Print("Error creating CCI indicator");
return(INIT_FAILED);
}
//--- OK
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- release indicator handle
IndicatorRelease(ExtIndicatorHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- save the next bar start time; all checks at bar opening only
static datetime next_bar_open=0;
//--- Phase 1 - check the emergence of a new bar and update the status
if(TimeCurrent()>=next_bar_open)
{
//--- get the current state of environment on the new bar
// namely, set the values of global variables:
// ExtPatternDetected - pattern detection
// ExtConfirmed - pattern confirmation
// ExtSignalOpen - signal to open
// ExtSignalClose - signal to close
// ExtPatternInfo - current pattern information
if(CheckState())
{
//--- set the new bar opening time
next_bar_open=TimeCurrent();
next_bar_open-=next_bar_open%PeriodSeconds(_Period);
next_bar_open+=PeriodSeconds(_Period);
//--- report the emergence of a new bar only once within a bar
if(ExtPatternDetected && ExtConfirmed)
Print(ExtPatternInfo);
}
else
{
//--- error getting the status, retry on the next tick
return;
}
}
//--- Phase 2 - if there is a signal and no position in this direction
if(ExtSignalOpen && !PositionExist(ExtSignalOpen))
{
Print("\r\nSignal to open position ", ExtDirection);
PositionOpen();
if(PositionExist(ExtSignalOpen))
ExtSignalOpen=SIGNAL_NOT;
}
//--- Phase 3 - close if there is a signal to close
if(ExtSignalClose && PositionExist(ExtSignalClose))
{
Print("\r\nSignal to close position ", ExtDirection);
CloseBySignal(ExtSignalClose);
if(!PositionExist(ExtSignalClose))
ExtSignalClose=SIGNAL_NOT;
}
//--- Phase 4 - close upon expiration
if(ExtCloseByTime && PositionExpiredByTimeExist())
{
CloseByTime();
ExtCloseByTime=PositionExpiredByTimeExist();
}
}
//+------------------------------------------------------------------+
//| Get the current environment and check for a pattern |
//+------------------------------------------------------------------+
bool CheckState()
{
//--- check if there is a pattern
if(!CheckPattern())
{
Print("Error, failed to check pattern");
return(false);
}
//--- check for confirmation
if(!CheckConfirmation())
{
Print("Error, failed to check pattern confirmation");
return(false);
}
//--- if there is no confirmation, cancel the signal
if(!ExtConfirmed)
ExtSignalOpen=SIGNAL_NOT;
//--- check if there is a signal to close a position
if(!CheckCloseSignal())
{
Print("Error, failed to check the closing signal");
return(false);
}
//--- if positions are to be closed after certain holding time in bars
if(InpDuration)
ExtCloseByTime=true; // set flag to close upon expiration
//--- all checks done
return(true);
}
//+------------------------------------------------------------------+
//| Open a position in the direction of the signal |
//+------------------------------------------------------------------+
bool PositionOpen()
{
ExtSymbolInfo.Refresh();
ExtSymbolInfo.RefreshRates();
double price=0;
//--- Stop Loss and Take Profit are not set by default
double stoploss=0.0;
double takeprofit=0.0;
int digits=ExtSymbolInfo.Digits();
double point=ExtSymbolInfo.Point();
double spread=ExtSymbolInfo.Ask()-ExtSymbolInfo.Bid();
//--- uptrend
if(ExtSignalOpen==SIGNAL_BUY)
{
price=NormalizeDouble(ExtSymbolInfo.Ask(), digits);
//--- if Stop Loss is set
if(InpSL>0)
{
if(spread>=InpSL*point)
{
PrintFormat("StopLoss (%d points) <= current spread = %.0f points. Spread value will be used", InpSL, spread/point);
stoploss = NormalizeDouble(price-spread, digits);
}
else
stoploss = NormalizeDouble(price-InpSL*point, digits);
}
//--- if Take Profit is set
if(InpTP>0)
{
if(spread>=InpTP*point)
{
PrintFormat("TakeProfit (%d points) < current spread = %.0f points. Spread value will be used", InpTP, spread/point);
takeprofit = NormalizeDouble(price+spread, digits);
}
else
takeprofit = NormalizeDouble(price+InpTP*point, digits);
}
if(!ExtTrade.Buy(InpLot, Symbol(), price, stoploss, takeprofit))
{
PrintFormat("Failed %s buy %G at %G (sl=%G tp=%G) failed. Ask=%G error=%d",
Symbol(), InpLot, price, stoploss, takeprofit, ExtSymbolInfo.Ask(), GetLastError());
return(false);
}
}
//--- downtrend
if(ExtSignalOpen==SIGNAL_SELL)
{
price=NormalizeDouble(ExtSymbolInfo.Bid(), digits);
//--- if Stop Loss is set
if(InpSL>0)
{
if(spread>=InpSL*point)
{
PrintFormat("StopLoss (%d points) <= current spread = %.0f points. Spread value will be used", InpSL, spread/point);
stoploss = NormalizeDouble(price+spread, digits);
}
else
stoploss = NormalizeDouble(price+InpSL*point, digits);
}
//--- if Take Profit is set
if(InpTP>0)
{
if(spread>=InpTP*point)
{
PrintFormat("TakeProfit (%d points) < current spread = %.0f points. Spread value will be used", InpTP, spread/point);
takeprofit = NormalizeDouble(price-spread, digits);
}
else
takeprofit = NormalizeDouble(price-InpTP*point, digits);
}
if(!ExtTrade.Sell(InpLot, Symbol(), price, stoploss, takeprofit))
{
PrintFormat("Failed %s sell at %G (sl=%G tp=%G) failed. Bid=%G error=%d",
Symbol(), price, stoploss, takeprofit, ExtSymbolInfo.Bid(), GetLastError());
ExtTrade.PrintResult();
Print(" ");
return(false);
}
}
return(true);
}
//+------------------------------------------------------------------+
//| Close a position based on the specified signal |
//+------------------------------------------------------------------+
void CloseBySignal(int type_close)
{
//--- if there is no signal to close, return successful completion
if(type_close==SIGNAL_NOT)
return;
//--- if there are no positions opened by our EA
if(PositionExist(ExtSignalClose)==0)
return;
//--- closing direction
long type;
switch(type_close)
{
case CLOSE_SHORT:
type=POSITION_TYPE_SELL;
break;
case CLOSE_LONG:
type=POSITION_TYPE_BUY;
break;
default:
Print("Error! Signal to close not detected");
return;
}
//--- check all positions and close ours based on the signal
int positions=PositionsTotal();
for(int i=positions-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket!=0)
{
//--- get the name of the symbol and the position id (magic)
string symbol=PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
if(PositionGetInteger(POSITION_TYPE)==type)
{
ExtTrade.PositionClose(ticket, InpSlippage);
ExtTrade.PrintResult();
Print(" ");
}
}
}
}
}
//+------------------------------------------------------------------+
//| Close positions upon holding time expiration in bars |
//+------------------------------------------------------------------+
void CloseByTime()
{
//--- if there are no positions opened by our EA
if(PositionExist(ExtSignalOpen)==0)
return;
//--- check all positions and close ours based on the holding time in bars
int positions=PositionsTotal();
for(int i=positions-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket!=0)
{
//--- get the name of the symbol and the position id (magic)
string symbol=PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- position opening time
datetime open_time=(datetime)PositionGetInteger(POSITION_TIME);
//--- check position holding time in bars
if(BarsHold(open_time)>=(int)InpDuration)
{
Print("\r\nTime to close position #", ticket);
ExtTrade.PositionClose(ticket, InpSlippage);
ExtTrade.PrintResult();
Print(" ");
}
}
}
}
}
//+------------------------------------------------------------------+
//| Returns true if there are open positions |
//+------------------------------------------------------------------+
bool PositionExist(int signal_direction)
{
bool check_type=(signal_direction!=SIGNAL_NOT);
//--- what positions to search
ENUM_POSITION_TYPE search_type=WRONG_VALUE;
if(check_type)
switch(signal_direction)
{
case SIGNAL_BUY:
search_type=POSITION_TYPE_BUY;
break;
case SIGNAL_SELL:
search_type=POSITION_TYPE_SELL;
break;
case CLOSE_LONG:
search_type=POSITION_TYPE_BUY;
break;
case CLOSE_SHORT:
search_type=POSITION_TYPE_SELL;
break;
default:
//--- entry direction is not specified; nothing to search
return(false);
}
//--- go through the list of all positions
int positions=PositionsTotal();
for(int i=0; i<positions; i++)
{
if(PositionGetTicket(i)!=0)
{
//--- if the position type does not match, move on to the next one
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if(check_type && (type!=search_type))
continue;
//--- get the name of the symbol and the expert id (magic number)
string symbol =PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- yes, this is the right position, stop the search
return(true);
}
}
}
//--- open position not found
return(false);
}
//+------------------------------------------------------------------+
//| Returns true if there are open positions with expired time |
//+------------------------------------------------------------------+
bool PositionExpiredByTimeExist()
{
//--- go through the list of all positions
int positions=PositionsTotal();
for(int i=0; i<positions; i++)
{
if(PositionGetTicket(i)!=0)
{
//--- get the name of the symbol and the expert id (magic number)
string symbol =PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- position opening time
datetime open_time=(datetime)PositionGetInteger(POSITION_TIME);
//--- check position holding time in bars
int check=BarsHold(open_time);
//--- id the value is -1, the check completed with an error
if(check==-1 || (BarsHold(open_time)>=(int)InpDuration))
return(true);
}
}
}
//--- open position not found
return(false);
}
//+------------------------------------------------------------------+
//| Checks position closing time in bars |
//+------------------------------------------------------------------+
int BarsHold(datetime open_time)
{
//--- first run a basic simple check
if(TimeCurrent()-open_time<PeriodSeconds(_Period))
{
//--- opening time is inside the current bar
return(0);
}
MqlRates bars[];
if(CopyRates(_Symbol, _Period, open_time, TimeCurrent(), bars)==-1)
{
Print("Error. CopyRates() failed, error = ", GetLastError());
return(-1);
}
//--- check position holding time in bars
return(ArraySize(bars));
}
//+------------------------------------------------------------------+
//| Returns the open price of the specified bar |
//+------------------------------------------------------------------+
double Open(int index)
{
double val=iOpen(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the close price of the specified bar |
//+------------------------------------------------------------------+
double Close(int index)
{
double val=iClose(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the low price of the specified bar |
//+------------------------------------------------------------------+
double Low(int index)
{
double val=iLow(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the high price of the specified bar |
//+------------------------------------------------------------------+
double High(int index)
{
double val=iHigh(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the middle body price for the specified bar |
//+------------------------------------------------------------------+
double MidPoint(int index)
{
return(High(index)+Low(index))/2.;
}
//+------------------------------------------------------------------+
//| Returns the middle price of the range for the specified bar |
//+------------------------------------------------------------------+
double MidOpenClose(int index)
{
return((Open(index)+Close(index))/2.);
}
//+------------------------------------------------------------------+
//| Returns the average candlestick body size for the specified bar |
//+------------------------------------------------------------------+
double AvgBody(int index)
{
double sum=0;
for(int i=index; i<index+ExtAvgBodyPeriod; i++)
{
sum+=MathAbs(Open(i)-Close(i));
}
return(sum/ExtAvgBodyPeriod);
}
//+------------------------------------------------------------------+
//| Returns true in case of successful pattern check |
//+------------------------------------------------------------------+
bool CheckPattern()
{
ExtPatternDetected=false;
//--- check if there is a pattern
ExtSignalOpen=SIGNAL_NOT;
ExtPatternInfo="\r\nPattern not detected";
ExtDirection="";
//--- check 3 Black Crows
if((Open(3)-Close(3)>AvgBody(1)) && // long black
(Open(2)-Close(2)>AvgBody(1)) &&
(Open(1)-Close(1)>AvgBody(1)) &&
(MidPoint(2)<MidPoint(3)) && // lower midpoints
(MidPoint(1)<MidPoint(2)))
{
ExtPatternDetected=true;
ExtSignalOpen=SIGNAL_SELL;
ExtPatternInfo="\r\n3 Black Crows detected";
ExtDirection="Sell";
return(true);
}
//--- check 3 White Soldiers
if((Close(3)-Open(3)>AvgBody(1)) && // long white
(Close(2)-Open(2)>AvgBody(1)) &&
(Close(1)-Open(1)>AvgBody(1)) &&
(MidPoint(2)>MidPoint(3)) && // higher midpoints
(MidPoint(1)>MidPoint(2)))
{
ExtPatternDetected=true;
ExtSignalOpen=SIGNAL_BUY;
ExtPatternInfo="\r\n3 White Soldiers detected";
ExtDirection="Buy";
return(true);
}
//--- result of checking
return(ExtCheckPassed);
}
//+------------------------------------------------------------------+
//| Returns true in case of successful confirmation check |
//+------------------------------------------------------------------+
bool CheckConfirmation()
{
ExtConfirmed=false;
//--- if there is no pattern, do not search for confirmation
if(!ExtPatternDetected)
return(true);
//--- get the value of the stochastic indicator to confirm the signal
double signal=CCI(1);
if(signal==EMPTY_VALUE)
{
//--- failed to get indicator value, check failed
return(false);
}
//--- check the Buy signal
if(ExtSignalOpen==SIGNAL_BUY && (signal<-50))
{
ExtConfirmed=true;
ExtPatternInfo+="\r\n Confirmed: CCI<-50";
}
//--- check the Sell signal
if(ExtSignalOpen==SIGNAL_SELL && (signal>50))
{
ExtConfirmed=true;
ExtPatternInfo+="\r\n Confirmed: CCI>50";
}
//--- successful completion of the check
return(true);
}
//+------------------------------------------------------------------+
//| Check if there is a signal to close |
//+------------------------------------------------------------------+
bool CheckCloseSignal()
{
ExtSignalClose=false;
//--- if there is a signal to enter the market, do not check the signal to close
if(ExtSignalOpen!=SIGNAL_NOT)
return(true);
//--- check if there is a signal to close a long position
if(((CCI(1)<80) && (CCI(2)>80)) || ((CCI(1)<-80) && (CCI(2)>-80)))
{
//--- there is a signal to close a long position
ExtSignalClose=CLOSE_LONG;
ExtDirection="Long";
}
//--- check if there is a signal to close a short position
if(((CCI(1)>-80) && (CCI(2)<-80)) || ((CCI(1)>80) && (CCI(2)<80)))
{
//--- there is a signal to close a short position
ExtSignalClose=CLOSE_SHORT;
ExtDirection="Short";
}
//--- successful completion of the check
return(true);
}
//+------------------------------------------------------------------+
//| CCI indicator value at the specified bar |
//+------------------------------------------------------------------+
double CCI(int index)
{
double indicator_values[];
if(CopyBuffer(ExtIndicatorHandle, 0, index, 1, indicator_values)<0)
{
//--- if the copying fails, report the error code
PrintFormat("Failed to copy data from the CCI indicator, error code %d", GetLastError());
return(EMPTY_VALUE);
}
return(indicator_values[0]);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,657 @@
//+------------------------------------------------------------------+
//| BlackCrows WhiteSoldiers MFI.mq5 |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#define SIGNAL_BUY 1 // Buy signal
#define SIGNAL_NOT 0 // no trading signal
#define SIGNAL_SELL -1 // Sell signal
#define CLOSE_LONG 2 // signal to close Long
#define CLOSE_SHORT -2 // signal to close Short
//--- Input parameters
input int InpAverBodyPeriod=12; // period for calculating average candlestick size
input int InpPeriodMFI =37; // MFI period
input ENUM_APPLIED_VOLUME InpVolume=VOLUME_TICK; // volume type
//--- trade parameters
input uint InpDuration=10; // position holding time in bars
input uint InpSL =200; // Stop Loss in points
input uint InpTP =200; // Take Profit in points
input uint InpSlippage=10; // slippage in points
//--- money management parameters
input double InpLot =0.1; // lot
//--- Expert ID
input long InpMagicNumber=120200; // Magic Number
//--- global variables
int ExtAvgBodyPeriod; // average candlestick calculation period
int ExtSignalOpen =0; // Buy/Sell signal
int ExtSignalClose =0; // signal to close a position
string ExtPatternInfo =""; // current pattern information
string ExtDirection =""; // position opening direction
bool ExtPatternDetected=false; // pattern detected
bool ExtConfirmed =false; // pattern confirmed
bool ExtCloseByTime =true; // requires closing by time
bool ExtCheckPassed =true; // status checking error
//--- indicator handle
int ExtIndicatorHandle=INVALID_HANDLE;
//--- service objects
CTrade ExtTrade;
CSymbolInfo ExtSymbolInfo;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
Print("InpSL=", InpSL);
Print("InpTP=", InpTP);
//--- set parameters for trading operations
ExtTrade.SetDeviationInPoints(InpSlippage); // slippage
ExtTrade.SetExpertMagicNumber(InpMagicNumber); // Expert Advisor ID
ExtTrade.LogLevel(LOG_LEVEL_ERRORS); // logging level
ExtAvgBodyPeriod=InpAverBodyPeriod;
//--- indicator initialization
ExtIndicatorHandle=iMFI(_Symbol, _Period, InpPeriodMFI, InpVolume);
if(ExtIndicatorHandle==INVALID_HANDLE)
{
Print("Error creating MFI indicator");
return(INIT_FAILED);
}
//--- OK
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- release indicator handle
IndicatorRelease(ExtIndicatorHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- save the next bar start time; all checks at bar opening only
static datetime next_bar_open=0;
//--- Phase 1 - check the emergence of a new bar and update the status
if(TimeCurrent()>=next_bar_open)
{
//--- get the current state of environment on the new bar
// namely, set the values of global variables:
// ExtPatternDetected - pattern detection
// ExtConfirmed - pattern confirmation
// ExtSignalOpen - signal to open
// ExtSignalClose - signal to close
// ExtPatternInfo - current pattern information
if(CheckState())
{
//--- set the new bar opening time
next_bar_open=TimeCurrent();
next_bar_open-=next_bar_open%PeriodSeconds(_Period);
next_bar_open+=PeriodSeconds(_Period);
//--- report the emergence of a new bar only once within a bar
if(ExtPatternDetected && ExtConfirmed)
Print(ExtPatternInfo);
}
else
{
//--- error getting the status, retry on the next tick
return;
}
}
//--- Phase 2 - if there is a signal and no position in this direction
if(ExtSignalOpen && !PositionExist(ExtSignalOpen))
{
Print("\r\nSignal to open position ", ExtDirection);
PositionOpen();
if(PositionExist(ExtSignalOpen))
ExtSignalOpen=SIGNAL_NOT;
}
//--- Phase 3 - close if there is a signal to close
if(ExtSignalClose && PositionExist(ExtSignalClose))
{
Print("\r\nSignal to close position ", ExtDirection);
CloseBySignal(ExtSignalClose);
if(!PositionExist(ExtSignalClose))
ExtSignalClose=SIGNAL_NOT;
}
//--- Phase 4 - close upon expiration
if(ExtCloseByTime && PositionExpiredByTimeExist())
{
CloseByTime();
ExtCloseByTime=PositionExpiredByTimeExist();
}
}
//+------------------------------------------------------------------+
//| Get the current environment and check for a pattern |
//+------------------------------------------------------------------+
bool CheckState()
{
//--- check if there is a pattern
if(!CheckPattern())
{
Print("Error, failed to check pattern");
return(false);
}
//--- check for confirmation
if(!CheckConfirmation())
{
Print("Error, failed to check pattern confirmation");
return(false);
}
//--- if there is no confirmation, cancel the signal
if(!ExtConfirmed)
ExtSignalOpen=SIGNAL_NOT;
//--- check if there is a signal to close a position
if(!CheckCloseSignal())
{
Print("Error, failed to check the closing signal");
return(false);
}
//--- if positions are to be closed after certain holding time in bars
if(InpDuration)
ExtCloseByTime=true; // set flag to close upon expiration
//--- all checks done
return(true);
}
//+------------------------------------------------------------------+
//| Open a position in the direction of the signal |
//+------------------------------------------------------------------+
bool PositionOpen()
{
ExtSymbolInfo.Refresh();
ExtSymbolInfo.RefreshRates();
double price=0;
//--- Stop Loss and Take Profit are not set by default
double stoploss=0.0;
double takeprofit=0.0;
int digits=ExtSymbolInfo.Digits();
double point=ExtSymbolInfo.Point();
double spread=ExtSymbolInfo.Ask()-ExtSymbolInfo.Bid();
//--- uptrend
if(ExtSignalOpen==SIGNAL_BUY)
{
price=NormalizeDouble(ExtSymbolInfo.Ask(), digits);
//--- if Stop Loss is set
if(InpSL>0)
{
if(spread>=InpSL*point)
{
PrintFormat("StopLoss (%d points) <= current spread = %.0f points. Spread value will be used", InpSL, spread/point);
stoploss = NormalizeDouble(price-spread, digits);
}
else
stoploss = NormalizeDouble(price-InpSL*point, digits);
}
//--- if Take Profit is set
if(InpTP>0)
{
if(spread>=InpTP*point)
{
PrintFormat("TakeProfit (%d points) < current spread = %.0f points. Spread value will be used", InpTP, spread/point);
takeprofit = NormalizeDouble(price+spread, digits);
}
else
takeprofit = NormalizeDouble(price+InpTP*point, digits);
}
if(!ExtTrade.Buy(InpLot, Symbol(), price, stoploss, takeprofit))
{
PrintFormat("Failed %s buy %G at %G (sl=%G tp=%G) failed. Ask=%G error=%d",
Symbol(), InpLot, price, stoploss, takeprofit, ExtSymbolInfo.Ask(), GetLastError());
return(false);
}
}
//--- downtrend
if(ExtSignalOpen==SIGNAL_SELL)
{
price=NormalizeDouble(ExtSymbolInfo.Bid(), digits);
//--- if Stop Loss is set
if(InpSL>0)
{
if(spread>=InpSL*point)
{
PrintFormat("StopLoss (%d points) <= current spread = %.0f points. Spread value will be used", InpSL, spread/point);
stoploss = NormalizeDouble(price+spread, digits);
}
else
stoploss = NormalizeDouble(price+InpSL*point, digits);
}
//--- if Take Profit is set
if(InpTP>0)
{
if(spread>=InpTP*point)
{
PrintFormat("TakeProfit (%d points) < current spread = %.0f points. Spread value will be used", InpTP, spread/point);
takeprofit = NormalizeDouble(price-spread, digits);
}
else
takeprofit = NormalizeDouble(price-InpTP*point, digits);
}
if(!ExtTrade.Sell(InpLot, Symbol(), price, stoploss, takeprofit))
{
PrintFormat("Failed %s sell at %G (sl=%G tp=%G) failed. Bid=%G error=%d",
Symbol(), price, stoploss, takeprofit, ExtSymbolInfo.Bid(), GetLastError());
ExtTrade.PrintResult();
Print(" ");
return(false);
}
}
return(true);
}
//+------------------------------------------------------------------+
//| Close a position based on the specified signal |
//+------------------------------------------------------------------+
void CloseBySignal(int type_close)
{
//--- if there is no signal to close, return successful completion
if(type_close==SIGNAL_NOT)
return;
//--- if there are no positions opened by our EA
if(PositionExist(ExtSignalClose)==0)
return;
//--- closing direction
long type;
switch(type_close)
{
case CLOSE_SHORT:
type=POSITION_TYPE_SELL;
break;
case CLOSE_LONG:
type=POSITION_TYPE_BUY;
break;
default:
Print("Error! Signal to close not detected");
return;
}
//--- check all positions and close ours based on the signal
int positions=PositionsTotal();
for(int i=positions-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket!=0)
{
//--- get the name of the symbol and the position id (magic)
string symbol=PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
if(PositionGetInteger(POSITION_TYPE)==type)
{
ExtTrade.PositionClose(ticket, InpSlippage);
ExtTrade.PrintResult();
Print(" ");
}
}
}
}
}
//+------------------------------------------------------------------+
//| Close positions upon holding time expiration in bars |
//+------------------------------------------------------------------+
void CloseByTime()
{
//--- if there are no positions opened by our EA
if(PositionExist(ExtSignalOpen)==0)
return;
//--- check all positions and close ours based on the holding time in bars
int positions=PositionsTotal();
for(int i=positions-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket!=0)
{
//--- get the name of the symbol and the position id (magic)
string symbol=PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- position opening time
datetime open_time=(datetime)PositionGetInteger(POSITION_TIME);
//--- check position holding time in bars
if(BarsHold(open_time)>=(int)InpDuration)
{
Print("\r\nTime to close position #", ticket);
ExtTrade.PositionClose(ticket, InpSlippage);
ExtTrade.PrintResult();
Print(" ");
}
}
}
}
}
//+------------------------------------------------------------------+
//| Returns true if there are open positions |
//+------------------------------------------------------------------+
bool PositionExist(int signal_direction)
{
bool check_type=(signal_direction!=SIGNAL_NOT);
//--- what positions to search
ENUM_POSITION_TYPE search_type=WRONG_VALUE;
if(check_type)
switch(signal_direction)
{
case SIGNAL_BUY:
search_type=POSITION_TYPE_BUY;
break;
case SIGNAL_SELL:
search_type=POSITION_TYPE_SELL;
break;
case CLOSE_LONG:
search_type=POSITION_TYPE_BUY;
break;
case CLOSE_SHORT:
search_type=POSITION_TYPE_SELL;
break;
default:
//--- entry direction is not specified; nothing to search
return(false);
}
//--- go through the list of all positions
int positions=PositionsTotal();
for(int i=0; i<positions; i++)
{
if(PositionGetTicket(i)!=0)
{
//--- if the position type does not match, move on to the next one
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if(check_type && (type!=search_type))
continue;
//--- get the name of the symbol and the expert id (magic number)
string symbol =PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- yes, this is the right position, stop the search
return(true);
}
}
}
//--- open position not found
return(false);
}
//+------------------------------------------------------------------+
//| Returns true if there are open positions with expired time |
//+------------------------------------------------------------------+
bool PositionExpiredByTimeExist()
{
//--- go through the list of all positions
int positions=PositionsTotal();
for(int i=0; i<positions; i++)
{
if(PositionGetTicket(i)!=0)
{
//--- get the name of the symbol and the expert id (magic number)
string symbol =PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- position opening time
datetime open_time=(datetime)PositionGetInteger(POSITION_TIME);
//--- check position holding time in bars
int check=BarsHold(open_time);
//--- id the value is -1, the check completed with an error
if(check==-1 || (BarsHold(open_time)>=(int)InpDuration))
return(true);
}
}
}
//--- open position not found
return(false);
}
//+------------------------------------------------------------------+
//| Checks position closing time in bars |
//+------------------------------------------------------------------+
int BarsHold(datetime open_time)
{
//--- first run a basic simple check
if(TimeCurrent()-open_time<PeriodSeconds(_Period))
{
//--- opening time is inside the current bar
return(0);
}
//---
MqlRates bars[];
if(CopyRates(_Symbol, _Period, open_time, TimeCurrent(), bars)==-1)
{
Print("Error. CopyRates() failed, error = ", GetLastError());
return(-1);
}
//--- check position holding time in bars
return(ArraySize(bars));
}
//+------------------------------------------------------------------+
//| Returns the open price of the specified bar |
//+------------------------------------------------------------------+
double Open(int index)
{
double val=iOpen(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the close price of the specified bar |
//+------------------------------------------------------------------+
double Close(int index)
{
double val=iClose(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the low price of the specified bar |
//+------------------------------------------------------------------+
double Low(int index)
{
double val=iLow(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the high price of the specified bar |
//+------------------------------------------------------------------+
double High(int index)
{
double val=iHigh(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the middle body price for the specified bar |
//+------------------------------------------------------------------+
double MidPoint(int index)
{
return(High(index)+Low(index))/2.;
}
//+------------------------------------------------------------------+
//| Returns the middle price of the range for the specified bar |
//+------------------------------------------------------------------+
double MidOpenClose(int index)
{
return((Open(index)+Close(index))/2.);
}
//+------------------------------------------------------------------+
//| Returns the average candlestick body size for the specified bar |
//+------------------------------------------------------------------+
double AvgBody(int index)
{
double sum=0;
for(int i=index; i<index+ExtAvgBodyPeriod; i++)
{
sum+=MathAbs(Open(i)-Close(i));
}
return(sum/ExtAvgBodyPeriod);
}
//+------------------------------------------------------------------+
//| Returns true in case of successful pattern check |
//+------------------------------------------------------------------+
bool CheckPattern()
{
ExtPatternDetected=false;
//--- check if there is a pattern
ExtSignalOpen=SIGNAL_NOT;
ExtPatternInfo="\r\nPattern not detected";
ExtDirection="";
//--- check 3 Black Crows
if((Open(3)-Close(3)>AvgBody(1)) && // long black
(Open(2)-Close(2)>AvgBody(1)) &&
(Open(1)-Close(1)>AvgBody(1)) &&
(MidPoint(2)<MidPoint(3)) && // lower midpoints
(MidPoint(1)<MidPoint(2)))
{
ExtPatternDetected=true;
ExtSignalOpen=SIGNAL_SELL;
ExtPatternInfo="\r\n3 Black Crows detected";
ExtDirection="Sell";
return(true);
}
//--- check 3 White Soldiers
if((Close(3)-Open(3)>AvgBody(1)) && // long white
(Close(2)-Open(2)>AvgBody(1)) &&
(Close(1)-Open(1)>AvgBody(1)) &&
(MidPoint(2)>MidPoint(3)) && // higher midpoints
(MidPoint(1)>MidPoint(2)))
{
ExtPatternDetected=true;
ExtSignalOpen=SIGNAL_BUY;
ExtPatternInfo="\r\n3 White Soldiers detected";
ExtDirection="Buy";
return(true);
}
//--- result of checking
return(ExtCheckPassed);
}
//+------------------------------------------------------------------+
//| Returns true in case of successful confirmation check |
//+------------------------------------------------------------------+
bool CheckConfirmation()
{
ExtConfirmed=false;
//--- if there is no pattern, do not search for confirmation
if(!ExtPatternDetected)
return(true);
//--- get the value of the stochastic indicator to confirm the signal
double signal=MFI(1);
if(signal==EMPTY_VALUE)
{
//--- failed to get indicator value, check failed
return(false);
}
//--- check the Buy signal
if(ExtSignalOpen==SIGNAL_BUY && (signal<40))
{
ExtConfirmed=true;
ExtPatternInfo+="\r\n Confirmed: MFI<40";
}
//--- check the Sell signal
if(ExtSignalOpen==SIGNAL_SELL && (signal>60))
{
ExtConfirmed=true;
ExtPatternInfo+="\r\n Confirmed: MFI>60";
}
//--- successful completion of the check
return(true);
}
//+------------------------------------------------------------------+
//| Check if there is a signal to close |
//+------------------------------------------------------------------+
bool CheckCloseSignal()
{
ExtSignalClose=false;
//--- if there is a signal to enter the market, do not check the signal to close
if(ExtSignalOpen!=SIGNAL_NOT)
return(true);
//--- check if there is a signal to close a long position
if(((MFI(1)<70) && (MFI(2)>70)) || ((MFI(1)<30) && (MFI(2)>30)))
{
//--- there is a signal to close a long position
ExtSignalClose=CLOSE_LONG;
ExtDirection="Long";
}
//--- check if there is a signal to close a short position
if(((MFI(1)>30) && (MFI(2)<30)) || ((MFI(1)>70) && (MFI(2)<70)))
{
//--- there is a signal to close a short position
ExtSignalClose=CLOSE_SHORT;
ExtDirection="Short";
}
//--- successful completion of the check
return(true);
}
//+------------------------------------------------------------------+
//| MFI indicator value at the specified bar |
//+------------------------------------------------------------------+
double MFI(int index)
{
double indicator_values[];
if(CopyBuffer(ExtIndicatorHandle, 0, index, 1, indicator_values)<0)
{
//--- if the copying fails, report the error code
PrintFormat("Failed to copy data from the MFI indicator, error code %d", GetLastError());
return(EMPTY_VALUE);
}
return(indicator_values[0]);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,657 @@
//+------------------------------------------------------------------+
//| BlackCrows WhiteSoldiers RSI.mq5 |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#define SIGNAL_BUY 1 // Buy signal
#define SIGNAL_NOT 0 // no trading signal
#define SIGNAL_SELL -1 // Sell signal
#define CLOSE_LONG 2 // signal to close Long
#define CLOSE_SHORT -2 // signal to close Short
//--- Input parameters
input int InpAverBodyPeriod=12; // period for calculating average candlestick size
input int InpPeriodRSI =37; // RSI period
input ENUM_APPLIED_PRICE InpPrice=PRICE_CLOSE; // price type
//--- trade parameters
input uint InpDuration=10; // position holding time in bars
input uint InpSL =200; // Stop Loss in points
input uint InpTP =200; // Take Profit in points
input uint InpSlippage=10; // slippage in points
//--- money management parameters
input double InpLot =0.1; // lot
//--- Expert ID
input long InpMagicNumber=120300; // Magic Number
//--- global variables
int ExtAvgBodyPeriod; // average candlestick calculation period
int ExtSignalOpen =0; // Buy/Sell signal
int ExtSignalClose =0; // signal to close a position
string ExtPatternInfo =""; // current pattern information
string ExtDirection =""; // position opening direction
bool ExtPatternDetected=false; // pattern detected
bool ExtConfirmed =false; // pattern confirmed
bool ExtCloseByTime =true; // requires closing by time
bool ExtCheckPassed =true; // status checking error
//--- indicator handle
int ExtIndicatorHandle=INVALID_HANDLE;
//--- service objects
CTrade ExtTrade;
CSymbolInfo ExtSymbolInfo;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
Print("InpSL=", InpSL);
Print("InpTP=", InpTP);
//--- set parameters for trading operations
ExtTrade.SetDeviationInPoints(InpSlippage); // slippage
ExtTrade.SetExpertMagicNumber(InpMagicNumber); // Expert Advisor ID
ExtTrade.LogLevel(LOG_LEVEL_ERRORS); // logging level
ExtAvgBodyPeriod=InpAverBodyPeriod;
//--- indicator initialization
ExtIndicatorHandle=iRSI(_Symbol, _Period, InpPeriodRSI, InpPrice);
if(ExtIndicatorHandle==INVALID_HANDLE)
{
Print("Error creating CCI indicator");
return(INIT_FAILED);
}
//--- OK
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- release indicator handle
IndicatorRelease(ExtIndicatorHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- save the next bar start time; all checks at bar opening only
static datetime next_bar_open=0;
//--- Phase 1 - check the emergence of a new bar and update the status
if(TimeCurrent()>=next_bar_open)
{
//--- get the current state of environment on the new bar
// namely, set the values of global variables:
// ExtPatternDetected - pattern detection
// ExtConfirmed - pattern confirmation
// ExtSignalOpen - signal to open
// ExtSignalClose - signal to close
// ExtPatternInfo - current pattern information
if(CheckState())
{
//--- set the new bar opening time
next_bar_open=TimeCurrent();
next_bar_open-=next_bar_open%PeriodSeconds(_Period);
next_bar_open+=PeriodSeconds(_Period);
//--- report the emergence of a new bar only once within a bar
if(ExtPatternDetected && ExtConfirmed)
Print(ExtPatternInfo);
}
else
{
//--- error getting the status, retry on the next tick
return;
}
}
//--- Phase 2 - if there is a signal and no position in this direction
if(ExtSignalOpen && !PositionExist(ExtSignalOpen))
{
Print("\r\nSignal to open position ", ExtDirection);
PositionOpen();
if(PositionExist(ExtSignalOpen))
ExtSignalOpen=SIGNAL_NOT;
}
//--- Phase 3 - close if there is a signal to close
if(ExtSignalClose && PositionExist(ExtSignalClose))
{
Print("\r\nSignal to close position ", ExtDirection);
CloseBySignal(ExtSignalClose);
if(!PositionExist(ExtSignalClose))
ExtSignalClose=SIGNAL_NOT;
}
//--- Phase 4 - close upon expiration
if(ExtCloseByTime && PositionExpiredByTimeExist())
{
CloseByTime();
ExtCloseByTime=PositionExpiredByTimeExist();
}
}
//+------------------------------------------------------------------+
//| Get the current environment and check for a pattern |
//+------------------------------------------------------------------+
bool CheckState()
{
//--- check if there is a pattern
if(!CheckPattern())
{
Print("Error, failed to check pattern");
return(false);
}
//--- check for confirmation
if(!CheckConfirmation())
{
Print("Error, failed to check pattern confirmation");
return(false);
}
//--- if there is no confirmation, cancel the signal
if(!ExtConfirmed)
ExtSignalOpen=SIGNAL_NOT;
//--- check if there is a signal to close a position
if(!CheckCloseSignal())
{
Print("Error, failed to check the closing signal");
return(false);
}
//--- if positions are to be closed after certain holding time in bars
if(InpDuration)
ExtCloseByTime=true; // set flag to close upon expiration
//--- all checks done
return(true);
}
//+------------------------------------------------------------------+
//| Open a position in the direction of the signal |
//+------------------------------------------------------------------+
bool PositionOpen()
{
ExtSymbolInfo.Refresh();
ExtSymbolInfo.RefreshRates();
double price=0;
//--- Stop Loss and Take Profit are not set by default
double stoploss=0.0;
double takeprofit=0.0;
int digits=ExtSymbolInfo.Digits();
double point=ExtSymbolInfo.Point();
double spread=ExtSymbolInfo.Ask()-ExtSymbolInfo.Bid();
//--- uptrend
if(ExtSignalOpen==SIGNAL_BUY)
{
price=NormalizeDouble(ExtSymbolInfo.Ask(), digits);
//--- if Stop Loss is set
if(InpSL>0)
{
if(spread>=InpSL*point)
{
PrintFormat("StopLoss (%d points) <= current spread = %.0f points. Spread value will be used", InpSL, spread/point);
stoploss = NormalizeDouble(price-spread, digits);
}
else
stoploss = NormalizeDouble(price-InpSL*point, digits);
}
//--- if Take Profit is set
if(InpTP>0)
{
if(spread>=InpTP*point)
{
PrintFormat("TakeProfit (%d points) < current spread = %.0f points. Spread value will be used", InpTP, spread/point);
takeprofit = NormalizeDouble(price+spread, digits);
}
else
takeprofit = NormalizeDouble(price+InpTP*point, digits);
}
if(!ExtTrade.Buy(InpLot, Symbol(), price, stoploss, takeprofit))
{
PrintFormat("Failed %s buy %G at %G (sl=%G tp=%G) failed. Ask=%G error=%d",
Symbol(), InpLot, price, stoploss, takeprofit, ExtSymbolInfo.Ask(), GetLastError());
return(false);
}
}
//--- downtrend
if(ExtSignalOpen==SIGNAL_SELL)
{
price=NormalizeDouble(ExtSymbolInfo.Bid(), digits);
//--- if Stop Loss is set
if(InpSL>0)
{
if(spread>=InpSL*point)
{
PrintFormat("StopLoss (%d points) <= current spread = %.0f points. Spread value will be used", InpSL, spread/point);
stoploss = NormalizeDouble(price+spread, digits);
}
else
stoploss = NormalizeDouble(price+InpSL*point, digits);
}
//--- if Take Profit is set
if(InpTP>0)
{
if(spread>=InpTP*point)
{
PrintFormat("TakeProfit (%d points) < current spread = %.0f points. Spread value will be used", InpTP, spread/point);
takeprofit = NormalizeDouble(price-spread, digits);
}
else
takeprofit = NormalizeDouble(price-InpTP*point, digits);
}
if(!ExtTrade.Sell(InpLot, Symbol(), price, stoploss, takeprofit))
{
PrintFormat("Failed %s sell at %G (sl=%G tp=%G) failed. Bid=%G error=%d",
Symbol(), price, stoploss, takeprofit, ExtSymbolInfo.Bid(), GetLastError());
ExtTrade.PrintResult();
Print(" ");
return(false);
}
}
return(true);
}
//+------------------------------------------------------------------+
//| Close a position based on the specified signal |
//+------------------------------------------------------------------+
void CloseBySignal(int type_close)
{
//--- if there is no signal to close, return successful completion
if(type_close==SIGNAL_NOT)
return;
//--- if there are no positions opened by our EA
if(PositionExist(ExtSignalClose)==0)
return;
//--- closing direction
long type;
switch(type_close)
{
case CLOSE_SHORT:
type=POSITION_TYPE_SELL;
break;
case CLOSE_LONG:
type=POSITION_TYPE_BUY;
break;
default:
Print("Error! Signal to close not detected");
return;
}
//--- check all positions and close ours based on the signal
int positions=PositionsTotal();
for(int i=positions-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket!=0)
{
//--- get the name of the symbol and the position id (magic)
string symbol=PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
if(PositionGetInteger(POSITION_TYPE)==type)
{
ExtTrade.PositionClose(ticket, InpSlippage);
ExtTrade.PrintResult();
Print(" ");
}
}
}
}
}
//+------------------------------------------------------------------+
//| Close positions upon holding time expiration in bars |
//+------------------------------------------------------------------+
void CloseByTime()
{
//--- if there are no positions opened by our EA
if(PositionExist(ExtSignalOpen)==0)
return;
//--- check all positions and close ours based on the holding time in bars
int positions=PositionsTotal();
for(int i=positions-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket!=0)
{
//--- get the name of the symbol and the position id (magic)
string symbol=PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- position opening time
datetime open_time=(datetime)PositionGetInteger(POSITION_TIME);
//--- check position holding time in bars
if(BarsHold(open_time)>=(int)InpDuration)
{
Print("\r\nTime to close position #", ticket);
ExtTrade.PositionClose(ticket, InpSlippage);
ExtTrade.PrintResult();
Print(" ");
}
}
}
}
}
//+------------------------------------------------------------------+
//| Returns true if there are open positions |
//+------------------------------------------------------------------+
bool PositionExist(int signal_direction)
{
bool check_type=(signal_direction!=SIGNAL_NOT);
//--- what positions to search
ENUM_POSITION_TYPE search_type=WRONG_VALUE;
if(check_type)
switch(signal_direction)
{
case SIGNAL_BUY:
search_type=POSITION_TYPE_BUY;
break;
case SIGNAL_SELL:
search_type=POSITION_TYPE_SELL;
break;
case CLOSE_LONG:
search_type=POSITION_TYPE_BUY;
break;
case CLOSE_SHORT:
search_type=POSITION_TYPE_SELL;
break;
default:
//--- entry direction is not specified; nothing to search
return(false);
}
//--- go through the list of all positions
int positions=PositionsTotal();
for(int i=0; i<positions; i++)
{
if(PositionGetTicket(i)!=0)
{
//--- if the position type does not match, move on to the next one
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if(check_type && (type!=search_type))
continue;
//--- get the name of the symbol and the expert id (magic number)
string symbol =PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- yes, this is the right position, stop the search
return(true);
}
}
}
//--- open position not found
return(false);
}
//+------------------------------------------------------------------+
//| Returns true if there are open positions with expired time |
//+------------------------------------------------------------------+
bool PositionExpiredByTimeExist()
{
//--- go through the list of all positions
int positions=PositionsTotal();
for(int i=0; i<positions; i++)
{
if(PositionGetTicket(i)!=0)
{
//--- get the name of the symbol and the expert id (magic number)
string symbol =PositionGetString(POSITION_SYMBOL);
long magic =PositionGetInteger(POSITION_MAGIC);
//--- if they correspond to our values
if(symbol==Symbol() && magic==InpMagicNumber)
{
//--- position opening time
datetime open_time=(datetime)PositionGetInteger(POSITION_TIME);
//--- check position holding time in bars
int check=BarsHold(open_time);
//--- id the value is -1, the check completed with an error
if(check==-1 || (BarsHold(open_time)>=(int)InpDuration))
return(true);
}
}
}
//--- open position not found
return(false);
}
//+------------------------------------------------------------------+
//| Checks position closing time in bars |
//+------------------------------------------------------------------+
int BarsHold(datetime open_time)
{
//--- first run a basic simple check
if(TimeCurrent()-open_time<PeriodSeconds(_Period))
{
//--- opening time is inside the current bar
return(0);
}
//---
MqlRates bars[];
if(CopyRates(_Symbol, _Period, open_time, TimeCurrent(), bars)==-1)
{
Print("Error. CopyRates() failed, error = ", GetLastError());
return(-1);
}
//--- check position holding time in bars
return(ArraySize(bars));
}
//+------------------------------------------------------------------+
//| Returns the open price of the specified bar |
//+------------------------------------------------------------------+
double Open(int index)
{
double val=iOpen(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the close price of the specified bar |
//+------------------------------------------------------------------+
double Close(int index)
{
double val=iClose(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the low price of the specified bar |
//+------------------------------------------------------------------+
double Low(int index)
{
double val=iLow(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the high price of the specified bar |
//+------------------------------------------------------------------+
double High(int index)
{
double val=iHigh(_Symbol, _Period, index);
//--- if the current check state was successful and an error was received
if(ExtCheckPassed && val==0)
ExtCheckPassed=false; // switch the status to failed
return(val);
}
//+------------------------------------------------------------------+
//| Returns the middle body price for the specified bar |
//+------------------------------------------------------------------+
double MidPoint(int index)
{
return(High(index)+Low(index))/2.;
}
//+------------------------------------------------------------------+
//| Returns the middle price of the range for the specified bar |
//+------------------------------------------------------------------+
double MidOpenClose(int index)
{
return((Open(index)+Close(index))/2.);
}
//+------------------------------------------------------------------+
//| Returns the average candlestick body size for the specified bar |
//+------------------------------------------------------------------+
double AvgBody(int index)
{
double sum=0;
for(int i=index; i<index+ExtAvgBodyPeriod; i++)
{
sum+=MathAbs(Open(i)-Close(i));
}
return(sum/ExtAvgBodyPeriod);
}
//+------------------------------------------------------------------+
//| Returns true in case of successful pattern check |
//+------------------------------------------------------------------+
bool CheckPattern()
{
ExtPatternDetected=false;
//--- check if there is a pattern
ExtSignalOpen=SIGNAL_NOT;
ExtPatternInfo="\r\nPattern not detected";
ExtDirection="";
//--- check 3 Black Crows
if((Open(3)-Close(3)>AvgBody(1)) && // long black
(Open(2)-Close(2)>AvgBody(1)) &&
(Open(1)-Close(1)>AvgBody(1)) &&
(MidPoint(2)<MidPoint(3)) && // lower midpoints
(MidPoint(1)<MidPoint(2)))
{
ExtPatternDetected=true;
ExtSignalOpen=SIGNAL_SELL;
ExtPatternInfo="\r\n3 Black Crows detected";
ExtDirection="Sell";
return(true);
}
//--- check 3 White Soldiers
if((Close(3)-Open(3)>AvgBody(1)) && // long white
(Close(2)-Open(2)>AvgBody(1)) &&
(Close(1)-Open(1)>AvgBody(1)) &&
(MidPoint(2)>MidPoint(3)) && // higher midpoints
(MidPoint(1)>MidPoint(2)))
{
ExtPatternDetected=true;
ExtSignalOpen=SIGNAL_BUY;
ExtPatternInfo="\r\n3 White Soldiers detected";
ExtDirection="Buy";
return(true);
}
//--- result of checking
return(ExtCheckPassed);
}
//+------------------------------------------------------------------+
//| Returns true in case of successful confirmation check |
//+------------------------------------------------------------------+
bool CheckConfirmation()
{
ExtConfirmed=false;
//--- if there is no pattern, do not search for confirmation
if(!ExtPatternDetected)
return(true);
//--- get the value of the stochastic indicator to confirm the signal
double signal=RSI(1);
if(signal==EMPTY_VALUE)
{
//--- failed to get indicator value, check failed
return(false);
}
//--- check the Buy signal
if(ExtSignalOpen==SIGNAL_BUY && (signal<40))
{
ExtConfirmed=true;
ExtPatternInfo+="\r\n Confirmed: RSI<40";
}
//--- check the Sell signal
if(ExtSignalOpen==SIGNAL_SELL && (signal>60))
{
ExtConfirmed=true;
ExtPatternInfo+="\r\n Confirmed: RSI>60";
}
//--- successful completion of the check
return(true);
}
//+------------------------------------------------------------------+
//| Check if there is a signal to close |
//+------------------------------------------------------------------+
bool CheckCloseSignal()
{
ExtSignalClose=false;
//--- if there is a signal to enter the market, do not check the signal to close
if(ExtSignalOpen!=SIGNAL_NOT)
return(true);
//--- check if there is a signal to close a long position
if(((RSI(1)<70) && (RSI(2)>70)) || ((RSI(1)<30) && (RSI(2)>30)))
{
//--- there is a signal to close a long position
ExtSignalClose=CLOSE_LONG;
ExtDirection="Long";
}
//--- check if there is a signal to close a short position
if(((RSI(1)>30) && (RSI(2)<30)) || ((RSI(1)>70) && (RSI(2)<70)))
{
//--- there is a signal to close a short position
ExtSignalClose=CLOSE_SHORT;
ExtDirection="Short";
}
//--- successful completion of the check
return(true);
}
//+------------------------------------------------------------------+
//| RSI indicator value at the specified bar |
//+------------------------------------------------------------------+
double RSI(int index)
{
double indicator_values[];
if(CopyBuffer(ExtIndicatorHandle, 0, index, 1, indicator_values)<0)
{
//--- if the copying fails, report the error code
PrintFormat("Failed to copy data from the RSI indicator, error code %d", GetLastError());
return(EMPTY_VALUE);
}
return(indicator_values[0]);
}
//+------------------------------------------------------------------+

Some files were not shown because too many files have changed in this diff Show More