Backup Workspace ...

This commit is contained in:
2025-01-25 03:57:57 +03:30
parent 05c7493201
commit fe5c50066a
89 changed files with 139298 additions and 0 deletions
+580
View File
@@ -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 <typename T>
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);
}
+195
View File
@@ -0,0 +1,195 @@
//+------------------------------------------------------------------+
//| SuperTrend.mq5 |
//| Copyright 2011, FxGeek |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, FxGeek"
#property link " http://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 9
#property indicator_plots 2
#property indicator_label1 "Filling"
#property indicator_type1 DRAW_FILLING
#property indicator_color1 clrBisque, clrPaleGreen
#property indicator_label2 "SuperTrend"
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_color2 clrGreen, clrRed
input int Periode=10;
input double Multiplier=3;
input bool Show_Filling=true; // Show as DRAW_FILLING
double Filled_a[];
double Filled_b[];
double SuperTrend[];
double ColorBuffer[];
double Atr[];
double Up[];
double Down[];
double Middle[];
double trend[];
int atrHandle;
int changeOfTrend;
int flag;
int flagh;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Filled_a,INDICATOR_DATA);
SetIndexBuffer(1,Filled_b,INDICATOR_DATA);
SetIndexBuffer(2,SuperTrend,INDICATOR_DATA);
SetIndexBuffer(3,ColorBuffer,INDICATOR_COLOR_INDEX);
SetIndexBuffer(4,Atr,INDICATOR_CALCULATIONS);
SetIndexBuffer(5,Up,INDICATOR_CALCULATIONS);
SetIndexBuffer(6,Down,INDICATOR_CALCULATIONS);
SetIndexBuffer(7,Middle,INDICATOR_CALCULATIONS);
SetIndexBuffer(8,trend,INDICATOR_CALCULATIONS);
atrHandle=iATR(_Symbol,_Period,Periode);
//---
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
//---
int to_copy;
if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
else
{
to_copy=rates_total-prev_calculated;
if(prev_calculated>0) to_copy++;
}
if(IsStopped()) return(0); //Checking for stop flag
if(CopyBuffer(atrHandle,0,0,to_copy,Atr)<=0)
{
Print("Getting Atr is failed! Error",GetLastError());
return(0);
}
int first;
if(prev_calculated>rates_total || prev_calculated<=0) // checking for the first start of calculation of an indicator
{
first=Periode; // starting index for calculation of all bars
}
else
{
first=prev_calculated-1; // starting number for calculation of new bars
}
for(int i=first; i<rates_total && !IsStopped(); i++)
{
Middle[i]=(high[i]+low[i])/2;
Up[i] = Middle[i] +(Multiplier*Atr[i]);
Down[i]= Middle[i] -(Multiplier*Atr[i]);
if(close[i]>Up[i-1])
{
trend[i]=1;
if(trend[i-1]==-1) changeOfTrend=1;
}
else if(close[i]<Down[i-1])
{
trend[i]=-1;
if(trend[i-1]==1) changeOfTrend=1;
}
else if(trend[i-1]==1)
{
trend[i]=1;
changeOfTrend=0;
}
else if(trend[i-1]==-1)
{
trend[i]=-1;
changeOfTrend=0;
}
if(trend[i]<0 && trend[i-1]>0)
{
flag=1;
}
else
{
flag=0;
}
if(trend[i]>0 && trend[i-1]<0)
{
flagh=1;
}
else
{
flagh=0;
}
if(trend[i]>0 && Down[i]<Down[i-1])
Down[i]=Down[i-1];
if(trend[i]<0 && Up[i]>Up[i-1])
Up[i]=Up[i-1];
if(flag==1)
Up[i]=Middle[i]+(Multiplier*Atr[i]);
if(flagh==1)
Down[i]=Middle[i]-(Multiplier*Atr[i]);
//-- Draw the indicator
if(trend[i]==1)
{
SuperTrend[i]=Down[i];
if(changeOfTrend==1)
{
SuperTrend[i-1]=SuperTrend[i-2];
changeOfTrend=0;
}
ColorBuffer[i]=0.0;
}
else if(trend[i]==-1)
{
SuperTrend[i]=Up[i];
if(changeOfTrend==1)
{
SuperTrend[i-1]= SuperTrend[i-2];
changeOfTrend = 0;
}
ColorBuffer[i]=1.0;
}
if(Show_Filling)
{
Filled_a[i]= SuperTrend[i];
Filled_b[i]= close[i];
}else{
Filled_a[i]= EMPTY_VALUE;
Filled_b[i]= EMPTY_VALUE;
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
+319
View File
@@ -0,0 +1,319 @@
//
// Reading Previous Conditions ...
ENUM_XPOI_EVENTS consolidationPoiEventsPrev[];
ENUM_X_CYCLE_EVENTS consolidationCycleEventsPrev[];
X121SMCCycleConditions consolidationConditionsPrev;
result = consolidationCycleHelper.GetConditions(
consolidationCycleEventsPrev,
consolidationPoiEventsPrev,
consolidationConditionsPrev,
cIndex,
loopback //
);
if (!result)
{
return result;
}
//
X121SMCCycleConditions conditionState = consolidationConditions;
X121SMCCycleConditions conditionStatePrev = consolidationConditionsPrev;
//
XOHCL cCBar;
result = cCBar.Init(
conditionState.symbol,
conditionState.period,
cIndex //
);
if (!result)
{
return result;
}
//
XOHCL cPBar;
result = cCBar.GetPreviousBar(cPBar);
if (!result)
{
return result;
}
//
// Engulf ...
ENUM_X_DIRECTION cCBarEngulfDir;
bool isCCBarEngulfed = consolidationCycleHelper
.mBarAnalyser
.IsEngulfBar(
cCBar,
cCBarEngulfDir,
0 // Extended ...
);
bool isCCBarBullishEngulfed =
isCCBarEngulfed &&
IsBullish(cCBarEngulfDir);
bool isCCBarBearishEngulfed =
isCCBarEngulfed &&
IsBearish(cCBarEngulfDir);
//
// Momentum ...
ENUM_X_DIRECTION cCBarMomentumDir;
bool isCCBarMomentum = consolidationCycleHelper
.mBarAnalyser
.IsMomentumBar(
cCBar,
cCBarMomentumDir,
1 // Extended ...
);
bool isCCBarBullishMomentum =
isCCBarMomentum &&
IsBullish(cCBarMomentumDir);
bool isCCBarBearishMomentum =
isCCBarMomentum &&
IsBearish(cCBarMomentumDir);
//
// Reject ...
ENUM_X_DIRECTION cCBarRejectDir;
bool isCCBarRejected = consolidationCycleHelper
.mBarAnalyser
.IsRejectionBar(
cCBar,
cCBarRejectDir,
1 // Extended ...
);
bool isCCBarBullishRejected =
isCCBarRejected &&
IsBullish(cCBarRejectDir);
bool isCCBarBearishRejected =
isCCBarRejected &&
IsBearish(cCBarRejectDir);
//
// Bar Checking Summary ...
//
// Bullish ...
bool isCCBarPassedBullish =
//
isCCBarBullishEngulfed ||
isCCBarBullishMomentum ||
isCCBarBullishRejected
//
;
//
// Bearish ...
bool isCCBarPassedBearish =
//
isCCBarBearishEngulfed ||
isCCBarBearishMomentum ||
isCCBarBearishRejected
//
;
//
double cPeakPrev = conditionStatePrev.x121Conditions.peaksBuffer[0];
double cValePrev = conditionStatePrev.x121Conditions.valesBuffer[0];
//
double cPeak = conditionState.x121Conditions.peaksBuffer[1];
double cVale = conditionState.x121Conditions.valesBuffer[1];
//
bool isCPeakSame = cPeak == cPeakPrev;
bool isCValeSame = cVale == cValePrev;
//
bool isCNewPeakPrev = conditionStatePrev.x121Conditions.isNewPeak;
bool isCNewPeakOverLastPrev = conditionStatePrev.x121Conditions.isNewPeakOverLast;
bool isCNewPeakUnderLastPrev = conditionStatePrev.x121Conditions.isNewPeakUnderLast;
//
bool isCNewValePrev = conditionStatePrev.x121Conditions.isNewVale;
bool isCNewValeOverLastPrev = conditionStatePrev.x121Conditions.isNewValeOverLast;
bool isCNewValeUnderLastPrev = conditionStatePrev.x121Conditions.isNewValeUnderLast;
//
bool isCRSIOverSold = conditionState.x121Conditions.isRSIOverSold;
bool isCRSICrossedOverOverSold = conditionState.x121Conditions.isRSICrossedOverOverSold;
bool isCRSICrossedUnderOverSold = conditionState.x121Conditions.isRSICrossedUnderOverSold;
//
bool isCRSIOverBought = conditionState.x121Conditions.isRSIOverBought;
bool isCRSICrossedOverOverBought = conditionState.x121Conditions.isRSICrossedOverOverBought;
bool isCRSICrossedUnderOverBought = conditionState.x121Conditions.isRSICrossedUnderOverBought;
//
bool isCRSIOverSoldPrev = conditionStatePrev.x121Conditions.isRSIOverSold;
bool isCRSICrossedOverOverSoldPrev = conditionStatePrev.x121Conditions.isRSICrossedOverOverSold;
bool isCRSICrossedUnderOverSoldPrev = conditionStatePrev.x121Conditions.isRSICrossedUnderOverSold;
//
bool isCRSIOverBoughtPrev = conditionStatePrev.x121Conditions.isRSIOverBought;
bool isCRSICrossedOverOverBoughtPrev = conditionStatePrev.x121Conditions.isRSICrossedOverOverBought;
bool isCRSICrossedUnderOverBoughtPrev = conditionStatePrev.x121Conditions.isRSICrossedUnderOverBought;
//
isBullish =
//
isCNewValePrev &&
isCCBarPassedBullish
//
;
//
isBearish =
//
isCNewPeakPrev &&
isCCBarPassedBearish
//
;
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
conditions.pivot =
isBullish
? conditionState.x121Conditions.valesBuffer[1]
: conditionState.x121Conditions.peaksBuffer[1];
//
double peak = analyseConditions.x121Conditions.peaksBuffer[1];
double vale = analyseConditions.x121Conditions.valesBuffer[1];
//
double strUpper = analyseConditions.x121Conditions.strUpBuffer[1];
double strLower = analyseConditions.x121Conditions.strDownBuffer[1];
//
bool isStrSwitchedToBullish = analyseConditions.x121Conditions.isStrSwitchedToBullish;
bool isStrSwitchedToBearish = analyseConditions.x121Conditions.isStrSwitchedToBearish;
//
isBullish = isStrSwitchedToBullish;
isBearish = isStrSwitchedToBearish;
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
conditions.pivot =
isBullish
? peak
: vale;
//
// Looking For Sar Change ...
//
double sar = analyseConditions.x121Conditions.sarBuffer[1];
//
double peak = analyseConditions.x121Conditions.peaksBuffer[1];
double vale = analyseConditions.x121Conditions.valesBuffer[1];
//
bool isSarEqualsToPeak = analyseConditions.x121Conditions.isSarEqualsToPeak;
bool isSarEqualsToVale = analyseConditions.x121Conditions.isSarEqualsToVale;
//
bool isSarSwitchedToBullish = analyseConditions.x121Conditions.isSarSwitchedToBullish;
bool isSarSwitchedToBearish = analyseConditions.x121Conditions.isSarSwitchedToBearish;
//
isBullish =
isBullish &&
isSarEqualsToPeak &&
isSarSwitchedToBullish;
//
isBearish =
isBearish &&
isSarEqualsToVale &&
isSarSwitchedToBearish;
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
Print("Sar Switched ...");
//
// Detect a Zone Arround Price Zone ...
int supplyZonesCount = consolidationState.CountSupplyZones();
if (IsValidSize(supplyZonesCount)) {
//
for (int i = 0; i < supplyZonesCount; i++) {
//
XCSupplyZone *iZone = consolidationState.supplyZones[i];
//
bool isOver = iZone.Lower() > pzUpper;
bool isUnder = iZone.Upper() < pzLower;
//
bool isValid =
isOver ||
isUnder;
if (isValid) {
}
}
}
//
// Method 1 ...
// VWap Switch Start ...
//
bool bullishMethod1 =
//
isSarBullish &&
isStrBullish &&
isSlopesBullish &&
hasBullishTrend &&
cBar.IsBullish() &&
isAtrBullishSlope &&
isPVBullishFormed &&
isRsiBullishFormed &&
isVWapBullishFormed
//
;
//
bool bearishMethod1 =
//
isSarBearish &&
isStrBearish &&
isSlopesBearish &&
hasBearishTrend &&
cBar.IsBearish() &&
isAtrBearishSlope &&
isPVBearishFormed &&
isRsiBearishFormed &&
isVWapBearishFormed
//
;
+530
View File
@@ -0,0 +1,530 @@
//////////////////////////////////////////////////////////////////////////////////
////// Detect Price Zones :
/////////////////////////////////////////////////////////////////////////////////
//
XPriceZones priceZone;
bool isPriceZoneValidForPeak;
bool isPriceZoneValidForVale;
//
priceZone.Clean();
isPriceZoneValidForPeak = false;
isPriceZoneValidForVale = false;
//
// Detect Price Zone ...
//
double pzPeak = decisionXConditions.peaksBuffer[1];
double pzVale = decisionXConditions.valesBuffer[1];
//
// Detecting Decision Price ones ...
XPriceZones decisionPriceZone;
bool hasDecisionPriceZone = CalculatePriceInsideZones(
decisionPriceZone,
decisionState,
cBar //
);
double decisionPriceZoneUpper = 0;
double decisionPriceZoneLower = 0;
bool isDecisionPriceZoneValidForPeak = false;
bool isDecisionPriceZoneValidForVale = false;
if (hasDecisionPriceZone)
{
//
bool hasBoundary = decisionPriceZone.GetBoundary(
X_DIRECTION_ALL,
decisionPriceZoneUpper,
decisionPriceZoneLower //
);
//
isDecisionPriceZoneValidForPeak =
hasBoundary &&
pzPeak <= decisionPriceZoneUpper &&
pzPeak >= decisionPriceZoneLower;
//
isDecisionPriceZoneValidForVale =
hasBoundary &&
pzVale <= decisionPriceZoneUpper &&
pzVale >= decisionPriceZoneLower;
}
//
// Detecting Analyse Price ones ...
XPriceZones analysePriceZone;
bool hasAnalysePriceZone = CalculatePriceInsideZones(
analysePriceZone,
analyseState,
cBar //
);
double analysePriceZoneUpper = 0;
double analysePriceZoneLower = 0;
bool isAnalysePriceZoneValidForPeak = false;
bool isAnalysePriceZoneValidForVale = false;
if (hasAnalysePriceZone)
{
//
bool hasBoundary = analysePriceZone.GetBoundary(
X_DIRECTION_ALL,
analysePriceZoneUpper,
analysePriceZoneLower //
);
//
isAnalysePriceZoneValidForPeak =
hasBoundary &&
pzPeak <= analysePriceZoneUpper &&
pzPeak >= analysePriceZoneLower;
//
isAnalysePriceZoneValidForVale =
hasBoundary &&
pzVale <= analysePriceZoneUpper &&
pzVale >= analysePriceZoneLower;
}
//
// Detecting Verification Price ones ...
XPriceZones verificationPriceZone;
bool hasVerificationPriceZone = CalculatePriceInsideZones(
verificationPriceZone,
verificationState,
cBar //
);
double verificationPriceZoneUpper = 0;
double verificationPriceZoneLower = 0;
bool isVerificationPriceZoneValidForPeak = false;
bool isVerificationPriceZoneValidForVale = false;
if (hasVerificationPriceZone)
{
//
bool hasBoundary = verificationPriceZone.GetBoundary(
X_DIRECTION_ALL,
verificationPriceZoneUpper,
verificationPriceZoneLower //
);
//
isVerificationPriceZoneValidForPeak =
hasBoundary &&
pzPeak <= verificationPriceZoneUpper &&
pzPeak >= verificationPriceZoneLower;
//
isVerificationPriceZoneValidForVale =
hasBoundary &&
pzVale <= verificationPriceZoneUpper &&
pzVale >= verificationPriceZoneLower;
}
//////////////////////////////////////////////////////////////////////////////////
////// Detect Pivot Zones :
/////////////////////////////////////////////////////////////////////////////////
//
double X121SMCXPivotPeak;
double X121SMCXPivotVale;
datetime X121SMCXPivotEnd;
datetime X121SMCXPivotStart;
ENUM_XPV_PIVOTS X121SMCXPivotType = XPV_NONE;
//
// Detect PV Pivot ...
//
bool isPivotPeakZoneRejected = false;
bool isPivotPeakZoneBreakedUp = false;
bool isPivotPeakZoneBreakedDown = false;
bool isPivotValeZoneRejected = false;
bool isPivotValeZoneBreakedUp = false;
bool isPivotValeZoneBreakedDown = false;
bool hasPivot = conditions.pivotZone.IsValid();
if (!hasPivot)
{
//
hasPivot = IsValid(X121SMCXPivotStart);
if (!hasPivot)
{
//
bool isNewVale = decisionXConditions.isNewVale;
bool isNewValeOverLast = decisionXConditions.isNewValeOverLast;
bool isNewValeUnderLast = decisionXConditions.isNewValeUnderLast;
bool isSameVales = decisionXConditions.valesBuffer[1] ==
decisionXConditions.valesBuffer[2] &&
decisionXConditions.valesBuffer[2] ==
decisionXConditions.valesBuffer[3];
bool isSameCycleVales = decisionXConditions.valesBuffer[1] ==
analyseXConditions.valesBuffer[1] &&
analyseXConditions.valesBuffer[1] ==
verificationXConditions.valesBuffer[1];
//
bool isNewPeak = decisionXConditions.isNewPeak;
bool isNewPeakOverLast = decisionXConditions.isNewPeakOverLast;
bool isNewPeakUnderLast = decisionXConditions.isNewPeakUnderLast;
bool isSamePeaks = decisionXConditions.peaksBuffer[1] ==
decisionXConditions.peaksBuffer[2] &&
decisionXConditions.peaksBuffer[2] ==
decisionXConditions.peaksBuffer[3];
bool isSameCyclePeaks = decisionXConditions.peaksBuffer[1] ==
analyseXConditions.peaksBuffer[1] &&
analyseXConditions.peaksBuffer[1] ==
verificationXConditions.peaksBuffer[1];
//
bool isValeStart =
isSameVales &&
isSameCycleVales;
bool isPeakStart =
isSamePeaks &&
isSameCyclePeaks;
//
bool isStart = isPeakStart ||
isValeStart;
if (isStart)
{
//
X121SMCXPivotStart = cTime;
X121SMCXPivotType =
isPeakStart
? XPV_PEAK
: XPV_VALE;
//
X121SMCXPivotPeak = decisionXConditions.peaksBuffer[1];
X121SMCXPivotVale = decisionXConditions.valesBuffer[1];
}
//
hasPivot = IsValid(X121SMCXPivotStart);
//
// Create XPVPivot instance ...
if (hasPivot)
{
//
conditions.pivotZone.symbol = symbol;
conditions.pivotZone.period = period;
//
conditions.pivotZone.to = cTime;
conditions.pivotZone.repetition = 3;
//
conditions.pivotZone.upper = X121SMCXPivotPeak;
conditions.pivotZone.lower = X121SMCXPivotVale;
//
conditions.pivotZone.type = X121SMCXPivotType;
conditions.pivotZone.from = X121SMCXPivotStart;
}
}
}
//
if (hasPivot)
{
//
bool isBreaked = X121SMCXPivotType == XPV_PEAK
? decisionXConditions.isBreakedUpPrevPeak
: decisionXConditions.isBreakedDownPrevVale;
//
if (!isBreaked)
{
//
X121SMCXPivotPeak = decisionXConditions.peaksBuffer[1];
X121SMCXPivotVale = decisionXConditions.valesBuffer[1];
//
conditions.pivotZone.to = cTime;
conditions.pivotZone.repetition++;
conditions.pivotZone.upper = X121SMCXPivotPeak;
conditions.pivotZone.lower = X121SMCXPivotVale;
}
else
{
//
X121SMCXPivotEnd = cTime;
conditions.pivotZone.to = cTime;
}
//
// Fill Pivot State ...
//
XPOIState analysePivotState;
DetectPivotPOIs(
conditions.pivotZone,
analyseState,
analysePivotState //
);
//
XPOIState decisionPivotState;
DetectPivotPOIs(
conditions.pivotZone,
decisionState,
decisionPivotState //
);
//
// Combine two State ...
XPOIState combinedPivotState;
XPOIState iStates[];
AddRef(
analysePivotState,
iStates //
);
AddRef(
decisionPivotState,
iStates //
);
CombineStates(
combinedPivotState,
iStates //
);
combinedPivotState = decisionPivotState;
//
ArrayFree(iStates);
//
combinedPivotState.time = decisionPivotState.time;
combinedPivotState.symbol = decisionPivotState.symbol;
combinedPivotState.period = decisionPivotState.period;
//
// Hold Only Areas Which on Upper or Lower bondary of Pivot Zone ...
FilterPivotState(
conditions.pivotZone,
combinedPivotState //
);
//
conditions.pivotZone.state = combinedPivotState;
//
double peakUpper = 0;
double peakLower = 0;
double valeUpper = 0;
double valeLower = 0;
//
datetime peakTo = NULL;
datetime valeTo = NULL;
datetime peakFrom = NULL;
datetime valeFrom = NULL;
//
bool hasBoxData = DetectPivotStateBoxData(
conditions.pivotZone,
peakUpper,
peakLower,
peakFrom,
peakTo,
valeUpper,
valeLower,
valeFrom,
valeTo //
);
//
// Calculate Pivot Tick Zones ...
//
int ticksLevels = decisionCycleHelper
.mPOIDetector
.TicksRangeZoneLevel();
int ticksRange = decisionCycleHelper
.mPOIDetector
.TicksRangeZoneRange();
//
CalculatePivotTickZone(
conditions.pivotZone,
ticksLevels,
ticksRange //
);
//
isPivotPeakZoneRejected =
hasBoxData &&
(
//
IsBarReject(
peakLower,
X_DIRECTION_BEARISH,
cBar //
)
//
||
//
IsBarReject(
peakUpper,
X_DIRECTION_BEARISH,
cBar //
)
//
);
isPivotPeakZoneBreakedUp =
hasBoxData &&
IsBarBreak(
peakUpper,
X_DIRECTION_BULLISH,
cBar //
);
isPivotPeakZoneBreakedDown =
hasBoxData &&
IsBarBreak(
peakLower,
X_DIRECTION_BEARISH,
cBar //
);
//
isPivotValeZoneRejected =
hasBoxData &&
(
//
IsBarReject(
valeLower,
X_DIRECTION_BULLISH,
cBar //
)
//
||
//
IsBarReject(
valeUpper,
X_DIRECTION_BULLISH,
cBar //
)
//
);
isPivotValeZoneBreakedUp =
hasBoxData &&
IsBarBreak(
valeUpper,
X_DIRECTION_BULLISH,
cBar //
);
isPivotValeZoneBreakedDown =
hasBoxData &&
IsBarBreak(
valeLower,
X_DIRECTION_BEARISH,
cBar //
);
}
//
bool isPivotEnded = IsValid(X121SMCXPivotEnd);
if (isPivotEnded)
{
//
X121SMCXPivotPeak = 0;
X121SMCXPivotVale = 0;
X121SMCXPivotEnd = NULL;
X121SMCXPivotStart = NULL;
X121SMCXPivotType = XPV_NONE;
//
conditions.pivotZone.Clean();
}
//////////////////////////////////////////////////////////////////////////////////
////// Detect Pivot Zones :
/////////////////////////////////////////////////////////////////////////////////
//
bool isCondition1Bullish =
//
hasPivot &&
//
isCBarBullishFormed &&
isCBarBullishPullbacked &&
//
hasAnalyseBullishTrend &&
hasDecisionBullishTrend &&
hasVerificationBullishTrend &&
//
decisionXConditions.isSarBullish &&
analyseXConditions.isSarBullish &&
verificationXConditions.isSarBullish &&
//
false
//
;
//
bool isCondition1Bearish =
//
hasPivot &&
//
isCBarBearishFormed &&
isCBarBearishPullbacked &&
//
hasAnalyseBearishTrend &&
hasDecisionBearishTrend &&
hasVerificationBearishTrend &&
//
decisionXConditions.isSarBearish &&
analyseXConditions.isSarBearish &&
verificationXConditions.isSarBearish &&
//
false
//
;
//
bool hasCondition1 = isCondition1Bullish ||
isCondition1Bearish;
if (hasCondition1)
{
//
ENUM_X_DIRECTION pzDir =
isCondition1Bullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
conditions.priceZone = analysePriceZone;
conditions.isPriceZoneValidForPeak = isAnalysePriceZoneValidForPeak;
conditions.isPriceZoneValidForVale = isAnalysePriceZoneValidForVale;
//
pzPeak = analysePriceZoneUpper;
pzVale = analysePriceZoneLower;
//
double point = GetEntry(
conditions.symbol,
pzDir //
);
//
// Manipulate Conditions Point ...
//
// point =
// isCondition1Bullish ? pzPeak
// : pzVale;
conditions.point = point;
//
// Manipulate Conditions Pivot ...
//
conditions.pivot =
isCondition1Bullish
? pzVale
: pzPeak;
}
+729
View File
@@ -0,0 +1,729 @@
//
double cPZoneUpper = 0;
double cPZoneLower = 0;
datetime cPZoneFrom = NULL;
datetime cPZoneTo = NULL;
result = consolidationPriceZone.GetBoxData(
X_DIRECTION_ALL,
cPZoneUpper,
cPZoneLower,
cPZoneFrom,
cPZoneTo //
);
if (!result)
{
return result;
}
//
double aPZoneUpper = 0;
double aPZoneLower = 0;
datetime aPZoneFrom = NULL;
datetime aPZoneTo = NULL;
result = analysePriceZone.GetBoxData(
X_DIRECTION_ALL,
aPZoneUpper,
aPZoneLower,
aPZoneFrom,
aPZoneTo //
);
if (!result)
{
return result;
}
//
// RSI ...
double rsi = decisionConditions.x121Conditions.rsiBuffer[1];
//
bool isRSIOverBought = decisionConditions.x121Conditions.isRSIOverBought;
bool isRSICrossedOverOverBought = decisionConditions.x121Conditions.isRSICrossedOverOverBought;
bool isRSICrossedUnderOverBought = decisionConditions.x121Conditions.isRSICrossedUnderOverBought;
//
bool isRSIOverSold = decisionConditions.x121Conditions.isRSIOverSold;
bool isRSICrossedOverOverSold = decisionConditions.x121Conditions.isRSICrossedOverOverSold;
bool isRSICrossedUnderOverSold = decisionConditions.x121Conditions.isRSICrossedUnderOverSold;
//
// PV ...
double peak = decisionConditions.x121Conditions.peaksBuffer[1];
double vale = decisionConditions.x121Conditions.valesBuffer[1];
//
bool isNewPeak = decisionConditions.x121Conditions.isNewPeak;
bool isNewPeakOverLast = decisionConditions.x121Conditions.isNewPeakOverLast;
bool isNewPeakUnderLast = decisionConditions.x121Conditions.isNewPeakUnderLast;
//
bool isNewVale = decisionConditions.x121Conditions.isNewVale;
bool isNewValeOverLast = decisionConditions.x121Conditions.isNewValeOverLast;
bool isNewValeUnderLast = decisionConditions.x121Conditions.isNewValeUnderLast;
//
// STR ...
double str = decisionConditions.x121Conditions.strBuffer[1];
//
bool isStrBullish = decisionConditions.x121Conditions.isStrBullish;
bool isStrBearish = decisionConditions.x121Conditions.isStrBearish;
//
bool isStrSwitchedToBullish = decisionConditions.x121Conditions.isStrSwitchedToBullish;
bool isStrSwitchedToBearish = decisionConditions.x121Conditions.isStrSwitchedToBearish;
//
// ATR ...
double atr = decisionConditions.x121Conditions.atrBuffer[1];
double atrUpper = decisionConditions.x121Conditions.atrUpperBuffer[1];
double atrLower = decisionConditions.x121Conditions.atrLowerBuffer[1];
//
bool isCloseOverATRUpper = decisionConditions.x121Conditions.isCloseOverATRUpper;
bool isCloseOverATRLower = decisionConditions.x121Conditions.isCloseOverATRLower;
//
bool isCloseUnderATRUpper = decisionConditions.x121Conditions.isCloseUnderATRUpper;
bool isCloseUnderATRLower = decisionConditions.x121Conditions.isCloseUnderATRLower;
//
bool isRejectUpATRUpper = decisionConditions.x121Conditions.isRejectUpATRUpper;
bool isRejectDownATRUpper = decisionConditions.x121Conditions.isRejectDownATRUpper;
//
bool isRejectUpATRLower = decisionConditions.x121Conditions.isRejectUpATRLower;
bool isRejectDownATRLower = decisionConditions.x121Conditions.isRejectDownATRLower;
//
bool isBreakUpATRUpper = decisionConditions.x121Conditions.isBreakUpATRUpper;
bool isBreakDownATRUpper = decisionConditions.x121Conditions.isBreakDownATRUpper;
//
bool isBreakUpATRLower = decisionConditions.x121Conditions.isBreakUpATRLower;
bool isBreakDownATRLower = decisionConditions.x121Conditions.isBreakDownATRLower;
//
// SAR ...
double sar = decisionConditions.x121Conditions.sarBuffer[1];
//
bool isSarBullish = decisionConditions.x121Conditions.isSarBullish;
bool isSarBearish = decisionConditions.x121Conditions.isSarBearish;
//
bool isSarSwitchedToBullish = decisionConditions.x121Conditions.isSarSwitchedToBullish;
bool isSarSwitchedToBearish = decisionConditions.x121Conditions.isSarSwitchedToBearish;
//
// DON ...
//
double donOpenUpper = decisionConditions.x121Conditions.donOpenUpperBuffer[1];
double donOpenLower = decisionConditions.x121Conditions.donOpenLowerBuffer[1];
double donHighUpper = decisionConditions.x121Conditions.donHighUpperBuffer[1];
double donHighLower = decisionConditions.x121Conditions.donHighLowerBuffer[1];
double donLowUpper = decisionConditions.x121Conditions.donLowUpperBuffer[1];
double donLowLower = decisionConditions.x121Conditions.donLowLowerBuffer[1];
double donCloseUpper = decisionConditions.x121Conditions.donCloseUpperBuffer[1];
double donCloseLower = decisionConditions.x121Conditions.donCloseLowerBuffer[1];
//
bool isRejectDonOpenUpper = decisionConditions.x121Conditions.isRejectDonOpenUpper;
bool isRejectDonHighUpper = decisionConditions.x121Conditions.isRejectDonHighUpper;
bool isRejectDonLowUpper = decisionConditions.x121Conditions.isRejectDonLowUpper;
bool isRejectDonCloseUpper = decisionConditions.x121Conditions.isRejectDonCloseUpper;
//
bool isRejectDonOpenLower = decisionConditions.x121Conditions.isRejectDonOpenLower;
bool isRejectDonHighLower = decisionConditions.x121Conditions.isRejectDonHighLower;
bool isRejectDonLowLower = decisionConditions.x121Conditions.isRejectDonLowLower;
bool isRejectDonCloseLower = decisionConditions.x121Conditions.isRejectDonCloseLower;
//
bool isBreakDonOpenUpper = decisionConditions.x121Conditions.isBreakDonOpenUpper;
bool isBreakDonHighUpper = decisionConditions.x121Conditions.isBreakDonHighUpper;
bool isBreakDonLowUpper = decisionConditions.x121Conditions.isBreakDonLowUpper;
bool isBreakDonCloseUpper = decisionConditions.x121Conditions.isBreakDonCloseUpper;
//
bool isBreakDonOpenLower = decisionConditions.x121Conditions.isBreakDonOpenLower;
bool isBreakDonHighLower = decisionConditions.x121Conditions.isBreakDonHighLower;
bool isBreakDonLowLower = decisionConditions.x121Conditions.isBreakDonLowLower;
bool isBreakDonCloseLower = decisionConditions.x121Conditions.isBreakDonCloseLower;
//
// VWAP ...
//
// COMPLEX ...
// Complex Conditions ...
//
bool isNewPeakOverATRUpper =
isNewPeak &&
peak > atrUpper;
//
bool isNewValeUnderATRLower =
isNewVale &&
vale < atrLower;
//
bool isDonHighUpperEqualsToPeak =
donHighUpper == peak;
//
bool isDonLowLowerEqualsToVale =
donLowLower == vale;
//
bool isBullishSign = (
//
triggerConditions.x121Conditions.isBreakUpATRLower ||
triggerConditions.x121Conditions.isRejectUpATRLower ||
triggerConditions.x121Conditions.isBreakDonHighLower ||
triggerConditions.x121Conditions.isRejectDonHighLower ||
triggerConditions.x121Conditions.isBreakDonCloseLower ||
triggerConditions.x121Conditions.isRejectDonCloseLower
//
);
bool isBearishSign = (
//
triggerConditions.x121Conditions.isBreakDownATRUpper ||
triggerConditions.x121Conditions.isRejectDownATRUpper ||
triggerConditions.x121Conditions.isBreakDonLowUpper ||
triggerConditions.x121Conditions.isRejectDonLowUpper ||
triggerConditions.x121Conditions.isBreakDonCloseUpper ||
triggerConditions.x121Conditions.isRejectDonCloseUpper
//
);
//
// Check RSI in Over Bought or Over Sold ...
//
bool isRSICrossedOverOverSold = consolidationConditions.x121Conditions.isRSICrossedOverOverSold;
bool isRSICrossedUnderOverBought = consolidationConditions.x121Conditions.isRSICrossedUnderOverBought;
//
result = isRSICrossedOverOverSold ||
isRSICrossedUnderOverBought;
if (!result)
{
return result;
}
///////////////////////////////////////////////
/**
* Draw X121 SMC Conditions ...
*
* @param conditions: X121SMCStrategyConditions instance Reference ...
* @param drawMarketStructure: Boolean ...
* @param drawPriceZones: Boolean ...
* @param drawDecisionZones: Boolean ...
*
* @return ( int )
*/
int DrawX121SMCStrategyConditions(
X121SMCStrategyConditions &conditions,
XCBaseObject *&drawnObjects[],
XCPOIDrawer *drawer,
bool drawMarketStructure = true,
bool drawPriceZones = true,
bool drawDecisionZones = true,
bool drawOnlyPriceZonesBoundary = true //
)
{
//
int result = 0;
//
Clean(drawnObjects);
//
if (drawer == NULL ||
!conditions.IsValid() ||
!HasDirection(conditions.signalDir))
{
return result;
}
//
bool isBullish = IsBullish(conditions.signalDir);
// //
// bool hasPriceZones = conditions.priceZones.IsValid();
// if (hasPriceZones &&
// drawPriceZones)
// {
// //
// XCBaseObject *objects[];
// int objectsCount = drawer.DrawPriceZone(
// conditions.priceZones,
// objects,
// conditions.signalDir,
// drawOnlyPriceZonesBoundary //
// );
// if (IsValidSize(objectsCount))
// {
// //
// Copy(
// objects,
// drawnObjects,
// false //
// );
// }
// }
// //
// bool hasDecisionZones = conditions.decisionZones.IsValid();
// if (hasDecisionZones &&
// drawDecisionZones)
// {
// //
// XCBaseObject *objects[];
// int objectsCount = drawer.DrawPriceZone(
// conditions.decisionZones,
// objects,
// conditions.signalDir,
// drawOnlyPriceZonesBoundary //
// );
// if (IsValidSize(objectsCount))
// {
// //
// Copy(
// objects,
// drawnObjects,
// false //
// );
// }
// }
// //
// bool hasMarketStructure = conditions.marketStructure.IsValid();
// if (hasMarketStructure &&
// drawMarketStructure)
// {
// //
// XCBaseObject *objects[];
// int objectsCount = drawer.DrawMarketStructure(
// conditions.marketStructure,
// objects //
// );
// if (IsValidSize(objectsCount))
// {
// //
// Copy(
// objects,
// drawnObjects,
// false //
// );
// }
// }
//
result = ArraySize(drawnObjects);
//
return result;
}
////////////////////////////////////////////////
// //
// isCBarBearishFormed &&
// (isPivotToDownRejected ||
// isPivotToDownBreaked) &&
// conditions.pivotZone.IsVale() &&
// //
// // SAR ...
// isSarBearishFormed &&
// // //
// // // STR ...
// // !(decisionXConditions.isStrBullish) &&
// // //
// // // VWAP ...
// // !(decisionXConditions.isVWapBullishState ||
// // decisionXConditions.isVWapBullishOrdered) &&
// //
// //
// isCBarBullishFormed &&
// (isPivotToUpRejected ||
// isPivotToUpBreaked) &&
// conditions.pivotZone.IsPeak() &&
// //
// // SAR ...
// isSarBullishFormed &&
// // //
// // // STR ...
// // !(decisionXConditions.isStrBearish) &&
// // //
// // // VWAP ...
// // !(decisionXConditions.isVWapBearishState ||
// // decisionXConditions.isVWapBearishOrdered) &&
// //
/////////////////////////////////////////////////////////////////////
visionXConditions.isBreakedUpPrevCheMax &&
visionXConditions.isCheSwitchedToBullish
visionXConditions.isCheSwitchedToBearish &&
visionXConditions.isBreakedDownPrevCheMin
//////////////////////////////////////////////////////////////////////
//
bool hasOrderBlock = hasBullishOrderBlocks ||
hasBearishOrderBlocks;
if (hasOrderBlock)
{
//
Print("Detect Order Block ...");
//
XCBaseObject *drawnObjects[];
//
if (hasBullishOrderBlocks)
{
//
for (int i = 0; i < bullishOrderBlocksCount; i++)
{
//
XCOrderBlock *iOb = bullishOBs[i];
//
XCBullishOrderBlockObject *iObObj;
bool isCreated = triggerCycleHelper
.mPOIDetector
.mDrawer
.CreateBullishOrderBlock(
iOb,
iObObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObObj,
drawnObjects //
);
}
}
}
//
if (hasBearishOrderBlocks)
{
//
for (int i = 0; i < bearishOrderBlocksCount; i++)
{
//
XCOrderBlock *iOb = bearishOBs[i];
//
XCBearishOrderBlockObject *iObObj;
bool isCreated = triggerCycleHelper
.mPOIDetector
.mDrawer
.CreateBearishOrderBlock(
iOb,
iObObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObObj,
drawnObjects //
);
}
}
}
//
int drawnCount = ArraySize(drawnObjects);
if (IsValidSize(drawnCount))
{
Print("");
}
}
//////////////////////////////////////////////////////////////////////
//
// Summarize Conditions ...
//
bool isCondition1Bullish =
//
// Vision ...
(
//
false
//
)
//
&&
//
// Consolidation ...
(
//
true
//
)
//
&&
//
// Verification ...
(
//
true
//
)
//
&&
//
// Analyse ...
(
//
true
//
)
//
&&
//
// Decision ...
(
//
true
//
)
//
;
//
bool isCondition1Bearish =
//
// Vision ...
(
//
false
//
)
//
&&
//
// Consolidation ...
(
//
true
//
)
//
&&
//
// Verification ...
(
//
true
//
)
//
&&
//
// Analyse ...
(
//
true
//
)
//
&&
//
// Decision ...
(
//
true
//
)
//
;
//
bool hasCondition1 = isCondition1Bullish ||
isCondition1Bearish;
if (hasCondition1)
{
//
ENUM_X_DIRECTION pzDir =
isCondition1Bullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
double point = GetEntry(
conditions.symbol,
pzDir //
);
//
// Manipulate Conditions Point ...
//
conditions.point = point;
//
// Manipulate Conditions Pivot ...
//
// conditions.pivot =
// isCondition1Bullish
// ? conditions.pivotZone.upper
// : conditions.pivotZone.lower;
}
/////////////////////////////////////////////////////////////////////////
//
// DRAW ...
//
//
XCBaseObject *drawnObjects[];
//
if (hasBullishOrderBlocks)
{
//
for (int i = 0; i < bullishOrderBlocksCount; i++)
{
//
XCOrderBlock *iOb = conditions.bullishOBs[i];
//
XCBullishOrderBlockObject *iObObj;
bool isCreated = visionCycleHelper
.mPOIDrawer
.CreateBullishOrderBlock(
iOb,
iObObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObObj,
drawnObjects //
);
}
}
}
//
if (hasBearishOrderBlocks)
{
//
for (int i = 0; i < bearishOrderBlocksCount; i++)
{
//
XCOrderBlock *iOb = conditions.bearishOBs[i];
//
XCBearishOrderBlockObject *iObObj;
bool isCreated = visionCycleHelper
.mPOIDrawer
.CreateBearishOrderBlock(
iOb,
iObObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObObj,
drawnObjects //
);
}
}
}
//
// if (hasOldestBullishOB)
// {
// //
// XCBullishOrderBlockObject *iObj;
// bool isCreated = visionCycleHelper
// .mPOIDrawer
// .CreateBullishOrderBlock(
// oldestBullishOB,
// iObj //
// );
// if (isCreated)
// {
// }
// }
// //
// if (hasYoungestBullishOB)
// {
// //
// XCBullishOrderBlockObject *iObj;
// bool isCreated = visionCycleHelper
// .mPOIDrawer
// .CreateBullishOrderBlock(
// youngestBullishOB,
// iObj //
// );
// if (isCreated)
// {
// }
// }
// //
// if (hasOldestBearishOB)
// {
// //
// XCBearishOrderBlockObject *iObj;
// bool isCreated = visionCycleHelper
// .mPOIDrawer
// .CreateBearishOrderBlock(
// oldestBearishOB,
// iObj //
// );
// if (isCreated)
// {
// }
// }
// //
// if (hasYoungestBearishOB)
// {
// //
// XCBearishOrderBlockObject *iObj;
// bool isCreated = visionCycleHelper
// .mPOIDrawer
// .CreateBearishOrderBlock(
// youngestBearishOB,
// iObj //
// );
// if (isCreated)
// {
// }
// }
/////////////////////////////////////////////////////////////////////////
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,137 @@
//
// OPEN ...
double triggerDonOpenUpper = triggerConditions.x121Conditions.donOpenUpperBuffer[1];
double triggerDonOpenLower = triggerConditions.x121Conditions.donOpenLowerBuffer[1];
double triggerDonOpenUpperPrev = triggerConditions.x121Conditions.donOpenUpperBuffer[2];
double triggerDonOpenLowerPrev = triggerConditions.x121Conditions.donOpenLowerBuffer[2];
//
// HIGH ...
double triggerDonHighUpper = triggerConditions.x121Conditions.donHighUpperBuffer[1];
double triggerDonHighLower = triggerConditions.x121Conditions.donHighLowerBuffer[1];
double triggerDonHighUpperPrev = triggerConditions.x121Conditions.donHighUpperBuffer[2];
double triggerDonHighLowerPrev = triggerConditions.x121Conditions.donHighLowerBuffer[2];
//
// CLOSE ...
double triggerDonCloseUpper = triggerConditions.x121Conditions.donCloseUpperBuffer[1];
double triggerDonCloseLower = triggerConditions.x121Conditions.donCloseLowerBuffer[1];
double triggerDonCloseUpperPrev = triggerConditions.x121Conditions.donCloseUpperBuffer[2];
double triggerDonCloseLowerPrev = triggerConditions.x121Conditions.donCloseLowerBuffer[2];
//
// LOW ...
double triggerDonLowUpper = triggerConditions.x121Conditions.donLowUpperBuffer[1];
double triggerDonLowLower = triggerConditions.x121Conditions.donLowLowerBuffer[1];
double triggerDonLowUpperPrev = triggerConditions.x121Conditions.donLowUpperBuffer[2];
double triggerDonLowLowerPrev = triggerConditions.x121Conditions.donLowLowerBuffer[2];
//
// Calculate PBar Rejected Don Upper and Lower ...
//
bool isPBarRejectDonLowUpper = pBar.high > triggerDonLowUpperPrev;
bool isPBarRejectDonOpenUpper = pBar.high > triggerDonOpenUpperPrev;
bool isPBarRejectDonCloseUpper = pBar.high > triggerDonCloseUpperPrev;
bool isPBarRejectedDonUpper = isPBarRejectDonLowUpper ||
isPBarRejectDonOpenUpper ||
isPBarRejectDonCloseUpper;
//
bool isPBarRejectDonHighLower = pBar.low < triggerDonHighLowerPrev;
bool isPBarRejectDonOpenLower = pBar.low < triggerDonOpenLowerPrev;
bool isPBarRejectDonCloseLower = pBar.low < triggerDonCloseLowerPrev;
bool isPBarRejectedDonLower = isPBarRejectDonHighLower ||
isPBarRejectDonOpenLower ||
isPBarRejectDonCloseLower;
//
// Calculate PBar Breaked Don Upper and Lower ...
//
bool isPBarBreakdDonLowUpper = pBar.GetUp() > triggerDonLowUpperPrev &&
pBar.GetDown() < triggerDonLowUpperPrev;
bool isPBarBreakdDonOpenUpper = pBar.GetUp() > triggerDonOpenUpperPrev &&
pBar.GetDown() < triggerDonOpenUpperPrev;
bool isPBarBreakdDonCloseUpper = pBar.GetUp() > triggerDonCloseUpperPrev &&
pBar.GetDown() < triggerDonCloseUpperPrev;
bool isPBarBreakedDonUpper = isPBarBreakdDonLowUpper ||
isPBarBreakdDonOpenUpper ||
isPBarBreakdDonCloseUpper;
//
bool isPBarBreakdDonHighLower = pBar.GetUp() > triggerDonHighLowerPrev &&
pBar.GetDown() < triggerDonHighLowerPrev;
bool isPBarBreakdDonOpenLower = pBar.GetUp() > triggerDonOpenLowerPrev &&
pBar.GetDown() < triggerDonOpenLowerPrev;
bool isPBarBreakdDonCloseLower = pBar.GetUp() > triggerDonCloseLowerPrev &&
pBar.GetDown() < triggerDonCloseLowerPrev;
bool isPBarBreakedDonLower = isPBarBreakdDonHighLower ||
isPBarBreakdDonOpenLower ||
isPBarBreakdDonCloseLower;
//
bool isRejectTriggerDonUpper =
//
// PBar ...
isPBarBearishRejected &&
isPBarRejectedDonUpper &&
//
// CBar ...
isCBarBearishMomentumBar &&
cBar.close < triggerDonLowUpper &&
//
triggerPeak == triggerDonHighUpper
//
;
//
bool isRejectTriggerDonLower =
//
// PBar ...
isPBarBullishRejected &&
isPBarRejectedDonLower &&
//
// CBar ...
isCBarBullishMomentumBar &&
cBar.close > triggerDonHighLower &&
//
triggerVale == triggerDonLowLower
//
;
//
if (isRejectTriggerDonUpper ||
isRejectTriggerDonLower)
{
Print("Don Rejected ...");
}
//
bool isBreakedDonUpper =
//
false
//
;
//
bool isBreakedDonLower =
//
false
//
;
//
bool isEngulfedDonUpper =
//
false
//
;
//
bool isEngulfedDonLower =
//
false
//
;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,957 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 X121 SMC Signal Class
// -------------------------------------------------
// Name:
// Description: provide all Signalling functions ...
//
//
// 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-121.smc.market.cycle.helper.class.mq5"
#include "../Libraries/x-121.smc.lib.mq5"
//
// Definitions ...
struct X121SMCStrategyXTWPVSignalConditions
{
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
double sl;
double target;
ENUM_X_DIRECTION dir;
ENUM_X_POSITION_TYPES type;
//
// Setup Props ...
//
datetime setupTime;
datetime triggerTime;
//
datetime newPeakOverATRUpperAt;
datetime newValeUnderATRLowerAt;
//
datetime donHighUpperEqualsToPeakAt;
datetime donLowLowerEqualsToValeAt;
//
datetime closeOverATRUpperAt;
datetime closeUnderATRLowerAt;
//
datetime rsiOverSoldAt;
datetime rsiOverBoughtAt;
//
datetime newPeakOverLastAt;
datetime newValeUnderLastAt;
//
datetime bullishBarSignAt;
datetime bearishBarSignAt;
//
XPriceZones priceZone;
//
// Constructor ...
X121SMCStrategyXTWPVSignalConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleaning Up ...
*/
void Clean()
{
//
sl = 0;
target = 0;
//
dir = X_DIRECTION_NONE;
type = X_POSITION_TYPE_NONE;
//
symbol = NULL;
period = NULL;
setupTime = NULL;
triggerTime = NULL;
//
ExtensionClean();
}
/**
* Check Condition is Setting Up ...
*
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
*
* @return ( bool )
*/
bool IsSetuped()
{
//
bool result = false;
//
result = IsValid(setupTime) &&
HasDirection(dir);
if (!result)
{
return result;
}
//
return result;
}
/**
* Calculate Setup Age ...
*
* @return ( int )
*/
int GetSetupAge()
{
//
int result = 0;
//
if (!IsSetuped())
{
return result;
}
//
result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period);
//
return result;
}
/**
* Detect How we Can Trigger Signal ...
*
* @return ( bool )
*/
bool CanTrigger()
{
//
bool result = false;
//
result =
//
sl > 0 &&
IsValid(symbol) &&
IsValid(period) &&
IsValid(triggerTime) &&
type != X_POSITION_TYPE_ALL &&
type != X_POSITION_TYPE_NONE
//
;
//
return result;
}
//
// Extensions ...
/**
* Clean Additional Properties ...
*/
void ExtensionClean()
{
//
priceZone.Clean();
//
newPeakOverATRUpperAt = NULL;
newValeUnderATRLowerAt = NULL;
//
donHighUpperEqualsToPeakAt = NULL;
donLowLowerEqualsToValeAt = NULL;
//
closeOverATRUpperAt = NULL;
closeUnderATRLowerAt = NULL;
//
rsiOverSoldAt = NULL;
rsiOverBoughtAt = NULL;
//
newPeakOverLastAt = NULL;
newValeUnderLastAt = NULL;
//
bullishBarSignAt = NULL;
bearishBarSignAt = NULL;
}
/**
* Check if Conditions Filled ...
*
* @return ( bool )
*/
bool IsFilled(ENUM_X_DIRECTION &fillDir)
{
//
bool result = false;
//
fillDir = X_DIRECTION_NONE;
//
bool hasNewPeakOverATRUpper = IsValid(newPeakOverATRUpperAt);
bool hasNewValeUnderATRLower = IsValid(newValeUnderATRLowerAt);
//
bool hasDonHighUpperEqualsToPeak = IsValid(donHighUpperEqualsToPeakAt);
bool hasDonLowLowerEqualsToVale = IsValid(donLowLowerEqualsToValeAt);
//
bool hasCloseOverATRUpper = IsValid(closeOverATRUpperAt);
bool hasCloseUnderATRLower = IsValid(closeUnderATRLowerAt);
//
bool hasRsiOverSold = IsValid(rsiOverSoldAt);
bool hasRsiOverBought = IsValid(rsiOverBoughtAt);
//
bool hasNewPeakOverLast = IsValid(newPeakOverLastAt);
bool hasNewValeUnderLast = IsValid(newValeUnderLastAt);
//
bool hasBullishBarSign = IsValid(bullishBarSignAt);
bool hasBearishBarSign = IsValid(bearishBarSignAt);
//
bool isBullish =
(
//
hasRsiOverSold &&
hasBullishBarSign &&
hasNewValeUnderLast &&
hasCloseUnderATRLower &&
hasNewValeUnderATRLower &&
hasDonLowLowerEqualsToVale
//
);
//
bool isBearish =
(
//
hasRsiOverBought &&
hasBearishBarSign &&
hasNewPeakOverLast &&
hasCloseOverATRUpper &&
hasNewPeakOverATRUpper &&
hasDonHighUpperEqualsToPeak
//
);
//
result =
(isBullish || isBearish) &&
!(isBullish && isBearish);
if (result)
{
//
fillDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
bool HasPriceZone()
{
return priceZone.IsValid();
}
//
};
//
// Extension Functions ...
//
// Detect Setup Conditions ...
bool DetectX121SMCXTWPVSiganlSetup(
string _symbol,
ENUM_TIMEFRAMES _period,
//
X121SMCStrategyXTWPVSignalConditions &conditions,
//
XC121SMCCycleHelper *triggerCycleHelper,
XC121SMCCycleHelper *decisionCycleHelper,
XC121SMCCycleHelper *analyseCycleHelper,
XC121SMCCycleHelper *verificationCycleHelper,
XC121SMCCycleHelper *consolidationCycleHelper,
XC121SMCCycleHelper *visionCycleHelper
//
)
{
//
bool result = false;
//
bool isBullish = false;
bool isBearish = false;
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
int loopback = 10;
//
string symbol = _symbol;
ENUM_TIMEFRAMES period = _period;
//
conditions.symbol = symbol;
conditions.period = period;
//
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = pBar.Init(
symbol,
period,
pIndex //
);
if (!result)
{
return result;
}
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
double points = GetPoints(symbol);
//
int swingLoopback = 9;
double ll = cBar.FindLowest(swingLoopback, MODE_LOW);
double hh = cBar.FindHighest(swingLoopback, MODE_HIGH);
double llDown = cBar.FindLowesttDown(swingLoopback);
double hhUp = cBar.FindHighestUp(swingLoopback);
//
// Cycles Conditions ...
//
// Trigger ...
ENUM_XPOI_EVENTS triggerPoiEvents[];
ENUM_X_CYCLE_EVENTS triggerCycleEvents[];
X121SMCCycleConditions triggerConditions;
result = triggerCycleHelper.GetConditions(
triggerCycleEvents,
triggerPoiEvents,
triggerConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Decision ...
ENUM_XPOI_EVENTS decisionPoiEvents[];
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
X121SMCCycleConditions decisionConditions;
result = decisionCycleHelper.GetConditions(
decisionCycleEvents,
decisionPoiEvents,
decisionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Analyse ...
ENUM_XPOI_EVENTS analysePoiEvents[];
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
X121SMCCycleConditions analyseConditions;
result = analyseCycleHelper.GetConditions(
analyseCycleEvents,
analysePoiEvents,
analyseConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Verification ...
ENUM_XPOI_EVENTS verificationPoiEvents[];
ENUM_X_CYCLE_EVENTS verificationCycleEvents[];
X121SMCCycleConditions verificationConditions;
result = verificationCycleHelper.GetConditions(
verificationCycleEvents,
verificationPoiEvents,
verificationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Consolidation ...
ENUM_XPOI_EVENTS consolidationPoiEvents[];
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
X121SMCCycleConditions consolidationConditions;
result = consolidationCycleHelper.GetConditions(
consolidationCycleEvents,
consolidationPoiEvents,
consolidationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Vision ...
ENUM_XPOI_EVENTS visionPoiEvents[];
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
X121SMCCycleConditions visionConditions;
result = visionCycleHelper.GetConditions(
visionCycleEvents,
visionPoiEvents,
visionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Cycles POI States ...
XPOIState triggerState = triggerConditions.state;
XPOIState decisionState = decisionConditions.state;
XPOIState analyseState = analyseConditions.state;
XPOIState verificationState = verificationConditions.state;
XPOIState consolidationState = consolidationConditions.state;
XPOIState visionState = visionConditions.state;
//
// Setup Conditions ...
//
result = analyseConditions.x121Conditions.isStrSwitchedToBullish ||
analyseConditions.x121Conditions.isStrSwitchedToBearish;
if (!result)
{
return result;
}
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
conditions.setupTime = cTime;
conditions.dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
//
// Detect Trigger Conditions ...
bool DetectX121SMCXTWPVSiganlTrigger(
//
X121SMCStrategyXTWPVSignalConditions &conditions,
//
string _symbol,
ENUM_TIMEFRAMES _period,
//
XC121SMCCycleHelper *triggerCycleHelper,
XC121SMCCycleHelper *decisionCycleHelper,
XC121SMCCycleHelper *analyseCycleHelper,
XC121SMCCycleHelper *verificationCycleHelper,
XC121SMCCycleHelper *consolidationCycleHelper,
XC121SMCCycleHelper *visionCycleHelper,
//
int maxAllowedSetupAge = 60 //
//
)
{
//
bool result = false;
//
result = conditions.IsSetuped();
if (!result)
{
return result;
}
//
datetime setupTime = conditions.setupTime;
ENUM_X_DIRECTION setupDir = conditions.dir;
//
bool isBullish = IsBullish(setupDir);
bool isBearish = IsBearish(setupDir);
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
int loopback = 10;
//
string symbol = _symbol;
ENUM_TIMEFRAMES period = _period;
//
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = pBar.Init(
symbol,
period,
pIndex //
);
if (!result)
{
return result;
}
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
double points = GetPoints(symbol);
//
int swingLoopback = 9;
double ll = cBar.FindLowest(swingLoopback, MODE_LOW);
double hh = cBar.FindHighest(swingLoopback, MODE_HIGH);
double llDown = cBar.FindLowesttDown(swingLoopback);
double hhUp = cBar.FindHighestUp(swingLoopback);
//
// Cycles Conditions ...
//
// Trigger ...
ENUM_XPOI_EVENTS triggerPoiEvents[];
ENUM_X_CYCLE_EVENTS triggerCycleEvents[];
X121SMCCycleConditions triggerConditions;
result = triggerCycleHelper.GetConditions(
triggerCycleEvents,
triggerPoiEvents,
triggerConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Decision ...
ENUM_XPOI_EVENTS decisionPoiEvents[];
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
X121SMCCycleConditions decisionConditions;
result = decisionCycleHelper.GetConditions(
decisionCycleEvents,
decisionPoiEvents,
decisionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Analyse ...
ENUM_XPOI_EVENTS analysePoiEvents[];
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
X121SMCCycleConditions analyseConditions;
result = analyseCycleHelper.GetConditions(
analyseCycleEvents,
analysePoiEvents,
analyseConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Verification ...
ENUM_XPOI_EVENTS verificationPoiEvents[];
ENUM_X_CYCLE_EVENTS verificationCycleEvents[];
X121SMCCycleConditions verificationConditions;
result = verificationCycleHelper.GetConditions(
verificationCycleEvents,
verificationPoiEvents,
verificationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Consolidation ...
ENUM_XPOI_EVENTS consolidationPoiEvents[];
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
X121SMCCycleConditions consolidationConditions;
result = consolidationCycleHelper.GetConditions(
consolidationCycleEvents,
consolidationPoiEvents,
consolidationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Vision ...
ENUM_XPOI_EVENTS visionPoiEvents[];
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
X121SMCCycleConditions visionConditions;
result = visionCycleHelper.GetConditions(
visionCycleEvents,
visionPoiEvents,
visionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Cycles POI States ...
XPOIState triggerState = triggerConditions.state;
XPOIState decisionState = decisionConditions.state;
XPOIState analyseState = analyseConditions.state;
XPOIState verificationState = verificationConditions.state;
XPOIState consolidationState = consolidationConditions.state;
XPOIState visionState = visionConditions.state;
//
// Trigger Conditions ...
//
// Detect Bullish Conditions ...
isBullish =
isBullish &&
cBar.IsBullish();
//
// Detect Bearish Conditions ...
isBearish =
isBearish &&
cBar.IsBearish();
//
result = isBullish ||
isBearish;
if (!result)
{
//
// Cleanup Setup Conditions ...
int setupAge = conditions.GetSetupAge();
if (IsValidSize(setupAge) &&
IsValidSize(maxAllowedSetupAge) &&
setupAge >= maxAllowedSetupAge)
{
conditions.Clean();
}
//
return result;
}
//
// Detect Nearest Pivot Point ...
//
// Detect Target ...
double target = CalculateTarget(
cBar,
analyseState,
setupDir //
);
if (target == 0)
{
//
target = CalculateTarget(
cBar,
verificationState,
setupDir //
);
}
//
double oppositTarget = CalculateTarget(
cBar,
analyseState,
Opposit(setupDir) //
);
//
double entry = GetEntry(
conditions.symbol,
setupDir //
);
//
// Filling SL Candidates ...
//
double sls[];
//
double atr = triggerConditions.x121Conditions.atrBuffer[1];
double peak = triggerConditions.x121Conditions.peaksBuffer[1];
double vale = triggerConditions.x121Conditions.valesBuffer[1];
//
if (isBullish)
{
//
double lowerVale = triggerCycleHelper.mX121Helper.xpvHelper.GetLowerVale(vale);
if (lowerVale > 0)
{
//
Add(
lowerVale,
sls //
);
}
}
else if (isBearish)
{
//
double higherPeak = triggerCycleHelper.mX121Helper.xpvHelper.GetHigherPeak(peak);
if (higherPeak > 0)
{
//
Add(
higherPeak,
sls //
);
}
}
//
if (ArraySize(sls) == 0)
{
}
//
double slsMin = GetMin(sls);
double slsMax = GetMax(sls);
//
double sl = isBullish
? slsMin - atr
: slsMax + atr;
double risk = MathAbs(entry - sl);
double targetDelta = 2 * (risk / 3);
if (target == 0)
{
//
int minTargetPint = 50;
double minTargetPointValue = minTargetPint * points;
if (targetDelta < minTargetPointValue)
{
targetDelta = minTargetPointValue;
}
//
// Force Target On Half Risk ...
target =
isBullish
? entry + targetDelta
: entry - targetDelta;
//
target = 0;
//
}
//
// Ignore Target ...
target = 0;
//
// Filling Conditions Props ...
conditions.sl = sl;
conditions.target = target;
conditions.triggerTime = cTime;
conditions.type = isBullish
? X_POSITION_TYPE_LONG
: X_POSITION_TYPE_SHORT;
//
return result;
}
//
// Draw Signal ...
int DrawX121SMCXTWPVSiganl(
X121SMCStrategyXTWPVSignalConditions &conditions,
XCBaseObject *&drawnObjects[],
XCPOIDrawer *drawer //
)
{
//
int result = 0;
//
Clean(drawnObjects);
//
if (drawer == NULL)
{
return result;
}
//
bool isSetuped = conditions.IsSetuped();
if (!isSetuped)
{
return result;
}
//
bool isBullish = IsBullish(conditions.dir);
//
result = ArraySize(drawnObjects);
//
return result;
}
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,325 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 ???
// Description: ??? ...
//
//
// 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 ??? Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 ???"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
//
// Presentation ...
input group "Presentation";
//
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
//
// Buffers ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#property indicator_chart_window
//
#property indicator_buffers 0
#property indicator_plots 0
//
// Plot Buffers ...
//
// Data Buffers ...
//
int mLastBufferIndex = 20;
//
// 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;
}
//
// Initialize Indicator Handlers ...
//
// 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;
}
/**
* 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);
//
// Validate Calculated Bars ...
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// 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 =
//
false
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// Data Buffers ...
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* 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)
{
}
else
{
FillBuffersZero(bar_index);
}
}
//
// Custom ...
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
}
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,279 @@
<mxfile host="65bd71144e">
<diagram id="QReEEfusIJtThQdlE9lK" name="Page-1">
<mxGraphModel dx="1382" dy="987" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="15" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="3">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="420" y="100"/>
<mxPoint x="100" y="100"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="16" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="6">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="420" y="100"/>
<mxPoint x="780" y="100"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="2" value="Position" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="360" y="40" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="17" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="4">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="100" y="340"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="18" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="5">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="100" y="620"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="3" value="States" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="40" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="27" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="420"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="28" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="500"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="4" value="InDrawdown" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="320" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="29" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="700"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="30" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="780"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="5" value="InProfit" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="600" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="19" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="8">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="20" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="9">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="21" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="11">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="22" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="10">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="460"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="6" value="Events" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="720" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="31" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="38" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="220"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="39" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="220"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="43" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="220"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8" value="Bullish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="200" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="32" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="37" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="300"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="40" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="300"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="44" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="300"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9" value="Bearish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="280" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="34" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="400" as="targetPoint"/>
<Array as="points">
<mxPoint x="520" y="460"/>
<mxPoint x="520" y="360"/>
<mxPoint x="260" y="360"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="35" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="460"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="42" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="680" as="targetPoint"/>
<Array as="points">
<mxPoint x="560" y="460"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="46" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="24">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="810" as="targetPoint"/>
<Array as="points">
<mxPoint x="560" y="460"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="10" value="Bearish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="440" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="33" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="380"/>
<mxPoint x="520" y="360"/>
<mxPoint x="260" y="360"/>
<mxPoint x="260" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="36" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="380"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="41" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="380"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="45" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="380"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="11" value="Bullish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="360" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="23" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="680" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="24" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="760" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="25" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="400" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="26" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="480" width="120" height="40" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@@ -0,0 +1,506 @@
/**
* XColor Tools Module ...
* a module for handle colorify text contents in node js ...
*
* Maintainer
*
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
*/
//
//#region Module Imports ...
const XValueTools = require("./x-value.tools");
//#endregion
//
//#region Constants ...
/**
* these are available style which can applied to an string ...
*/
const AVAILABLE_STYLES = {
//
Bold: "\x1b[1m",
Dim: "\x1b[2m",
Underlined: "\x1b[4m",
Blink: "\x1b[5m",
ReverseFandB: "\x1b[7m",
Hidden: "\x1b[8m",
//
// Commonly used for reset all Styles ...
Reset: "\x1b[0m"
};
/**
* these are available foreground colors which can applied to an string ...
*/
const AVAILABLE_FOREGROUND_COLORS = {
Default: "\x1b[39m",
Black: "\x1b[30m",
Red: "\x1b[31m",
Green: "\x1b[32m",
Yellow: "\x1b[33m",
Blue: "\x1b[34m",
Magenta: "\x1b[35m",
Cyan: "\x1b[36m",
LightGray: "\x1b[37m",
DarkGray: "\x1b[90m",
LightRed: "\x1b[91m",
LightGreen: "\x1b[92m",
LightYellow: "\x1b[93m",
LightBlue: "\x1b[94m",
LightMagenta: "\x1b[95m",
LightCyan: "\x1b[96m",
White: "\x1b[97m",
};
/**
* these are available background colors which can applied to an string ...
*/
const AVAILABLE_BACKGROUND_COLORS = {
Default: "\x1b[49m",
Black: "\x1b[40m",
Red: "\x1b[41m",
Green: "\x1b[42m",
Yellow: "\x1b[43m",
Blue: "\x1b[44m",
Magenta: "\x1b[45m",
Cyan: "\x1b[46m",
LightGray: "\x1b[47m",
DarkGray: "\x1b[100m",
LightRed: "\x1b[101m",
LightGreen: "\x1b[102m",
LightYellow: "\x1b[103m",
LightBlue: "\x1b[104m",
LightMagenta: "\x1b[105m",
LightCyan: "\x1b[106m",
White: "\x1b[107m",
};
/**
* these are available style names, which exports from module and
* users can use them ...
*/
const STYLE_NAMES = {
Bold: "Bold",
Dim: "Dim",
Underlined: "Underlined",
Blink: "Blink",
ReverseFandB: "ReverseFandB",
Hidden: "Hidden",
Reset: "Reset",
};
/**
* these are available color names, which exports from module and
* users can use them ...
*/
const COLOR_NAMES = {
Default: "Default",
Black: "Black",
Red: "Red",
Green: "Green",
Yellow: "Yellow",
Blue: "Blue",
Magenta: "Magenta",
Cyan: "Cyan",
LightGray: "LightGray",
DarkGray: "DarkGray",
LightRed: "LightRed",
LightGreen: "LightGreen",
LightYellow: "LightYellow",
LightBlue: "LightBlue",
LightMagenta: "LightMagenta",
LightCyan: "LightCyan",
White: "White",
};
//#endregion
//
//#region Actions ...
/**
* apply specified style and color on a content ...
*
* @param {string} content specified content for styling ...
* @param {string} color specific color name for using to styling ...
* @param {string} style soecufic style name to use ...
* @param {boolean} toForeground apply specified color as foreground ...
* @param {boolean} toBackground apply specified color as background ...
* @returns {string} styled content ...
*/
function apply(
content,
color,
style,
toForeground = true,
toBackground = false
) {
//
let result = content;
//
// Validate Arg ...
if (!XValueTools.isValidArg(content)) {
return result;
}
//
// Detect and Validate Style and Apply it ...
let eStyle = AVAILABLE_STYLES[style];
if (XValueTools.isValidArg(eStyle)) {
result = `${eStyle}${result}${AVAILABLE_STYLES.Reset}`;
}
//
// Detect and Validate Foreground Color and Apply it ...
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
if (
!!toForeground
&& XValueTools.isValidArg(eFColor)
) {
result = `${eFColor}${result}${AVAILABLE_STYLES.Reset}`;
}
//
// Detect and Validate Background Color and Apply it ...
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
if (
!!toBackground
&& XValueTools.isValidArg(eBColor)
) {
result = `${eBColor}${result}${AVAILABLE_STYLES.Reset}`;
}
}
/**
* apply specific style on a content ...
*
* @param {string} content specific content which going to styled ...
* @param {string} style a member of STYLE_NAMES which specified that which style going to applied to content ...
* @returns {string} styled content ...
*/
function applyStyle(content, style) {
//
// Validate Arg ...
if (!XValueTools.isValidArg(content)) {
return content;
}
//
let eStyle = AVAILABLE_STYLES[style];
if (eStyle === undefined) {
return content;
}
//
return `${eStyle}${content}${AVAILABLE_STYLES.Reset}`;
}
/**
* apply specific foreground color on a content ...
*
* @param {string} content specific content which going to colorified ...
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
* @returns {string} colorified content ...
*/
function applyForegroundColor(content, color) {
//
// Validate Arg ...
if (!XValueTools.isValidArg(content)) {
return content;
}
//
let eColor = AVAILABLE_FOREGROUND_COLORS[color];
if (eColor === undefined) {
return content;
}
//
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
}
/**
* apply specific background color on a content ...
*
* @param {string} content specific content which going to colorified ...
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
* @returns {string} colorified content ...
*/
function applyBackgroundColor(content, color) {
//
// Validate Arg ...
if (!XValueTools.isValidArg(content)) {
return content;
}
//
let eColor = AVAILABLE_BACKGROUND_COLORS[color];
if (eColor === undefined) {
return content;
}
//
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
}
/**
* generate style and color applier expression ...
*
* @param {string} color specific color name for using to styling ...
* @param {string} style soecufic style name to use ...
* @param {boolean} reset close applier string by reset styles ...
* @param {boolean} toForeground apply specified color as foreground ...
* @param {boolean} toBackground apply specified color as background ...
* @returns {string} style and color applier string ...
*/
function getApplier(
style = "",
color = "",
reset = false,
toForeground = true,
toBackground = false
) {
//
let result = "";
//
// Detect and Validate Style and Apply it ...
let eStyle = AVAILABLE_STYLES[style];
if (XValueTools.isValidArg(eStyle)) {
result = `${eStyle}`;
}
//
// Detect and Validate Foreground Color and Apply it ...
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
if (
!!toForeground
&& XValueTools.isValidArg(eFColor)
) {
result = `${eFColor}`;
}
//
// Detect and Validate Background Color and Apply it ...
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
if (
!!toBackground
&& XValueTools.isValidArg(eBColor)
) {
result = `${eBColor}`;
}
//
if (
!!reset &&
result.length > 0
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
/**
* generate style applier expression ...
*
* @param {string} style soecufic style name to use ...
* @param {boolean} reset close applier string by reset styles ...
* @returns {string} style applier string ...
*/
function getStyleApplier(
style = "",
reset = false
) {
//
let result = "";
//
// Detect and Validate Style and Apply it ...
let eStyle = AVAILABLE_STYLES[style];
if (XValueTools.isValidArg(eStyle)) {
result = `${eStyle}`;
}
//
if (
!!reset &&
result.length > 0
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
/**
* generate color applier expression ...
*
* @param {string} color specific color name for using to styling ...
* @param {boolean} reset close applier string by reset styles ...
* @param {boolean} toForeground apply specified color as foreground ...
* @param {boolean} toBackground apply specified color as background ...
* @returns {string} color applier string ...
*/
function getColorApplier(
color = "",
reset = false,
toForeground = true,
toBackground = false
) {
//
let result = "";
//
// Detect and Validate Foreground Color and Apply it ...
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
if (
!!toForeground
&& XValueTools.isValidArg(eFColor)
) {
result = `${eFColor}`;
}
//
// Detect and Validate Background Color and Apply it ...
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
if (
!!toBackground
&& XValueTools.isValidArg(eBColor)
) {
result = `${eBColor}`;
}
//
if (
!!reset &&
result.length > 0
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
/**
* colorified specific content ...
*
* @param {string} content specified content for styling ...
* @param {string} color specific color name for using to styling ...
* @param {boolean} toForeground apply specified color as foreground ...
* @param {boolean} toBackground apply specified color as background ...
* @returns {string}
*/
function colorifyContent(
content = "",
color = "",
toForeground = true,
toBackground = false
) {
//
let result = content;
//
if (!XValueTools.isValidArg(content)) {
return result;
}
//
// Finde Colors ...
//
// Detect and Validate Foreground Color and Apply it ...
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
if (
!!toForeground
&& XValueTools.isValidArg(eFColor)
) {
result = `${eFColor}${result}`;
}
//
// Detect and Validate Background Color and Apply it ...
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
if (
!!toBackground
&& XValueTools.isValidArg(eBColor)
) {
result = `${eBColor}${result}`;
}
//
if (
result.length > 0
&& (
XValueTools.isValidArg(eFColor) ||
XValueTools.isValidArg(eBColor)
)
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
/**
* apply style on specific content ...
*
* @param {string} content specified content for styling ...
* @param {string} style soecufic style name to use ...
* @returns {string}
*/
function stylifiyContent(
content = "",
style = "",
) {
//
let result = content;
//
if (!XValueTools.isValidArg(content)) {
return result;
}
//
// Detect and Validate Style and Apply it ...
let eStyle = AVAILABLE_STYLES[style];
if (XValueTools.isValidArg(eStyle)) {
result = `${eStyle}${result}`;
}
//
if (
result.length > 0
&& XValueTools.isValidArg(eStyle)
) {
result = `${result}${AVAILABLE_STYLES.Reset}`;
}
//
return result;
}
//#endregion
//
//#region Module Exports ...
module.exports = {
//
STYLE_NAMES,
COLOR_NAMES,
//
apply,
applyStyle,
getApplier,
getColorApplier,
getStyleApplier,
colorifyContent,
stylifiyContent,
applyForegroundColor,
applyBackgroundColor,
}
//#endregion
@@ -0,0 +1,887 @@
/**
* XFile Tools Module ...
* a module for handle all file/folder manipulating task in node js ...
*
* Maintainer
*
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
*/
//
//#region Module Imports ...
const fs = require('fs');
const os = require('os');
const Path = require('path');
const http = require('http');
const https = require('https');
const XValueTools = require('./x-value.tools');
//#endregion
//
//#region Constants ...
/**
* current os path separators ...
*/
const PathSeparator = Path.sep;
/**
* current directory ...
*/
const CurrentDir = __dirname;
//#endregion
//
//#region Actions ...
//
//#region Global ...
/**
* retrieve a path status ...
*
* @param {string} path a path value to check ...
* @returns an stat object ...
*/
function getStatus(path = '') {
//
if (!XValueTools.isValidArg(path)) {
return undefined;
}
//
return fs.statSync(path);
}
/**
* retrieve user's Home path ...
*
* @returns {string} a path ...
*/
function getHomePath() {
return os.homedir();
}
//#endregion
//
//#region Path ...
/**
* retrieve the base name of specific address path ...
*
* @param {string} path address of file or folder ...
* @returns string ...
*/
function basename(path = '') {
//
if (!XValueTools.isValidArg(path)) {
return '';
}
//
const result = Path.basename(path);
return result;
}
/**
* join several path segments together ...
*
* @param {...string} path path params ...
* @returns a joined paths ...
*/
function joinPath(...path) {
return Path.join(...path);
}
/**
* resolve a relative path to absolute ...
*
* @param {string[]} path a path value to check ...
* @returns {string}
*/
function resolvePath(...path) {
return Path.resolve(...path);
}
//#endregion
//
//#region File ...
/**
* determines a path destination is a file or not ...
*
* @param {string} path a path value to check ...
* @returns a boolean value ...
*/
function isFileExists(path = '') {
//
if (!XValueTools.isValidArg(path)) {
return false;
}
//
try {
const stat = getStatus(path);
if (!stat) {
return false;
}
//
return stat.isFile();
} catch {
return false;
}
}
/**
* remove a file ...
*
* @param {string} path a file path ...
* @returns {Promise<boolean>} action done or not ...
*/
function removeFile(path = '') {
return new Promise((resolve) => {
//
if (!isFileExists(path)) {
resolve(false);
}
//
fs.unlink(path, (err) => {
//
if (err) {
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* copy a file to destination path ...
*
* @param {string} source source file path ...
* @param {string} dest dest folder path ...
* @returns {Promise<boolean>} action done or not ...
*/
function copyFile(
source = '',
dest = ''
) {
return new Promise((resolve) => {
//
if (
!isFileExists(source) ||
!isDirectoryExists(dest)
) {
resolve(false);
return;
}
//
const destFilePath = Path.join(dest, Path.basename(source));
fs.copyFile(source, destFilePath, (err) => {
//
if (err) {
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* reading specified file content ...
*
* @param {string} path a file path ...
* @returns {Promise<string>} file content ...
*/
function readFile(path = '') {
return new Promise((resolve) => {
//
if (!isFileExists(path)) {
resolve('');
return;
}
//
fs.readFile(path, 'utf8', (err, content) => {
//
if (err) {
resolve(undefined);
return;
}
//
resolve(content);
});
});
}
/**
* write content to a file ...
*
* @param {string} path a file path ...
* @param {string} content the content which going to write to the file ...
* @param {bool} overwrite determines file overwrite if exists ...
* @returns {Promise<boolean>} action done or not ...
*/
function writeFile(
path = '',
content = '',
overwrite = true
) {
return new Promise((resolve) => {
//
if (isFileExists(path) && !overwrite) {
//
resolve(false);
return;
}
//
// Normalize Content ...
content = XValueTools.isValidArg(content) ?
content :
'';
//
fs.writeFile(path, content, (err) => {
//
if (err) {
//
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* create a file ...
*
* @param {string} path file path ...
* @param {string} fileName file name ...
* @returns {Promise<boolean>} action done or not ...
*/
function createFile(
path = '',
fileName = ''
) {
return new Promise((resolve) => {
//
const filePath = Path.join(path, fileName);
if (
isFileExists(filePath) ||
!XValueTools.isValidArg(path) ||
!XValueTools.isValidArg(fileName)
) {
//
resolve(false);
return;
}
//
fs.writeFile(filePath, '', (err) => {
//
if (err) {
//
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* remove a file name extension ...
*
* @param {string} name
* @returns {string} name without extension ...
*/
function removeFileExtension(name = '') {
return name.substring(0, name.lastIndexOf('.')) || name;
}
/**
* retrieve a file extension ...
*
* @param {string} path a path which locate a file ...
* @returns {string}
*/
function getFileExtension(path = '') {
//
let result = "";
//
// Validate Arg ...
if (
!XValueTools.isValidArg(path)
|| !isFileExists(path)
) {
return result;
}
//
// Retrieve just file name ...
const fileName = basename(path);
result = fileName.replace(
removeFileExtension(fileName),
""
);
//
return result;
}
/**
* retrieve all files list recursively from specific path ...
*
* @param {string} path a source folder path ...
* @param {string[]} extensions which file extensions need to be listed, live empty for all files ...
* @returns {Promise<string[]>}
*/
async function getRecursiveFilesList(
path = "",
extensions = []
) {
//
let result = [];
//
// Validate Args ...
if (
!XValueTools.isValidArg(path)
|| !isDirectoryExists(path)
) {
return result;
}
//
const contents = await getDirectoryContents(path);
for (const item of contents) {
//
const itemPath = joinPath(
path,
item
);
//
const isItemFile = isFileExists(itemPath);
if (isItemFile) {
//
const itemFileExtension = getFileExtension(itemPath);
const isFileInSupportedExtensions =
extensions === undefined || extensions.length === 0
? true
: extensions.includes(itemFileExtension)
;
if (isFileInSupportedExtensions) {
result.push(itemPath);
}
} else if (isDirectoryExists(itemPath)) {
//
const itemPathFiles = await getRecursiveFilesList(itemPath, extensions);
result.push(...itemPathFiles);
}
}
//
return result;
}
/**
* Extract Specific files from a folder and it's content ...
*
* @param {string} path Folder Path ...
* @returns
*/
async function extractFiles(path = "", ext = [], excludeWorkspaceFolders = []) {
//
const result = [];
//
if (!ext || ext.length == 0) {
return result;
}
//
const pathContent = await getDirectoryContents(path);
if (!pathContent || pathContent.length == 0) {
return result;
}
//
// Loop through Content ...
for (const c of pathContent) {
//
// Prepare full path ...
const cPath = joinPath(path, c);
//
// check content path is file or not ...
const isCFile = isFileExists(cPath);
const isCDirectory = isDirectoryExists(cPath);
if (isCFile) {
//
// Check it is MQL file or not ...
const cExt = getFileExtension(cPath);
if (ext.includes(cExt)) {
result.push(cPath);
}
} else if (isCDirectory) {
//
const destFolderName = basename(cPath);
const isExcluded = excludeWorkspaceFolders.includes(destFolderName);
if (isExcluded) {
continue;
}
//
const cFiles = await extractFiles(cPath, ext);
if (cFiles && cFiles.length > 0) {
result.push(...cFiles);
}
}
}
//
return result;
}
//#endregion
//
//#region Directory ...
/**
* create a directory ...
*
* @param {string} path destination path including dir name ...
* @param {boolean} recursive create directories recursively ...
* @returns action done or not ...
*/
function createDirectory(
path = '',
recursive = true
) {
//
let result = false;
//
if (
isDirectoryExists(path) ||
!XValueTools.isValidArg(path)
) {
return false;
}
//
try {
//
fs.mkdirSync(path, { recursive: recursive });
result = true;
return result;
} catch {
return false;
}
}
/**
* remove a directory ...
*
* @param {string} path destination path including dir name ...
* @param {boolean} recursive removes directories recursively ...
* @returns {Promise<boolean>} action done or not ...
*/
function removeDirectory(
path = '',
recursive = false
) {
return new Promise((resolve) => {
//
if (!isDirectoryExists(path)) {
resolve(false);
return;
}
//
fs.rm(path, {
recursive
}, (err) => {
//
if (err) {
resolve(false);
return;
}
//
resolve(true);
});
});
}
/**
* determines a path destination is a directory or not ...
*
* @param {string} path a folder path ...
* @returns represent destnation path is Directory or not ...
*/
function isDirectoryExists(path = '') {
//
if (!XValueTools.isValidArg(path)) {
return false;
}
//
try {
//
const isExists = fs.existsSync(path);
if (!isExists) {
return false;
}
//
const stat = getStatus(path);
if (!stat) {
return false;
}
//
const result = stat.isDirectory();
return result;
} catch {
return false;
}
}
/**
* retrieve a directory content ...
*
* @param {string} path a folder path ...
* @returns {Promise<string[]>} a collection of folder files ...
*/
function getDirectoryContents(path = '') {
return new Promise((resolve) => {
//
if (!isDirectoryExists(path)) {
resolve([]);
return;
}
//
fs.readdir(path, (err, content) => {
//
if (err) {
resolve([]);
return;
}
//
resolve(content);
});
});
}
/**
* retrieve a directory files ...
*
* @param {string} path a folder path ...
* @returns {Promise<string[]>} a collection of folder files ...
*/
function getDirectoryFiles(
path = '',
containsHiddenFiles = false
) {
return new Promise((resolve) => {
//
if (!isDirectoryExists(path)) {
resolve([]);
return;
}
//
fs.readdir(path, (err, content) => {
//
if (err) {
resolve([]);
return;
}
//
if (!containsHiddenFiles) {
content = content.filter(c => !c.startsWith('.'));
}
//
const result = [];
content
.forEach(c => {
//
const cPath = Path.join(path, c);
if (isFileExists(cPath)) {
result.push(c);
}
});
//
resolve(result);
});
});
}
/**
* retrieve a directory folders ...
*
* @param {string} path a folder path ...
* @returns {Promise<string[]>} a collection of folder names ...
*/
function getDirectoryFolders(path = '') {
return new Promise((resolve) => {
//
if (!isDirectoryExists(path)) {
resolve([]);
return;
}
//
fs.readdir(path, (err, content) => {
//
if (err) {
resolve([]);
return;
}
//
const result = [];
content.forEach(c => {
//
const cPath = Path.join(path, c);
if (isDirectoryExists(cPath)) {
result.push(c);
}
});
//
resolve(result);
});
});
}
/**
* copy a folder with all of it's content to dest ...
*
* @param {string} source source folder path ...
* @param {string} dest dest folder path ...
* @returns {Promise<boolean>} action done or not ...
*/
async function copyFolder(
source = '',
dest = ''
) {
//
if (
!isDirectoryExists(source) ||
!XValueTools.isValidArg(dest) ||
!XValueTools.isValidArg(source)
) {
return false;
}
//
const folderName = Path.basename(source);
const destPath = Path.join(dest, folderName);
//
// Create Dest Path folder if not exists ...
if (!isDirectoryExists(destPath)) {
//
let result = createDirectory(destPath, true);
if (!result) {
return false;
}
}
//
// Files ...
const files = await getDirectoryFiles(source);
if (files && files.constructor === Array && files.length > 0) {
//
const filesPromises = files.map(file => copyFile(Path.join(source, file), destPath));
const filesResult = (await Promise.all(filesPromises)).every(r => !!r);
if (!filesResult) {
return false;
}
}
//
// Folders ...
const folders = await getDirectoryFolders(source);
if (folders && folders.constructor === Array && folders.length > 0) {
//
const folderPromises = folders.map(folder => copyFolder(Path.join(source, folder), destPath));
const filesResult = (await Promise.all(folderPromises)).every(r => !!r);
if (!filesResult) {
return false;
}
}
//
return true;
}
//#endregion
//
//#region Downloader ...
/**
* download a file from specific url and store it ...
*
* @param {string} filepath the file name and path which required to put download file on it ...
* @param {string} url the web url for downloading ...
*/
function download(filepath, url) {
//
// Validate Args ...
if (
!XValueTools.isValidArg(url)
|| !XValueTools.isValidURL(url)
|| !XValueTools.isValidArg(filepath)
) {
return;
}
//
var file = fs.createWriteStream(filepath);
//
if (url.startsWith('https:')) {
https.get(url, function (response) {
response.pipe(file);
});
} else if (url.startsWith('http:')) {
http.get(url, function (response) {
response.pipe(file);
});
}
}
//#endregion
//
//#region JSON ...
/**
* read and parse a JSON content from a file ...
*
* @param {string} path source file path ...
* @returns {any}
*/
function readJSON(path = "") {
//
// Validate Args ...
if (!isFileExists(path)) {
return undefined;
}
//
let result = undefined;
try {
result = require(path);
} catch {
result = undefined;
}
//
return result;
}
/**
* write a JSON Object content into a file ...
*
* @param {string} path dest file path ...
* @param {any} content an object which required to write to file ...
* @returns {Promise<boolean>}
*/
async function writeJSON(
path = "",
content = undefined
) {
//
let result = false;
//
// Validate Args ...
if (!XValueTools.isValidArg(path)) {
return result;
}
//
// Normallize Content ...
if (content === undefined) {
content = {};
}
//
const contentString = XValueTools.beautifyJSON(content);
//
result = await writeFile(
path,
contentString,
true
);
//
return result;
}
//#endregion
//#endregion
//
//#region Module Exports ...
module.exports = {
//
CurrentDir,
PathSeparator,
//
getStatus,
getHomePath,
//
basename,
joinPath,
resolvePath,
//
download,
//
readJSON,
writeJSON,
//
copyFile,
readFile,
writeFile,
createFile,
removeFile,
isFileExists,
getFileExtension,
removeFileExtension,
getRecursiveFilesList,
extractFiles,
//
copyFolder,
createDirectory,
removeDirectory,
isDirectoryExists,
getDirectoryFiles,
getDirectoryFolders,
getDirectoryContents,
};
//#endregion
@@ -0,0 +1,219 @@
/**
* XShell Tools Module ...
* a module for handling shell actions and retrieve OS Info in node js ...
*
* Maintainer
*
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
*/
//
//#region Imports ...
const os = require('os');
const process = require('process');
const { exec } = require("child_process");
const XFileTools = require('./x-file.tools');
//#endregion
//
//#region Constants ...
//
const OS = {
Aix: 'aix',
Darwin: 'darwin',
FreeBSD: 'freebsd',
Linux: 'linux',
OpenBSD: 'openbsd',
SnOS: 'sunos',
Windows: 'win32'
};
//
const isWindows = process.platform === OS.Windows;
//#endregion
//
//#region Actions ...
//
//#region Pure shell commands ...
/**
* execute a command using NodeJS on shell ...
*
* @param {string} cmd command to execute ...
* @param {string} cwd working directory ...
*
* @returns Promise<any, errr> instance ...
*/
function execute(cmd, cwd) {
return new Promise((resolve, reject) => {
//
if (!cmd || cmd.toString().length === 0 || (cwd && !XFileTools.isDirectoryExists(cwd))) {
reject('invalid args ...');
return;
}
//
exec(cmd, { cwd }, (err, result, stdError) => {
//
if (err) {
reject(err);
return;
}
//
if (stdError) {
//
// reject(stdError);
// return;
}
//
resolve(result);
});
});
};
/**
* determines a command exists on host or not ...
*
* @param {string} name specific command name ...
*
* @returns boolean Promise ...
*/
function checkCommandExists(name) {
return new Promise(resolve => {
//
if (!name) {
resolve(false);
return;
}
//
const cmd = isWindows ? `${name} >nul 2>&1` : `type ${name} >/dev/null 2>&1`;
execute(cmd).then(result => {
resolve(true);
})
.catch(err => {
resolve(false);
});
});
}
//#endregion
//
//#region required commands state ...
/**
* check al required commands exists or not ...
*
* @returns
*/
async function isRequiredCommandsExists() {
//
let result = false;
//
// const isTarExists = await isTarCommandExists();
// const isCatExists = await isCatCommandExists();
// const isGrepExists = await isGrepCommandExists();
// const isSedExists = await isSedCommandExists();
const isNpmExists = await isNpmCommandExists();
const isNgExists = await isNgCommandExists();
const isIonicExists = await isIonicCommandExists();
const isCordovaExists = await isCordovaCommandExists();
//
result = isNpmExists
&& isNgExists
&& isIonicExists
&& isCordovaExists
;
//
return result;
}
/**
* retrieve required commands state object ...
*
* @returns
*/
async function getRequiredCommandsStates() {
//
const result = {};
//
// const isTarExists = await isTarCommandExists();
// const isCatExists = await isCatCommandExists();
// const isGrepExists = await isGrepCommandExists();
// const isSedExists = await isSedCommandExists();
const isNpmExists = await isNpmCommandExists();
const isNgExists = await isNgCommandExists();
const isIonicExists = await isIonicCommandExists();
const isCordovaExists = await isCordovaCommandExists();
//
result['npm'] = isNpmExists;
result['ng'] = isNgExists;
result['ionic'] = isIonicExists;
result['cordova'] = isCordovaExists;
//
return result;
}
//#endregion
//
//#region Commonly used Command Checkers ...
/**
* determines npm command exists or not ...
*
* @returns
*/
function isNpmCommandExists() {
return checkCommandExists('npm');
}
/**
* determines ng command exists or not ...
*
* @returns
*/
function isNgCommandExists() {
return checkCommandExists('ng');
}
/**
* determines ionic command exists or not ...
*
* @returns
*/
function isIonicCommandExists() {
return checkCommandExists('ionic');
}
/**
* determines cordova command exists or not ...
*
* @returns
*/
function isCordovaCommandExists() {
return checkCommandExists('cordova');
}
//#endregion
//#endregion
//
//#region Module Exports ...
module.exports = {
//
execute,
checkCommandExists,
isRequiredCommandsExists,
getRequiredCommandsStates,
//
isNgCommandExists,
isIonicCommandExists,
isCordovaCommandExists,
}
//#endregion
@@ -0,0 +1,268 @@
/**
* DataType Tools Module ...
* a module for manipulate and detect supported data types in node js ...
*
* Maintainer
*
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
*/
//
//#region Constants ...
/**
* all supported data types ...
*/
const DataTypes = {
Null: 'null',
Date: 'date',
Array: 'array',
Object: 'object',
String: 'string',
Number: 'number',
Unknown: 'unknown',
Boolean: 'boolean',
Function: 'function',
Undefined: 'undefined',
};
//#endregion
//
//#region Actions ...
/**
* detect type of a content ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function getType(value) {
//
const type = typeof value;
//
let result = DataTypes.Unknown;
let dateIdentifier = '[object Date]';
let constructor = value && value.constructor ?
value.constructor.toString() :
'';
//
switch (type) {
//
case 'undefined':
result = DataTypes.Undefined;
break;
//
case 'boolean':
result = DataTypes.Boolean;
break;
//
case 'string':
result = DataTypes.String;
break;
//
case 'number':
result = DataTypes.Number;
break;
//
case 'function':
result = DataTypes.Function;
break;
//
case 'object':
//
// Null ...
if (value === null) {
result = DataTypes.Null;
} else
//
// Array ...
if (Array.isArray(value)) {
result = DataTypes.Array;
} else
//
// Data ...
if (
value instanceof Date ||
isFunction(value.getMonth) ||
constructor.includes(dateIdentifier) ||
Object.prototype.toString.call(value) === dateIdentifier
) {
result = DataTypes.Date;
} else
//
// Object ...
{
result = DataTypes.Object;
}
break;
//
default:
result = DataTypes.Unknown;
break;
}
//
return result;
}
/**
* retrieve an object constructor ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function getConstructor(value) {
//
const result = value && value.constructor ?
value.constructor.toString() :
'';
//
return result;
}
/**
* retrieve an object prototype ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function getPrototype(value) {
//
const result = value ?
Object.prototype.toString.call(value) :
'';
//
return result;
}
/**
* check an object is null or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isNull(value) {
return getType(value) === DataTypes.Null;
}
/**
* check an object is undefined or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isUndefined(value) {
return getType(value) === DataTypes.Undefined;
}
/**
* check an object is null or undefined or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isNullOrUndefined(value) {
return isNull(value) || isUndefined(value);
}
/**
* check an object is a date or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isDate(value) {
return getType(value) === DataTypes.Date;
}
/**
* check an object is number or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isNumber(value) {
return getType(value) === DataTypes.Number;
}
/**
* check an object is string or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isString(value) {
return getType(value) === DataTypes.String;
}
/**
* check an object is boolean or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isBoolean(value) {
return getType(value) === DataTypes.Boolean;
}
/**
* check an object is an Array or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isArray(value) {
return getType(value) === DataTypes.Array;
}
/**
* check an object is and Object or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isObject(value) {
return getType(value) === DataTypes.Object;
}
/**
* check an object is a Function or not ...
*
* @param {any} value the content which going to check ...
* @returns
*/
function isFunction(value) {
return getType(value) === DataTypes.Function;
}
//#endregion
//
//#region Module Exports ...
module.exports = {
//
DataTypes,
//
getType,
getConstructor,
getPrototype,
isNull,
isUndefined,
isNullOrUndefined,
isDate,
isNumber,
isString,
isBoolean,
isArray,
isObject,
isFunction,
}
//#endregion
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,542 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XTest MQL5 Expert Advisor
// -------------------------------------------------
// Name: XEATemplate
// Description: a Template For Exper Advisors
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////x
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XEATemplate"
#property strict
//
#define ShortName "XEATemplate"
//
// Imports ...
#include "../Classes/x-saherelm.xalert.class.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
#include "../Helpers/x-saherelm.xcc.helper.mq5"
#include "../Helpers/x-saherelm.xct.helper.mq5"
//
// Inputs ...
//
// Common ...
input group "Common";
input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
//
// Alert ...
// Here we Provider All Requirements for
// Configuring Alert Provider ...
input group "Alert";
input bool eAEnableAlerts = true; // Enable Alerts
input bool eALogAlerts = true; // Log Alerts
input bool eAMailAlerts = false; // Mail Alerts
input bool eAPushAlerts = false; // Push Alerts
input bool eATerminalAlerts = false; // Terminal Alerts
//
// Time Report ...
input group "Reports";
input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = false; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
//
// Define Local Variables ...
//
string eaLogTag; // EA Log Prefix ...
XSCAlert *eaAlert; // Alert Provider for Expert Adviser ...
XSCTrade *eaTrader; // Trader of Expert Adviser ...
XTimeTracker eaTimeTracker; // Time Tracker for Providing Reports ...
XSCXCTHelper *eaCHelper; // Bar Timer Indicator Helper class ...
XSCXCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs and Required Parameters
// for EA to Works fine ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Timer ...
if (!InitTimer()) {
return INIT_FAILED;
}
//
// Initialize all Requirements ...
if (!InitEA())
{
return INIT_FAILED;
}
//
// Initialize all GUI Objects and Classes ...
if (!InitGUI())
{
return INIT_FAILED;
}
//
// Alert Initialization ...
string msg = "Initialized Successfully ...";
eaAlert.Alert(msg);
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
// Destroy Timer ...
DestroyTimer();
//
// Destroy all GUI Requirements ...
DestroyGUI();
//
// Alert De Initialization Succeeded ...
string msg = "De Initialized Successfully ...";
eaAlert.Alert(msg);
//
// Destroy all EA Requirements ...
DestroyEA();
}
//
// On Tick Handler ...
void OnTick()
{
//
UpdateGUI();
HandleReportTime();
UpdatePositionsState();
//
// TODO: Implemetn Tick Processors Algorithm ...
}
//
// Handle On Trade Event ...
void OnTrade()
{
eaTrader.HandleOnTrade();
}
//
// On Timer ...
void OnTimer()
{
//
// TODO: Implement Time Based Functionalities ...
}
//
// Chart Event Handler ...
void OnChartEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
//
// Handle OnClick Event ...
if (id == CHARTEVENT_OBJECT_CLICK)
{
HandleOnClickEvent(sparam);
}
}
//
// Custom Event Handlers ...
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Force Close a Position ...
*
* @param ticket: Position Ticket ...
* @param position: XPosition ...
* @param comment: Closing Comment ...
*/
void OnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
//
HandleReportBalance();
}
//
// Custom Functions ...
/**
* Validate all Inputs of Expert Adviser ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
eaSlippage > 0 &&
eaMagicNumber > 0
//
);
if (!isCommonValid)
{
//
errMessage += "common configurations error;" + "\n";
}
//
result =
//
// Common ...
isCommonValid &&
//
// Otere ...
true
//
;
//
if (!result)
{
//
// Since here Logger not Initiallized, we Use Raw Print Command ...
Print(ShortName + " Errors: \n", errMessage);
}
//
return result;
}
/**
* Initialize Timer ...
*
* @return ( bool )
*/
bool InitTimer() {
//
bool result = false;
//
// TODO: Initialize Timer if necessary ...
// result = EventSetTimer(1);
// result = EventSetMillisecondTimer(100);
result = true;
//
return result;
}
/**
* Destroy Timer ...
*/
void DestroyTimer() {
//
// TODO: Use This ...
// EventKillTimer();
}
/**
* Initialize all Requirements for Working Fine ...
*
* @return ( bool )
*/
bool InitEA()
{
//
bool result = false;
//
// Locally Apply Changes on Prefix ...
eaLogTag = ShortName + ">" + eaLogSuffix;
//
// Bar Timer ...
XCTInputs ctInputs;
ctInputs.Default(); // Default Configurations ...
eaCHelper = new XSCXCTHelper();
result = eaCHelper.Init(
_Symbol,
_Period,
ctInputs //
);
if (!result)
{
return result;
}
//
// Bar Styles ...
XCCInputs ccInputs;
ccInputs.Default(); // Default Configurations ...
eaCCHelper = new XSCXCCHelper();
result = eaCCHelper.Init(
_Symbol,
_Period,
ccInputs //
);
if (!result)
{
return result;
}
//
// Create Instance of Alert Class and Configure it ...
eaAlert = new XSCAlert();
eaAlert.SetPrefix(eaLogTag);
eaAlert.SetLogAlerts(eALogAlerts);
eaAlert.SetMailAlerts(eAMailAlerts);
eaAlert.SetPushAlerts(eAPushAlerts);
eaAlert.SetEnableAlerts(eAEnableAlerts);
eaAlert.SetTerminalAlerts(eATerminalAlerts);
//
// Create Trader Instance and Configure it ...
eaTrader = new XSCTrade(
eaSlippage,
eaMagicNumber //
);
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
//
return result;
}
/**
* Destroy all Initialized EA Requirements ...
*/
void DestroyEA()
{
//
delete eaCHelper;
delete eaCCHelper;
//
delete eaAlert;
}
/**
* Initialize all GUI Requirements for EA ...
*
* @return ( bool )
*/
bool InitGUI()
{
//
bool result = false;
//
// TODO: Fix This ...
result = true;
//
return result;
}
/**
* Update GUI based on Each Ticks ...
*/
void UpdateGUI()
{
//
// TODO: Implement this ...
}
/**
* Destroy all Initialized GUi Requirements ...
*/
void DestroyGUI()
{
//
// TODO: Complete this ...
}
//
// Others ...
/**
* Update Positions States ...
*/
void UpdatePositionsState()
{
//
// TODO: Implement this ...
}
/**
* Handle On Click Event for GUI Components ...
*
* @param name: Object Name ...
*/
void HandleOnClickEvent(string name)
{
//
if (!IsValid(name))
{
return;
}
//
bool isClicked = false;
//
// TODO: Implement Chart Objects On Click ...
//
if (isClicked)
{
UpdateGUI();
}
}
/**
* Report Account Balance ...
*/
void HandleReportBalance()
{
//
if (!IsRunningOnTestMode())
{
return;
}
//
string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance());
eaAlert.Log(msg);
}
/**
* Time Reporting based on Inputs ...
*/
void HandleReportTime()
{
//
// Monthly Report ....
if (eaReportNewMonths &&
eaTimeTracker.IsNewMonth())
{
//
string msg = "New Month ...";
//
eaAlert.Alert(msg);
}
//
// Weekly Report ....
if (eaReportNewWeeks &&
eaTimeTracker.IsNewWeek())
{
//
string msg = "New Week ...";
//
eaAlert.Alert(msg);
}
//
// Daily Report ....
if (eaReportNewDays &&
eaTimeTracker.IsNewDay())
{
//
string msg = "New Day ...";
//
eaAlert.Alert(msg);
}
//
// Hourly Report ....
if (eaReportNewHours &&
eaTimeTracker.IsNewHour())
{
//
string msg = "New Hour ...";
//
eaAlert.Alert(msg);
}
}
//
@@ -0,0 +1,575 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XTest MQL5 Expert Advisor
// -------------------------------------------------
// Name: XPanelEA
// Description: an Exper Advisor which used Panels
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////x
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XPanelEA"
#property strict
//
#define ShortName "XPANELEA"
//
// Imports ...
#include "../Classes/x-saherelm.x-app-dialog.class.mq5"
#include "../Classes/x-saherelm.xalert.class.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
#include "../Helpers/x-saherelm.xcc.helper.mq5"
#include "../Helpers/x-saherelm.xct.helper.mq5"
//
// Inputs ...
//
// Common ...
input group "Common";
input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
//
// Alert ...
// Here we Provider All Requirements for
// Configuring Alert Provider ...
input group "Alert";
input bool eAEnableAlerts = true; // Enable Alerts
input bool eALogAlerts = true; // Log Alerts
input bool eAMailAlerts = false; // Mail Alerts
input bool eAPushAlerts = false; // Push Alerts
input bool eATerminalAlerts = false; // Terminal Alerts
//
// Time Report ...
input group "Reports";
input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = false; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
//
// Define Local Variables ...
//
string eaLogTag; // EA Log Prefix ...
XSCAlert *eaAlert; // Alert Provider for Expert Adviser ...
XSCTrade *eaTrader; // Trader of Expert Adviser ...
XTimeTracker eaTimeTracker; // Time Tracker for Providing Reports ...
XSCXCTHelper *eaCTHelper; // Bar Timer Indicator Helper class ...
XSCXCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
//
XCAppDialog eaMainWindow; // EA Main Dialog ...
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs and Required Parameters
// for EA to Works fine ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Timer ...
if (!InitTimer())
{
return INIT_FAILED;
}
//
// Initialize all Requirements ...
if (!InitEA())
{
return INIT_FAILED;
}
//
// Initialize all GUI Objects and Classes ...
if (!InitGUI())
{
return INIT_FAILED;
}
//
// Alert Initialization ...
string msg = "Initialized Successfully ...";
eaAlert.Alert(msg);
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
// Destroy Timer ...
DestroyTimer();
//
// Destroy all GUI Requirements ...
DestroyGUI();
//
// Alert De Initialization Succeeded ...
string msg = "De Initialized Successfully ...";
eaAlert.Alert(msg);
//
// Destroy all EA Requirements ...
DestroyEA();
}
//
// On Tick Handler ...
void OnTick()
{
//
UpdateGUI();
HandleReportTime();
UpdatePositionsState();
//
// TODO: Implemetn Tick Processors Algorithm ...
}
//
// Handle On Trade Event ...
void OnTrade()
{
eaTrader.HandleOnTrade();
}
//
// On Timer ...
void OnTimer()
{
//
// TODO: Implement Time Based Functionalities ...
}
//
// Chart Event Handler ...
void OnChartEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
//
// Apply Chart Event on Main Window ...
eaMainWindow.ChartEvent(id, lparam, dparam, sparam);
//
// Handle OnClick Event ...
if (id == CHARTEVENT_OBJECT_CLICK)
{
HandleOnClickEvent(sparam);
}
}
//
// Custom Event Handlers ...
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Force Close a Position ...
*
* @param ticket: Position Ticket ...
* @param position: XPosition ...
* @param comment: Closing Comment ...
*/
void OnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
//
HandleReportBalance();
}
//
// Custom Functions ...
/**
* Validate all Inputs of Expert Adviser ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
eaSlippage > 0 &&
eaMagicNumber > 0
//
);
if (!isCommonValid)
{
//
errMessage += "common configurations error;" + "\n";
}
//
result =
//
// Common ...
isCommonValid &&
//
// Otere ...
true
//
;
//
if (!result)
{
//
// Since here Logger not Initiallized, we Use Raw Print Command ...
Print(ShortName + " Errors: \n", errMessage);
}
//
return result;
}
/**
* Initialize Timer ...
*
* @return ( bool )
*/
bool InitTimer()
{
//
bool result = false;
//
// TODO: Initialize Timer if necessary ...
// result = EventSetTimer(1);
// result = EventSetMillisecondTimer(100);
result = true;
//
return result;
}
/**
* Destroy Timer ...
*/
void DestroyTimer()
{
//
// TODO: Use This ...
// EventKillTimer();
}
/**
* Initialize all Requirements for Working Fine ...
*
* @return ( bool )
*/
bool InitEA()
{
//
bool result = false;
//
// Locally Apply Changes on Prefix ...
eaLogTag = ShortName + ">" + eaLogSuffix;
//
// Bar Timer ...
XCTInputs ctInputs;
ctInputs.Default(); // Default Configurations ...
eaCTHelper = new XSCXCTHelper();
result = eaCTHelper.Init(
_Symbol,
_Period,
ctInputs //
);
if (!result)
{
return result;
}
//
// Bar Styles ...
XCCInputs ccInputs;
ccInputs.Default(); // Default Configurations ...
eaCCHelper = new XSCXCCHelper();
result = eaCCHelper.Init(
_Symbol,
_Period,
ccInputs //
);
if (!result)
{
return result;
}
//
// Create Instance of Alert Class and Configure it ...
eaAlert = new XSCAlert();
eaAlert.SetPrefix(eaLogTag);
eaAlert.SetLogAlerts(eALogAlerts);
eaAlert.SetMailAlerts(eAMailAlerts);
eaAlert.SetPushAlerts(eAPushAlerts);
eaAlert.SetEnableAlerts(eAEnableAlerts);
eaAlert.SetTerminalAlerts(eATerminalAlerts);
//
// Create Trader Instance and Configure it ...
eaTrader = new XSCTrade(
eaSlippage,
eaMagicNumber //
);
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
//
return result;
}
/**
* Destroy all Initialized EA Requirements ...
*/
void DestroyEA()
{
//
delete eaCTHelper;
delete eaCCHelper;
//
delete eaAlert;
}
/**
* Initialize all GUI Requirements for EA ...
*
* @return ( bool )
*/
bool InitGUI()
{
//
bool result = false;
//
// Initialize Application Main Window ...
result = eaMainWindow.Create(
ChartID(),
ShortName, // Dialog Name ...
0, // SubWindow ...
10, // X1 ...
35, // Y1 ...
300, // X2 ...
200 // Y2 ...
);
//
// Configuring Dialog ...
// eaMainWindow.MinimizeButton(false); // Hide Minimize Button ...
// eaMainWindow.CloseButton(false); // Hide Close Button ...
eaMainWindow.BackgroundColor(clrBlack);
// result = true;
//
// Try To Run Main Window ...
if (result)
{
eaMainWindow.Run();
}
//
return result;
}
/**
* Update GUI based on Each Ticks ...
*/
void UpdateGUI()
{
//
// TODO: Implement this ...
}
/**
* Destroy all Initialized GUi Requirements ...
*/
void DestroyGUI()
{
//
eaMainWindow.Destroy();
}
//
// Others ...
/**
* Update Positions States ...
*/
void UpdatePositionsState()
{
//
// TODO: Implement this ...
}
/**
* Handle On Click Event for GUI Components ...
*
* @param name: Object Name ...
*/
void HandleOnClickEvent(string name)
{
//
if (!IsValid(name))
{
return;
}
//
bool isClicked = false;
//
// TODO: Implement Chart Objects On Click ...
//
if (isClicked)
{
UpdateGUI();
}
}
/**
* Report Account Balance ...
*/
void HandleReportBalance()
{
//
if (!IsRunningOnTestMode())
{
return;
}
//
string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance());
eaAlert.Log(msg);
}
/**
* Time Reporting based on Inputs ...
*/
void HandleReportTime()
{
//
// Monthly Report ....
if (eaReportNewMonths &&
eaTimeTracker.IsNewMonth())
{
//
string msg = "New Month ...";
//
eaAlert.Alert(msg);
}
//
// Weekly Report ....
if (eaReportNewWeeks &&
eaTimeTracker.IsNewWeek())
{
//
string msg = "New Week ...";
//
eaAlert.Alert(msg);
}
//
// Daily Report ....
if (eaReportNewDays &&
eaTimeTracker.IsNewDay())
{
//
string msg = "New Day ...";
//
eaAlert.Alert(msg);
}
//
// Hourly Report ....
if (eaReportNewHours &&
eaTimeTracker.IsNewHour())
{
//
string msg = "New Hour ...";
//
eaAlert.Alert(msg);
}
}
//