diff --git a/Classes/x-saherelm.xdata-collector.class.mq5 b/Classes/x-saherelm.xdata-collector.class.mq5 new file mode 100644 index 00000000..2fa76542 --- /dev/null +++ b/Classes/x-saherelm.xdata-collector.class.mq5 @@ -0,0 +1,444 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCDataCollector +// Description: provides Data Collection 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 + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +template +class XSCDataCollector : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + void XSCDataCollector( + string path = NULL, // Base Folder for Data Store + string fileName = NULL // File Name for Data Store + ) + { + // + if (!IsValid(path)) + { + path = GetType(); + } + + // + if (!IsValid(fileName)) + { + fileName = GetType() + ".txt"; + } + + // + Path(path); + FileName(fileName); + } + + // + // Deconstructor ... + void ~XSCDataCollector() {} + + // + // Properties ... + + // + bool Path(string value) + { + // + bool result = false; + + // + result = IsValid(value); + if (!result) + { + return result; + } + + // + result = value != mPath; + if (!result) + { + return result; + } + + // + mPath = value; + + // + return result; + } + + // + string Path() + { + return mPath; + } + + // + bool FileName(string value) + { + // + bool result = false; + + // + result = IsValid(value); + if (!result) + { + return result; + } + + // + result = value != mFileName; + if (!result) + { + return result; + } + + // + mFileName = value; + + // + return result; + } + + // + string FileName() + { + return mFileName; + } + + // + // Tools ... + + // + // Clear Exists Collected Data ... + void Clear() + { + // + ResetLastError(); + + // + string dataStorePath = GetStorePath(); + + // + // Check Data Store Exists or not ... + bool isExists = FileIsExist(dataStorePath); + if (!isExists) + { + return; + } + + // + FileDelete(dataStorePath); + } + + // + // Collect All Stored Items ... + int Collect( + T &items[] // Hold Result + ) + { + // + int result = 0; + + // + Clean(items); + + // + // Reading Store Whole Content ... + + // + string storePath = GetStorePath(); + int mFileHandler = FileOpen( + storePath, + FILE_READ | FILE_TXT); + result = mFileHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Parse Store Content and Read Data ... + while (!FileIsEnding(mFileHandler)) + { + // + // Each Line Represent One Model ... + string content = FileReadString(mFileHandler); + + // + T iItem; + bool isValid = iItem.Parse(content); + if (isValid) + { + // + AddRef( + iItem, + items + // + ); + } + } + + // + // Close File ... + FileClose(mFileHandler); + + // + result = ArraySize(items); + + // + return result; + } + + // + // Add Item ... + bool Add( + T &item // Item to Store + ) + { + // + bool result = false; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + string content = item.ToString(); + result = IsValid(content); + if (!result) + { + return result; + } + + // + string storePath = GetStorePath(); + int mFileHandler = FileOpen( + storePath, + FILE_READ | FILE_WRITE | FILE_TXT); + result = mFileHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileSeek(mFileHandler, 0, SEEK_END); + FileWrite(mFileHandler, content); + FileFlush(mFileHandler); + FileClose(mFileHandler); + + // + return result; + } + + // + // Add Items ... + int Add( + T &items[] // Items to Add ... + ) + { + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + T iItem = items[i]; + + // + if (!iItem.IsValid()) + { + continue; + } + + // + bool isAdded = Add(iItem); + if (isAdded) + { + result++; + } + } + + // + return result; + } + + // + // Remove Item ... + bool Remove( + T &item // Item to Remove + ) + { + // + bool result = false; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + T items[]; + int itemsCount = Collect(items); + if (itemsCount <= 0) + { + return result; + } + + // + int itemIndex = item.FindIndex(items); + result = ArrayRemove( + items, + itemIndex, + 1); + if (!result) + { + return result; + } + + // + Clear(); + + // + int itemsAdded = Add(items); + + // + result = itemsAdded == ArraySize(items); + + // + return result; + } + + // + // Protected ... +protected: + // + // Tools ... + + // + // Retrieve Type of Class as String ... + string GetType() + { + // + string mType = (string) typename(T); + + // + string result = mType; + + // + string parts[]; + int partsCount = SplitContent( + parts, + result, + " " + // + ); + if (partsCount <= 0) + { + // + result = mType; + return result; + } + + // + bool hasLastPart = GetLastItem( + result, + parts + // + ); + if (!hasLastPart) + { + // + result = mType; + return result; + } + + // + return result; + } + + // + // Pricate ... +private: + // + // Props ... + + // + string mPath; // Path + string mFileName; // Data Store File Name + + // + // Tools ... + + // + // Generate Full File Path ... + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + Path() + "\\" + fileName + // + ; + + // + return result; + } + + // + // Retrieve Data Store File Address ... + string GetStorePath() + { + // + string result = NULL; + + // + result = GetFilePath(mFileName); + + // + return result; + } +}; + +// \ No newline at end of file diff --git a/Helpers/x-saherelm.xama.helper.mq5 b/Helpers/x-saherelm.xama.helper.mq5 index f74af6a6..0e0a7add 100644 --- a/Helpers/x-saherelm.xama.helper.mq5 +++ b/Helpers/x-saherelm.xama.helper.mq5 @@ -39,11 +39,16 @@ struct XXAMAInputs { // // Props ... + // + // Market ... int length; // Period int fastEMA; // Fast EMA Period int slowEMA; // Slow EMA Period int maShift; // Shift ENUM_APPLIED_PRICE appliedTo; // Applied To + // + // Presentation ... + bool showLine; // Show Line // // Constructor(s) ... @@ -65,6 +70,7 @@ struct XXAMAInputs fastEMA = 0; slowEMA = 0; maShift = 0; + showLine = false; appliedTo = PRICE_CLOSE; } @@ -77,6 +83,7 @@ struct XXAMAInputs fastEMA = 2; slowEMA = 30; maShift = 0; + showLine = true; appliedTo = PRICE_CLOSE; } @@ -169,11 +176,18 @@ public: "x-saherelm.xama", // // Inputs ... - mInputs.length, // Period - mInputs.fastEMA, // Fast EMA Period - mInputs.slowEMA, // Slow EMA Period - mInputs.maShift, // Shift - mInputs.appliedTo // Applied To + // + // Market ... + "", + mInputs.length, // Period + mInputs.fastEMA, // Fast EMA Period + mInputs.slowEMA, // Slow EMA Period + mInputs.maShift, // Shift + mInputs.appliedTo, // Applied To + // + // Presentation ... + "", + mInputs.showLine // Show Line // ); result = mHandler != INVALID_HANDLE; diff --git a/Helpers/x-saherelm.xtm.helper.mq5 b/Helpers/x-saherelm.xtm.helper.mq5 index 4f69093c..c1f3a062 100644 --- a/Helpers/x-saherelm.xtm.helper.mq5 +++ b/Helpers/x-saherelm.xtm.helper.mq5 @@ -39,10 +39,15 @@ struct XXTMInputs { // // Props ... + // + // Market ... int maPeriod; // Period int maShift; // Shift ENUM_MA_METHOD maMethod; // Method ENUM_APPLIED_PRICE maAppliedTo; // Applied To + // + // Presentation ... + bool showLine; // Show Line // // Constructor(s) ... @@ -62,6 +67,7 @@ struct XXTMInputs // maShift = 0; maPeriod = 0; + showLine = false; maMethod = MODE_SMA; maAppliedTo = PRICE_CLOSE; } @@ -73,6 +79,7 @@ struct XXTMInputs // maShift = 0; maPeriod = 14; + showLine = true; maMethod = MODE_SMA; maAppliedTo = PRICE_CLOSE; } @@ -163,10 +170,17 @@ public: "x-saherelm.xtm", // // Inputs ... - mInputs.maPeriod, // Period - mInputs.maShift, // Shift - mInputs.maMethod, // Method - mInputs.maAppliedTo // Applied To + // + // Market ... + "", + mInputs.maPeriod, // Period + mInputs.maShift, // Shift + mInputs.maMethod, // Method + mInputs.maAppliedTo, // Applied To + // + // Presentation ... + "", + mInputs.showLine // Show Line // ); result = mHandler != INVALID_HANDLE; diff --git a/Indicators/x-saherelm.xama.mq5 b/Indicators/x-saherelm.xama.mq5 index e2df3fe5..714a25d7 100644 --- a/Indicators/x-saherelm.xama.mq5 +++ b/Indicators/x-saherelm.xama.mq5 @@ -20,33 +20,35 @@ #property strict // -// START Constants ... -// +// Constants ... + #define ShortName "XAMA" // -// XAMA Indicator States ... +// Indicator States ... enum ENUM_X_XAMA_STATES { X_XAMA_BULLISH = 1, X_XAMA_BEARISH = -1, X_XAMA_NEUTURAL = 0, }; -// -// END Constants ... -// // -// START Inputs ... +// Inputs ... + // +// Market ... +input group "Market"; input int length = 18; // Period input int fastEMA = 2; // Fast EMA Period input int slowEMA = 30; // Slow EMA Period input int maShift = 0; // Shift input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + // -// END Inputs ... -// +// Presentation ... +input group "Presentation"; +input bool showLine = true; // Show Line // // Includes Common Library ... @@ -73,7 +75,7 @@ double stateBuffer[]; #property indicator_label1 "XAMA" #property indicator_type1 DRAW_COLOR_LINE -#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_color1 clrLime, clrGray, clrRed, CLR_NONE #property indicator_style1 STYLE_SOLID #property indicator_width1 1 // @@ -313,8 +315,7 @@ void CalculateBuffers(int bar_index) candle.Init( _Symbol, _Period, - bar_index - ); + bar_index); // double maValue = maBuffer[bar_index]; @@ -335,7 +336,7 @@ void CalculateBuffers(int bar_index) // // Set Ma Buffer Color Index ... - maColorBuffer[bar_index] = lineColorIndex; + maColorBuffer[bar_index] = showLine ? lineColorIndex : 3; // // Set State Buffer Value ... diff --git a/Indicators/x-saherelm.xche.mq5 b/Indicators/x-saherelm.xche.mq5 new file mode 100644 index 00000000..f47d3639 --- /dev/null +++ b/Indicators/x-saherelm.xche.mq5 @@ -0,0 +1,631 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XCHE +// Description: Chandelier Exit Indicator ... +// +// +// 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 XCHE Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XCHE" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 35; // Length +input int loopback = 26; // Loopback +input double multiplier1 = 3.0; // 1st Multiplier +input double multiplier2 = 3.5; // 2nd Multiplier + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showLongExit1Line = true; // Show 1st Long Exit +input bool showShortExit1Line = true; // Show 1st Short Exit +input bool showLongExit2Line = true; // Show 2st Long Exit +input bool showShortExit2Line = true; // Show 2st Short Exit + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +// Long Exit 1 ... +#define longExit1BufferIndex 0 +double longExit1Buffer[]; + +// +#property indicator_label1 "XCHE LE 1" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_DOT + +// +// Short Exit 1 ... +#define shortExit1BufferIndex 1 +double shortExit1Buffer[]; + +// +#property indicator_label2 "XCHE SE 1" +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color2 clrRed + +// +// Long Exit 2 ... +#define longExit2BufferIndex 2 +double longExit2Buffer[]; + +// +#property indicator_label3 "XCHE LE 2" +#property indicator_type3 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color3 clrAqua + +// +// Short Exit 2 ... +#define shortExit2BufferIndex 3 +double shortExit2Buffer[]; + +// +#property indicator_label4 "XCHE SE 2" +#property indicator_type4 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color4 clrMagenta + +// +// START Arrows ... + +// +// Long Exit 1 Start ... +#define longExit1StartBufferIndex 4 +double longExit1StartBuffer[]; + +// +#property indicator_label5 "XCHE LES 1" +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrLime + +// +// Short Exit 1 Start ... +#define shortExit1StartBufferIndex 5 +double shortExit1StartBuffer[]; + +// +#property indicator_label6 "XCHE SES 1" +#property indicator_type6 DRAW_ARROW +#property indicator_color6 clrRed + +// +// Long Exit 2 Start ... +#define longExit2StartBufferIndex 6 +double longExit2StartBuffer[]; + +// +#property indicator_label7 "XCHE LES 2" +#property indicator_type7 DRAW_ARROW +#property indicator_color7 clrAqua + +// +// Short Exit 2 Start ... +#define shortExit2StartBufferIndex 7 +double shortExit2StartBuffer[]; + +// +#property indicator_label8 "XCHE SES 2" +#property indicator_type8 DRAW_ARROW +#property indicator_color8 clrMagenta + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// Working Array ... +double work[][6]; +#define hi1Idx 0 +#define lo1Idx 1 +#define hi2Idx 2 +#define lo2Idx 3 +#define trend1Idx 4 +#define trend2Idx 5 + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 mPeriod 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 +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + if (Bars(_Symbol, _Period) < rates_total) + { + return (prev_calculated); + } + + // + if (ArrayRange(work, 0) != rates_total) + { + ArrayResize(work, rates_total); + } + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + low, + close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + loopback >= 0; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(length, loopback); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + uint arrowCode = 159; + + // + // LEVEL 1 ... + + // + // Long Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit1DrawType = showLongExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit1StartDrawType = showLongExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit1BufferIndex, longExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_SHOW_DATA, showLongExit1Line); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_DRAW_TYPE, longExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit1StartBufferIndex, longExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_DRAW_TYPE, longExit1StartDrawType); + + // + // Short Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit1DrawType = showShortExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit1StartDrawType = showShortExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit1BufferIndex, shortExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_SHOW_DATA, showShortExit1Line); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_DRAW_TYPE, shortExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit1StartBufferIndex, shortExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_DRAW_TYPE, shortExit1StartDrawType); + + // + // LEVEL 2 ... + + // + // Long Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit2DrawType = showLongExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit2StartDrawType = showLongExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit2BufferIndex, longExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_SHOW_DATA, showLongExit2Line); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_DRAW_TYPE, longExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit2StartBufferIndex, longExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_DRAW_TYPE, longExit2StartDrawType); + + // + // Short Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit2DrawType = showShortExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit2StartDrawType = showShortExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit2BufferIndex, shortExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_SHOW_DATA, showShortExit2Line); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_DRAW_TYPE, shortExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit2StartBufferIndex, shortExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_DRAW_TYPE, shortExit2StartDrawType); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int prevCalculated, // Previous Calculated + int ratesTotal, // Total Rates + const double &open[], // Rates Open ... + const double &high[], // Rates High ... + const double &low[], // Rates Low ... + const double &close[] // Rates Close ... +) +{ + // + // Cleanup Buffers ... + longExit1Buffer[bar_index] = longExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index] = shortExit1StartBuffer[bar_index] = EMPTY_VALUE; + longExit2Buffer[bar_index] = longExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index] = shortExit2StartBuffer[bar_index] = EMPTY_VALUE; + + // + int start = MathMax(bar_index - loopback, 0); + + // + // Calculate ATR Value ... + double atrValue = 0; + for (int k = 1; k <= length && (bar_index - k - 1) >= 0; k++) + { + // + atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) - + MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]); + } + atrValue /= (double)length; + + // + // Retrieve Highest High and Lowest Lows ... + double loopbackMax = high[ArrayMaximum(high, start, loopback)]; + double loopbackMin = low[ArrayMinimum(low, start, loopback)]; + + // + // Fill Multi Dimesional Working Array ... + work[bar_index][hi1Idx] = loopbackMax - multiplier1 * atrValue; + work[bar_index][lo1Idx] = loopbackMin + multiplier1 * atrValue; + work[bar_index][hi2Idx] = loopbackMax - multiplier2 * atrValue; + work[bar_index][lo2Idx] = loopbackMin + multiplier2 * atrValue; + work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0; + work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0; + + // + if (bar_index > 0) + { + // + // Calculate Trends ... + if (close[bar_index] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][trend1Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][trend1Idx] = -1; + } + + // + if (close[bar_index] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][trend2Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][trend2Idx] = -1; + } + + // + // Calculate Exit Values ... + + // + // Exit 1 ... + + // + // Long ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == 1) + { + // + if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx]; + } + + // + longExit1Buffer[bar_index] = work[bar_index][hi1Idx]; + + // + if (longExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit1StartBuffer[bar_index] = longExit1Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == -1) + { + // + if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx]; + } + + // + shortExit1Buffer[bar_index] = work[bar_index][lo1Idx]; + + // + if (shortExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index]; + } + } + + // + // Exit 2 ... + + // + // Long ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == 1) + { + if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx]; + } + + // + longExit2Buffer[bar_index] = work[bar_index][hi2Idx]; + + // + if (longExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit2StartBuffer[bar_index] = longExit2Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == -1) + { + // + if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx]; + } + + // + shortExit2Buffer[bar_index] = work[bar_index][lo2Idx]; + + // + if (shortExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index]; + } + } + } +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xdon.mq5 b/Indicators/x-saherelm.xdon.mq5 new file mode 100644 index 00000000..e479e65c --- /dev/null +++ b/Indicators/x-saherelm.xdon.mq5 @@ -0,0 +1,365 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XDON +// Description: DONCHAIN Channel ... +// +// 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 XDON Indicator" +#property strict + +// +#define ShortName "XDON" + +// +// INPUT ... + +// +input int length = 52; // Market Length +input double offset = 0; // Offset + +// +// BUFFERS ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +#define upperOBufferIndex 0 +double upperOBuffer[]; + +// +#property indicator_label1 "XDON OU" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrCornflowerBlue +#property indicator_width1 2 + +// +#define lowerOBufferIndex 1 +double lowerOBuffer[]; + +// +#property indicator_label2 "XDON OL" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrCornflowerBlue +#property indicator_width2 2 + +// +#define upperCBufferIndex 2 +double upperCBuffer[]; + +// +#property indicator_label3 "XDON CU" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrCoral +#property indicator_width3 2 + +// +#define lowerCBufferIndex 3 +double lowerCBuffer[]; + +// +#property indicator_label4 "XDON CL" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrCoral +#property indicator_width4 2 + +// +#define upperHBufferIndex 4 +double upperHBuffer[]; + +// +#property indicator_label5 "XDON HU" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAquamarine +#property indicator_width5 2 + +// +#define lowerHBufferIndex 5 +double lowerHBuffer[]; + +// +#property indicator_label6 "XDON HL" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAquamarine +#property indicator_width6 2 + +// +#define upperLBufferIndex 6 +double upperLBuffer[]; + +// +#property indicator_label7 "XDON LU" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrDarkOrchid +#property indicator_width7 2 + +// +#define lowerLBufferIndex 7 +double lowerLBuffer[]; + +// +#property indicator_label8 "XDON LL" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrDarkOrchid +#property indicator_width8 2 + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + if (rates_total < length - 1) + { + return prev_calculated; + } + + // + int start = prev_calculated == 0 + ? length + : prev_calculated - 1; + + // + // Main Loop ... + for (int barIndex = start; barIndex < rates_total; barIndex++) + { + // + // OPEN ... + + // + double upperOValue = open[ArrayMaximum(open, barIndex - length + 1, length)]; + double lowerOValue = open[ArrayMinimum(open, barIndex - length + 1, length)]; + + // + double oDelta = MathAbs(upperOValue - lowerOValue); + double oOffsetValue = oDelta * (offset) * 0.01; + + // + upperOBuffer[barIndex] = upperOValue - oOffsetValue; + lowerOBuffer[barIndex] = lowerOValue + oOffsetValue; + + // + // CLOSE ... + + // + double upperCValue = close[ArrayMaximum(close, barIndex - length + 1, length)]; + double lowerCValue = close[ArrayMinimum(close, barIndex - length + 1, length)]; + + // + double cDelta = MathAbs(upperCValue - lowerCValue); + double cOffsetValue = cDelta * (offset) * 0.01; + + // + upperCBuffer[barIndex] = upperCValue - cOffsetValue; + lowerCBuffer[barIndex] = lowerCValue + cOffsetValue; + + // + // HIGH ... + + // + double upperHValue = high[ArrayMaximum(high, barIndex - length + 1, length)]; + double lowerHValue = high[ArrayMinimum(high, barIndex - length + 1, length)]; + + // + double hDelta = MathAbs(upperHValue - lowerHValue); + double hOffsetValue = hDelta * (offset) * 0.01; + + // + upperHBuffer[barIndex] = upperHValue - hOffsetValue; + lowerHBuffer[barIndex] = lowerHValue + hOffsetValue; + + // + // LOW ... + + // + double upperLValue = low[ArrayMaximum(low, barIndex - length + 1, length)]; + double lowerLValue = low[ArrayMinimum(low, barIndex - length + 1, length)]; + + // + double lDelta = MathAbs(upperLValue - lowerLValue); + double lOffsetValue = lDelta * (offset) * 0.01; + + // + upperLBuffer[barIndex] = upperLValue - lOffsetValue; + lowerLBuffer[barIndex] = lowerLValue + lOffsetValue; + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = length >= 7; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Open ... + + // + // UPPER ... + SetIndexBuffer(upperOBufferIndex, upperOBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperOBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(upperOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // LOWER ... + SetIndexBuffer(lowerOBufferIndex, lowerOBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerOBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(lowerOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // Close ... + + // + // UPPER ... + SetIndexBuffer(upperCBufferIndex, upperCBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperCBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(upperCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // LOWER ... + SetIndexBuffer(lowerCBufferIndex, lowerCBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerCBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(lowerCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // High ... + + // + // UPPER ... + SetIndexBuffer(upperHBufferIndex, upperHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperHBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(upperHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // LOWER ... + SetIndexBuffer(lowerHBufferIndex, lowerHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerHBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(lowerHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // Low ... + + // + // UPPER ... + SetIndexBuffer(upperLBufferIndex, upperLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upperLBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(upperLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + + // + // LOWER ... + SetIndexBuffer(lowerLBufferIndex, lowerLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowerLBufferIndex, PLOT_SHOW_DATA, true); + PlotIndexSetDouble(lowerLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} diff --git a/Indicators/x-saherelm.xhk.mq5 b/Indicators/x-saherelm.xhk.mq5 new file mode 100644 index 00000000..ca4a6b33 --- /dev/null +++ b/Indicators/x-saherelm.xhk.mq5 @@ -0,0 +1,486 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------------- +// Name: XHK +// Description: Hiken Ashi ... +// Market Analysor ... +// +// +// 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 X121_XHK Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XHK" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Presentation"; +input bool drawCandles = true; // Draw Hiken Ashi Candle +input bool drawCandleLines = false; // Show HikenAshi Lines + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 13 +#property indicator_plots 5 + +// +// PLOTTED Buffers ... + +// +// Open ... +#define openBufferIndex 0 +double openBuffer[]; + +// +// High ... +#define highBufferIndex 1 +double highBuffer[]; + +// +// Low ... +#define lowBufferIndex 2 +double lowBuffer[]; + +// +// Close ... +#define closeBufferIndex 3 +double closeBuffer[]; + +// +// Candle Color ... +#define candleColorBufferIndex 4 +double candleColorBuffer[]; + +// +#define candlesBufferIndex 0 + +// +#property indicator_label1 "X121_XHK Open;X121_XHK High;X121_XHK Low;X121_XHK Close" +#property indicator_type1 DRAW_COLOR_CANDLES +#property indicator_color1 clrAqua, clrMagenta, CLR_NONE + +// +#define openHKBufferIndex 5 +#define openHKColorBufferIndex 6 +double openHKBuffer[]; +double openHKColorBuffer[]; + +// +#define openHKBufferPlotIndex 1 +#property indicator_label2 "X121_XHK O" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrAqua, clrMagenta, clrLightGray +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#define highHKBufferIndex 7 +#define highHKColorBufferIndex 8 +double highHKBuffer[]; +double highHKColorBuffer[]; + +// +#define highHKBufferPlotIndex 2 +#property indicator_label3 "X121_XHK H" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrAqua, clrMagenta, clrLightGray +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define lowHKBufferIndex 9 +#define lowHKColorBufferIndex 10 +double lowHKBuffer[]; +double lowHKColorBuffer[]; + +// +#define lowHKBufferPlotIndex 3 +#property indicator_label4 "X121_XHK L" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 clrAqua, clrMagenta, clrLightGray +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define closeHKBufferIndex 11 +#define closeHKColorBufferIndex 12 +double closeHKBuffer[]; +double closeHKColorBuffer[]; + +// +#define closeHKBufferPlotIndex 4 +#property indicator_label5 "X121_XHK C" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 clrAqua, clrMagenta, clrLightGray +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, prev_calculated, rates_total, open, high, close, low); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Candles Color ... + ArraySetAsSeries(candleColorBuffer, true); + SetIndexBuffer(candleColorBufferIndex, candleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(candlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(candlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(candleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(openBuffer, true); + PlotIndexSetInteger(openBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(highBuffer, true); + SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(closeBuffer, true); + SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(lowBuffer, true); + SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open HK ... + ENUM_DRAW_TYPE openDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(openHKBuffer, true); + SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(openHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(openHKBufferPlotIndex, PLOT_DRAW_TYPE, openDrawType); + + // + ArraySetAsSeries(openHKColorBuffer, true); + SetIndexBuffer(openHKColorBufferIndex, openHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // High HK ... + ENUM_DRAW_TYPE highDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(highHKBuffer, true); + SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(highHKBufferPlotIndex, PLOT_DRAW_TYPE, highDrawType); + + // + ArraySetAsSeries(highHKColorBuffer, true); + SetIndexBuffer(highHKColorBufferIndex, highHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Low HK ... + ENUM_DRAW_TYPE lowDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(lowHKBuffer, true); + SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(lowHKBufferPlotIndex, PLOT_DRAW_TYPE, lowDrawType); + + // + ArraySetAsSeries(lowHKColorBuffer, true); + SetIndexBuffer(lowHKColorBufferIndex, lowHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Close HK ... + ENUM_DRAW_TYPE closeDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(closeHKBuffer, true); + SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(closeHKBufferPlotIndex, PLOT_DRAW_TYPE, closeDrawType); + + // + ArraySetAsSeries(closeHKColorBuffer, true); + SetIndexBuffer(closeHKColorBufferIndex, closeHKColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[]) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = openBuffer[bar_index + 1]; + mPrevHKCloseValue = closeBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + openBuffer[bar_index] = mHKOpenValue; + highBuffer[bar_index] = mHKHighValue; + lowBuffer[bar_index] = mHKLowValue; + closeBuffer[bar_index] = mHKCloseValue; + + // + double candleColorValue = + mHKOpenValue < mHKCloseValue ? 0 : 1; + + // + candleColorBuffer[bar_index] = drawCandles ? candleColorValue : 2; + + // + openHKBuffer[bar_index] = mHKOpenValue; + openHKColorBuffer[bar_index] = candleColorValue; + + // + highHKBuffer[bar_index] = mHKHighValue; + highHKColorBuffer[bar_index] = candleColorValue; + + // + lowHKBuffer[bar_index] = mHKLowValue; + lowHKColorBuffer[bar_index] = candleColorValue; + + // + closeHKBuffer[bar_index] = mHKCloseValue; + closeHKColorBuffer[bar_index] = candleColorValue; +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xhull.mq5 b/Indicators/x-saherelm.xhull.mq5 new file mode 100644 index 00000000..f822995f --- /dev/null +++ b/Indicators/x-saherelm.xhull.mq5 @@ -0,0 +1,602 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XHULL +// Description: Hull Trend Indicator ... +// +// +// 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 XHULL Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XHULL" + +// +struct XHullData +{ + // + double value; + double value3; + + // + double wsum1; + double wsum2; + double wsum3; + + // + double lsum1; + double lsum2; + double lsum3; +}; + +// +// END Constants ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START XSCHULL Class Definition ... +// + +// +// a Class For Hull Calculations ... +class XSCHull +{ + // +public: + // + // Constructor ... + XSCHull() : mFullPeriod(1), mHalfPeriod(1), mSqrtPeriod(1), mArraySize(-1) + { + // + // These are a way above to assign Private variables at Construct time ... + } + + // + // Deconstructor ... + ~XSCHull() + { + ArrayFree(mData); + } + + // + // Initial Hull ... + bool Init( + int mPeriod, + double mDivisor) + { + // + bool result = false; + + // + mFullPeriod = (int)(mPeriod > 1 ? mPeriod : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (mDivisor > 1 ? mDivisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; + +// +// END XSCHULL Class Definition ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 72; // Length +input double divisor = 2.0; // Divisor (Speed) + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showUpZone = true; // Show Up Zone +input bool showDownZone = true; // Show Down Zone + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// UP Zone ... + +// +#define upZoneBufferIndex 0 +#define upZoneColorBufferIndex 1 + +// +double upZoneBuffer[]; +double upZoneColorBuffer[]; + +// +#property indicator_label1 "XHULL Up" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLightGray, clrAqua, clrMagenta +#property indicator_width1 1 + +// +// DOWN Zone ... + +// +#define downZoneBufferIndex 2 +#define downZoneColorBufferIndex 3 + +// +double downZoneBuffer[]; +double downZoneColorBuffer[]; + +// +#property indicator_label2 "XHULL Down" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrLightGray, clrAqua, clrMagenta +#property indicator_width2 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XSCHull *mUpZHull; +XSCHull *mDownZHull; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Make an Instance of Hull Class ... + + // + mUpZHull = new XSCHull(); + mUpZHull.Init( + length, + divisor); + + // + mDownZHull = new XSCHull(); + mDownZHull.Init( + length, + divisor); + + // + // 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 mPeriod 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 + + // + delete mUpZHull; + delete mDownZHull; +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + double upPrice = getPrice( + upAppliedTo, + open, high, low, close, i); + + // + double downPrice = getPrice( + downAppliedTo, + open, high, low, close, i); + + // + CalculateBuffers( + i, + rates_total, + upPrice, + downPrice); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + divisor >= 0.5; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE upZoneDrawType = showUpZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(upZoneBufferIndex, upZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_SHOW_DATA, showUpZone); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_DRAW_TYPE, upZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(upZoneColorBufferIndex, upZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE downZoneDrawType = showDownZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(downZoneBufferIndex, downZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_SHOW_DATA, showDownZone); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_DRAW_TYPE, downZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(downZoneColorBufferIndex, downZoneColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int ratesTotal, // Total Rates + double upPrice, // Up Price ... + double downPrice // Down Price ... +) +{ + // + double upValue = mUpZHull.Calculate( + upPrice, + bar_index, + ratesTotal); + upZoneBuffer[bar_index] = upValue; + double upColorIDX = (bar_index > 0) + ? (upZoneBuffer[bar_index] > upZoneBuffer[bar_index - 1]) + ? 1 + : (upZoneBuffer[bar_index] < upZoneBuffer[bar_index - 1]) + ? 2 + : upZoneColorBuffer[bar_index - 1] + : 0; + upZoneColorBuffer[bar_index] = upColorIDX; + + // + double downValue = mDownZHull.Calculate( + downPrice, + bar_index, + ratesTotal); + downZoneBuffer[bar_index] = downValue; + double downColorIDX = (bar_index > 0) + ? (downZoneBuffer[bar_index] > downZoneBuffer[bar_index - 1]) + ? 1 + : (downZoneBuffer[bar_index] < downZoneBuffer[bar_index - 1]) + ? 2 + : downZoneColorBuffer[bar_index - 1] + : 0; + downZoneColorBuffer[bar_index] = downColorIDX; +} + +// +// END Functions ... +// + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/Indicators/x-saherelm.xich.mq5 b/Indicators/x-saherelm.xich.mq5 new file mode 100644 index 00000000..00bf6fbb --- /dev/null +++ b/Indicators/x-saherelm.xich.mq5 @@ -0,0 +1,846 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XICH +// Description: Ichimoku Kinko Hyo ... +// +// +// 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 XICH Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XICH" + +// +// Ichimoku Golden Numbers ... +enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS +{ + X_ICH_BASE = 9, + X_ICH_GOLDEN = 17, + X_ICH_CYCLE = 26, + X_ICH_PERIOD = 35, + X_ICH_STAR = 45, + X_ICH_MED = 52, + X_ICH_LONG = 63, + X_ICH_FULL = 72 +}; + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ICHIMOKU Kinko Hyo ... + +// +// TENKANSEN ... +input group "Tenkan Sen"; +input int tenkanSenLength = 9; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// KIJUNSEN ... +input group "Kijun Sen"; +input int kijunSenLength = 26; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// SENKOUSPANB ... +input group "Senkou Span B"; +input int senkouSpanBLength = 52; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// CHIKOUSPAN ... +input group "Chikou Span"; +input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type + +// +input group "Presentation"; +input bool showTenkanSen = true; // Show Tenkan Sen +input bool showKijunSen = true; // Show Kijun Sen +input bool showKijunSenPlus = false; // Show Kijun Sen + +input bool showKijunSenNegative = false; // Show Kijun Sen - +input bool showChikouSpan = true; // Show Chikou Span +input bool showSenkouSpanA = true; // Show Senkou Span A +input bool showSenkouSpanB = true; // Show Senkou Span B +input bool showKumo = true; // Show Kumo +input bool shiftKumo = true; // Shift Kumo to Future + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 15 +#property indicator_plots 8 + +// +// PLOTTED Buffers ... + +// +// ICHIMOKU ... + +// +// TENKANSEN ... + +// +#define tenkanSenBufferIndex 0 +double tenkanSenBuffer[]; + +// +#property indicator_label1 "XICH TK" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// KIJUNSEN ... + +// +#define kijunSenBufferIndex 1 +double kijunSenBuffer[]; + +// +#property indicator_label2 "XICH KJ" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDodgerBlue +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#define kijunSenPlusBufferIndex 2 +double kijunSenPlusBuffer[]; + +// +#property indicator_label3 "XICH KJ+" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrMediumTurquoise +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define kijunSenNegativeBufferIndex 3 +double kijunSenNegativeBuffer[]; + +// +#property indicator_label4 "XICH KJ-" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrDarkSeaGreen +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CHIKOUSPAN ... + +// +#define chikouSpanBufferIndex 4 +double chikouSpanBuffer[]; + +// +#property indicator_label5 "XICH CS" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrDarkGreen +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +#define senkouABufferIndex 5 +double senkouABuffer[]; + +// +#property indicator_label6 "XICH SSA" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrLightGray +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +#define senkouBBufferIndex 6 +double senkouBBuffer[]; + +// +#property indicator_label7 "XICH SSB" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLightGray +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// KUMO ... + +// +// SENKOUSPANA ... + +// +#define senkouSpanABufferIndex 7 +double senkouSpanABuffer[]; + +// +// SENKOUSPANB ... + +// +#define senkouSpanBBufferIndex 8 +double senkouSpanBBuffer[]; + +// +// KUMOCLOUD ... + +// +#define kumoBufferIndex 7 + +// +#property indicator_label8 "XICH Kumo" +#property indicator_type8 DRAW_FILLING +#property indicator_color8 clrAqua, clrMagenta +#property indicator_style8 STYLE_SOLID +#property indicator_width8 1 + +// +// DATA Buffers ... + +// +#define dTenkanBufferIndex 9 +double dTenkanBuffer[]; + +// +#define dKijunBufferIndex 10 +double dKijunBuffer[]; + +// +#define dChikouBufferIndex 11 +double dChikouBuffer[]; + +// +#define dSSABufferIndex 12 +double dSSABuffer[]; + +// +#define dSSBBufferIndex 13 +double dSSBBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; +int mHandler; + +// +ENUM_SERIESMODE mTenkanSenTopMode = NULL; +ENUM_SERIESMODE mTenkanSenBottomMode = NULL; + +// +ENUM_SERIESMODE mKijunSenTopMode = NULL; +ENUM_SERIESMODE mKijunSenBottomMode = NULL; + +// +ENUM_SERIESMODE mSenkouSpanBTopMode = NULL; +ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Init Handler ... + mHandler = iIchimoku( + _Symbol, + _Period, + tenkanSenLength, + kijunSenLength, + senkouSpanBLength); + if (mHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 + + // + IndicatorRelease(mHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int ichCalculatedBars = BarsCalculated(mHandler); + if (ichCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedTenkans = CopyBuffer(mHandler, TENKANSEN_LINE, 0, limit, dTenkanBuffer); + int copiedKijuns = CopyBuffer(mHandler, KIJUNSEN_LINE, 0, limit, dKijunBuffer); + int copiedChikous = CopyBuffer(mHandler, CHIKOUSPAN_LINE, 0, limit, dChikouBuffer); + int copiedSSAs = CopyBuffer(mHandler, SENKOUSPANA_LINE, 0, limit, dSSABuffer); + int copiedSSBs = CopyBuffer(mHandler, SENKOUSPANB_LINE, 0, limit, dSSBBuffer); + if ( + copiedSSAs < 0 || + copiedSSBs < 0 || + copiedKijuns < 0 || + copiedTenkans < 0 || + copiedChikous < 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (tenkanSenLength > 2 && + kijunSenLength > tenkanSenLength && + senkouSpanBLength > kijunSenLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ichimoku ... + result = MathMax(result, tenkanSenLength); + result = MathMax(result, kijunSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // ICHIMOKU ... + + // + // TENKANSEN ... + + // + ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(tenkanSenBuffer, true); + SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType); + + // + // KIJUNSEN ... + + // + ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenBuffer, true); + SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType); + + // + // KIJUNSEN Plus ... + + // + ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenPlusBuffer, true); + SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType); + + // + // KIJUNSEN Negative ... + + // + ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenNegativeBuffer, true); + SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType); + + // + // CHIKOUSPAN ... + + // + ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(chikouSpanBuffer, true); + SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType); + + // + // SENKOUSPAN A and B ... + int shiftSize = shiftKumo ? kijunSenLength : 0; + + // + // SENKOUSPANA ... + ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouABuffer, true); + SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType); + + // + // SENKOUSPANB ... + ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouBBuffer, true); + SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType); + + // + // KUMO ... + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // KUMO ... + + // + ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE; + + // + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType); + + // + // DATA Buffers ... + + // + // D Tenkan ... + ArraySetAsSeries(dTenkanBuffer, true); + SetIndexBuffer(dTenkanBufferIndex, dTenkanBuffer, INDICATOR_CALCULATIONS); + + // + // D Kijun ... + ArraySetAsSeries(dKijunBuffer, true); + SetIndexBuffer(dKijunBufferIndex, dKijunBuffer, INDICATOR_CALCULATIONS); + + // + // D Chikou ... + ArraySetAsSeries(dChikouBuffer, true); + SetIndexBuffer(dChikouBufferIndex, dChikouBuffer, INDICATOR_CALCULATIONS); + + // + // D SSA ... + ArraySetAsSeries(dSSABuffer, true); + SetIndexBuffer(dSSABufferIndex, dSSABuffer, INDICATOR_CALCULATIONS); + + // + // D SSB ... + ArraySetAsSeries(dSSBBuffer, true); + SetIndexBuffer(dSSBBufferIndex, dSSBBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // ICHIMOKU ... + + // + double topValue; + double bottomValue; + + // + // TENKANSEN ... + + // + // Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ... + if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL) + { + // + switch (tenkanSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mTenkanSenTopMode = MODE_HIGH; + mTenkanSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mTenkanSenTopMode = MODE_OPEN; + mTenkanSenBottomMode = MODE_CLOSE; + break; + } + } + + // + XOHCL bar; + bar.Init( + _Symbol, + _Period, + bar_index + // + ); + + // + // Calculate Top ... + topValue = bar + .FindHighest( + tenkanSenLength, + mTenkanSenTopMode + // + ); + + // + // Calculate Bottom ... + bottomValue = bar + .FindLowest( + tenkanSenLength, + mTenkanSenBottomMode + // + ); + + // + double tenkanSenValue = (topValue + bottomValue) / 2; + tenkanSenBuffer[bar_index] = tenkanSenValue; + + // + // KIJUNSEN ... + + // + // Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ... + if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL) + { + // + switch (kijunSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mKijunSenTopMode = MODE_HIGH; + mKijunSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mKijunSenTopMode = MODE_OPEN; + mKijunSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = bar + .FindHighest( + kijunSenLength, + mKijunSenTopMode + // + ); + + // + // Calculate Bottom ... + bottomValue = bar + .FindLowest( + kijunSenLength, + mKijunSenBottomMode + // + ); + + // + double kijunSenValue = (topValue + bottomValue) / 2; + kijunSenBuffer[bar_index] = kijunSenValue; + + // + kijunSenPlusBuffer[bar_index] = kijunSenValue; + kijunSenNegativeBuffer[bar_index] = kijunSenValue; + + // + // CHIKOUSPAN ... + double chikouSpanValue = bar + .GetPrice(chikuoSpanAppliedTo); + + // + chikouSpanBuffer[bar_index] = chikouSpanValue; + + // + // KUMO ... + + // + // SENKOUSPANA ... + double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2; + senkouABuffer[bar_index] = senkouSpanAValue; + senkouSpanABuffer[bar_index] = senkouSpanAValue; + + // + // SENKOUSPANB ... + + // + // Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ... + if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL) + { + // + switch (senkouSpanBMode) + { + // + case X_XICH_HH_LL_MODE: + // + mSenkouSpanBTopMode = MODE_HIGH; + mSenkouSpanBBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mSenkouSpanBTopMode = MODE_OPEN; + mSenkouSpanBBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = bar + .FindHighest( + senkouSpanBLength, + mSenkouSpanBTopMode + // + ); + + // + // Calculate Bottom ... + bottomValue = bar + .FindLowest( + senkouSpanBLength, + mSenkouSpanBBottomMode + // + ); + + // + double senkouSpanBValue = (topValue + bottomValue) / 2; + senkouBBuffer[bar_index] = senkouSpanBValue; + senkouSpanBBuffer[bar_index] = senkouSpanBValue; +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xmc.mq5 b/Indicators/x-saherelm.xmc.mq5 new file mode 100644 index 00000000..ebcb8429 --- /dev/null +++ b/Indicators/x-saherelm.xmc.mq5 @@ -0,0 +1,469 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XMC MA Cross Indicator +// --------------------------------------------------- +// Name: XMC +// Description: Moving Average Crosses +// Market Analysor ... +// +// +// 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 XMC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XMC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Fast"; +input int fastMaLength = 9; // Length +input int fastMaShift = 0; // Shift +input ENUM_MA_METHOD fastMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE fastMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Slow"; +input int slowMaLength = 18; // Length +input int slowMaShift = 0; // Shift +input ENUM_MA_METHOD slowMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE slowMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Verifier"; +input int verifierMaLength = 50; // Length +input int verifierMaShift = 0; // Shift +input ENUM_MA_METHOD verifierMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE verifierMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow +input bool showVerifierMa = true; // Show Verifier + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// PLOTTED Buffers ... + +// +// MA ... + +// +// FAST ... +#define fastMaBufferIndex 0 +double fastMaBuffer[]; + +// +#property indicator_label1 "XMC MA F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrYellow +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// SLOW ... +#define slowMaBufferIndex 1 +double slowMaBuffer[]; + +// +#property indicator_label2 "XMC MA S" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDarkOrange +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// VERIFIER ... +#define verifierMaBufferIndex 2 +double verifierMaBuffer[]; + +// +#property indicator_label3 "XMC MA V" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrDarkBlue +#property indicator_style3 STYLE_SOLID +#property indicator_width3 2 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int fastMaHandler = INVALID_HANDLE; +int slowMaHandler = INVALID_HANDLE; +int verifierMaHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // MA Initialization ... + + // + // FAST ... + fastMaHandler = iMA( + _Symbol, + _Period, + fastMaLength, + fastMaShift, + fastMaMethod, + fastMaAppliedTo); + if (fastMaHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + return INIT_FAILED; + } + + // + // SLOW ... + slowMaHandler = iMA( + _Symbol, + _Period, + slowMaLength, + slowMaShift, + slowMaMethod, + slowMaAppliedTo); + if (slowMaHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + return INIT_FAILED; + } + + // + // VERIFIER ... + verifierMaHandler = iMA( + _Symbol, + _Period, + verifierMaLength, + verifierMaShift, + verifierMaMethod, + verifierMaAppliedTo); + if (verifierMaHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + 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 + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(fastMaHandler); + IndicatorRelease(slowMaHandler); + IndicatorRelease(verifierMaHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int fastMaCalculatedBars = BarsCalculated(fastMaHandler); + int slowMaCalculatedBars = BarsCalculated(slowMaHandler); + int verifierMaCalculatedBars = BarsCalculated(verifierMaHandler); + if (fastMaCalculatedBars < maxLength || + slowMaCalculatedBars < maxLength || + verifierMaCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFastMas = CopyBuffer(fastMaHandler, 0, 0, limit, fastMaBuffer); + int copiedSlowMas = CopyBuffer(slowMaHandler, 0, 0, limit, slowMaBuffer); + int copiedVerifierMas = CopyBuffer(verifierMaHandler, 0, 0, limit, verifierMaBuffer); + if (copiedFastMas <= 0 || + copiedSlowMas <= 0 || + copiedVerifierMas <= 0 + ) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + // Validate Ma ... + (fastMaLength > 2 && + slowMaLength > fastMaLength && + verifierMaLength > slowMaLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ma ... + result = MathMax(result, fastMaLength); + result = MathMax(result, slowMaLength); + result = MathMax(result, verifierMaLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // MA ... + + // + // FAST ... + ENUM_DRAW_TYPE fastMaDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastMaDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowMaDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowMaDrawType); + + // + // VERIFIER ... + ENUM_DRAW_TYPE verifierMaDrawType = showVerifierMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(verifierMaBuffer, true); + SetIndexBuffer(verifierMaBufferIndex, verifierMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_DRAW_TYPE, verifierMaDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xmrb.mq5 b/Indicators/x-saherelm.xmrb.mq5 new file mode 100644 index 00000000..3eb55e2b --- /dev/null +++ b/Indicators/x-saherelm.xmrb.mq5 @@ -0,0 +1,786 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------- +// Name: XMRB +// Description: Moving Average Ribbon +// +// +// 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 XMRB Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XMRB" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Ribbon 1"; +input int fast1Length = 3; // Fast +input int slow1Length = 5; // Slow + +// +input group "Ribbon 2"; +input int fast2Length = 8; // Fast +input int slow2Length = 13; // Slow + +// +input group "Ribbon 3"; +input int fast3Length = 21; // Fast +input int slow3Length = 34; // Slow + +// +input group "Ribbon 4"; +input int fast4Length = 55; // Fast +input int slow4Length = 89; // Slow + +// +input group "Ribbon 5"; +input int fast5Length = 144; // Fast +input int slow5Length = 233; // Slow + +// +input group "Calculation"; +input ENUM_MA_METHOD ribbonMode = MODE_EMA; // Mode +input ENUM_APPLIED_PRICE ribbonAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow +input bool showRibbon = false; // Show Ribbon + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 12 +#property indicator_plots 12 + +// +// PLOTTED Buffers ... + +// +// MA ... + +// +// FAST ... +#define fastMaBufferIndex 0 +double fastMaBuffer[]; + +// +#property indicator_label1 "XMRB F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// SLOW ... +#define slowMaBufferIndex 1 +double slowMaBuffer[]; + +// +#property indicator_label2 "XMRB S" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +// FAST ... + +// +#define fast1BufferIndex 2 +double fast1Buffer[]; + +// +#property indicator_label3 "XMRB 1 F" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrAquamarine +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define fast2BufferIndex 3 +double fast2Buffer[]; + +// +#property indicator_label4 "XMRB 2 F" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrAquamarine +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define fast3BufferIndex 4 +double fast3Buffer[]; + +// +#property indicator_label5 "XMRB 3 F" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAquamarine +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +#define fast4BufferIndex 5 +double fast4Buffer[]; + +// +#property indicator_label6 "XMRB 4 F" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAquamarine +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +#define fast5BufferIndex 6 +double fast5Buffer[]; + +// +#property indicator_label7 "XMRB 5 F" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrAquamarine +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// SLOW ... + +// +#define slow1BufferIndex 7 +double slow1Buffer[]; + +// +#property indicator_label8 "XMRB 1 S" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrPlum +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +#define slow2BufferIndex 8 +double slow2Buffer[]; + +// +#property indicator_label9 "XMRB 2 S" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrPlum +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define slow3BufferIndex 9 +double slow3Buffer[]; + +// +#property indicator_label10 "XMRB 3 S" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrPlum +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define slow4BufferIndex 10 +double slow4Buffer[]; + +// +#property indicator_label11 "XMRB 4 S" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrPlum +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define slow5BufferIndex 11 +double slow5Buffer[]; + +// +#property indicator_label12 "XMRB 5 S" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrPlum +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int fast1MaHandler = INVALID_HANDLE; +int fast2MaHandler = INVALID_HANDLE; +int fast3MaHandler = INVALID_HANDLE; +int fast4MaHandler = INVALID_HANDLE; +int fast5MaHandler = INVALID_HANDLE; + +// +int slow1MaHandler = INVALID_HANDLE; +int slow2MaHandler = INVALID_HANDLE; +int slow3MaHandler = INVALID_HANDLE; +int slow4MaHandler = INVALID_HANDLE; +int slow5MaHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize MAs ... + if (!InitializeMas()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(fast1MaHandler); + IndicatorRelease(fast2MaHandler); + IndicatorRelease(fast3MaHandler); + IndicatorRelease(fast4MaHandler); + IndicatorRelease(fast5MaHandler); + + // + IndicatorRelease(slow1MaHandler); + IndicatorRelease(slow2MaHandler); + IndicatorRelease(slow3MaHandler); + IndicatorRelease(slow4MaHandler); + IndicatorRelease(slow5MaHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + // + int fast1MaCalculatedBars = BarsCalculated(fast1MaHandler); + int fast2MaCalculatedBars = BarsCalculated(fast2MaHandler); + int fast3MaCalculatedBars = BarsCalculated(fast3MaHandler); + int fast4MaCalculatedBars = BarsCalculated(fast4MaHandler); + int fast5MaCalculatedBars = BarsCalculated(fast5MaHandler); + // + int slow1MaCalculatedBars = BarsCalculated(slow1MaHandler); + int slow2MaCalculatedBars = BarsCalculated(slow2MaHandler); + int slow3MaCalculatedBars = BarsCalculated(slow3MaHandler); + int slow4MaCalculatedBars = BarsCalculated(slow4MaHandler); + int slow5MaCalculatedBars = BarsCalculated(slow5MaHandler); + if ( + fast1MaCalculatedBars < maxLength || + fast2MaCalculatedBars < maxLength || + fast3MaCalculatedBars < maxLength || + fast4MaCalculatedBars < maxLength || + fast5MaCalculatedBars < maxLength || + slow1MaCalculatedBars < maxLength || + slow2MaCalculatedBars < maxLength || + slow3MaCalculatedBars < maxLength || + slow4MaCalculatedBars < maxLength || + slow5MaCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + // + int copiedFast1Mas = CopyBuffer(fast1MaHandler, 0, 0, limit, fast1Buffer); + int copiedFast2Mas = CopyBuffer(fast2MaHandler, 0, 0, limit, fast2Buffer); + int copiedFast3Mas = CopyBuffer(fast3MaHandler, 0, 0, limit, fast3Buffer); + int copiedFast4Mas = CopyBuffer(fast4MaHandler, 0, 0, limit, fast4Buffer); + int copiedFast5Mas = CopyBuffer(fast5MaHandler, 0, 0, limit, fast5Buffer); + // + int copiedSlow1Mas = CopyBuffer(slow1MaHandler, 0, 0, limit, slow1Buffer); + int copiedSlow2Mas = CopyBuffer(slow2MaHandler, 0, 0, limit, slow2Buffer); + int copiedSlow3Mas = CopyBuffer(slow3MaHandler, 0, 0, limit, slow3Buffer); + int copiedSlow4Mas = CopyBuffer(slow4MaHandler, 0, 0, limit, slow4Buffer); + int copiedSlow5Mas = CopyBuffer(slow5MaHandler, 0, 0, limit, slow5Buffer); + if ( + copiedFast1Mas <= 0 || + copiedFast2Mas <= 0 || + copiedFast3Mas <= 0 || + copiedFast4Mas <= 0 || + copiedFast5Mas <= 0 || + copiedSlow1Mas <= 0 || + copiedSlow2Mas <= 0 || + copiedSlow3Mas <= 0 || + copiedSlow4Mas <= 0 || + copiedSlow5Mas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (fast1Length > 2 && + fast2Length > fast1Length && + fast3Length > fast2Length && + fast4Length > fast3Length && + fast5Length > fast4Length && + slow1Length > fast1Length && + slow2Length > fast2Length && + slow3Length > fast3Length && + slow4Length > fast4Length && + slow5Length > fast5Length && + slow2Length > slow1Length && + slow3Length > slow2Length && + slow4Length > slow3Length && + slow5Length > slow4Length + // + ) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ma ... + + // + result = MathMax(fast1Length, fast2Length); + result = MathMax(result, fast3Length); + result = MathMax(result, fast4Length); + result = MathMax(result, fast5Length); + + // + result = MathMax(result, slow1Length); + result = MathMax(result, slow2Length); + result = MathMax(result, slow3Length); + result = MathMax(result, slow4Length); + result = MathMax(result, slow5Length); + + // + return result; +} + +// +// Initialize Ma Handlers ... +bool InitializeMas() +{ + // + bool result = false; + + // + fast1MaHandler = iMA( + _Symbol, + _Period, + fast1Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast2MaHandler = iMA( + _Symbol, + _Period, + fast2Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast3MaHandler = iMA( + _Symbol, + _Period, + fast3Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast4MaHandler = iMA( + _Symbol, + _Period, + fast4Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast5MaHandler = iMA( + _Symbol, + _Period, + fast5Length, + 0, + ribbonMode, + ribbonAppliedTo); + + // + slow1MaHandler = iMA( + _Symbol, + _Period, + slow1Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow2MaHandler = iMA( + _Symbol, + _Period, + slow2Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow3MaHandler = iMA( + _Symbol, + _Period, + slow3Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow4MaHandler = iMA( + _Symbol, + _Period, + slow4Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow5MaHandler = iMA( + _Symbol, + _Period, + slow5Length, + 0, + ribbonMode, + ribbonAppliedTo); + + // + result = + fast1MaHandler != INVALID_HANDLE && + fast2MaHandler != INVALID_HANDLE && + fast3MaHandler != INVALID_HANDLE && + fast4MaHandler != INVALID_HANDLE && + fast5MaHandler != INVALID_HANDLE && + slow1MaHandler != INVALID_HANDLE && + slow2MaHandler != INVALID_HANDLE && + slow3MaHandler != INVALID_HANDLE && + slow4MaHandler != INVALID_HANDLE && + slow5MaHandler != INVALID_HANDLE; + + // + if (!result) + { + // + string message = "Error Initializing Handlers ..."; + Print(message); + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // FAST ... + ENUM_DRAW_TYPE fastDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, showFastMa); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, showSlowMa); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowDrawType); + + // + // DATA ... + ENUM_DRAW_TYPE ribbonDrawType = showRibbon ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(fast1Buffer, true); + SetIndexBuffer(fast1BufferIndex, fast1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast2Buffer, true); + SetIndexBuffer(fast2BufferIndex, fast2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast3Buffer, true); + SetIndexBuffer(fast3BufferIndex, fast3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast4Buffer, true); + SetIndexBuffer(fast4BufferIndex, fast4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast5Buffer, true); + SetIndexBuffer(fast5BufferIndex, fast5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow1Buffer, true); + SetIndexBuffer(slow1BufferIndex, slow1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow2Buffer, true); + SetIndexBuffer(slow2BufferIndex, slow2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow3Buffer, true); + SetIndexBuffer(slow3BufferIndex, slow3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow4Buffer, true); + SetIndexBuffer(slow4BufferIndex, slow4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow5Buffer, true); + SetIndexBuffer(slow5BufferIndex, slow5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Retireve Values ... + + // + double fast1Value = fast1Buffer[bar_index]; + double fast2Value = fast2Buffer[bar_index]; + double fast3Value = fast3Buffer[bar_index]; + double fast4Value = fast4Buffer[bar_index]; + double fast5Value = fast5Buffer[bar_index]; + + // + double slow1Value = slow1Buffer[bar_index]; + double slow2Value = slow2Buffer[bar_index]; + double slow3Value = slow3Buffer[bar_index]; + double slow4Value = slow4Buffer[bar_index]; + double slow5Value = slow5Buffer[bar_index]; + + // + double fastValue = (fast1Value + fast2Value + fast3Value + fast4Value + fast5Value) / 5; + fastMaBuffer[bar_index] = fastValue; + + // + double slowValue = (slow1Value + slow2Value + slow3Value + slow4Value + slow5Value) / 5; + slowMaBuffer[bar_index] = slowValue; +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xosc.mq5 b/Indicators/x-saherelm.xosc.mq5 new file mode 100644 index 00000000..ecf3a27b --- /dev/null +++ b/Indicators/x-saherelm.xosc.mq5 @@ -0,0 +1,721 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XOSC +// Description: provides some oscillator values +// as empty Indicator ... +// +// +// 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 X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XOSC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ATR ... +input group "ATR"; +input int atrLength = 14; // Length + +// +// RVI ... +// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "RVI"; +input int rviLength = 10; // Length + +// +// BULLPOWER ... +input group "Bulls Power"; +input int bullpLength = 13; // Length + +// +// BEARPOWER ... +input group "Bears Power"; +input int bearpLength = 13; // Length + +// +// VOLUME ... +input group "Volumes"; +input ENUM_APPLIED_VOLUME volumeAppliedTo = VOLUME_TICK; // Applied To + +// +// RSI ... +input group "RSI"; +input int rsiLength = 14; // Length +input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // Applied To + +// +// CCI ... +input group "CCI"; +input int cciLength = 14; // Length +input ENUM_APPLIED_PRICE cciAppliedTo = PRICE_TYPICAL; // Applied To + +// +// STDDEV ... +input group "Standard Deviation"; +input int stddevLength = 20; // Length +input int stddevShift = 0; // Shift +input ENUM_MA_METHOD stddevMethod = MODE_SMA; // Mode +input ENUM_APPLIED_PRICE stddevAppliedTo = PRICE_CLOSE; // AppliedTo + +// +// MOMENTUM ... +input group "Momentum"; +input int momentumLength = 14; // Length +input ENUM_APPLIED_PRICE momentumAppliedTo = PRICE_CLOSE; // Applied To + +// +// SAR ... +input group "SAR"; +input double sarStep = 0.02; // Step +input double sarMaximum = 0.2; // Maximum + +// +// MACD ... +// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "MACD"; +input int macdFastLength = 12; // Fast Length +input int macdSlowLength = 26; // Slow Length +input int macdSignaLength = 9; // Signal Length +input ENUM_APPLIED_PRICE macdAppliedTo = PRICE_CLOSE; // Applied To + +// +// STOCHASTIC ... +// The buffer numbers: 0 - MAIN_LINE, 1 - SIGNAL_LINE. +input group "Stochastic"; +input int stochKLength = 5; // K Length +input int stochDLength = 3; // D Length +input int stochSlowing = 3; // Slowing +input ENUM_MA_METHOD stochMaMethod = MODE_SMA; // Ma Method +input ENUM_STO_PRICE stochMode = STO_LOWHIGH; // Calculation Mode + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 15 +#property indicator_plots 0 + +// +// ATR ... +#define atrBufferIndex 0 +double atrBuffer[]; + +// +// RVI ... +#define rviMainBufferIndex 1 +#define rviSignalBufferIndex 2 +double rviMainBuffer[]; +double rviSignalBuffer[]; + +// +// BULLPOWER ... +#define bullPBufferIndex 3 +double bullPBuffer[]; + +// +// BEARPOWER ... +#define bearPBufferIndex 4 +double bearPBuffer[]; + +// +// VOLUME ... +#define volumeBufferIndex 5 +double volumeBuffer[]; + +// +// RSI ... +#define rsiBufferIndex 6 +double rsiBuffer[]; + +// +// CCI ... +#define cciBufferIndex 7 +double cciBuffer[]; + +// +// MOMENTUM ... +#define momentumBufferIndex 8 +double momentumBuffer[]; + +// +// SAR ... +#define sarBufferIndex 9 +double sarBuffer[]; + +// +// MACD ... +#define macdMainBufferIndex 10 +#define macdSignalBufferIndex 11 +double macdMainBuffer[]; +double macdSignalBuffer[]; + +// +// STOCHASTIC ... +#define stochMainBufferIndex 12 +#define stochSignalBufferIndex 13 +double stochMainBuffer[]; +double stochSignalBuffer[]; + +// +// STANDARDDEVIATION ... +#define stddevBufferIndex 14 +double stddevBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int atrHandler = INVALID_HANDLE; +int rviHandler = INVALID_HANDLE; +int bullPHandler = INVALID_HANDLE; +int bearPHandler = INVALID_HANDLE; +int volumeHandler = INVALID_HANDLE; +int rsiHandler = INVALID_HANDLE; +int cciHandler = INVALID_HANDLE; +int momentumHandler = INVALID_HANDLE; +int sarHandler = INVALID_HANDLE; +int macdHandler = INVALID_HANDLE; +int stochHandler = INVALID_HANDLE; +int stddevHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initializing Handlers ... + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + atrLength); + + // + // RVI ... + rviHandler = iRVI( + _Symbol, + _Period, + rviLength); + + // + // BULLSPOWER ... + bullPHandler = iBullsPower( + _Symbol, + _Period, + bullpLength); + + // + // BEARSPOWER ... + bearPHandler = iBearsPower( + _Symbol, + _Period, + bullpLength); + + // + // VOLUMES ... + volumeHandler = iVolumes( + _Symbol, + _Period, + volumeAppliedTo); + + // + // RSI ... + rsiHandler = iRSI( + _Symbol, + _Period, + rsiLength, + rsiAppliedTo); + + // + // CCI ... + cciHandler = iCCI( + _Symbol, + _Period, + cciLength, + cciAppliedTo); + + // + // MOMENTUM ... + momentumHandler = iMomentum( + _Symbol, + _Period, + momentumLength, + momentumAppliedTo); + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMaximum); + + // + // MACD ... + macdHandler = iMACD( + _Symbol, + _Period, + macdFastLength, + macdSlowLength, + macdSignaLength, + macdAppliedTo); + + // + // STOCHASTIC ... + stochHandler = iStochastic( + _Symbol, + _Period, + stochKLength, + stochDLength, + stochSlowing, + stochMaMethod, + stochMode); + + // + // STANDARDDEVIATION ... + stddevHandler = iStdDev( + _Symbol, + _Period, + stddevLength, + stddevShift, + stddevMethod, + stddevAppliedTo); + + // + bool isAllHandlersInit = + // + atrHandler != INVALID_HANDLE && + rviHandler != INVALID_HANDLE && + bullPHandler != INVALID_HANDLE && + bearPHandler != INVALID_HANDLE && + volumeHandler != INVALID_HANDLE && + rsiHandler != INVALID_HANDLE && + cciHandler != INVALID_HANDLE && + momentumHandler != INVALID_HANDLE && + sarHandler != INVALID_HANDLE && + macdHandler != INVALID_HANDLE && + stochHandler != INVALID_HANDLE && + stddevHandler != INVALID_HANDLE + // + ; + if (!isAllHandlersInit) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); + IndicatorRelease(rviHandler); + IndicatorRelease(bullPHandler); + IndicatorRelease(bearPHandler); + IndicatorRelease(volumeHandler); + IndicatorRelease(rsiHandler); + IndicatorRelease(cciHandler); + IndicatorRelease(momentumHandler); + IndicatorRelease(sarHandler); + IndicatorRelease(macdHandler); + IndicatorRelease(stochHandler); + IndicatorRelease(stddevHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int atrCalculatedBars = BarsCalculated(atrHandler); + int rviCalculatedBars = BarsCalculated(rviHandler); + int bullPCalculatedBars = BarsCalculated(bullPHandler); + int bearPCalculatedBars = BarsCalculated(bearPHandler); + int volumeCalculatedBars = BarsCalculated(volumeHandler); + int rsiCalculatedBars = BarsCalculated(rsiHandler); + int cciCalculatedBars = BarsCalculated(cciHandler); + int momentumCalculatedBars = BarsCalculated(momentumHandler); + int sarCalculatedBars = BarsCalculated(sarHandler); + int macdCalculatedBars = BarsCalculated(macdHandler); + int stochCalculatedBars = BarsCalculated(stochHandler); + int stddevCalculatedBars = BarsCalculated(stddevHandler); + + // + bool isCalculatedBarsPassed = + // + atrCalculatedBars >= maxLength && + rviCalculatedBars >= maxLength && + bullPCalculatedBars >= maxLength && + bearPCalculatedBars >= maxLength && + volumeCalculatedBars >= maxLength && + rsiCalculatedBars >= maxLength && + cciCalculatedBars >= maxLength && + momentumCalculatedBars >= maxLength && + sarCalculatedBars >= maxLength && + macdCalculatedBars >= maxLength && + stochCalculatedBars >= maxLength && + stddevCalculatedBars >= maxLength + // + ; + if (!isCalculatedBarsPassed) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int atrCopiedItems = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer); + int rviMainCopiedItems = CopyBuffer(rviHandler, MAIN_LINE, 0, limit, rviMainBuffer); + int rviSignalCopiedItems = CopyBuffer(rviHandler, SIGNAL_LINE, 0, limit, rviSignalBuffer); + int bullPCopiedItems = CopyBuffer(bullPHandler, 0, 0, limit, bullPBuffer); + int bearPCopiedItems = CopyBuffer(bearPHandler, 0, 0, limit, bearPBuffer); + int volumeCopiedItems = CopyBuffer(volumeHandler, 0, 0, limit, volumeBuffer); + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + int cciCopiedItems = CopyBuffer(cciHandler, 0, 0, limit, cciBuffer); + int momentumCopiedItems = CopyBuffer(momentumHandler, 0, 0, limit, momentumBuffer); + int sarCopiedItems = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); + int macdMainCopiedItems = CopyBuffer(macdHandler, MAIN_LINE, 0, limit, macdMainBuffer); + int macdSignalCopiedItems = CopyBuffer(macdHandler, SIGNAL_LINE, 0, limit, macdSignalBuffer); + int stochMainCopiedItems = CopyBuffer(stochHandler, MAIN_LINE, 0, limit, stochMainBuffer); + int stocSignalhCopiedItems = CopyBuffer(stochHandler, SIGNAL_LINE, 0, limit, stochSignalBuffer); + int stddevCopiedItems = CopyBuffer(stddevHandler, 0, 0, limit, stddevBuffer); + + // + bool isCopiedBarsPassed = + // + atrCopiedItems > 0 && + rviMainCopiedItems > 0 && + rviSignalCopiedItems > 0 && + bullPCopiedItems > 0 && + bearPCopiedItems > 0 && + volumeCopiedItems > 0 && + rsiCopiedItems > 0 && + cciCopiedItems > 0 && + momentumCopiedItems > 0 && + sarCopiedItems > 0 && + macdMainCopiedItems > 0 && + macdSignalCopiedItems > 0 && + stochMainCopiedItems > 0 && + stocSignalhCopiedItems > 0 && + stddevCopiedItems > 0 + // + ; + if (!isCopiedBarsPassed) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + // HERE We Do Not anything ... + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + atrLength >= 2 && + rviLength >= 2 && + bullpLength >= 2 && + bearpLength >= 2 && + rsiLength >= 2 && + cciLength >= 2 && + momentumLength >= 2 && + sarStep > 0 && + sarStep < sarMaximum && + macdFastLength >= 2 && + macdSlowLength > macdFastLength && + macdSignaLength >= 2 && + stochKLength >= 2 && + stochDLength >= 2 && + stochSlowing >= 2 && + stddevLength >= 2 && + stddevShift >= 0 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(atrLength, rviLength); + result = MathMax(result, bullpLength); + result = MathMax(result, bearpLength); + result = MathMax(result, rsiLength); + result = MathMax(result, cciLength); + result = MathMax(result, momentumLength); + result = MathMax(result, macdFastLength); + result = MathMax(result, macdSlowLength); + result = MathMax(result, macdSignaLength); + result = MathMax(result, stochKLength); + result = MathMax(result, stochDLength); + result = MathMax(result, stochSlowing); + result = MathMax(result, stddevLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // DATA Buffers ... + + // + // ATR ... + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // RVI ... + + // + // Main ... + ArraySetAsSeries(rviMainBuffer, true); + SetIndexBuffer(rviMainBufferIndex, rviMainBuffer, INDICATOR_CALCULATIONS); + + // + // Signal ... + ArraySetAsSeries(rviSignalBuffer, true); + SetIndexBuffer(rviSignalBufferIndex, rviSignalBuffer, INDICATOR_CALCULATIONS); + + // + // BULLPOWER ... + ArraySetAsSeries(bullPBuffer, true); + SetIndexBuffer(bullPBufferIndex, bullPBuffer, INDICATOR_CALCULATIONS); + + // + // BEARPOWER ... + ArraySetAsSeries(bearPBuffer, true); + SetIndexBuffer(bearPBufferIndex, bearPBuffer, INDICATOR_CALCULATIONS); + + // + // VOLUME ... + ArraySetAsSeries(volumeBuffer, true); + SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS); + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + + // + // CCI ... + ArraySetAsSeries(cciBuffer, true); + SetIndexBuffer(cciBufferIndex, cciBuffer, INDICATOR_CALCULATIONS); + + // + // MOMENTUM ... + ArraySetAsSeries(momentumBuffer, true); + SetIndexBuffer(momentumBufferIndex, momentumBuffer, INDICATOR_CALCULATIONS); + + // + // SAR ... + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_CALCULATIONS); + + // + // STANDARDDEVIATION ... + ArraySetAsSeries(stddevBuffer, true); + SetIndexBuffer(stddevBufferIndex, stddevBuffer, INDICATOR_CALCULATIONS); + + // + // MACD ... + + // + // Main ... + ArraySetAsSeries(macdMainBuffer, true); + SetIndexBuffer(macdMainBufferIndex, macdMainBuffer, INDICATOR_CALCULATIONS); + + // + // Signal ... + ArraySetAsSeries(macdSignalBuffer, true); + SetIndexBuffer(macdSignalBufferIndex, macdSignalBuffer, INDICATOR_CALCULATIONS); +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xpv.mq5 b/Indicators/x-saherelm.xpv.mq5 new file mode 100644 index 00000000..4e29dcc0 --- /dev/null +++ b/Indicators/x-saherelm.xpv.mq5 @@ -0,0 +1,1210 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XPV +// Description: Peaks and Vales ... +// +// +// 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 XPV Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "XPV" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Makret Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +input group "Fibonacci"; +input double fiboLevel1 = 0.236; // Fibio 1st Level +input double fiboLevel2 = 0.382; // Fibio 2st Level +input double fiboLevel3 = 0.5; // Fibio 3rd Level +input double fiboLevel4 = 0.618; // Fibio 4th Level +input double fiboLevel5 = 0.764; // Fibio 5th Level + +// +input group "Boundary Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showPeaksAndVales = true; // Show Peaks and Vales +input bool showLevels = false; // Show Levels +input bool showConsolidations = false; // Show Consolidations +input bool showFibo1Levels = false; // Show Fibo 1st Level +input bool showFibo2Levels = false; // Show Fibo 2nd Level +input bool showFibo3Levels = false; // Show Fibo 3rd Level +input bool showFibo4Levels = false; // Show Fibo 4th Level +input bool showFibo5Levels = false; // Show Fibo 5th Level + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 32 +#property indicator_plots 32 + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "XPV PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "XPV VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "XPV R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrAqua +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "XPV S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "XPV FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "XPV FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "XPV FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// FIBBO Level 4 ... + +// +#define fl4BufferIndex 12 +#define fl4BufferPlotIndex 7 +double fl4Buffer[]; + +// +#define fl4ColorBufferIndex 13 +double fl4ColorBuffer[]; + +// +#property indicator_label8 "XPV FL4" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrGold +#property indicator_style8 STYLE_DASHDOTDOT +#property indicator_width8 1 + +// +// FIBBO Level 5 ... + +// +#define fl5BufferIndex 14 +#define fl5BufferPlotIndex 8 +double fl5Buffer[]; + +// +#define fl5ColorBufferIndex 15 +double fl5ColorBuffer[]; + +// +#property indicator_label9 "XPV FL5" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 CLR_NONE, clrGold +#property indicator_style9 STYLE_DASHDOTDOT +#property indicator_width9 1 + +// +// LEVELS ... + +// +#define scHHBufferIndex 16 +#define scHHBufferPlotIndex 9 +double scHHBuffer[]; + +// +#define scHHColorBufferIndex 17 +double scHHColorBuffer[]; + +// +#property indicator_label10 "XPV SHH" +#property indicator_type10 DRAW_COLOR_LINE +#property indicator_color10 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +#define scLLBufferIndex 18 +#define scLLBufferPlotIndex 10 +double scLLBuffer[]; + +// +#define scLLColorBufferIndex 19 +double scLLColorBuffer[]; + +// +#property indicator_label11 "XPV SLL" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define mcHHBufferIndex 20 +#define mcHHBufferPlotIndex 11 +double mcHHBuffer[]; + +// +#define mcHHColorBufferIndex 21 +double mcHHColorBuffer[]; + +// +#property indicator_label12 "XPV MHH" +#property indicator_type12 DRAW_COLOR_LINE +#property indicator_color12 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define mcLLBufferIndex 22 +#define mcLLBufferPlotIndex 12 +double mcLLBuffer[]; + +// +#define mcLLColorBufferIndex 23 +double mcLLColorBuffer[]; + +// +#property indicator_label13 "XPV MLL" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define lcHHBufferIndex 24 +#define lcHHBufferPlotIndex 13 +double lcHHBuffer[]; + +// +#define lcHHColorBufferIndex 25 +double lcHHColorBuffer[]; + +// +#property indicator_label14 "XPV LHH" +#property indicator_type14 DRAW_COLOR_LINE +#property indicator_color14 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define lcLLBufferIndex 26 +#define lcLLBufferPlotIndex 14 +double lcLLBuffer[]; + +// +#define lcLLColorBufferIndex 27 +double lcLLColorBuffer[]; + +// +#property indicator_label15 "XPV LLL" +#property indicator_type15 DRAW_COLOR_LINE +#property indicator_color15 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define hcHHBufferIndex 28 +#define hcHHBufferPlotIndex 15 +double hcHHBuffer[]; + +// +#define hcHHColorBufferIndex 29 +double hcHHColorBuffer[]; + +// +#property indicator_label16 "XPV HHH" +#property indicator_type16 DRAW_COLOR_LINE +#property indicator_color16 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +#define hcLLBufferIndex 30 +#define hcLLBufferPlotIndex 16 +double hcLLBuffer[]; + +// +#define hcLLColorBufferIndex 31 +double hcLLColorBuffer[]; + +// +#property indicator_label17 "XPV HLL" +#property indicator_type17 DRAW_COLOR_LINE +#property indicator_color17 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +double mHideColorIDX = 0; + +// +XMarketCycle sc; +double mLastSCHH = 0; +double mLastSCLL = 0; + +// +XMarketCycle mc; +double mLastMCHH = 0; +double mLastMCLL = 0; + +// +XMarketCycle lc; +double mLastLCHH = 0; +double mLastLCLL = 0; + +// +XMarketCycle hc; +double mLastHCHH = 0; +double mLastHCLL = 0; + +// +double lastPeak = 0; +double lastVale = 0; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... + // +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(sc.length, mc.length); + result = MathMax(result, lc.length); + result = MathMax(result, hc.length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // Buffer ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // Buffer ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // Buffer ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 4 ... + + // + // Buffer ... + ArraySetAsSeries(fl4Buffer, true); + SetIndexBuffer(fl4BufferIndex, fl4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_SHOW_DATA, showFibo4Levels); + + // + // Color ... + ArraySetAsSeries(fl4ColorBuffer, true); + SetIndexBuffer(fl4ColorBufferIndex, fl4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 5 ... + + // + // Buffer ... + ArraySetAsSeries(fl5Buffer, true); + SetIndexBuffer(fl5BufferIndex, fl5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_SHOW_DATA, showFibo5Levels); + + // + // Color ... + ArraySetAsSeries(fl5ColorBuffer, true); + SetIndexBuffer(fl5ColorBufferIndex, fl5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(scHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(scHHColorBuffer, true); + SetIndexBuffer(scHHColorBufferIndex, scHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(scLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(scLLColorBuffer, true); + SetIndexBuffer(scLLColorBufferIndex, scLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mcHHColorBuffer, true); + SetIndexBuffer(mcHHColorBufferIndex, mcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mcLLColorBuffer, true); + SetIndexBuffer(mcLLColorBufferIndex, mcLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lcHHColorBuffer, true); + SetIndexBuffer(lcHHColorBufferIndex, lcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lcLLColorBuffer, true); + SetIndexBuffer(lcLLColorBufferIndex, lcLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hcHHBuffer, true); + SetIndexBuffer(hcHHBufferIndex, hcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hcHHColorBuffer, true); + SetIndexBuffer(hcHHColorBufferIndex, hcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(hcLLBuffer, true); + SetIndexBuffer(hcLLBufferIndex, hcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hcLLColorBuffer, true); + SetIndexBuffer(hcLLColorBufferIndex, hcLLColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate Cycles ... + CalculateCycles(bar_index); + + // + // Calculate Peaks and Vales ... + CalculatePeaksAndVales(bar_index); + + // + // Calculate Fibonnaci ... + CalculateFibonacci(bar_index); +} + +// +// Custom ... + +// +// Initial Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Short ... + result = sc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_SHORT, + scMethod, + scPeriod + // + ); + if (!result) + { + return result; + } + + // + // Medium ... + result = mc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_MEDIUM, + mcMethod, + mcPeriod + // + ); + if (!result) + { + return result; + } + + // + // Long ... + result = lc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_LONG, + lcMethod, + lcPeriod + // + ); + if (!result) + { + return result; + } + + // + // Hind ... + result = hc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_HIND, + hcMethod, + hcPeriod + // + ); + + // + return result; +} + +// +// Calculate Specified Cycles HH and LL ... +void CalculateCycle( + int barIndex, + XMarketCycle &cycle, + double &lastHH, + double &hhBuffer[], + double &hhColorBuffer[], + double &lastLL, + double &llBuffer[], + double &llColorBuffer[] // +) +{ + cycle.Update(barIndex); + + // + XOHCL bar; + bar.Init( + _Symbol, + _Period, + barIndex + // + ); + + // + double hhValue = bar.FindHighest( + cycle.length, + hhMode + // + ); + hhBuffer[barIndex] = hhValue; + + // + double hhColorIDX = + !showLevels + ? mHideColorIDX + : (hhValue == lastHH) + ? !showConsolidations + ? mHideColorIDX + : 1 + : hhValue > lastHH + ? 2 + : hhValue < lastHH + ? 3 + : mHideColorIDX; + hhColorBuffer[barIndex] = hhColorIDX; + + // + lastHH = hhValue; + + // + double llValue = bar.FindLowest( + cycle.length, + llMode + // + ); + llBuffer[barIndex] = llValue; + + // + double llColorIDX = + !showLevels + ? mHideColorIDX + : (llValue == lastLL) + ? !showConsolidations + ? mHideColorIDX + : 1 + : llValue > lastLL + ? 2 + : llValue < lastLL + ? 3 + : mHideColorIDX; + llColorBuffer[barIndex] = llColorIDX; + + // + lastLL = llValue; +} + +// +// Calculate Cycles Up and Down Boundaries ... +void CalculateCycles( + int barIndex // Bar Index +) +{ + // + // Short ... + CalculateCycle( + barIndex, + sc, + // + mLastSCHH, + scHHBuffer, + scHHColorBuffer, + // + mLastSCLL, + scLLBuffer, + scLLColorBuffer + // + ); + + // + // Medium ... + CalculateCycle( + barIndex, + mc, + // + mLastMCHH, + mcHHBuffer, + mcHHColorBuffer, + // + mLastMCLL, + mcLLBuffer, + mcLLColorBuffer + // + ); + + // + // Long ... + CalculateCycle( + barIndex, + lc, + // + mLastLCHH, + lcHHBuffer, + lcHHColorBuffer, + // + mLastLCLL, + lcLLBuffer, + lcLLColorBuffer + // + ); + + // + // Hind ... + CalculateCycle( + barIndex, + hc, + // + mLastHCHH, + hcHHBuffer, + hcHHColorBuffer, + // + mLastHCLL, + hcLLBuffer, + hcLLColorBuffer + // + ); +} + +// +// Calculate Peaks and Values ... +void CalculatePeaksAndVales( + int barIndex // Bar Index +) +{ + // + // Retrieve Requirements ... + + // + // Short ... + double scHHValue = scHHBuffer[barIndex]; + double scLLValue = scLLBuffer[barIndex]; + + // + // Medium ... + double mcHHValue = mcHHBuffer[barIndex]; + double mcLLValue = mcLLBuffer[barIndex]; + + // + // Long ... + double lcHHValue = lcHHBuffer[barIndex]; + double lcLLValue = lcLLBuffer[barIndex]; + + // + // Hind ... + double hcHHValue = hcHHBuffer[barIndex]; + double hcLLValue = hcLLBuffer[barIndex]; + + // + double rColorIDX = mHideColorIDX; + double sColorIDX = mHideColorIDX; + + // + // RESISTANCE ... + double rValue = (scHHValue + mcHHValue + lcHHValue + hcHHValue) / 4; + + // + // PEAKS ... + bool isPeak = rValue == hcHHValue && + hcHHValue == lcHHValue && + lcHHValue == mcHHValue && + mcHHValue == scHHValue; + + // + if (isPeak && lastPeak != rValue) + { + // + rColorIDX = 1; + lastPeak = rValue; + } + + // + // SUPPORT ... + double sValue = (scLLValue + mcLLValue + lcLLValue + hcLLValue) / 4; + + // + // VALES ... + bool isVale = sValue == hcLLValue && + hcLLValue == lcLLValue && + lcLLValue == mcLLValue && + mcLLValue == scLLValue; + + // + if (isVale && lastVale != sValue) + { + // + sColorIDX = 1; + + // + lastVale = sValue; + } + + // + rBuffer[barIndex] = rValue; + sBuffer[barIndex] = sValue; + peaksBuffer[barIndex] = lastPeak; + valesBuffer[barIndex] = lastVale; + + // + if (showPeaksAndVales) + { + // + rColorBuffer[barIndex] = rColorIDX; + sColorBuffer[barIndex] = sColorIDX; + } + else + { + // + rColorBuffer[barIndex] = mHideColorIDX; + sColorBuffer[barIndex] = mHideColorIDX; + } +} + +// +// Calculate Fibonacci Level 1 ... +void CalculateFibonacci( + int barIndex // Bar Index +) +{ + // + // Select Requirements ... + double upPrice = peaksBuffer[barIndex]; + double downPrice = valesBuffer[barIndex]; + + // + // Level 1 ... + double fibLevel1Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + // + // Level 2 ... + double fibLevel2Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + + // + // Level 3 ... + double fibLevel3Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + + // + // Level 4 ... + double fibLevel4Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel4, + 1); + + // + // Level 5 ... + double fibLevel5Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel5, + 1); + + // + fl1Buffer[barIndex] = fibLevel1Value; + fl2Buffer[barIndex] = fibLevel2Value; + fl3Buffer[barIndex] = fibLevel3Value; + fl4Buffer[barIndex] = fibLevel4Value; + fl5Buffer[barIndex] = fibLevel5Value; + + // + double fl1ColorIdx = showFibo1Levels ? 1 : mHideColorIDX; + double fl2ColorIdx = showFibo2Levels ? 1 : mHideColorIDX; + double fl3ColorIdx = showFibo3Levels ? 1 : mHideColorIDX; + double fl4ColorIdx = showFibo4Levels ? 1 : mHideColorIDX; + double fl5ColorIdx = showFibo5Levels ? 1 : mHideColorIDX; + + // + fl1ColorBuffer[barIndex] = fl1ColorIdx; + fl2ColorBuffer[barIndex] = fl2ColorIdx; + fl3ColorBuffer[barIndex] = fl3ColorIdx; + fl4ColorBuffer[barIndex] = fl4ColorIdx; + fl5ColorBuffer[barIndex] = fl5ColorIdx; +} + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.xsslc.mq5 b/Indicators/x-saherelm.xsslc.mq5 new file mode 100644 index 00000000..b94a7b41 --- /dev/null +++ b/Indicators/x-saherelm.xsslc.mq5 @@ -0,0 +1,437 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ---------------------------------------------------- +// Name: XSSLC +// Description: SSL Channel Indicator +// +// +// 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 XSSLC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "XSSLC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 36; // Length + +// +input group "Calculation"; +input ENUM_MA_METHOD method = MODE_SMA; // Method +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Applied To +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Applied To + +// +input group "Presentation"; +input bool showUp = true; // Show Up +input bool showDown = true; // Show Down + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 5 +#property indicator_plots 2 + +// +// PLOTTED Buffers ... + +// +#define upBufferIndex 0 +double upBuffer[]; + +// +#property indicator_label1 "XSSLC Up" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#define downBufferIndex 1 +double downBuffer[]; + +// +#property indicator_label2 "XSSLC Down" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +#define upMaBufferIndex 2 +double upMaBuffer[]; + +// +#define downMaBufferIndex 3 +double downMaBuffer[]; + +// +#define kpiBufferIndex 4 +double kpiBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int upHandler = INVALID_HANDLE; +int downHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize Requierd Handlers ... + upHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + upAppliedTo); + downHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + downAppliedTo); + if (upHandler == INVALID_HANDLE || downHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + Print(msg); + + // + 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 + + // + // Release Indicators ... + IndicatorRelease(upHandler); + IndicatorRelease(downHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int upCalculatedBars = BarsCalculated(upHandler); + int downCalculatedBars = BarsCalculated(downHandler); + if (upCalculatedBars < maxLength || + downCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedUps = CopyBuffer(upHandler, 0, 0, limit, upMaBuffer); + int copiedDowns = CopyBuffer(downHandler, 0, 0, limit, downMaBuffer); + if (copiedUps <= 0 || + copiedDowns <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, limit, rates_total, prev_calculated, close); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (length > 2) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP ... + + // + ENUM_DRAW_TYPE upDrawType = showUp ? DRAW_LINE : DRAW_NONE; + + + ArraySetAsSeries(upBuffer, true); + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_TYPE, upDrawType); + + // + // DOWN ... + + // + ENUM_DRAW_TYPE downDrawType = showDown ? DRAW_LINE : DRAW_NONE; + + + ArraySetAsSeries(downBuffer, true); + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downBufferIndex, PLOT_SHOW_DATA, showDown); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_TYPE, downDrawType); + + // + // DATA Buffers ... + + // + // UP MA ... + ArraySetAsSeries(upMaBuffer, true); + SetIndexBuffer(upMaBufferIndex, upMaBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN MA ... + ArraySetAsSeries(downMaBuffer, true); + SetIndexBuffer(downMaBufferIndex, downMaBuffer, INDICATOR_CALCULATIONS); + + // + // KPI ... + ArraySetAsSeries(kpiBuffer, true); + SetIndexBuffer(kpiBufferIndex, kpiBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int limit, + int ratesTotal, + int prevCalculated, + const double &close[]) +{ + // + double upMaValue = upMaBuffer[bar_index]; + double downMaValue = downMaBuffer[bar_index]; + + // + double closeValue = close[bar_index]; + + // + double kpiValue; + if (closeValue > upMaValue) { + kpiValue = 1; + } else if (closeValue < downMaValue) { + kpiValue = -1; + } else { + kpiValue = kpiBuffer[bar_index + 1]; + } + + // + kpiBuffer[bar_index] = kpiValue; + + // + double upValue = kpiValue < 0 ? downMaValue : upMaValue; + upBuffer[bar_index] = upValue; + + // + double downValue = kpiValue < 0 ? upMaValue : downMaValue; + downBuffer[bar_index] = downValue; +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xstr.mq5 b/Indicators/x-saherelm.xstr.mq5 new file mode 100644 index 00000000..90e6eeb9 --- /dev/null +++ b/Indicators/x-saherelm.xstr.mq5 @@ -0,0 +1,580 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XSTR +// Description: Super Trend Indicator ... +// +// +// 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 X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XSTR" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Market ... +input group "ATR"; +input int atrLength = 14; // Length +input double atrMultiplier = 3.0; // Multiplier +input ENUM_APPLIED_PRICE atrAppliedTo = PRICE_MEDIAN; // Applied To + +// +// Presentation ... +input group "Presentation"; +input bool showTrends = true; // Show Trends +input bool fillTrends = true; // Fill Trends + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 9 +#property indicator_plots 2 + +// +#define fillUpBufferIndex 0 +double fillUpBuffer[]; + +#define fillDownBufferIndex 1 +double fillDownBuffer[]; + +// +#define fillingPlotBufferIndex 0 + +// +#property indicator_label1 "XSTR Filling" +#property indicator_type1 DRAW_FILLING +#property indicator_color1 clrBisque, clrPaleGreen + +// +#define mainBufferIndex 2 +#define mainPlotBufferIndex 1 +double mainBuffer[]; + +// +#define mainColorBufferIndex 3 +double mainColorBuffer[]; + +// +#property indicator_label2 "XSTR" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style2 STYLE_DOT + +// +// DATA Buffers ... + +// +#define atrBufferIndex 4 +double atrBuffer[]; + +// +#define trendBufferIndex 5 +double trendBuffer[]; + +// +#define upBufferIndex 6 +double upBuffer[]; + +// +#define downBufferIndex 7 +double downBuffer[]; + +// +#define priceBufferIndex 8 +double priceBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int atrHandler = INVALID_HANDLE; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + atrHandler = iATR( + _Symbol, + _Period, + atrLength); + if (atrHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + int numOfRequiredAtrs; + if (prev_calculated > rates_total || prev_calculated < 0) + { + numOfRequiredAtrs = rates_total; + } + else + { + // + numOfRequiredAtrs = rates_total - prev_calculated; + if (prev_calculated > 0) + { + numOfRequiredAtrs++; + } + } + + // + // Checking for stop ... + if (IsStopped()) + { + return 0; + } + + // + // Check Number of items Copy or not ... + int copiedATRs = CopyBuffer(atrHandler, 0, 0, numOfRequiredAtrs, atrBuffer); + if (copiedATRs <= 0) + { + return 0; + } + + // + int limit; + + // + // checking for the limit start of calculation of an indicator ... + if (prev_calculated > rates_total || prev_calculated <= 0) + { + // + // starting index for calculation of all bars ... + limit = maxLength; + } + else + { + // + // starting number for calculation of new bars + limit = prev_calculated - 1; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + // Calculated Price ... + double price = getPrice( + atrAppliedTo, + open, + high, + low, + close, + i); + // price = (high[i] + low[i]) / 2; + priceBuffer[i] = price; + + // + double atr = atrBuffer[i]; + + // + // Up ... + upBuffer[i] = price + (atrMultiplier * atr); + + // + // Down ... + downBuffer[i] = price - (atrMultiplier * atr); + + // + if (close[i] > upBuffer[i - 1]) + { + // + trendBuffer[i] = 1; + if (trendBuffer[i - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[i] < downBuffer[i - 1]) + { + // + trendBuffer[i] = -1; + if (trendBuffer[i - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (trendBuffer[i - 1] == 1) + { + // + trendBuffer[i] = 1; + changeOfTrend = 0; + } + else if (trendBuffer[i - 1] == -1) + { + // + trendBuffer[i] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (trendBuffer[i] < 0 && trendBuffer[i - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (trendBuffer[i] > 0 && trendBuffer[i - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (trendBuffer[i] > 0 && downBuffer[i] < downBuffer[i - 1]) + { + downBuffer[i] = downBuffer[i - 1]; + } + + // + if (trendBuffer[i] < 0 && upBuffer[i] > upBuffer[i - 1]) + { + upBuffer[i] = upBuffer[i - 1]; + } + + // + if (startBearishTrend == 1) + { + upBuffer[i] = priceBuffer[i] + (atrMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + downBuffer[i] = priceBuffer[i] - (atrMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = 0; + mainColorBuffer[i] = colorIDX; + + // + if (trendBuffer[i] == 1) + { + // + mainBuffer[i] = downBuffer[i]; + if (changeOfTrend == 1) + { + mainBuffer[i - 1] = mainBuffer[i - 2]; + changeOfTrend = 0; + } + + // + colorIDX = 1; + } + else if (trendBuffer[i] == -1) + { + // + mainBuffer[i] = upBuffer[i]; + if (changeOfTrend == 1) + { + // + mainBuffer[i - 1] = mainBuffer[i - 2]; + changeOfTrend = 0; + } + + // + colorIDX = 2; + } + + // + if (showTrends) + { + mainColorBuffer[i] = colorIDX; + } + + // + // Filling ... + if (fillTrends) + { + // + fillUpBuffer[i] = mainBuffer[i]; + fillDownBuffer[i] = close[i]; + } + else + { + // + fillUpBuffer[i] = EMPTY_VALUE; + fillDownBuffer[i] = EMPTY_VALUE; + } + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + atrLength >= 2 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = atrLength; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PLOT Buffers ... + + // + // FILLINGS ... + SetIndexBuffer(fillUpBufferIndex, fillUpBuffer, INDICATOR_DATA); + SetIndexBuffer(fillDownBufferIndex, fillDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fillingPlotBufferIndex, PLOT_SHOW_DATA, false); + + // + // MAIN ... + SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mainPlotBufferIndex, PLOT_SHOW_DATA, showTrends); + SetIndexBuffer(mainColorBufferIndex, mainColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DATA Buffers ... + + // + // ATR ... + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // TREND ... + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_CALCULATIONS); + + // + // UP ... + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN ... + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS); + + // + // PRICE ... + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); +} + +// +// END Functions ... +// + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/Indicators/x-saherelm.xtm.mq5 b/Indicators/x-saherelm.xtm.mq5 index 7b924fbf..2ee52d1b 100644 --- a/Indicators/x-saherelm.xtm.mq5 +++ b/Indicators/x-saherelm.xtm.mq5 @@ -39,10 +39,18 @@ enum ENUM_X_XTM_STATES // // START Inputs ... // + +// +input group "Market"; input int maPeriod = 14; // Period input int maShift = 0; // Shift input ENUM_MA_METHOD maMethod = MODE_SMA; // Method input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showLine = true; // Show Line + // // END Inputs ... // @@ -72,7 +80,7 @@ double stateBuffer[]; #property indicator_label1 "XTM" #property indicator_type1 DRAW_COLOR_LINE -#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_color1 clrLime, clrGray, clrRed, CLR_NONE #property indicator_style1 STYLE_SOLID #property indicator_width1 1 // @@ -331,7 +339,7 @@ void CalculateBuffers(int bar_index) // // Set Ma Buffer Color Index ... - maColorBuffer[bar_index] = lineColorIndex; + maColorBuffer[bar_index] = showLine ? lineColorIndex : 3; // // Set State Buffer Value ... diff --git a/Indicators/x-saherelm.xzg.mq5 b/Indicators/x-saherelm.xzg.mq5 new file mode 100644 index 00000000..4a7ea22e --- /dev/null +++ b/Indicators/x-saherelm.xzg.mq5 @@ -0,0 +1,757 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XZG +// Description: Zogzag Implementation ... +// +// +// 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 XZG Indicator" +#property strict + +// +#define ShortName "XZG" + +// +// DEFINITIONS ... +enum ENUM_X_ZG_SEARCH_MODE +{ + X_ZG_SEARCH_EXTREMUM = 0, // searching for the first extremum + X_ZG_SEARCH_PEAK = 1, // searching for the next ZigZag peak + X_ZG_SEARCH_VALE = -1 // searching for the next ZigZag vale +}; + +// +// How to Calculate Up and Down Price ... +enum ENUM_X_ZG_PRICE_MODE +{ + // + X_ZG_PRICE_HIGH_LOW_MODE = 1, + X_ZG_PRICE_OPEN_CLOSE_MODE = 2, +}; + +// +// INPUT ... + +// +input int depth = 12; // Depth +input int deviation = 5; // Deviation +input int backStep = 3; // Back Step +input ENUM_X_ZG_PRICE_MODE mode = X_ZG_PRICE_HIGH_LOW_MODE; // Mode + +// +// BUFFERS ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 5 +#property indicator_plots 3 + +// +// ZigZag ... + +// +#define mainBufferIndex 0 +#define mainBufferPlotIndex 0 +double mainBuffer[]; + +// +#property indicator_label1 "XZG Main" +#property indicator_type1 DRAW_SECTION +#property indicator_color1 clrYellow +#property indicator_width1 2 + +// +// Highs ... + +// +// ZigZag Pointer or Line Indicator ... +#define arrowBufferIndex 1 +#define arrowBufferPlotIndex 1 +double arrowBuffer[]; + +// +#define arrowColorBufferIndex 2 +double arrowColorBuffer[]; + +// +#property indicator_label2 "XZG PV" +#property indicator_type2 DRAW_COLOR_ARROW +#property indicator_color2 clrAqua, clrMagenta +#property indicator_width2 1 + +// +#define highsBufferIndex 3 +double highsBuffer[]; + +// +// Lows ... + +// +#define lowsBufferIndex 4 +double lowsBuffer[]; + +// +// VARIABLES ... + +// +int mRecalc = 3; // Number of last extremes for recalculation + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // logTag = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[] // +) +{ + // + double mZGHigh[]; + double mZGLow[]; + if (mode == X_ZG_PRICE_OPEN_CLOSE_MODE) + { + // + ArrayCopy( + mZGHigh, + open + // + ); + + // + ArrayCopy( + mZGLow, + close + // + ); + } + else + { + // + ArrayCopy( + mZGHigh, + high + // + ); + + // + ArrayCopy( + mZGLow, + low + // + ); + } + + // + int zigZagResult = CalcukateZigZag( + prev_calculated, + rates_total, + mZGHigh, + mZGLow + // + ); + + // + if (zigZagResult != rates_total) + { + return zigZagResult; + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + depth > 0 && + deviation > 0 && + backStep > 0 + // + ; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Main ... + + // + SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mainBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(mainBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetDouble(mainBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Arrow ... + + // + SetIndexBuffer(arrowBufferIndex, arrowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_SHOW_DATA, true); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_DRAW_BEGIN, 0); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_ARROW, 159); + PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_ARROW_SHIFT, 0); + PlotIndexSetDouble(arrowBufferPlotIndex, PLOT_EMPTY_VALUE, 0); + + // + // Arrow Color ... + SetIndexBuffer(arrowColorBufferIndex, arrowColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Highs ... + SetIndexBuffer(highsBufferIndex, highsBuffer, INDICATOR_CALCULATIONS); + + // + // Lows ... + SetIndexBuffer(lowsBufferIndex, lowsBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculating Zig Zag ... +int CalcukateZigZag( + const int prev_calculated, + const int rates_total, + double &high[], + double &low[] + // +) +{ + // + if (rates_total < 100) + { + return 0; + } + + // + // Define Variables ... + int i = 0; + + // + int start = 0; + int extreme_counter = 0; + int extreme_search = X_ZG_SEARCH_EXTREMUM; + int shift = 0; + int back = 0; + int last_high_pos = 0; + int last_low_pos = 0; + + // + double val = 0; + double res = 0; + double curlow = 0; + double curhigh = 0; + double last_high = 0; + double last_low = 0; + + // + double colorIDX = 0; + double lastZigZagValue = 0; + + // + // Initializing ... + if (prev_calculated == 0) + { + // + ArrayInitialize(mainBuffer, 0); + ArrayInitialize(highsBuffer, 0); + ArrayInitialize(lowsBuffer, 0); + + // + start = depth; + } + + // + // Already Calculated Before ... + if (prev_calculated > 0) + { + // + i = rates_total - 1; + + // + // Searching for the third X_ZG_SEARCH_EXTREMUM from the last UnComplete Bar ... + while (extreme_counter < mRecalc && i > rates_total - 100) + { + // + res = mainBuffer[i]; + if (res != 0) + { + extreme_counter++; + } + + // + i--; + } + + // + i++; + start = i; + + // + // What type of X_ZG_SEARCH_EXTREMUM we Search for ... + if (lowsBuffer[i] != 0) + { + // + curlow = lowsBuffer[i]; + extreme_search = X_ZG_SEARCH_PEAK; + } + else + { + // + curhigh = highsBuffer[i]; + extreme_search = X_ZG_SEARCH_VALE; + } + + // + // Clear Values ... + for (i = start + 1; i < rates_total && !IsStopped(); i++) + { + // + mainBuffer[i] = 0; + lowsBuffer[i] = 0; + highsBuffer[i] = 0; + } + } + + // + // Search for High and Low Extremes ... + for (shift = start; shift < rates_total && !IsStopped(); shift++) + { + // + // Low ... + val = low[Lowest(low, depth, shift)]; + if (val == last_low) + { + val = 0; + } + else + { + // + last_low = val; + + // + if ((low[shift] - val) > deviation * _Point) + { + val = 0; + } + else + { + // + for (back = 1; back <= backStep; back++) + { + // + res = lowsBuffer[shift - back]; + if ((res != 0) && (res > val)) + { + lowsBuffer[shift - back] = 0; + } + } + } + } + + // + if (low[shift] == val) + { + lowsBuffer[shift] = val; + } + else + { + lowsBuffer[shift] = 0; + } + + // + // High ... + val = high[Highest(high, depth, shift)]; + if (val == last_high) + { + val = 0; + } + else + { + // + last_high = val; + + // + if ((val - high[shift]) > deviation * _Point) + { + val = 0; + } + else + { + // + for (back = 1; back <= backStep; back++) + { + // + res = highsBuffer[shift - back]; + if ((res != 0) && (res < val)) + { + highsBuffer[shift - back] = 0; + } + } + } + } + + // + if (high[shift] == val) + { + highsBuffer[shift] = val; + } + else + { + highsBuffer[shift] = 0; + } + } + + // + // Set Last Value ... + if (extreme_search == 0) // Undefined Values ... + { + // + last_low = 0; + last_high = 0; + } + else + { + // + last_low = curlow; + last_high = curhigh; + } + + // + // Final Selection of Extreme Points for ZigZag ... + for (shift = start; shift < rates_total && !IsStopped(); shift++) + { + // + res = 0; + + // + switch (extreme_search) + { + // + case X_ZG_SEARCH_EXTREMUM: + // + if (last_low == 0 && last_high == 0) + { + // + if (highsBuffer[shift] != 0) + { + // + last_high_pos = shift; + last_high = high[shift]; + + // + extreme_search = X_ZG_SEARCH_VALE; + + // + mainBuffer[shift] = last_high; + + // + res = 1; + } + + // + if (lowsBuffer[shift] != 0) + { + // + last_low_pos = shift; + last_low = low[shift]; + + // + extreme_search = X_ZG_SEARCH_PEAK; + + // + mainBuffer[shift] = last_low; + + // + res = 1; + } + } + break; + + // + case X_ZG_SEARCH_PEAK: + // + if (lowsBuffer[shift] != 0 && lowsBuffer[shift] < last_low && highsBuffer[shift] == 0) + { + // + mainBuffer[last_low_pos] = 0; + + // + last_low_pos = shift; + last_low = lowsBuffer[shift]; + + // + mainBuffer[shift] = last_low; + + // + res = 1; + } + + // + if (highsBuffer[shift] != 0 && lowsBuffer[shift] == 0) + { + // + last_high_pos = shift; + last_high = highsBuffer[shift]; + + // + mainBuffer[shift] = last_high; + + // + extreme_search = X_ZG_SEARCH_VALE; + + // + res = 1; + } + break; + + // + case X_ZG_SEARCH_VALE: + // + if (highsBuffer[shift] != 0 && highsBuffer[shift] > last_high && lowsBuffer[shift] == 0) + { + // + mainBuffer[last_high_pos] = 0; + + // + last_high_pos = shift; + last_high = highsBuffer[shift]; + + // + mainBuffer[shift] = last_high; + } + + // + if (lowsBuffer[shift] != 0 && highsBuffer[shift] == 0) + { + // + last_low_pos = shift; + last_low = lowsBuffer[shift]; + + // + mainBuffer[shift] = last_low; + + // + extreme_search = X_ZG_SEARCH_PEAK; + } + break; + } + + // + double iZigZagForColor = lastZigZagValue; + double iZigZag = mainBuffer[shift]; + if (iZigZag == 0 && lastZigZagValue != 0) + { + arrowBuffer[shift] = lastZigZagValue; + } + else if (iZigZag != 0) + { + // + lastZigZagValue = iZigZag; + arrowBuffer[shift] = lastZigZagValue; + } + + // + colorIDX = + lastZigZagValue > iZigZagForColor + ? 0 + : lastZigZagValue < iZigZagForColor + ? 1 + : colorIDX; + arrowColorBuffer[shift] = colorIDX; + } + + // + return rates_total; +} + +// +// TOOLS ... + +// +// Search for the index of the highest bar ... +int Highest( + const double &mArray[], + const int mDepth, + const int mStart // +) +{ + // + int result = 0; + + // + if (mStart < 0) + { + return result; + } + + // + double max = mArray[mStart]; + result = mStart; + + // + // Start searching ... + for (int i = mStart - 1; i > mStart - mDepth && i >= 0; i--) + { + // + if (mArray[i] > max) + { + // + result = i; + max = mArray[i]; + } + } + + // + // Return index of the highest bar + return result; +} + +// +// Search for the index of the lowest bar ... +int Lowest( + const double &mArray[], + const int mDepth, + const int mStart // +) +{ + // + int result = 0; + + // + if (mStart < 0) + { + return result; + } + + // + double min = mArray[mStart]; + result = mStart; + + // + // Start searching ... + for (int i = mStart - 1; i > mStart - mDepth && i >= 0; i--) + { + // + if (mArray[i] < min) + { + // + result = i; + min = mArray[i]; + } + } + + // + // Return index of the lowest bar + return result; +} diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 634b73b6..beaa20fa 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -18,7 +18,7 @@ #property link "https://www.saherelm.ir" #property version "1.00" #property strict -\ + // // Imports ... #include "../Classes/x-saherelm.xmd5.class.mq5" @@ -399,12 +399,6 @@ struct XOHCL // double result = 0; - // - if (mPType == NULL) - { - mPType = X_PRICE_CLOSE; - } - // if (!IsValid()) { @@ -438,7 +432,8 @@ struct XOHCL // // Retrieve Price base On Series Mode ... - double GetPrice(ENUM_SERIESMODE mMode) { + double GetPrice(ENUM_SERIESMODE mMode) + { // ENUM_X_PRICE mXMode = ToPrice(mMode); @@ -1029,9 +1024,6 @@ struct XOHCL return result; } - // - ENUM_X_PRICE pMode = ToPrice(mode); - // XOHCL iH; result = iH.Init( @@ -1046,7 +1038,7 @@ struct XOHCL } // - result = iH.GetPrice(pMode); + result = iH.GetPrice(mode); // return result; @@ -1111,9 +1103,6 @@ struct XOHCL return result; } - // - ENUM_X_PRICE pMode = ToPrice(mode); - // XOHCL iL; result = iL.Init( @@ -1128,7 +1117,7 @@ struct XOHCL } // - result = iL.GetPrice(pMode); + result = iL.GetPrice(mode); // return result; @@ -1890,6 +1879,30 @@ struct XMarketCycle return result; } + // + bool Init( + string mSymbol, // Trading Symbol + ENUM_TIMEFRAMES mHostPeriod, // Host Period + ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + ENUM_X_PERIOD_METHOD mMethod, // Period Selection Method + ENUM_TIMEFRAMES mPeriod, // Provided Period + string mPrefix = "" // Prefix + ) + { + // + this.period = mPeriod; + this.method = mMethod; + + // + return Init( + mSymbol, + mHostPeriod, + mCycle, + mPrefix + // + ); + } + // // Tools ... diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index c52370ba..fda76b6f 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -22,8 +22,7 @@ // // Imports ... #include -#include "../Libraries/x-saherelm.common.lib.mq5" -#include "../Classes/x-saherelm.xdata-collector.mq5" +#include "../Classes/x-saherelm.xdata-collector.class.mq5" // // Definitions ...