From 8278d132dd22bf1b1669272f16e3c4467fd3195e Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 26 Mar 2025 05:25:00 +0330 Subject: [PATCH] last ... --- Documents/BKP/x-pv.qween.ea.mq5 | 232 ++++ Documents/BKP/x-saherelm.x121.xich.mq5 | 846 +++++++++++++ Helpers/x-saherelm.x121.helper.mq5 | 296 ++++- Helpers/x-saherelm.x121.xich.helper.mq5 | 1061 +++++++++++++++++ Indicators/x-saherelm.x121.xich.mq5 | 625 ++++++++++ .../x-saherelm.common.extensions.lib.mq5 | 145 ++- Libraries/x-saherelm.x-enums.lib.mq5 | 63 + .../x-121.smc.market.cycle.helper.class.mq5 | 409 ++++++- .../Signals/x-121.smc.xwz.signal.lib.mq5 | 13 +- .../Strategy/x-121.smc.strategy.class.mq5 | 26 +- 10 files changed, 3686 insertions(+), 30 deletions(-) create mode 100644 Documents/BKP/x-pv.qween.ea.mq5 create mode 100644 Documents/BKP/x-saherelm.x121.xich.mq5 create mode 100644 Helpers/x-saherelm.x121.xich.helper.mq5 create mode 100644 Indicators/x-saherelm.x121.xich.mq5 diff --git a/Documents/BKP/x-pv.qween.ea.mq5 b/Documents/BKP/x-pv.qween.ea.mq5 new file mode 100644 index 00000000..683980d2 --- /dev/null +++ b/Documents/BKP/x-pv.qween.ea.mq5 @@ -0,0 +1,232 @@ +//+------------------------------------------------------------------+ +//| SaherElm IT Center MQL5 Expert Advisor | +//| | +//| Name: X121 XPV EA | +//| Description: Multi-Timeframe Peak & Vale Breakout Strategy | +//| Maintainer: Hadi Khazaee Asl | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Helpers/x-saherelm.x121.xpv.helper.mq5" + +// Input Parameters +input double RiskPercent = 1.0; // Risk per trade in percentage +input int StopLossPips = 50; // Stop Loss in pips +input int TakeProfitPips = 100; // Take Profit in pips +input bool UseTrailingStop = true; // Enable trailing stop +input int TrailingStopPips = 30; // Trailing stop distance in pips +input int MagicNumber = 123456; // Unique identifier for trades +input bool DebugMode = true; // Enable debug messages + +// +// Global Variables ... +X121XPVInputs mXPVInputs; +XCX121XPVHelper *mXPVHelper; + +//+------------------------------------------------------------------+ +//| Expert Initialization Function | +//+------------------------------------------------------------------+ +int OnInit() +{ + // + // Attach the X121 XPV indicator ... + mXPVInputs.Default(); + mXPVHelper = new XCX121XPVHelper(); + bool isInited = mXPVHelper.Init( + _Symbol, + _Period, + mXPVInputs // + ); + if (!isInited) + { + return INIT_FAILED; + } + + // + Print("X121 XPV EA Initialized."); + return INIT_SUCCEEDED; +} + +//+------------------------------------------------------------------+ +//| Expert Deinitialization Function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) +{ + // + mXPVInputs.Clean(); + ZeroMemory(mXPVHelper); + Print("X121 XPV EA Deinitialized."); +} + +//+------------------------------------------------------------------+ +//| Expert Tick Function | +//+------------------------------------------------------------------+ +void OnTick() +{ + // + // Check if there are open positions for this symbol + if (PositionSelect(_Symbol)) + { + ManageOpenPosition(); + return; + } + + // + X121XPVConditions pvConditions; + bool isRetrieved = mXPVHelper.GetConditions( + pvConditions, + 1 // + ); + if (!isRetrieved) + { + return; + } + + // + // Get indicator values + double peak = pvConditions.peaksBuffer[0]; + double vale = pvConditions.valesBuffer[0]; + double peakGoldenZone = pvConditions.peaksGoldenBuffer[0]; + double valeGoldenZone = pvConditions.valesGoldenBuffer[0]; + + // + // Validate indicator values + if (peak == EMPTY_VALUE || vale == EMPTY_VALUE || peakGoldenZone == EMPTY_VALUE || valeGoldenZone == EMPTY_VALUE) + { + // + if (DebugMode) + Print("Invalid indicator values. Skipping..."); + return; + } + + // + // Entry Conditions + double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); + double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Long Entry + if (bid > peak && bid > peakGoldenZone) + { + OpenTrade(ORDER_TYPE_BUY, peak, valeGoldenZone); + } + + // + // Short Entry + if (ask < vale && ask < valeGoldenZone) + { + OpenTrade(ORDER_TYPE_SELL, vale, peakGoldenZone); + } +} + +//+------------------------------------------------------------------+ +//| Open a Trade | +//+------------------------------------------------------------------+ +void OpenTrade(int orderType, double entryLevel, double targetLevel) +{ + // + double lotSize = CalculateLotSize(entryLevel, targetLevel); + double sl = (orderType == ORDER_TYPE_BUY) ? entryLevel - StopLossPips * Point() : entryLevel + StopLossPips * Point(); + double tp = (orderType == ORDER_TYPE_BUY) ? entryLevel + TakeProfitPips * Point() : entryLevel - TakeProfitPips * Point(); + + // + // Prepare trade request + MqlTradeRequest request = {}; + MqlTradeResult result = {}; + + // + request.action = TRADE_ACTION_DEAL; + request.symbol = _Symbol; + request.volume = lotSize; + request.type = (ENUM_ORDER_TYPE)orderType; + request.price = (orderType == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); + request.sl = sl; + request.tp = tp; + request.deviation = 10; + request.magic = MagicNumber; + + // + // Send trade request + if (!OrderSend(request, result)) + { + Print("Trade failed: ", result.retcode); + } + else + { + Print("Trade opened successfully."); + } +} + +//+------------------------------------------------------------------+ +//| Manage Open Position | +//+------------------------------------------------------------------+ +void ManageOpenPosition() +{ + ulong ticket = PositionGetInteger(POSITION_TICKET); + double currentPrice = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); + double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); + double sl = PositionGetDouble(POSITION_SL); + double tp = PositionGetDouble(POSITION_TP); + + // Trailing Stop Logic + if (UseTrailingStop) + { + double newSL = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + ? currentPrice - TrailingStopPips * Point() + : currentPrice + TrailingStopPips * Point(); + + if ((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && newSL > sl) || + (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && newSL < sl)) + { + ModifyPosition(ticket, newSL, tp); + } + } +} + +//+------------------------------------------------------------------+ +//| Modify Position | +//+------------------------------------------------------------------+ +void ModifyPosition(ulong ticket, double newSL, double newTP) +{ + MqlTradeRequest request = {}; + MqlTradeResult result = {}; + + request.action = TRADE_ACTION_SLTP; + request.position = ticket; + request.sl = newSL; + request.tp = newTP; + + if (!OrderSend(request, result)) + { + Print("Failed to modify position: ", result.retcode); + } + else + { + Print("Position modified successfully."); + } +} + +//+------------------------------------------------------------------+ +//| Calculate Lot Size | +//+------------------------------------------------------------------+ +double CalculateLotSize(double entryLevel, double targetLevel) +{ + double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100; + double stopLossDistance = MathAbs(entryLevel - targetLevel) / Point(); + double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); + double lotSize = riskAmount / (stopLossDistance * tickValue); + + // Normalize lot size + double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); + double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); + double stepLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); + + lotSize = MathFloor(lotSize / stepLot) * stepLot; + lotSize = MathMax(minLot, MathMin(maxLot, lotSize)); + + return lotSize; +} \ No newline at end of file diff --git a/Documents/BKP/x-saherelm.x121.xich.mq5 b/Documents/BKP/x-saherelm.x121.xich.mq5 new file mode 100644 index 00000000..02df92f6 --- /dev/null +++ b/Documents/BKP/x-saherelm.x121.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 "X121 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/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index 19f2286c..c0d0e265 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -28,6 +28,7 @@ #include "../Helpers/x-saherelm.x121.xche.helper.mq5" #include "../Helpers/x-saherelm.x121.xdon.helper.mq5" #include "../Helpers/x-saherelm.x121.xhk.helper.mq5" +#include "../Helpers/x-saherelm.x121.xich.helper.mq5" #include "../Helpers/x-saherelm.x121.xmas.helper.mq5" #include "../Helpers/x-saherelm.x121.xpv.helper.mq5" #include "../Helpers/x-saherelm.x121.xstr.helper.mq5" @@ -43,6 +44,7 @@ struct X121Inputs X121XCCInputs xccInputs; X121XPVInputs xpvInputs; X121XHKInputs xhkInputs; + X121XICHInputs xichInputs; X121XMASInputs xmasInputs; X121XATRInputs xatrInputs; X121XSTRInputs xstrInputs; @@ -70,6 +72,7 @@ struct X121Inputs xccInputs.Clean(); xpvInputs.Clean(); xhkInputs.Clean(); + xichInputs.Clean(); xmasInputs.Clean(); xatrInputs.Clean(); xstrInputs.Clean(); @@ -90,6 +93,7 @@ struct X121Inputs xccInputs.Default(); xpvInputs.Default(); xhkInputs.Default(); + xichInputs.Default(); xmasInputs.Default(); xatrInputs.Default(); xstrInputs.Default(); @@ -115,6 +119,7 @@ struct X121Inputs xccInputs.IsValid() && xpvInputs.IsValid() && xhkInputs.IsValid() && + xichInputs.IsValid() && xmasInputs.IsValid() && xatrInputs.IsValid() && xstrInputs.IsValid() && @@ -146,6 +151,7 @@ struct X121Inputs int xstrMax = xstrInputs.Max(); int xcheMax = xcheInputs.Max(); int xdonMax = xdonInputs.Max(); + int xichMax = xichInputs.Max(); int xvwapMax = xvwapInputs.Max(); // @@ -155,6 +161,7 @@ struct X121Inputs result = MathMax(result, xstrMax); result = MathMax(result, xcheMax); result = MathMax(result, xdonMax); + result = MathMax(result, xichMax); result = MathMax(result, xvwapMax); // @@ -203,12 +210,13 @@ struct X121Conditions double strUpBuffer[]; double downTBuffer[]; double masMidBuffer[]; - double masUpperBuffer[]; - double masLowerBuffer[]; double strDownBuffer[]; double vwapMidBuffer[]; double upTrendBuffer[]; double x3maMidBuffer[]; + double masUpperBuffer[]; + double masLowerBuffer[]; + double kijunSenBuffer[]; double le1StartBuffer[]; double se1StartBuffer[]; double le2StartBuffer[]; @@ -223,6 +231,7 @@ struct X121Conditions double x3maFastBuffer[]; double x3maSlowBuffer[]; double supportsBuffer[]; + double tenkanSenBuffer[]; double downTrendBuffer[]; double vwapPriceBuffer[]; double xhkRawLowBuffer[]; @@ -232,6 +241,9 @@ struct X121Conditions double xhkRawHighBuffer[]; double xhkSMCloseBuffer[]; double vwapVolumeBuffer[]; + double chikouSpanBuffer[]; + double senkouSpanABuffer[]; + double senkouSpanBBuffer[]; double peaksGoldenBuffer[]; double valesGoldenBuffer[]; double xhkRawCloseBuffer[]; @@ -405,6 +417,19 @@ struct X121Conditions bool isRawHKSwitchedToBearish; bool isRawHKSwitchedToBullish; + // + // XICH ... + + // + bool isSenkouSpanAOverB; + bool isSenkouSpanAUnderB; + bool isTenkanSenOverKijunSen; + bool isTenkanSenUnderKijunSen; + bool isSenkouSpanACrossedOverB; + bool isSenkouSpanACrossedUnderB; + bool isTenkanSenCrossedOverKijunSen; + bool isTenkanSenCrossedUnderKijunSen; + // // Complex Conditions ... @@ -568,15 +593,20 @@ struct X121Conditions Clean(x3maFastBuffer); Clean(x3maSlowBuffer); Clean(supportsBuffer); + Clean(kijunSenBuffer); + Clean(tenkanSenBuffer); Clean(downTrendBuffer); Clean(vwapPriceBuffer); Clean(xhkRawLowBuffer); Clean(xhkSMOpenBuffer); Clean(xhkSMHighBuffer); + Clean(chikouSpanBuffer); Clean(xhkRawOpenBuffer); Clean(xhkRawHighBuffer); Clean(xhkSMCloseBuffer); Clean(vwapVolumeBuffer); + Clean(senkouSpanABuffer); + Clean(senkouSpanBBuffer); Clean(peaksGoldenBuffer); Clean(valesGoldenBuffer); Clean(xhkRawCloseBuffer); @@ -649,15 +679,20 @@ struct X121Conditions ArraySetAsSeries(x3maFastBuffer, true); ArraySetAsSeries(x3maSlowBuffer, true); ArraySetAsSeries(supportsBuffer, true); + ArraySetAsSeries(kijunSenBuffer, true); + ArraySetAsSeries(tenkanSenBuffer, true); ArraySetAsSeries(downTrendBuffer, true); ArraySetAsSeries(vwapPriceBuffer, true); ArraySetAsSeries(xhkRawLowBuffer, true); ArraySetAsSeries(xhkSMOpenBuffer, true); ArraySetAsSeries(xhkSMHighBuffer, true); + ArraySetAsSeries(chikouSpanBuffer, true); ArraySetAsSeries(xhkRawOpenBuffer, true); ArraySetAsSeries(xhkRawHighBuffer, true); ArraySetAsSeries(xhkSMCloseBuffer, true); ArraySetAsSeries(vwapVolumeBuffer, true); + ArraySetAsSeries(senkouSpanABuffer, true); + ArraySetAsSeries(senkouSpanBBuffer, true); ArraySetAsSeries(peaksGoldenBuffer, true); ArraySetAsSeries(valesGoldenBuffer, true); ArraySetAsSeries(xhkRawCloseBuffer, true); @@ -867,6 +902,17 @@ struct X121Conditions isSMHKSwitchedToBullish = false; isRawHKSwitchedToBullish = false; + // + // XICH ... + isSenkouSpanAOverB = false; + isSenkouSpanAUnderB = false; + isTenkanSenOverKijunSen = false; + isTenkanSenUnderKijunSen = false; + isSenkouSpanACrossedOverB = false; + isSenkouSpanACrossedUnderB = false; + isTenkanSenCrossedOverKijunSen = false; + isTenkanSenCrossedUnderKijunSen = false; + // // Complex Conditions ... @@ -1396,6 +1442,41 @@ struct X121Conditions bearishScore += highScore; } + // + // XICH ... + if (isSenkouSpanAOverB) + { + bullishScore += minScore; + } + if (isTenkanSenOverKijunSen) + { + bullishScore += minScore; + } + if (isSenkouSpanACrossedOverB) + { + bullishScore += highScore; + } + if (isTenkanSenCrossedOverKijunSen) + { + bullishScore += highScore; + } + if (isSenkouSpanAUnderB) + { + bearishScore += minScore; + } + if (isTenkanSenUnderKijunSen) + { + bearishScore += minScore; + } + if (isSenkouSpanACrossedUnderB) + { + bearishScore += highScore; + } + if (isTenkanSenCrossedUnderKijunSen) + { + bearishScore += highScore; + } + // // Complex Conditions ... @@ -1896,6 +1977,18 @@ struct X121Conditions ToString("isRawHKSwitchedToBullish", isRawHKSwitchedToBullish, ignoreFalseConditions, separator) + // "-----------------------" + separator + + "XICH ..." + separator + + "-----------------------" + separator + + ToString("isTenkanSenOverKijunSen", isTenkanSenOverKijunSen, ignoreFalseConditions, separator) + + ToString("isTenkanSenUnderKijunSen", isTenkanSenUnderKijunSen, ignoreFalseConditions, separator) + + ToString("isTenkanSenCrossedOverKijunSen", isTenkanSenCrossedOverKijunSen, ignoreFalseConditions, separator) + + ToString("isTenkanSenCrossedUnderKijunSen", isTenkanSenCrossedUnderKijunSen, ignoreFalseConditions, separator) + + ToString("isSenkouSpanAOverB", isSenkouSpanAOverB, ignoreFalseConditions, separator) + + ToString("isSenkouSpanAUnderB", isSenkouSpanAUnderB, ignoreFalseConditions, separator) + + ToString("isSenkouSpanACrossedOverB", isSenkouSpanACrossedOverB, ignoreFalseConditions, separator) + + ToString("isSenkouSpanACrossedUnderB", isSenkouSpanACrossedUnderB, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + "Slopes ..." + separator + "-----------------------" + separator + ToString("isRsiSlopeBullish", isRsiSlopeBullish, ignoreFalseConditions, separator) + @@ -1919,7 +2012,6 @@ struct X121Conditions ToString("isSarIncreased", isSarIncreased, ignoreFalseConditions, separator) + ToString("isSarDecreased", isSarDecreased, ignoreFalseConditions, separator) + ToString("isSarEqualsToPeak", isSarEqualsToPeak, ignoreFalseConditions, separator) + - ToString("isStrEqualsToPeak", isStrEqualsToPeak, ignoreFalseConditions, separator) + ToString("isStrEqualsToVale", isStrEqualsToVale, ignoreFalseConditions, separator) + ToString("isPeakOverAtrUpper", isPeakOverAtrUpper, ignoreFalseConditions, separator) + @@ -2025,6 +2117,7 @@ class XCX121Helper : public XCBase XCX121XCCHelper *xccHelper; XCX121XPVHelper *xpvHelper; XCX121XHKHelper *xhkHelper; + XCX121XICHHelper *xichHelper; XCX121XMASHelper *xmasHelper; XCX121XATRHelper *xatrHelper; XCX121XSTRHelper *xstrHelper; @@ -2048,6 +2141,7 @@ class XCX121Helper : public XCBase xccInputs.Clean(); xpvInputs.Clean(); xhkInputs.Clean(); + xichInputs.Clean(); xmasInputs.Clean(); xatrInputs.Clean(); xdonInputs.Clean(); @@ -2060,6 +2154,7 @@ class XCX121Helper : public XCBase delete xccHelper; delete xpvHelper; delete xhkHelper; + delete xichHelper; delete xmasHelper; delete xatrHelper; delete xstrHelper; @@ -2072,6 +2167,7 @@ class XCX121Helper : public XCBase ZeroMemory(xccHelper); ZeroMemory(xpvHelper); ZeroMemory(xhkHelper); + ZeroMemory(xichHelper); ZeroMemory(xmasHelper); ZeroMemory(xatrHelper); ZeroMemory(xstrHelper); @@ -2136,6 +2232,7 @@ class XCX121Helper : public XCBase xccInputs = inputs.xccInputs; xpvInputs = inputs.xpvInputs; xhkInputs = inputs.xhkInputs; + xichInputs = inputs.xichInputs; xmasInputs = inputs.xmasInputs; xatrInputs = inputs.xatrInputs; xstrInputs = inputs.xstrInputs; @@ -2212,6 +2309,19 @@ class XCX121Helper : public XCBase return result; } + // + // XICH ... + xichHelper = new XCX121XICHHelper(); + result = xichHelper.Init( + symbol, + period, + xichInputs // + ); + if (!result) + { + return result; + } + // // XSTR ... xstrHelper = new XCX121XSTRHelper(); @@ -2369,6 +2479,28 @@ class XCX121Helper : public XCBase return result; } + // + // XICH ... + bool GetICHConditions( + X121XICHConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = false; + + // + result = xichHelper.GetConditions( + conditions, + barIndex, + loopback // + ); + + // + return result; + } + // // XATR ... bool GetATRConditions( @@ -2507,6 +2639,7 @@ class XCX121Helper : public XCBase // xpvHelper.Free(); xhkHelper.Free(); + xichHelper.Free(); xmasHelper.Free(); xatrHelper.Free(); xstrHelper.Free(); @@ -2591,6 +2724,10 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + + // return result; } @@ -2604,6 +2741,30 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + + // + return result; + } + + // + // XICH ... + X121XICHConditions xichConditions; + result = GetICHConditions( + xichConditions, + barIndex, + loopback // + ); + if (!result) + { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + xichConditions.Clean(); + + // return result; } @@ -2617,6 +2778,13 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + xichConditions.Clean(); + xmasConditions.Clean(); + + // return result; } @@ -2630,6 +2798,14 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + xichConditions.Clean(); + xmasConditions.Clean(); + xatrConditions.Clean(); + + // return result; } @@ -2643,6 +2819,15 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + xichConditions.Clean(); + xmasConditions.Clean(); + xatrConditions.Clean(); + xstrConditions.Clean(); + + // return result; } @@ -2656,6 +2841,16 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + xichConditions.Clean(); + xmasConditions.Clean(); + xatrConditions.Clean(); + xstrConditions.Clean(); + xcheConditions.Clean(); + + // return result; } @@ -2669,6 +2864,17 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + xichConditions.Clean(); + xmasConditions.Clean(); + xatrConditions.Clean(); + xstrConditions.Clean(); + xcheConditions.Clean(); + xdonConditions.Clean(); + + // return result; } @@ -2682,6 +2888,18 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + xichConditions.Clean(); + xmasConditions.Clean(); + xatrConditions.Clean(); + xstrConditions.Clean(); + xcheConditions.Clean(); + xdonConditions.Clean(); + x3maConditions.Clean(); + + // return result; } @@ -2695,6 +2913,19 @@ class XCX121Helper : public XCBase ); if (!result) { + // + xpvConditions.Clean(); + xhkConditions.Clean(); + xichConditions.Clean(); + xmasConditions.Clean(); + xatrConditions.Clean(); + xstrConditions.Clean(); + xcheConditions.Clean(); + xdonConditions.Clean(); + x3maConditions.Clean(); + xvwapConditions.Clean(); + + // return result; } @@ -3340,6 +3571,61 @@ class XCX121Helper : public XCBase conditions.isVWapSwitchedToBullishOrdered = xvwapConditions.isVWapSwitchedToBullishOrdered; conditions.isVWapSwitchedToBearishOrdered = xvwapConditions.isVWapSwitchedToBearishOrdered; + // + // XICH ... + + // + // Buffers ... + + // + Copy( + xichConditions.kijunSenBuffer, + conditions.kijunSenBuffer // + ); + + // + Copy( + xichConditions.tenkanSenBuffer, + conditions.tenkanSenBuffer // + ); + + // + Copy( + xichConditions.chikouSpanBuffer, + conditions.chikouSpanBuffer // + ); + + // + Copy( + xichConditions.senkouSpanABuffer, + conditions.senkouSpanABuffer // + ); + + // + Copy( + xichConditions.senkouSpanBBuffer, + conditions.senkouSpanBBuffer // + ); + + // + // Conditions ... + + // + conditions.isTenkanSenOverKijunSen = xichConditions.isTenkanSenOverKijunSen; + conditions.isTenkanSenUnderKijunSen = xichConditions.isTenkanSenUnderKijunSen; + + // + conditions.isTenkanSenCrossedOverKijunSen = xichConditions.isTenkanSenCrossedOverKijunSen; + conditions.isTenkanSenCrossedUnderKijunSen = xichConditions.isTenkanSenCrossedUnderKijunSen; + + // + conditions.isSenkouSpanAOverB = xichConditions.isSenkouSpanAOverB; + conditions.isSenkouSpanAUnderB = xichConditions.isSenkouSpanAUnderB; + + // + conditions.isSenkouSpanACrossedOverB = xichConditions.isSenkouSpanACrossedOverB; + conditions.isSenkouSpanACrossedUnderB = xichConditions.isSenkouSpanACrossedUnderB; + // // Slopes ... @@ -3563,7 +3849,6 @@ class XCX121Helper : public XCBase double cheMin = GetMin(ches); double cheMax = GetMax(ches); - // bool isSarCrossedUnderPeak = conditions.sarBuffer[cIDX] < conditions.peaksBuffer[cIDX] && @@ -3808,9 +4093,11 @@ class XCX121Helper : public XCBase conditions.isStrLowerCrossedUnderDonLowLower = isStrLowerCrossedUnderDonLowLower; conditions.isStrUpperCrossedUnderDonHighUpper = isStrUpperCrossedUnderDonHighUpper; + // // xpvConditions.Clean(); xhkConditions.Clean(); + xichConditions.Clean(); xmasConditions.Clean(); xatrConditions.Clean(); xstrConditions.Clean(); @@ -3844,6 +4131,7 @@ class XCX121Helper : public XCBase X121XCCInputs xccInputs; X121XPVInputs xpvInputs; X121XHKInputs xhkInputs; + X121XICHInputs xichInputs; X121XMASInputs xmasInputs; X121XATRInputs xatrInputs; X121XDONInputs xdonInputs; diff --git a/Helpers/x-saherelm.x121.xich.helper.mq5 b/Helpers/x-saherelm.x121.xich.helper.mq5 new file mode 100644 index 00000000..ebb2a30e --- /dev/null +++ b/Helpers/x-saherelm.x121.xich.helper.mq5 @@ -0,0 +1,1061 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCX121XICHHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.x-helper.class.mq5" + +// +// Definitions ... + +// +// Definitions ... +enum ENUM_X121_XICH_BUFFERS +{ + X121_XICH_TENKANSEN_LINE = 0, + X121_XICH_KIJUNSEN_LINE = 1, + X121_XICH_CHIKOUSPAN_LINE = 2, + X121_XICH_SENKOUSPANA_LINE = 3, + X121_XICH_SENKOUSPANB_LINE = 4, +}; + +// +// Input Models ... +struct X121XICHInputs +{ + // + // Props ... + + // + // Market ... + ENUM_X_PRICE chikouSpanMode; // ChikouSpan Mode + int tenkanSenLength; // TenkanSen Length + ENUM_X_BOUNDARY_PRICE tenkanSenMode; // TencanSen Mode + int kijunSenLength; // KijunSen Length + ENUM_X_BOUNDARY_PRICE kijunSenMode; // KijunSen Mode + int senkouSpanBLength; // SenkouSpan B Length + ENUM_X_BOUNDARY_PRICE senkouSpanBMode; // SenkouSpan B Mode + + // + // Presentation ... + int startCalculationForLastBars; // Calculate Last n Bars + bool shiftKumo; // Shift Kumo + bool showTenkanSen; // Show TenkanSen + bool showKijunSen; // Show KijunSen + bool showChikouSpan; // Show ChikouSpan + bool showSenkouSpanA; // Show Senkou Span A + bool showSenkouSpanB; // Show Senkou Span B + bool showKumo; // Show Kumo + + // + // Constructor(s) ... + X121XICHInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + chikouSpanMode = X_PRICE_NONE; // ChikouSpan Mode + tenkanSenLength = 0; // TenkanSen Length + tenkanSenMode = X_BOUNDARY_PRICE_NONE; // TencanSen Mode + kijunSenLength = 0; // KijunSen Length + kijunSenMode = X_BOUNDARY_PRICE_NONE; // KijunSen Mode + senkouSpanBLength = 0; // SenkouSpan B Length + senkouSpanBMode = X_BOUNDARY_PRICE_NONE; // SenkouSpan B Mode + + // + // Presentation ... + startCalculationForLastBars = 0; // Calculate Last n Bars + shiftKumo = false; // Shift Kumo + showTenkanSen = false; // Show TenkanSen + showKijunSen = false; // Show KijunSen + showChikouSpan = false; // Show ChikouSpan + showSenkouSpanA = false; // Show Senkou Span A + showSenkouSpanB = false; // Show Senkou Span B + showKumo = false; // Show Kumo + + // + ZeroMemory(this); + } + + // + // Default ... + void Default() + { + // + // Market ... + chikouSpanMode = X_PRICE_CLOSE; // ChikouSpan Mode + tenkanSenLength = 9; // TenkanSen Length + tenkanSenMode = X_BOUNDARY_PRICE_HIGH_LOW; // TencanSen Mode + kijunSenLength = 26; // KijunSen Length + kijunSenMode = X_BOUNDARY_PRICE_HIGH_LOW; // KijunSen Mode + senkouSpanBLength = 52; // SenkouSpan B Length + senkouSpanBMode = X_BOUNDARY_PRICE_HIGH_LOW; // SenkouSpan B Mode + + // + // Presentation ... + startCalculationForLastBars = 1000; // Calculate Last n Bars + shiftKumo = true; // Shift Kumo + showTenkanSen = true; // Show TenkanSen + showKijunSen = true; // Show KijunSen + showChikouSpan = true; // Show ChikouSpan + showSenkouSpanA = true; // Show Senkou Span A + showSenkouSpanB = true; // Show Senkou Span B + showKumo = true; // Show Kumo + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + kijunSenLength > 0 && + tenkanSenLength > 0 && + senkouSpanBLength > 0 && + IsValid(kijunSenMode) && + IsValid(tenkanSenMode) && + IsValid(chikouSpanMode) && + IsValid(senkouSpanBMode) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(kijunSenLength, tenkanSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; + } +}; + +// +// Conditions ... +struct X121XICHConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + double kijunSenBuffer[]; + double tenkanSenBuffer[]; + double chikouSpanBuffer[]; + double senkouSpanABuffer[]; + double senkouSpanBBuffer[]; + + // + // Conditions ... + + // + bool isTenkanSenOverKijunSen; + bool isTenkanSenUnderKijunSen; + + // + bool isTenkanSenCrossedOverKijunSen; + bool isTenkanSenCrossedUnderKijunSen; + + // + bool isSenkouSpanAOverB; + bool isSenkouSpanAUnderB; + + // + bool isSenkouSpanACrossedOverB; + bool isSenkouSpanACrossedUnderB; + + // + // Constructor ... + X121XICHConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + // Commons ... + symbol = NULL; + period = NULL; + time = NULL; + + // + // Buffers ... + + // + Clean(kijunSenBuffer); + Clean(tenkanSenBuffer); + Clean(chikouSpanBuffer); + Clean(senkouSpanABuffer); + Clean(senkouSpanBBuffer); + + // + ArraySetAsSeries(kijunSenBuffer, true); + ArraySetAsSeries(tenkanSenBuffer, true); + ArraySetAsSeries(chikouSpanBuffer, true); + ArraySetAsSeries(senkouSpanABuffer, true); + ArraySetAsSeries(senkouSpanBBuffer, true); + + // + // Conditions ... + + // + isTenkanSenOverKijunSen = false; + isTenkanSenUnderKijunSen = false; + + // + isTenkanSenCrossedOverKijunSen = false; + isTenkanSenCrossedUnderKijunSen = false; + + // + isSenkouSpanAOverB = false; + isSenkouSpanAUnderB = false; + + // + isSenkouSpanACrossedOverB = false; + isSenkouSpanACrossedUnderB = false; + + // + ZeroMemory(this); + } + + /** + * Generate Conditions Scores ... + * + * @param bullishScore: Double, Directional Scores Reference ... + * @param bearishScore: Double, Directional Scores Reference ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // TODO: Implement if Required ... + } + + /** + * Generate Summary String for Represent Conditions State ... + * + * @param onlyCommons: Boolean, Just Generate Only Commons Conditions ... + * @param onlyConditions: Boolean, Just Generate Only Conditions ... + * @param includeScores: Boolean, Attach Scores Representations on Result ... + * @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ... + * @param separator: String, Separate Lines ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + ToString("isTenkanSenOverKijunSen", isTenkanSenOverKijunSen, ignoreFalseConditions, separator) + + ToString("isTenkanSenUnderKijunSen", isTenkanSenUnderKijunSen, ignoreFalseConditions, separator) + + ToString("isTenkanSenCrossedOverKijunSen", isTenkanSenCrossedOverKijunSen, ignoreFalseConditions, separator) + + ToString("isTenkanSenCrossedUnderKijunSen", isTenkanSenCrossedUnderKijunSen, ignoreFalseConditions, separator) + + ToString("isSenkouSpanAOverB", isSenkouSpanAOverB, ignoreFalseConditions, separator) + + ToString("isSenkouSpanAUnderB", isSenkouSpanAUnderB, ignoreFalseConditions, separator) + + ToString("isSenkouSpanACrossedOverB", isSenkouSpanACrossedOverB, ignoreFalseConditions, separator) + + ToString("isSenkouSpanACrossedUnderB", isSenkouSpanACrossedUnderB, ignoreFalseConditions, separator) + + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + /** + * Retrieve nique Tag Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + return GetTypeName(this); + } + + // +}; + +// +// Class ... +class XCX121XICHHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCX121XICHHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCX121XICHHelper() + { + // + Clean(kijunSenBuffer); + Clean(tenkanSenBuffer); + Clean(chikouSpanBuffer); + Clean(senkouSpanABuffer); + Clean(senkouSpanBBuffer); + + // + mInputs.Clean(); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X121XICHInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + ArraySetAsSeries(kijunSenBuffer, true); + ArraySetAsSeries(tenkanSenBuffer, true); + ArraySetAsSeries(chikouSpanBuffer, true); + ArraySetAsSeries(senkouSpanABuffer, true); + ArraySetAsSeries(senkouSpanBBuffer, true); + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xich", + // + // Inputs ... + // + // Market ... + "", + mInputs.chikouSpanMode, // ChikouSpan Mode + mInputs.tenkanSenLength, // TenkanSen Length + mInputs.tenkanSenMode, // TencanSen Mode + mInputs.kijunSenLength, // KijunSen Length + mInputs.kijunSenMode, // KijunSen Mode + mInputs.senkouSpanBLength, // SenkouSpan B Length + mInputs.senkouSpanBMode, // SenkouSpan B Mode + // + // Presentation ... + "", + mInputs.startCalculationForLastBars, // Calculate Last n Bars + mInputs.shiftKumo, // Shift Kumo + mInputs.showTenkanSen, // Show TenkanSen + mInputs.showKijunSen, // Show KijunSen + mInputs.showChikouSpan, // Show ChikouSpan + mInputs.showSenkouSpanA, // Show Senkou Span A + mInputs.showSenkouSpanB, // Show Senkou Span B + mInputs.showKumo // Show Kumo + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X121XICHInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X121XICHInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Readers ... + + // + double GetTenkanSen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(tenkanSenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return tenkanSenBuffer[barIndex]; + } + + // + int CopyTenkanSen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + tenkanSenBuffer, + buffer, + forceClean + // + ); + } + + // + double GetKijunSen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(kijunSenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return kijunSenBuffer[barIndex]; + } + + // + int CopyKijunSen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + kijunSenBuffer, + buffer, + forceClean + // + ); + } + + // + double GetChikouSpan( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(chikouSpanBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return chikouSpanBuffer[barIndex]; + } + + // + int CopyChikouSpan( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + chikouSpanBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSenkouSpanA( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(senkouSpanABuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return senkouSpanABuffer[barIndex]; + } + + // + int CopySenkouSpanA( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + senkouSpanABuffer, + buffer, + forceClean + // + ); + } + + // + double GetSenkouSpanB( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(senkouSpanBBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return senkouSpanBBuffer[barIndex]; + } + + // + int CopySenkouSpanB( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + senkouSpanBBuffer, + buffer, + forceClean + // + ); + } + + // + void Free() override + { + Cleanup(10); + } + + // + bool GetConditions( + X121XICHConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + XOHCL zBar; + result = zBar.Init( + mSymbol, + mPeriod, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + mSymbol, + mPeriod, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + mSymbol, + mPeriod, + pIndex // + ); + if (!result) + { + return result; + } + + // + // Buffers ... + + // + CopyTenkanSen( + zIndex, + loopback, + conditions.tenkanSenBuffer // + ); + + // + CopyKijunSen( + zIndex, + loopback, + conditions.kijunSenBuffer // + ); + + // + CopyChikouSpan( + zIndex, + loopback, + conditions.chikouSpanBuffer // + ); + + // + CopySenkouSpanA( + zIndex, + loopback, + conditions.senkouSpanABuffer // + ); + + // + CopySenkouSpanB( + zIndex, + loopback, + conditions.senkouSpanBBuffer // + ); + + // + // Conditions ... + + // + int cIDX = 1; + int pIDX = cIDX + 1; + + // + bool isTenkanSenOverKijunSen = + conditions.tenkanSenBuffer[cIDX] > conditions.kijunSenBuffer[cIDX]; + bool isTenkanSenOverKijunSenPrev = + conditions.tenkanSenBuffer[pIDX] > conditions.kijunSenBuffer[pIDX]; + + // + bool isTenkanSenUnderKijunSen = + conditions.tenkanSenBuffer[cIDX] < conditions.kijunSenBuffer[cIDX]; + bool isTenkanSenUnderKijunSenPrev = + conditions.tenkanSenBuffer[pIDX] < conditions.kijunSenBuffer[pIDX]; + + // + bool isTenkanSenCrossedOverKijunSen = isTenkanSenOverKijunSen && + !isTenkanSenOverKijunSenPrev; + bool isTenkanSenCrossedUnderKijunSen = isTenkanSenUnderKijunSen && + !isTenkanSenUnderKijunSenPrev; + + // + bool isSenkouSpanAOverB = + conditions.senkouSpanABuffer[cIDX] > conditions.senkouSpanABuffer[cIDX]; + bool isSenkouSpanAOverBPrev = + conditions.senkouSpanABuffer[pIDX] > conditions.senkouSpanABuffer[pIDX]; + + // + bool isSenkouSpanAUnderB = + conditions.senkouSpanABuffer[cIDX] < conditions.senkouSpanABuffer[cIDX]; + bool isSenkouSpanAUnderBPrev = + conditions.senkouSpanABuffer[pIDX] < conditions.senkouSpanABuffer[pIDX]; + + // + bool isSenkouSpanACrossedOverB = isSenkouSpanAOverB && + !isSenkouSpanAOverBPrev; + bool isSenkouSpanACrossedUnderB = isSenkouSpanAUnderB && + !isSenkouSpanAUnderBPrev; + + // + conditions.isSenkouSpanAOverB = isSenkouSpanAOverB; + conditions.isSenkouSpanAUnderB = isSenkouSpanAUnderB; + conditions.isTenkanSenOverKijunSen = isTenkanSenOverKijunSen; + conditions.isTenkanSenUnderKijunSen = isTenkanSenUnderKijunSen; + conditions.isSenkouSpanACrossedOverB = isSenkouSpanACrossedOverB; + conditions.isSenkouSpanACrossedUnderB = isSenkouSpanACrossedUnderB; + conditions.isTenkanSenCrossedOverKijunSen = isTenkanSenCrossedOverKijunSen; + conditions.isTenkanSenCrossedUnderKijunSen = isTenkanSenCrossedUnderKijunSen; + + // + Cleanup(); + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X121XICHInputs mInputs; // Inputs ... + + // + // Buffers ... + double kijunSenBuffer[]; + double tenkanSenBuffer[]; + double chikouSpanBuffer[]; + double senkouSpanABuffer[]; + double senkouSpanBBuffer[]; + + // + void Calculate( + int maxRequiredBars = 100 // + ) + { + // + // Buffers ... + + // + CopyBuffer( + mHandler, + X121_XICH_KIJUNSEN_LINE, + 0, + maxRequiredBars, + kijunSenBuffer + // + ); + + // + CopyBuffer( + mHandler, + X121_XICH_TENKANSEN_LINE, + 0, + maxRequiredBars, + tenkanSenBuffer + // + ); + + // + CopyBuffer( + mHandler, + X121_XICH_CHIKOUSPAN_LINE, + 0, + maxRequiredBars, + chikouSpanBuffer + // + ); + + // + CopyBuffer( + mHandler, + X121_XICH_SENKOUSPANA_LINE, + 0, + maxRequiredBars, + senkouSpanABuffer + // + ); + + // + CopyBuffer( + mHandler, + X121_XICH_SENKOUSPANB_LINE, + 0, + maxRequiredBars, + senkouSpanBBuffer + // + ); + } + + // + void Cleanup( + int maxAllowed = 100 // + ) + { + // + CleanupArray( + kijunSenBuffer, + maxAllowed // + ); + + // + CleanupArray( + tenkanSenBuffer, + maxAllowed // + ); + + // + CleanupArray( + chikouSpanBuffer, + maxAllowed // + ); + + // + CleanupArray( + senkouSpanABuffer, + maxAllowed // + ); + + // + CleanupArray( + senkouSpanBBuffer, + maxAllowed // + ); + + // + } + + // +}; + +// +// Tools ... \ No newline at end of file diff --git a/Indicators/x-saherelm.x121.xich.mq5 b/Indicators/x-saherelm.x121.xich.mq5 new file mode 100644 index 00000000..fc2f459b --- /dev/null +++ b/Indicators/x-saherelm.x121.xich.mq5 @@ -0,0 +1,625 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XWZ +// Description: XWZ ... +// +// +// 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 XWZ Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121_XICH" + +// +// Imports ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input ENUM_X_PRICE chikouSpanMode = X_PRICE_CLOSE; // ChikouSpan Mode +input int tenkanSenLength = 9; // TenkanSen Length +input ENUM_X_BOUNDARY_PRICE tenkanSenMode = X_BOUNDARY_PRICE_HIGH_LOW; // TencanSen Mode +input int kijunSenLength = 26; // KijunSen Length +input ENUM_X_BOUNDARY_PRICE kijunSenMode = X_BOUNDARY_PRICE_HIGH_LOW; // KijunSen Mode +input int senkouSpanBLength = 52; // SenkouSpan B Length +input ENUM_X_BOUNDARY_PRICE senkouSpanBMode = X_BOUNDARY_PRICE_HIGH_LOW; // SenkouSpan B Mode + +// +// Presentation ... +input group "Presentation"; + +// +input int startCalculationForLastBars = 1000; // Calculate Last n Bars +input bool shiftKumo = true; // Shift Kumo +input bool showTenkanSen = true; // Show TenkanSen +input bool showKijunSen = true; // Show KijunSen +input bool showChikouSpan = true; // Show ChikouSpan +input bool showSenkouSpanA = true; // Show Senkou Span A +input bool showSenkouSpanB = true; // Show Senkou Span B +input bool showKumo = true; // Show Kumo + +// +// Buffers ... + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 6 + +// +// Plot Buffers ... + +// +#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 + +// +#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 chikouSpanBufferIndex 2 +double chikouSpanBuffer[]; + +// +#property indicator_label3 "XICH CS" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrDarkGreen +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +#define senkouSpanABufferIndex 3 +double senkouSpanABuffer[]; + +// +#property indicator_label4 "XICH SSA" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrLightGray +#property indicator_style4 STYLE_DASHDOTDOT +#property indicator_width4 1 + +// +#define senkouSpanBBufferIndex 4 +double senkouSpanBBuffer[]; + +// +#property indicator_label5 "XICH SSB" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrLightGray +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +#define senkouABufferIndex 5 +double senkouABuffer[]; + +// +#define senkouBBufferIndex 6 +double senkouBBuffer[]; + +// +#define kumoBufferIndex 5 + +// +#property indicator_label6 "XICH Kumo" +#property indicator_type6 DRAW_FILLING +#property indicator_color6 clrAqua, clrMagenta +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + +// +// Data Buffers ... + +// +int mLastBufferIndex = 6; + +// +// Variables, Properties and etc ... + +// +// this counts Available Bars ... +int limit; + +// +int maxLength; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +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(); + IndicatorSetInteger(INDICATOR_DIGITS, 2); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +/** + * De Initialize Indicator ... + * + * @param reason: Integer, De Initialization Reason ... + */ +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 +} + +/** + * Calculate Bars ... + * + * @param rates_total: Integer, Total Bars on Chart ... + * @param prev_calculated: Integer, Total Calculated Bars on Charts ... + * @param time: DateTime Array, History of Open Time ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param low: Double Array, History of Low Prices ... + * @param close: Double Array, History of Close Prices ... + * @param tick_volume: Long, History of Tick Volumes on Bar ... + * @param volume: Long, History of Trade Volumes ... + * @param spread: Double, History of Spread Price ... + * + * @return ( int ) + */ +int OnCalculate( + const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + 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); + + // + 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, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + kijunSenLength > 0 && + tenkanSenLength > 0 && + senkouSpanBLength > 0 && + IsValid(kijunSenMode) && + IsValid(tenkanSenMode) && + IsValid(chikouSpanMode) && + IsValid(senkouSpanBMode) + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(kijunSenLength, tenkanSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; +} + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + 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); + + // + 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); + + // + 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); + + // + int shiftSize = shiftKumo ? kijunSenLength : 0; + + // + ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(senkouSpanABuffer, true); + SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType); + + // + ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(senkouSpanBBuffer, true); + SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType); + + // + ArraySetAsSeries(senkouABuffer, true); + SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + ArraySetAsSeries(senkouBBuffer, true); + SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + 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); +} + +/** + * Calculate Custom Buffers ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + * @param tickVolume: Long, History of Tick Volumes on Bar ... + */ +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[], + const long &tickVolume[] // +) +{ + // + int barsLimit = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : 0; + // + // bool canCalculate = true; + bool canCalculate = + barsLimit == 0 || + bar_index <= barsLimit; + if (canCalculate) + { + // + CalculateValues( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + } + else + { + FillBuffersZero(bar_index); + } +} + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + senkouABuffer[barIndex] = 0; + senkouBBuffer[barIndex] = 0; + kijunSenBuffer[barIndex] = 0; + tenkanSenBuffer[barIndex] = 0; + chikouSpanBuffer[barIndex] = 0; + senkouSpanABuffer[barIndex] = 0; + senkouSpanBBuffer[barIndex] = 0; +} + +/** + * Calculate Vales ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + * @param tickVolume: Long, History of Tick Volumes on Bar ... + */ +void CalculateValues( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double uppers[]; + double lowers[]; + + // + double uppersMax = 0; + double uppersMin = 0; + + // + double lowersMax = 0; + double lowersMin = 0; + + // + // Calculate ChikouSpan ... + double iChikouSpan = GetAppliedPrice( + _Symbol, + _Period, + bar_index, + chikouSpanMode // + ); + + // + // Calculate TenkanSen ... + GetPriceBoundary( + uppers, + lowers, + _Symbol, + _Period, + tenkanSenMode, + tenkanSenLength, + bar_index // + ); + + // + uppersMax = uppers[ArrayMaximum(uppers)]; + uppersMin = uppers[ArrayMinimum(uppers)]; + + // + lowersMax = lowers[ArrayMaximum(lowers)]; + lowersMin = lowers[ArrayMinimum(lowers)]; + + // + double iTenkanSen = (uppersMax + lowersMin) / 2; + + // + // Calculate KijunSen ... + GetPriceBoundary( + uppers, + lowers, + _Symbol, + _Period, + kijunSenMode, + kijunSenLength, + bar_index // + ); + + // + uppersMax = uppers[ArrayMaximum(uppers)]; + uppersMin = uppers[ArrayMinimum(uppers)]; + + // + lowersMax = lowers[ArrayMaximum(lowers)]; + lowersMin = lowers[ArrayMinimum(lowers)]; + + // + double iKijunSen = (uppersMax + lowersMin) / 2; + + // + // Calculate SenkouSpanB ... + GetPriceBoundary( + uppers, + lowers, + _Symbol, + _Period, + senkouSpanBMode, + senkouSpanBLength, + bar_index // + ); + + // + uppersMax = uppers[ArrayMaximum(uppers)]; + uppersMin = uppers[ArrayMinimum(uppers)]; + + // + lowersMax = lowers[ArrayMaximum(lowers)]; + lowersMin = lowers[ArrayMinimum(lowers)]; + + // + double iSenkouSpanB = (uppersMax + lowersMin) / 2; + + // + // Calculate SenkouSpanA ... + double iSenkouSpanA = (iTenkanSen + iKijunSen) / 2; + + // + // Setting Buffers ... + kijunSenBuffer[bar_index] = iKijunSen; + senkouABuffer[bar_index] = iSenkouSpanA; + senkouBBuffer[bar_index] = iSenkouSpanB; + tenkanSenBuffer[bar_index] = iTenkanSen; + chikouSpanBuffer[bar_index] = iChikouSpan; + senkouSpanABuffer[bar_index] = iSenkouSpanA; + senkouSpanBBuffer[bar_index] = iSenkouSpanB; +} + +// diff --git a/Libraries/x-saherelm.common.extensions.lib.mq5 b/Libraries/x-saherelm.common.extensions.lib.mq5 index c982c3e8..7e145ac1 100644 --- a/Libraries/x-saherelm.common.extensions.lib.mq5 +++ b/Libraries/x-saherelm.common.extensions.lib.mq5 @@ -306,6 +306,28 @@ ENUM_X_MARKET_CYCLES NormalizeCycle(ENUM_X_MARKET_CYCLES value) return value; } +/** + * Normalize Price Boundary ... + * + * @param value: ENUM_X_BOUNDARY_PRICE, Provided Boundary Mode ... + * + * @return ( ENUM_X_BOUNDARY_PRICE ) + */ +ENUM_X_BOUNDARY_PRICE NormalizeBoundary(ENUM_X_BOUNDARY_PRICE value) +{ + // + ENUM_X_BOUNDARY_PRICE result = value; + + // + if (!IsValid(result)) + { + result = X_BOUNDARY_PRICE_HIGH_LOW; + } + + // + return result; +} + /** * Normalize Integer Value ... * @@ -836,14 +858,14 @@ double GetPoints( /** * Converts Price to Point ... - * + * * @param price: double, price ... * @param mSymbol: string, Symbol ... - * + * * @return ( double ) */ double PriceToPoint( - double mPrice, // the price amount which required to calculate + double mPrice, // the price amount which required to calculate string mSymbol = NULL // Trading Symbol ) { @@ -5929,12 +5951,12 @@ double GetPipPrice( * @return ( double ) */ double GetAppliedPrice( - ENUM_X_PRICE mType, // Type of Price Selection - const double &mOpen[], // Open Prices - const double &mHigh[], // High Preices - const double &mLow[], // Low Prices - const double &mClose[], // Close Prices - int barIndex // Bar Index + ENUM_X_PRICE mType, // Type of Price Selection + const double &mOpen[], // Open Prices + const double &mHigh[], // High Preices + const double &mLow[], // Low Prices + const double &mClose[], // Close Prices + int barIndex // Bar Index ) { // @@ -6103,7 +6125,7 @@ double GetAppliedPrice( string mSymbol = NULL, // Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Period int barIndex = 0, // Bar Index - ENUM_X_PRICE mType = X_PRICE_CLOSE // Type of Price Selection, + ENUM_X_PRICE mType = X_PRICE_CLOSE // Type of Price Selection ) { // @@ -6177,7 +6199,7 @@ double GetAppliedPrice( string mSymbol = NULL, // Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Period datetime mTime = NULL, // Bar Time - ENUM_X_PRICE mType = X_PRICE_CLOSE // Type of Price Selection, + ENUM_X_PRICE mType = X_PRICE_CLOSE // Type of Price Selection ) { // @@ -6220,6 +6242,107 @@ double GetAppliedPrice( return result; } +/** + * Calculate Price Boundary ... + * + * @param upper: double collection reference, Upper Boundary ... + * @param lower: double collection reference, Lower Boundary ... + * @param mSymbol: string, Specified Symbol ... + * @param mPeriod: ENUM_TIMEFRAMES member, Specified PEriod ... + * @param mMode: ENUM_X_BOUNDARY_PRICE member, Specified Boundary Mode ... + * @param mLength: int, Loopback Length of Bondary ... + * @param barIndex: int, Specified Bar Index ... + * @return ( int ) + */ +int GetPriceBoundary( + double &upper[], // Upper Boundary + double &lower[], // Lower Boundary + string mSymbol = NULL, // Symbol + ENUM_TIMEFRAMES mPeriod = NULL, // Period + ENUM_X_BOUNDARY_PRICE mMode = NULL, // Boundary Mode + int mLength = 1, // Length + int barIndex = 0 // Bar Index +) +{ + // + int result = 0; + + // + Clean(upper); + Clean(lower); + + // + // Normalize Args ... + mMode = NormalizeBoundary(mMode); + mSymbol = NormalizeSymbol(mSymbol); + mPeriod = NormalizePeriod(mPeriod); + mLength = NormalizeInt(mLength, 1); + barIndex = NormalizeInt(barIndex, 0); + + // + // Prepare Boundary Price Types ... + ENUM_X_PRICE upperType = + mMode == X_BOUNDARY_PRICE_UP_DOWN + ? X_PRICE_UP + : mMode == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_HIGH + : X_PRICE_NONE; + ENUM_X_PRICE lowerType = + mMode == X_BOUNDARY_PRICE_UP_DOWN + ? X_PRICE_DOWN + : mMode == X_BOUNDARY_PRICE_HIGH_LOW + ? X_PRICE_LOW + : X_PRICE_NONE; + + // + // Check Boundary Type Validation ... + bool isValid = IsValid(lowerType) && + IsValid(upperType); + if (!isValid) + { + return result; + } + + // + // Loop through Loopbacks ... + int start = barIndex + mLength; + int end = barIndex; + for (int i = start; i >= end; i--) + { + // + double iUpper = GetAppliedPrice( + mSymbol, + mPeriod, + i, + upperType // + ); + double iLower = GetAppliedPrice( + mSymbol, + mPeriod, + i, + lowerType // + ); + + // + Add( + iUpper, + upper // + ); + + // + Add( + iLower, + lower // + ); + } + + // + result = ArraySize(upper); + + // + return result; +} + // // END Price ... // diff --git a/Libraries/x-saherelm.x-enums.lib.mq5 b/Libraries/x-saherelm.x-enums.lib.mq5 index 64b18aef..9a08aafa 100644 --- a/Libraries/x-saherelm.x-enums.lib.mq5 +++ b/Libraries/x-saherelm.x-enums.lib.mq5 @@ -309,6 +309,69 @@ string ToString(ENUM_X_PRICE value) // END Price Type ... // +// +// START Boundary Price Type ... +// + +// +// Available Boundary Price Types ... +enum ENUM_X_BOUNDARY_PRICE +{ + X_BOUNDARY_PRICE_NONE, // None + X_BOUNDARY_PRICE_UP_DOWN, // Up/Down + X_BOUNDARY_PRICE_HIGH_LOW, // High/Low +}; + +/** + * Validate ... + * + * @param value: ENUM_X_BOUNDARY_PRICE member ... + * + * @return ( bool ) + */ +bool IsValid(ENUM_X_BOUNDARY_PRICE value) +{ + // + bool result = false; + + // + result = + value != NULL && + value != X_BOUNDARY_PRICE_NONE; + + // + return result; +} + +/** + * Converts To String ... + * + * @param value: ENUM_X_BOUNDARY_PRICE member ... + * + * @return ( string ) + */ +string ToString(ENUM_X_BOUNDARY_PRICE value) +{ + // + string result = NULL; + + // + if (!IsValid(value)) + { + value = X_BOUNDARY_PRICE_NONE; + } + + // + result = EnumToString(value); + + // + return result; +} + +// +// END Boundary Price Type ... +// + // // START Direction ... // diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index 1f69586e..7ef06fd6 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -3604,6 +3604,409 @@ struct X121SMCStrategyConditionParser // // Checking Other Conditions ... + // + // Checking Bar Based on Positions State ... + ENUM_X_DIRECTION iBarPosDir; + bool isBarValidForDir = cHelper + .mBarAnalyser + .IsValidForPosition( + cBar, + iBarPosDir // + ); + bool isBarValidForBullish = + isBarValidForDir && + IsBullish(iBarPosDir); + bool isBarValidForBearish = + isBarValidForDir && + IsBearish(iBarPosDir); + + // // + // // Continuation Bullish ... + // bool isContinuationBullish = + // // + // isBarValidForBullish && + // cXConditions.isSarBullish && + // cXConditions.isStrBullish && + // cXConditions.isNewPeakOverLast + // // + // ; + + // // + // // Continuation Bearish ... + // bool isContinuationBearish = + // // + // isBarValidForBearish && + // cXConditions.isSarBearish && + // cXConditions.isStrBearish && + // cXConditions.isNewValeUnderLast + // // + // ; + + // + XBoxZone obBox; + XBoxZone fvgBox; + XBoxZone supResBox; + XBoxZone tmpBoxes[]; + bool isBullishFVGRejected = false; + bool isBearishFVGRejected = false; + bool isFVGLowerBullishRejected = false; + bool isFVGUpperBullishRejected = false; + bool isFVGLowerBearishRejected = false; + bool isFVGUpperBearishRejected = false; + has = cState.HasFairValueGaps(); + if (has) + { + // + // Converts FairValueGaps to Box ... + ToBox( + cState.fairValueGaps, + tmpBoxes // + ); + + // + // Select FVG ... + while (HasChild(tmpBoxes)) + { + // + idx = GetYoungest(tmpBoxes); + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + XBoxZone iBox = tmpBoxes[idx]; + ArrayRemove( + tmpBoxes, + idx, + 1 // + ); + + // + isFVGLowerBullishRejected = + // + cBar.low < iBox.lower && + cBar.GetDown() > iBox.lower + // + ; + + // + isFVGUpperBullishRejected = + // + cBar.low < iBox.upper && + cBar.GetDown() > iBox.upper + // + ; + + // + isFVGLowerBearishRejected = + // + cBar.high > iBox.lower && + cBar.GetUp() < iBox.lower + // + ; + + // + isFVGUpperBearishRejected = + // + cBar.high > iBox.upper && + cBar.GetUp() < iBox.upper + // + ; + + // + // + + // + isBullishFVGRejected = + // + iBox.IsBullish() && + cBar.IsBullish() && + (isFVGLowerBullishRejected + // || isFVGUpperBullishRejected + ) + // + ; + + // + isBearishFVGRejected = + // + iBox.IsBearish() && + cBar.IsBearish() && + ( // isFVGLowerBearishRejected || + isFVGUpperBearishRejected) + // + ; + + // + has = isBullishFVGRejected || + isBearishFVGRejected; + if (has) + { + // + iBox.to = TimeCurrent(); + fvgBox = iBox; + iBox.Clean(); + break; + } + + // + iBox.Clean(); + } + Clean(tmpBoxes); + + // + // Select Order Block which FVG is Inside it ... + has = fvgBox.IsValid(); + if (has) + { + // + // Converts Order Blocks to Box ... + ToBox( + cState.orderBlocks, + tmpBoxes // + ); + + // + // Select Order Blocks ... + has = HasChild(tmpBoxes); + if (has) + { + // + while (HasChild(tmpBoxes)) + { + // + idx = GetYoungest(tmpBoxes); + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + XBoxZone iBox = tmpBoxes[idx]; + ArrayRemove( + tmpBoxes, + idx, + 1 // + ); + + // + // Validate Order Blocks ... + bool isSameDir = iBox.dir == fvgBox.dir; + bool isFVGInsideOB = IsBoxInsideOr( + fvgBox, + iBox // + ); + + // + has = + isSameDir && + isFVGInsideOB; + if (has) + { + // + iBox.to = TimeCurrent(); + obBox = iBox; + iBox.Clean(); + break; + } + + // + iBox.Clean(); + } + } + } + + // + has = obBox.IsValid(); + if (!has) + { + // + obBox.Clean(); + fvgBox.Clean(); + + // + isBullishFVGRejected = false; + isBearishFVGRejected = false; + isFVGLowerBullishRejected = false; + isFVGUpperBullishRejected = false; + isFVGLowerBearishRejected = false; + isFVGUpperBearishRejected = false; + } + Clean(tmpBoxes); + + // + // Checking Support nad Resistance ... + bool isDirBullish = + obBox.IsBullish() && + fvgBox.IsBullish(); + has = + obBox.IsValid() && + fvgBox.IsValid(); + if (has) + { + // + // Converts Support or Resistance to Boxes ... + if (isDirBullish) + { + // + ToBox( + cState.supportZones, + tmpBoxes // + ); + } + else + { + // + ToBox( + cState.resistanceZones, + tmpBoxes // + ); + } + + // + // Selecting Support nad Resistance ... + has = HasChild(tmpBoxes); + if (has) + { + // + while (HasChild(tmpBoxes)) + { + // + idx = GetYoungest(tmpBoxes); + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + XBoxZone iBox = tmpBoxes[idx]; + ArrayRemove( + tmpBoxes, + idx, + 1 // + ); + + // + // Validate Support and Resistane ... + bool isDirPassed = iBox.dir == obBox.dir; + bool isPlacePassed = + IsBoxAbove( + iBox, + fvgBox // + ) || + IsBoxAbove( + fvgBox, + iBox // + ) || + IsBoxInside( + iBox, + fvgBox // + ) || + IsBoxInside( + fvgBox, + iBox // + ); + + has = + isDirPassed && + isPlacePassed; + if (has) + { + // + iBox.to = TimeCurrent(); + supResBox = iBox; + iBox.Clean(); + break; + } + + // + iBox.Clean(); + } + } + + // + has = obBox.IsValid() && + fvgBox.IsValid() && + supResBox.IsValid(); + if (!has) + { + // + obBox.Clean(); + fvgBox.Clean(); + supResBox.Clean(); + + // + isBullishFVGRejected = false; + isBearishFVGRejected = false; + isFVGLowerBullishRejected = false; + isFVGUpperBullishRejected = false; + isFVGLowerBearishRejected = false; + isFVGUpperBearishRejected = false; + } + } + } + Clean(tmpBoxes); + + // + // Checking OB and FVG Validation ... + has = obBox.IsValid() && + fvgBox.IsValid() && + supResBox.IsValid(); + if (has) + { + // + // Draw OB ... + if (obBox.IsValid()) + { + // + XCBoxObject *iObj; + has = drawer.DrawBox( + obBox, + iObj // + ); + if (has) + { + iObj.BoxStyle(STYLE_DASH); + } + } + + // + // Draw FVG ... + if (fvgBox.IsValid()) + { + // + XCBoxObject *iObj; + has = drawer.DrawBox( + fvgBox, + iObj // + ); + if (has) + { + iObj.BoxStyle(STYLE_SOLID); + } + } + + // + // Draw Sup/Res Box ... + if (supResBox.IsValid()) + { + // + XCBoxObject *iObj; + has = drawer.DrawBox( + supResBox, + iObj // + ); + if (has) + { + iObj.BoxStyle(STYLE_DOT); + } + } + } + // // Bullish Conditions ... isBullish = @@ -3611,7 +4014,8 @@ struct X121SMCStrategyConditionParser // Base Condition ... ( // - false + // false + isBullishFVGRejected // ) // @@ -3624,7 +4028,8 @@ struct X121SMCStrategyConditionParser // Base Condition ... ( // - false + // false + isBearishFVGRejected // ) // diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 index be3bf839..ddbeaff3 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 @@ -1901,12 +1901,13 @@ struct X121SMCStrategyXWZWorkingZone barIndex = 0; } - // - result = IsValid(); - if (!result) - { - return result; - } + // + // TODO: Ignor Working Zone Validation ... + // result = IsValid(); + // if (!result) + // { + // return result; + // } // int idx = -1; diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index b1132fa9..df0f7169 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -768,6 +768,9 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy x121Inputs.x3maInputs.x3maMidMALength = 50; x121Inputs.x3maInputs.x3maSlowMALength = 200; + // + x121Inputs.xichInputs.shiftKumo = false; + // // x121Inputs.xcheInputs.cheLength = 14; // x121Inputs.xcheInputs.cheLoopback = 7; @@ -796,12 +799,12 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // // XPV ... - x121Inputs.xpvInputs.showSar = showAll || true; - x121Inputs.xpvInputs.showPeaks = showAll || true; - x121Inputs.xpvInputs.showVales = showAll || true; + x121Inputs.xpvInputs.showSar = showAll || false; + x121Inputs.xpvInputs.showPeaks = showAll || false; + x121Inputs.xpvInputs.showVales = showAll || false; x121Inputs.xpvInputs.showSupports = showAll || false; x121Inputs.xpvInputs.showResistances = showAll || false; - x121Inputs.xpvInputs.showGoldenZones = showAll || true; + x121Inputs.xpvInputs.showGoldenZones = showAll || false; // // XHK ... @@ -814,9 +817,9 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // XMAS ... // - x121Inputs.xmasInputs.showUpper = showAll || true; - x121Inputs.xmasInputs.showMid = showAll || true; - x121Inputs.xmasInputs.showLower = showAll || true; + x121Inputs.xmasInputs.showUpper = showAll || false; + x121Inputs.xmasInputs.showMid = showAll || false; + x121Inputs.xmasInputs.showLower = showAll || false; // // XATR ... @@ -855,6 +858,15 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy x121Inputs.x3maInputs.showX3MaMid = showAll || false; x121Inputs.x3maInputs.showX3MaSlow = showAll || false; + // + // XICH ... + x121Inputs.xichInputs.showTenkanSen = showAll || true; + x121Inputs.xichInputs.showKijunSen = showAll || true; + x121Inputs.xichInputs.showChikouSpan = showAll || false; + x121Inputs.xichInputs.showSenkouSpanA = showAll || true; + x121Inputs.xichInputs.showSenkouSpanB = showAll || true; + x121Inputs.xichInputs.showKumo = showAll || false; + // // Initialize Cycle Helpers ...