add backup 14040103

This commit is contained in:
2025-03-23 04:07:25 +03:30
parent d5c9375f0f
commit eedd7beaab
93 changed files with 151299 additions and 0 deletions
+245
View File
@@ -0,0 +1,245 @@
//+------------------------------------------------------------------+
//| Valid_Break_Detector |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Detects Valid Breakouts of Zones with Rejection Confirmation"
// Input Parameters
input double LotSize = 0.1; // Lot size for trades
input int StopLoss = 50; // Stop Loss in points
input int TakeProfit = 100; // Take Profit in points
input bool RequireVolumeSpike = true; // Enable volume spike filter
input double VolumeThreshold = 1.5; // Minimum volume increase factor
input bool RequireCloseBeyond = true; // Require candle close beyond the zone
input int RejectionConfirmationCandles = 2; // Number of candles to confirm rejection
// Global Variables
int MagicNumber = 789101;
//
double _Ask = 0;
double _Bid = 0;
// Zone Boundaries
double ZoneHigh = 0;
double ZoneLow = 0;
//
double maBuffer[];
int maHandler = INVALID_HANDLE;
// Breakout Status
bool BullishBreakoutDetected = false;
bool BearishBreakoutDetected = false;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
ArraySetAsSeries(maBuffer, true);
maHandler = iMA(
_Symbol,
_Period,
14,
0,
MODE_SMA,
VOLUME_TICK //
);
if (maHandler == INVALID_HANDLE)
{
return (INIT_FAILED);
}
//
Print("Valid Break Detector EA Initialized");
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//
IndicatorRelease(maHandler);
Print("Valid Break Detector EA Deinitialized");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//
_Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
_Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
CopyBuffer(maHandler, MAIN_LINE, 0, 14, maBuffer);
// Define the zone dynamically (e.g., based on recent highs/lows)
DefineZone();
// Check for valid break of the zone
CheckValidBreak();
// Confirm rejection after breakout
if (BullishBreakoutDetected || BearishBreakoutDetected)
ConfirmRejection();
}
//+------------------------------------------------------------------+
//| Function to define the zone dynamically |
//+------------------------------------------------------------------+
void DefineZone()
{
// Example: Define zone based on recent highs and lows
ZoneHigh = iHigh(_Symbol, _Period, 1); // Recent high
ZoneLow = iLow(_Symbol, _Period, 2); // Recent low
}
//+------------------------------------------------------------------+
//| Function to check for a valid break of the zone |
//+------------------------------------------------------------------+
void CheckValidBreak()
{
double currentPrice = _Bid;
// Check if price breaks above the zone
if (!BullishBreakoutDetected && currentPrice > ZoneHigh)
{
if (IsValidBreak(ZoneHigh, true))
{
Print("Potential Bullish Break Above Zone Detected at ", TimeToString(TimeCurrent(), TIME_DATE));
BullishBreakoutDetected = true;
}
}
// Check if price breaks below the zone
if (!BearishBreakoutDetected && currentPrice < ZoneLow)
{
if (IsValidBreak(ZoneLow, false))
{
Print("Potential Bearish Break Below Zone Detected at ", TimeToString(TimeCurrent(), TIME_DATE));
BearishBreakoutDetected = true;
}
}
}
//+------------------------------------------------------------------+
//| Function to validate the breakout |
//+------------------------------------------------------------------+
bool IsValidBreak(double zoneLevel, bool isAbove)
{
// Check if the candle closed beyond the zone
if (RequireCloseBeyond)
{
double closePrice = iClose(_Symbol, _Period, 1);
if ((isAbove && closePrice <= zoneLevel) || (!isAbove && closePrice >= zoneLevel))
return false;
}
// Check for a volume spike
if (RequireVolumeSpike)
{
double currentVolume = (double) iVolume(_Symbol, _Period, 1);
double averageVolume = maBuffer[1];
if (currentVolume < VolumeThreshold * averageVolume)
return false;
}
// All conditions met, valid breakout
return true;
}
//+------------------------------------------------------------------+
//| Function to confirm rejection |
//+------------------------------------------------------------------+
void ConfirmRejection()
{
double currentPrice = _Bid;
if (BullishBreakoutDetected)
{
// Check if price rejects lower levels and confirms bullish breakout
bool confirmed = true;
for (int i = 1; i <= RejectionConfirmationCandles; i++)
{
double closePrice = iClose(_Symbol, _Period, i);
if (closePrice < ZoneHigh)
{
confirmed = false;
break;
}
}
if (confirmed)
{
Print("Bullish Breakout Confirmed at ", TimeToString(TimeCurrent(), TIME_DATE));
PlaceTrade(ORDER_TYPE_BUY, "Confirmed Bullish Breakout Buy");
BullishBreakoutDetected = false; // Reset breakout status
}
}
if (BearishBreakoutDetected)
{
// Check if price rejects higher levels and confirms bearish breakout
bool confirmed = true;
for (int i = 1; i <= RejectionConfirmationCandles; i++)
{
double closePrice = iClose(_Symbol, _Period, i);
if (closePrice > ZoneLow)
{
confirmed = false;
break;
}
}
if (confirmed)
{
Print("Bearish Breakout Confirmed at ", TimeToString(TimeCurrent(), TIME_DATE));
PlaceTrade(ORDER_TYPE_SELL, "Confirmed Bearish Breakout Sell");
BearishBreakoutDetected = false; // Reset breakout status
}
}
}
//+------------------------------------------------------------------+
//| Function to place a trade |
//+------------------------------------------------------------------+
void PlaceTrade(int orderType, string comment)
{
double price = (orderType == ORDER_TYPE_BUY) ? _Ask : _Bid;
double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * Point() : price + StopLoss * Point();
double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * Point() : price - TakeProfit * Point();
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = LotSize;
request.type = orderType;
request.price = price;
request.sl = sl;
request.tp = tp;
request.deviation = 10;
request.magic = MagicNumber;
request.comment = comment;
if (!OrderSend(request, result))
{
Print("Error placing order: ", result.retcode);
}
else
{
Print(comment, " Order placed successfully.");
}
}
@@ -0,0 +1,830 @@
//
bool HasSenario1Conditions(
ENUM_X_CYCLES cycle,
XBoxZone &box,
XBoxZone &holderBox,
ENUM_X_DIRECTION &dir,
XBoxZone &waitingBoxes[],
X121SMCStrategySignalProviderData &provider,
ENUM_X_CYCLES holderCycle = X_CYCLE_NONE,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Fil Selected Data ...
XPOIState cState;
X121Conditions cXConditions;
XPOIStateEvents cStateEvents;
XC121SMCCycleHelper *cHelper;
X121SMCCycleConditions cConditions;
result = provider.SelectCycle(
cycle,
cState,
cStateEvents,
cXConditions,
cHelper,
cConditions //
);
if (!result)
{
//
cState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
cStateEvents.Clean();
//
return result;
}
Parse(cXConditions);
//
// Fil Selected Data ...
XPOIState chState;
X121Conditions chXConditions;
XPOIStateEvents chStateEvents;
XC121SMCCycleHelper *chHelper;
X121SMCCycleConditions chConditions;
if (holderCycle != X_CYCLE_NONE)
{
//
result = provider.SelectCycle(
holderCycle,
chState,
chStateEvents,
chXConditions,
chHelper,
chConditions //
);
if (!result)
{
//
chState.Clean();
ZeroMemory(chHelper);
chConditions.Clean();
chXConditions.Clean();
chStateEvents.Clean();
//
return result;
}
//
Parse(chXConditions);
}
//
// Checking Waiting Baoxes Exists ...
result = HasChild(waitingBoxes);
if (!result)
{
return result;
}
//
XCPOIDrawer *drawer = provider
.visionCycleHelper
.mPOIDrawer;
//
// Normalize Args ...
//
box.Clean();
holderBox.Clean();
dir = X_DIRECTION_NONE;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int idx = -1;
int count = 0;
bool has = false;
//
int zIDX = barIndex;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int ppIDX = pIDX + 1;
//
bool isBullish = false;
bool isBearish = false;
//
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
//
// Initial Bars ...
result = zBar.Init(
cState.symbol,
cState.period,
barIndex //
);
result =
result &&
zBar.GetPreviousBar(cBar);
result =
result &&
cBar.GetPreviousBar(pBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
cState.Clean();
chState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
ZeroMemory(chHelper);
chConditions.Clean();
chXConditions.Clean();
//
return result;
}
//
// Detect Inside Box ...
XBoxZone insideBox;
count = ArraySize(waitingBoxes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = waitingBoxes[i];
bool isBullish = iBox.IsBullish();
double iMid = iBox.lower + ((iBox.upper - iBox.lower) / 2);
//
has =
//
isBullish
? cBar.low < iMid &&
cBar.low > iBox.lower
: cBar.high > iMid &&
cBar.high < iBox.upper
//
;
if (has)
{
//
insideBox = iBox;
break;
}
}
}
has = insideBox.IsValid();
//
ENUM_X_DIRECTION iBarPosDir;
bool isBarValidForDir = cHelper
.mBarAnalyser
.IsValidForPosition(
cBar,
iBarPosDir //
);
bool isBarValidForBullish =
isBarValidForDir &&
IsBullish(iBarPosDir);
bool isBarValidForBearish =
isBarValidForDir &&
IsBearish(iBarPosDir);
//
if (has)
{
//
XCBoxObject *iObj;
has = drawer.DrawBox(
insideBox,
iObj //
);
if (has)
{
//
Print("Dec Scores:");
Print("-------------");
Print("Bull: ", provider.decisionBullishScore);
Print("Bear: ", provider.decisionBearishScore);
Print("-------------");
Print("Anal Scores:");
Print("-------------");
Print("Bull: ", provider.analyseBullishScore);
Print("Bear: ", provider.analyseBearishScore);
Print("-------------");
Print("Bar Valid For: " + ToString(iBarPosDir));
Print("-------------");
Print(ToString(insideBox.dir), " Inside ...");
Print("-------------");
}
}
//
result = has;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
cState.Clean();
chState.Clean();
insideBox.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
ZeroMemory(chHelper);
chConditions.Clean();
chXConditions.Clean();
//
return result;
}
//
// Detecting Signal Conditions ...
//
// Bullish Conditions ...
isBullish =
//
// Base Condition ...
(
//
insideBox.IsBullish() &&
isBarValidForBullish
//
)
//
;
//
// Bearish Conditions ...
isBearish =
//
// Base Condition ...
(
//
insideBox.IsBearish() &&
isBarValidForBearish
//
)
//
;
//
// Filling Requirements ...
result =
isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
box.dir = dir;
box.to = TimeCurrent();
box.from = insideBox.from;
box.upper = insideBox.upper;
box.lower = insideBox.lower;
box.symbol = cXConditions.symbol;
box.period = cXConditions.period;
}
//
// Check All Conditions ...
result =
box.IsValid() &&
HasDirection(dir) &&
(isBullish ||
isBearish);
//
// Cleanup Resources ...
zBar.Clean();
cBar.Clean();
pBar.Clean();
cState.Clean();
chState.Clean();
insideBox.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cStateEvents.Clean();
cXConditions.Clean();
ZeroMemory(chHelper);
chConditions.Clean();
chStateEvents.Clean();
chXConditions.Clean();
//
return result;
}
/////////////////////////////////////////////////////
/**
* Checking a Box Exists in Collections or not ...
*
* @param box: XBoxZone instance reference ...
*
* @return ( bool )
*/
bool IsExists(XBoxZone &box)
{
//
bool result = false;
//
// Check Validation ...
result = box.IsValid() &&
(HasWaitingBoxes() ||
HasBreakedBoxes() ||
HasUnavailableBoxes());
if (!result)
{
return result;
}
//
int idx = -1;
bool has = false;
//
// Check Index in Waiting Boxes ...
has = HasWaitingBoxes();
if (has)
{
//
idx = FindIndex(
box,
waitingBoxes //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
}
//
// Check Index in Breaked Boxes ...
has = HasBreakedBoxes();
if (has)
{
//
idx = FindIndex(
box,
breakedBoxes //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
}
//
// Check Index in Unavailable Boxes ...
has = HasUnavailableBoxes();
if (has)
{
//
idx = FindIndex(
box,
unavailableBoxes //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
}
//
return result;
}
/**
* Detect Signal Boxes ...
*
* @param cycle: ENUM_X_CYCLES member ...
* @param provider: X121SMCStrategySignalProviderData instance reference ...
* @param barIndex: int ...
*
* @return ( bool )
*/
bool DetectSignalBoxes(
ENUM_X_CYCLES cycle,
X121SMCStrategySignalProviderData &provider,
int barIndex = 0 //
)
{
//
bool result = false;
//
int idx = -1;
int count = 0;
bool has = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
// Select Cycle ...
XPOIState cState;
XPOIStateEvents cStateEvents;
X121Conditions cXConditions;
XC121SMCCycleHelper *cHelper;
X121SMCCycleConditions cConditions;
result = provider.SelectCycle(
cycle,
cState,
cStateEvents,
cXConditions,
cHelper,
cConditions //
);
if (!result)
{
//
cState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cStateEvents.Clean();
cXConditions.Clean();
//
return result;
}
//
// Select Rejection Boxes ...
// //
// // Select Validate Rejection Boxes ...
// XBoxZone rejections[];
// int count = cHelper
// .DetectRejections(
// rejections,
// barIndex //
// );
// //
// result = IsValidSize(count);
// if (result)
// {
// //
// for (int i = 0; i < count; i++)
// {
// //
// has = IsExists(rejections[i]);
// if (!has)
// {
// //
// AddRef(
// rejections[i],
// waitingBoxes //
// );
// }
// }
// }
// //
// // Select Order Blocks ...
// if (cStateEvents.hasNewOrderBlock)
// {
// //
// idx = GetYoungest(cState.orderBlocks);
// has = IsValidIndex(idx);
// if (has)
// {
// //
// XCOrderBlock *iOB = cState.orderBlocks[idx];
// //
// XBoxZone iBox;
// has = ToBox(
// iBox,
// iOB //
// );
// if (has)
// {
// //
// has = IsExists(iBox);
// if (!has)
// {
// //
// AddRef(
// iBox,
// waitingBoxes //
// );
// }
// }
// }
// }
//
// Select Fair Value Gaps ...
// if (cStateEvents.hasNewFairValueGap)
// {
// //
// idx = GetYoungest(cState.fairValueGaps);
// has = IsValidIndex(idx);
// if (has)
// {
// //
// XCFVG *iOB = cState.fairValueGaps[idx];
// //
// XBoxZone iBox;
// has = ToBox(
// iBox,
// iOB //
// );
// if (has)
// {
// //
// has = IsExists(iBox);
// if (!has)
// {
// //
// AddRef(
// iBox,
// waitingBoxes //
// );
// }
// }
// }
// }
//
// Select Supply/Demand Zones ...
// if (cStateEvents.hasNewSupplyZone)
// {
// //
// idx = GetYoungest(cState.supplyZones);
// has = IsValidIndex(idx);
// if (has)
// {
// //
// XCSupplyZone *iSupply = cState.supplyZones[idx];
// //
// XBoxZone iBox;
// has = ToBox(
// iBox,
// iSupply //
// );
// if (has)
// {
// //
// has = IsExists(iBox);
// if (!has)
// {
// //
// AddRef(
// iBox,
// waitingBoxes //
// );
// }
// }
// }
// }
// if (cStateEvents.hasNewDemandZone)
// {
// //
// idx = GetYoungest(cState.demandZones);
// has = IsValidIndex(idx);
// if (has)
// {
// //
// XCDemandZone *iDemand = cState.demandZones[idx];
// //
// XBoxZone iBox;
// has = ToBox(
// iBox,
// iDemand //
// );
// if (has)
// {
// //
// has = IsExists(iBox);
// if (!has)
// {
// //
// AddRef(
// iBox,
// waitingBoxes //
// );
// }
// }
// }
// }
//
// Select Support/Resistance Zones ...
// if (cStateEvents.hasNewSupportZone)
// {
// //
// idx = GetYoungest(cState.supportZones);
// has = IsValidIndex(idx);
// if (has)
// {
// //
// XCSupportZone *iSupport = cState.supportZones[idx];
// //
// XBoxZone iBox;
// has = ToBox(
// iBox,
// iSupport //
// );
// if (has)
// {
// //
// has = IsExists(iBox);
// if (!has)
// {
// //
// AddRef(
// iBox,
// waitingBoxes //
// );
// }
// }
// }
// }
// if (cStateEvents.hasNewResistanceZone)
// {
// //
// idx = GetYoungest(cState.resistanceZones);
// has = IsValidIndex(idx);
// if (has)
// {
// //
// XCResistanceZone *iResistance = cState.resistanceZones[idx];
// //
// XBoxZone iBox;
// has = ToBox(
// iBox,
// iResistance //
// );
// if (has)
// {
// //
// has = IsExists(iBox);
// if (!has)
// {
// //
// AddRef(
// iBox,
// waitingBoxes //
// );
// }
// }
// }
// }
//
count = CountWaitingBoxes();
result = IsValidSize(count);
//
// Cleanup Resources ...
//
cState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
cStateEvents.Clean();
//
return result;
}
/**
* Validating Waiting Boxes and Detect Breaked Boxes ...
*
* @param barIndex: int ...
*
* @return ( int )
*/
int ValidateWaitingBoxes(
int barIndex = 0 //
)
{
//
int result = 0;
//
bool has = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex == 0)
{
barIndex = 1;
}
//
has = HasWaitingBoxes();
if (!has)
{
return result;
}
//
int removeIDX[];
result = CountWaitingBoxes();
for (int i = 0; i < result; i++)
{
//
XOHCL iBar;
XBoxZone iBox = waitingBoxes[i];
bool isInite = iBar
.Init(
iBox.symbol,
iBox.period,
iBox.from //
);
//
has = isInite &&
IsBoxBreaked(
iBox,
iBar.Index() - 1,
barIndex,
period //
);
if (has)
{
//
Add(
i,
removeIDX //
);
//
AddRef(
iBox,
breakedBoxes //
);
}
//
iBox.Clean();
iBar.Clean();
}
//
has = HasChild(removeIDX);
if (has)
{
//
CleanupArray(
removeIDX,
waitingBoxes //
);
}
Clean(removeIDX);
//
result = CountWaitingBoxes();
//
return result;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,121 @@
//+------------------------------------------------------------------+
//| Support and Resistance.mq5 |
//| https://t.me/ForexEaPremium |
//+------------------------------------------------------------------+
#property copyright "https://t.me/ForexEaPremium"
#property version "2.02"
#property description "Blue and red support and resistance levels displayed directly on the chart."
#property description "Alerts for close above resistance and close below support."
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
#property indicator_color1 clrRed
#property indicator_type1 DRAW_ARROW
#property indicator_width1 2
#property indicator_label1 "Resistance"
#property indicator_color2 clrBlue
#property indicator_type2 DRAW_ARROW
#property indicator_width2 2
#property indicator_label2 "Support"
enum enum_candle_to_check
{
Current,
Previous
};
input bool EnableNativeAlerts = false;
input bool EnableEmailAlerts = false;
input bool EnablePushAlerts = false;
input enum_candle_to_check TriggerCandle = Previous;
double Resistance[];
double Support[];
int myFractal;
datetime LastAlertTime = D'01.01.1970';
void OnInit()
{
PlotIndexSetInteger(0, PLOT_ARROW, 119);
PlotIndexSetInteger(1, PLOT_ARROW, 119);
SetIndexBuffer(0, Resistance);
SetIndexBuffer(1, Support);
ArraySetAsSeries(Resistance, true);
ArraySetAsSeries(Support, true);
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 5);
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, 5);
myFractal = iFractals(NULL, 0);
}
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[])
{
ArraySetAsSeries(High, true);
ArraySetAsSeries(Low, true);
ArraySetAsSeries(Close, true);
ArraySetAsSeries(Time, true);
//Get the values of the Fractals indicator before entering the cycle.
double FractalUpperBuffer[];
double FractalLowerBuffer[];
CopyBuffer(myFractal, 0, 0, rates_total, FractalUpperBuffer);
CopyBuffer(myFractal, 1, 0, rates_total, FractalLowerBuffer);
ArraySetAsSeries(FractalUpperBuffer, true);
ArraySetAsSeries(FractalLowerBuffer, true);
for (int i = rates_total - 2; i >= 0; i--)
{
if (FractalUpperBuffer[i] != EMPTY_VALUE) Resistance[i] = High[i];
else Resistance[i] = Resistance[i + 1];
if (FractalLowerBuffer[i] != EMPTY_VALUE) Support[i] = Low[i];
else Support[i] = Support[i + 1];
}
// Alerts
if (((TriggerCandle > 0) && (Time[0] > LastAlertTime)) || (TriggerCandle == 0))
{
string Text, TextNative;
// Resistance.
if ((Close[TriggerCandle] > Resistance[TriggerCandle]) && (Close[TriggerCandle + 1] <= Resistance[TriggerCandle]))
{
Text = "S&R: " + Symbol() + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()), 7) + " - Closed above Resistance: " + DoubleToString(Resistance[TriggerCandle], _Digits) + ".";
TextNative = "S&R: Closed above Resistance: " + DoubleToString(Resistance[TriggerCandle], _Digits) + ".";
if (EnableNativeAlerts) Alert(TextNative);
if (EnableEmailAlerts) SendMail("S&R Alert", Text);
if (EnablePushAlerts) SendNotification(Text);
LastAlertTime = Time[0];
}
// Support.
if ((Close[TriggerCandle] < Support[TriggerCandle]) && (Close[TriggerCandle + 1] >= Support[TriggerCandle]))
{
Text = "S&R: " + Symbol() + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()), 7) + " - Closed below Support: " + DoubleToString(Support[TriggerCandle], _Digits) + ".";
TextNative = "S&R: Closed below Support: " + DoubleToString(Support[TriggerCandle], _Digits) + ".";
if (EnableNativeAlerts) Alert(TextNative);
if (EnableEmailAlerts) SendMail("S&R Alert", Text);
if (EnablePushAlerts) SendNotification(Text);
LastAlertTime = Time[0];
}
}
return rates_total;
}
//+------------------------------------------------------------------+
@@ -0,0 +1,584 @@
//
// Configurations ...
bool useSharpChange = false;
bool useOrderBlockFVG = false;
//
// Select Order Blocks ...
if (useOrderBlockFVG)
{
//
if (obStateEvents.hasNewOrderBlock)
{
//
idx = GetYoungest(obState.orderBlocks);
has = IsValidIndex(idx);
if (has)
{
//
XCFVG *iFVG = NULL;
XCOrderBlock *iOB = obState.orderBlocks[idx];
bool isBullish = iOB.IsBullish();
//
// Detecting Inside FVG ...
has = fvgState.HasFairValueGaps();
if (has)
{
//
XCFVG *tmpFVGs[];
count = fvgState.CountFairValueGaps();
for (int i = 0; i < count; i++)
{
//
XCFVG *jFVG = fvgState.fairValueGaps[i];
//
bool isDirPassed = jFVG.GetDirection() == iOB.GetDirection();
bool isFromPassed = jFVG.From() >= iOB.From();
bool isPlacePassed = IsInsideOrDiff(
jFVG,
iOB,
false //
);
//
has = isDirPassed &&
isFromPassed &&
isPlacePassed;
if (has)
{
//
Add(
jFVG,
tmpFVGs //
);
}
//
ZeroMemory(jFVG);
}
//
// Selecting iFVG Based on Direction of OB ...
has = HasChild(tmpFVGs);
if (has)
{
//
idx =
isBullish
? GetLowest(tmpFVGs)
: GetHighest(tmpFVGs);
has = IsValidIndex(idx);
if (has)
{
iFVG = tmpFVGs[idx];
}
}
//
Clean(tmpFVGs);
}
//
XBoxZone iOBBox;
XBoxZone iFVGBox;
if (iFVG != NULL)
{
//
has = ToBox(
iFVGBox,
iFVG //
);
}
//
has = ToBox(
iOBBox,
iOB //
);
//
has = iOBBox.IsValid() &&
iFVGBox.IsValid();
if (has)
{
//
XSignalBox iSignalBox;
//
iSignalBox.ob = iOBBox;
iSignalBox.fvg = iFVGBox;
//
// Here We Check Waiting Box Contains Other Zones ...
// Like Support/Resistances ...
bool forceVerification = false;
if (forceVerification)
{
//
XBoxZone iVerificationBox;
XBoxZone tmpBoxes[];
if (isBullish)
{
//
ToBox(
provider.decisionState.supportZones,
tmpBoxes //
);
}
else
{
//
ToBox(
provider.decisionState.resistanceZones,
tmpBoxes //
);
}
has = HasChild(tmpBoxes);
if (has)
{
//
while (HasChild(tmpBoxes))
{
//
idx = GetYoungest(tmpBoxes);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
// Select Box ...
XBoxZone iBox = tmpBoxes[idx];
ArrayRemove(
tmpBoxes,
idx,
1 //
);
//
// Validate Box ...
bool isValidPassed = !IsBoxValid(
iBox,
barIndex //
);
bool isDirPassed = iBox.dir == iOBBox.dir;
bool isPlacePassed =
IsBoxInside(
iBox,
iOBBox //
)
//
&&
//
(!iFVGBox.IsValid()
? true
: IsBoxInsideOr(
iBox,
iFVGBox //
));
//
has =
isDirPassed &&
isValidPassed &&
isPlacePassed;
if (has)
{
//
iVerificationBox = iBox;
iBox.Clean();
break;
}
//
iBox.Clean();
}
}
has = iVerificationBox.IsValid();
Clean(tmpBoxes);
iVerificationBox.Clean();
}
//
if (has)
{
//
AddRef(
iSignalBox,
waitingBoxes //
);
}
//
iSignalBox.Clean();
}
//
iOBBox.Clean();
iFVGBox.Clean();
ZeroMemory(iOB);
ZeroMemory(iFVG);
}
}
}
//
// Checking Other Senario for Waiting Boxes ...
if (useSharpChange)
{
//
if (obStateEvents.hasNewSharp)
{
//
XBoxZone currSharp;
XBoxZone prevSharp;
XBoxZone sharpConsolidation;
//
// Retrieve Current Sharp ...
XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer;
XBoxZone tmpBoxes[];
Copy(
obState.sharps,
tmpBoxes //
);
idx = GetYoungest(tmpBoxes);
has = IsValidIndex(idx);
if (has)
{
//
currSharp = tmpBoxes[idx];
bool isBullish = currSharp.IsBullish();
//
ArrayRemove(
tmpBoxes,
idx,
1 //
);
//
while (HasChild(tmpBoxes))
{
//
idx = GetYoungest(tmpBoxes);
has = IsValidIndex(idx);
//
if (!has)
{
break;
}
//
XBoxZone iBox = tmpBoxes[idx];
ArrayRemove(
tmpBoxes,
idx,
1 //
);
//
if (iBox.dir == currSharp.dir)
{
//
prevSharp = iBox;
iBox.Clean();
break;
}
//
iBox.Clean();
}
//
Clean(tmpBoxes);
}
Clean(tmpBoxes);
//
// Preparing Sharp Consolidation Box ...
has = currSharp.IsValid() &&
prevSharp.IsValid() &&
prevSharp.lower < currSharp.upper;
if (has)
{
//
sharpConsolidation.type = "XSHCNZ";
sharpConsolidation.dir = currSharp.dir;
sharpConsolidation.symbol = currSharp.symbol;
sharpConsolidation.period = currSharp.period;
//
sharpConsolidation.from = prevSharp.to;
sharpConsolidation.to = currSharp.from;
//
int toIDX = GetBarIndex(
currSharp.symbol,
currSharp.period,
sharpConsolidation.to //
);
int fromIDX = GetBarIndex(
currSharp.symbol,
currSharp.period,
sharpConsolidation.from //
);
int length = fromIDX - toIDX;
//
XOHCL toBar;
has = toBar.Init(
sharpConsolidation.symbol,
sharpConsolidation.period,
toIDX //
);
//
if (has)
{
//
double upper = toBar.FindHighest(
length,
MODE_HIGH //
);
//
double lower = toBar.FindLowest(
length,
MODE_LOW //
);
//
sharpConsolidation.upper = upper;
sharpConsolidation.lower = lower;
}
//
has = sharpConsolidation.IsValid();
if (has)
{
//
XSignalBox iBox;
//
iBox.ob = sharpConsolidation;
//
AddRef(
iBox,
waitingBoxes //
);
//
iBox.Clean();
// //
// XCBoxObject *iCBoxObj;
// XCBoxObject *iPBoxObj;
// provider.visionCycleHelper.mPOIDrawer.DrawBox(
// currSharp,
// iCBoxObj //
// );
// provider.visionCycleHelper.mPOIDrawer.DrawBox(
// prevSharp,
// iPBoxObj //
// );
}
//
currSharp.Clean();
prevSharp.Clean();
sharpConsolidation.Clean();
}
}
//
// Update Exists Box ...
// XBoxZone fvgs[];
// count = ArraySize(waitingBoxes);
// has = IsValidSize(count);
// if (has)
// {
// //
// for (int i = 0; i < count; i++)
// {
// //
// bool isSharpBox = waitingBoxes[i].ob.type == "XSHCNZ";
// if (!isSharpBox)
// {
// continue;
// }
// //
// bool isBullish = waitingBoxes[i].ob.IsBullish();
// //
// // Extract Inside FVGS ...
// if (isBullish)
// {
// //
// ToBox(
// fvgState.bullishFairValueGaps,
// fvgs //
// );
// }
// else
// {
// //
// ToBox(
// fvgState.bearishFairValueGaps,
// fvgs //
// );
// }
// has = HasChild(fvgs);
// if (has)
// {
// //
// int removeds[];
// int iFVGsCount = ArraySize(fvgs);
// for (int j = 0; j < iFVGsCount; j++)
// {
// //
// XBoxZone iFVGBox = fvgs[j];
// bool isFromPassed = iFVGBox.from >= waitingBoxes[i].ob.from;
// bool isBoundaryPassed =
// isBullish
// ? iFVGBox.lower < waitingBoxes[i].ob.upper
// : iFVGBox.upper > waitingBoxes[i].ob.lower;
// //
// has = isFromPassed &&
// isBoundaryPassed;
// if (!has)
// {
// //
// Add(
// j,
// removeds //
// );
// }
// }
// //
// CleanupArray(
// removeds,
// fvgs //
// );
// Clean(removeds);
// }
// //
// // Select FVG ...
// has = HasChild(fvgs);
// if (has)
// {
// //
// idx = isBullish
// ? GetLowest(fvgs)
// : GetHighest(fvgs);
// has = IsValidIndex(idx);
// if (has)
// {
// waitingBoxes[i].fvg = fvgs[idx];
// }
// }
// else
// {
// waitingBoxes[i].fvg.Clean();
// }
// }
// }
//
// Clean(fvgs);
}
/////////////////////////////////////////////////////////////////////////////////////
if (signalProvider == X121SMC_XWZ_PROVIDER_XHKMA)
{
//
iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 0;
//
// Prepare Box fro SL ...
iSL = pivot;
Add(
iSL,
sls //
);
//
// Fix rf Reward ...
rfRewar = 2;
}
else if (signalProvider == X121SMC_XWZ_PROVIDER_XREJECTED_BOX)
{
//
iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 0;
//
Clean(sls);
//
// Prepare Box fro SL ...
iSL = signalBox.lower + ((signalBox.upper - signalBox.lower) / 2);
Add(
iSL,
sls //
);
//
// Fix rf Reward ...
rfRewar = 2;
}
else if (signalProvider == X121SMC_XWZ_PROVIDER_XACTIVATED_BOX)
{
//
iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 0;
//
Clean(sls);
//
// Prepare Box fro SL ...
iSL = pivot;
Add(
iSL,
sls //
);
//
// Fix rf Reward ...
rfRewar = 2;
}
else if (signalProvider == X121SMC_XWZ_PROVIDER_XBREAKED_BOX)
{
//
iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 0;
//
Clean(sls);
//
// Prepare Box fro SL ...
iSL = pivot;
Add(
iSL,
sls //
);
//
// Fix rf Reward ...
rfRewar = 2;
}
File diff suppressed because it is too large Load Diff
+520
View File
@@ -0,0 +1,520 @@
//
int DrawOrderBlock(
XCOrderBlock *zone,
XCBaseObject *&objects[],
//
bool drawStartedBar = true,
bool drawActivatedBar = true,
bool drawBreakedBar = true,
bool drawWorkedBar = true,
//
int widthStartedBar = 1,
color clrStartedBar = clrYellow,
ENUM_LINE_STYLE styleStartedBar = STYLE_SOLID,
//
int widthActivatedBar = 1,
color clrActivatedBar = clrLime,
ENUM_LINE_STYLE styleActivatedBar = STYLE_SOLID,
//
int widthBreakedBar = 1,
color clrBreakedBar = clrRed,
ENUM_LINE_STYLE styleBreakedBar = STYLE_SOLID,
//
int widthWorkedBar = 1,
color clrWorkedBar = clrAqua,
ENUM_LINE_STYLE styleWorkedBar = STYLE_SOLID
//
)
{
//
int result = 0;
//
Clean(objects);
//
if (zone == NULL ||
!zone.IsValid())
{
return result;
}
//
ENUM_X_DIRECTION zoneDir = zone.GetDirection();
//
// Started Bar ...
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = zone
.IsStarted(
zoneDir,
startedBar,
isBodyOut //
);
if (isStarted)
{
//
datetime iBarTo = startedBar.NextAt();
//
XCOHCLObject *iBarObj;
bool isCreated = CreateBar(
startedBar,
iBarObj,
iBarTo //
);
if (isCreated)
{
//
iBarObj.BodyWidth(widthStartedBar);
iBarObj.LowShadowWidth(widthStartedBar);
iBarObj.HighShadowWidth(widthStartedBar);
//
iBarObj.BodyStyle(styleStartedBar);
iBarObj.LowShadowStyle(styleStartedBar);
iBarObj.HighShadowStyle(styleStartedBar);
//
iBarObj.BodyColor(clrStartedBar);
iBarObj.LowShadowColor(clrStartedBar);
iBarObj.HighShadowColor(clrStartedBar);
//
Add(
(XCBaseObject *)iBarObj,
objects //
);
}
}
//
// Activated Bar ...
XOHCL activatedBar;
bool isBodyIn = false;
bool isActivated = zone
.IsActivated(
zoneDir,
activatedBar,
isBodyIn,
false // Force Body Out Started ...
);
if (isActivated)
{
//
datetime iBarTo = activatedBar.NextAt();
//
XCOHCLObject *iBarObj;
bool isCreated = CreateBar(
activatedBar,
iBarObj,
iBarTo //
);
if (isCreated)
{
//
iBarObj.BodyWidth(widthActivatedBar);
iBarObj.LowShadowWidth(widthActivatedBar);
iBarObj.HighShadowWidth(widthActivatedBar);
//
iBarObj.BodyStyle(styleActivatedBar);
iBarObj.LowShadowStyle(styleActivatedBar);
iBarObj.HighShadowStyle(styleActivatedBar);
//
iBarObj.BodyColor(clrActivatedBar);
iBarObj.LowShadowColor(clrActivatedBar);
iBarObj.HighShadowColor(clrActivatedBar);
//
Add(
(XCBaseObject *)iBarObj,
objects //
);
}
}
//
// Breaked Bar ...
XOHCL breakedBar;
isBodyOut = false;
bool isBreaked = zone
.IsBreaked(
zoneDir,
breakedBar,
isBodyOut,
false, // Ignore Start ...
false // Force Body Out Started ...
);
if (isBreaked)
{
//
datetime iBarTo = breakedBar.NextAt();
//
XCOHCLObject *iBarObj;
bool isCreated = CreateBar(
breakedBar,
iBarObj,
iBarTo //
);
if (isCreated)
{
//
iBarObj.BodyWidth(widthBreakedBar);
iBarObj.LowShadowWidth(widthBreakedBar);
iBarObj.HighShadowWidth(widthBreakedBar);
//
iBarObj.BodyStyle(styleBreakedBar);
iBarObj.LowShadowStyle(styleBreakedBar);
iBarObj.HighShadowStyle(styleBreakedBar);
//
iBarObj.BodyColor(clrBreakedBar);
iBarObj.LowShadowColor(clrBreakedBar);
iBarObj.HighShadowColor(clrBreakedBar);
//
Add(
(XCBaseObject *)iBarObj,
objects //
);
}
}
//
// Worked Bar ...
XOHCL workedBar;
isBodyOut = false;
bool isWorked = zone
.IsWorked(
zoneDir,
workedBar,
isBodyOut,
false, // Ignore Activation ...
false, // Force Body Out Started ...
false // Force Body In Activated ...
);
if (isWorked)
{
//
datetime iBarTo = workedBar.NextAt();
//
XCOHCLObject *iBarObj;
bool isCreated = CreateBar(
workedBar,
iBarObj,
iBarTo //
);
if (isCreated)
{
//
iBarObj.BodyWidth(widthWorkedBar);
iBarObj.LowShadowWidth(widthWorkedBar);
iBarObj.HighShadowWidth(widthWorkedBar);
//
iBarObj.BodyStyle(styleWorkedBar);
iBarObj.LowShadowStyle(styleWorkedBar);
iBarObj.HighShadowStyle(styleWorkedBar);
//
iBarObj.BodyColor(clrWorkedBar);
iBarObj.LowShadowColor(clrWorkedBar);
iBarObj.HighShadowColor(clrWorkedBar);
//
Add(
(XCBaseObject *)iBarObj,
objects //
);
}
}
//
XCBaseObject *iObj;
bool isCreated = CreateOrderBlock(
zone,
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
objects //
);
}
//
result = ArraySize(objects);
//
return result;
}
//
int DrawFairValueGap(
XCFVG *zone,
XCBaseObject *&objects[],
//
bool drawStartedBar = true,
bool drawActivatedBar = true,
bool drawBreakedBar = true,
bool drawWorkedBar = true,
//
int widthStartedBar = 1,
color clrStartedBar = clrYellow,
ENUM_LINE_STYLE styleStartedBar = STYLE_SOLID,
//
int widthActivatedBar = 1,
color clrActivatedBar = clrLime,
ENUM_LINE_STYLE styleActivatedBar = STYLE_SOLID,
//
int widthBreakedBar = 1,
color clrBreakedBar = clrRed,
ENUM_LINE_STYLE styleBreakedBar = STYLE_SOLID,
//
int widthWorkedBar = 1,
color clrWorkedBar = clrAqua,
ENUM_LINE_STYLE styleWorkedBar = STYLE_SOLID
//
)
{
//
int result = 0;
//
Clean(objects);
//
if (zone == NULL ||
!zone.IsValid())
{
return result;
}
//
ENUM_X_DIRECTION zoneDir = zone.GetDirection();
//
// Started Bar ...
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = zone
.IsStarted(
zoneDir,
startedBar,
isBodyOut //
);
if (isStarted)
{
//
datetime iBarTo = startedBar.NextAt();
//
XCOHCLObject *iBarObj;
bool isCreated = CreateBar(
startedBar,
iBarObj,
iBarTo //
);
if (isCreated)
{
//
iBarObj.BodyWidth(widthStartedBar);
iBarObj.LowShadowWidth(widthStartedBar);
iBarObj.HighShadowWidth(widthStartedBar);
//
iBarObj.BodyStyle(styleStartedBar);
iBarObj.LowShadowStyle(styleStartedBar);
iBarObj.HighShadowStyle(styleStartedBar);
//
iBarObj.BodyColor(clrStartedBar);
iBarObj.LowShadowColor(clrStartedBar);
iBarObj.HighShadowColor(clrStartedBar);
//
Add(
(XCBaseObject *)iBarObj,
objects //
);
}
}
//
// Activated Bar ...
XOHCL activatedBar;
bool isBodyIn = false;
bool isActivated = zone
.IsActivated(
zoneDir,
activatedBar,
isBodyIn,
false // Force Body Out Started ...
);
if (isActivated)
{
//
datetime iBarTo = activatedBar.NextAt();
//
XCOHCLObject *iBarObj;
bool isCreated = CreateBar(
activatedBar,
iBarObj,
iBarTo //
);
if (isCreated)
{
//
iBarObj.BodyWidth(widthActivatedBar);
iBarObj.LowShadowWidth(widthActivatedBar);
iBarObj.HighShadowWidth(widthActivatedBar);
//
iBarObj.BodyStyle(styleActivatedBar);
iBarObj.LowShadowStyle(styleActivatedBar);
iBarObj.HighShadowStyle(styleActivatedBar);
//
iBarObj.BodyColor(clrActivatedBar);
iBarObj.LowShadowColor(clrActivatedBar);
iBarObj.HighShadowColor(clrActivatedBar);
//
Add(
(XCBaseObject *)iBarObj,
objects //
);
}
}
//
// Breaked Bar ...
XOHCL breakedBar;
isBodyOut = false;
bool isBreaked = zone
.IsBreaked(
zoneDir,
breakedBar,
isBodyOut,
false, // Ignore Start ...
false // Force Body Out Started ...
);
if (isBreaked)
{
//
datetime iBarTo = breakedBar.NextAt();
//
XCOHCLObject *iBarObj;
bool isCreated = CreateBar(
breakedBar,
iBarObj,
iBarTo //
);
if (isCreated)
{
//
iBarObj.BodyWidth(widthBreakedBar);
iBarObj.LowShadowWidth(widthBreakedBar);
iBarObj.HighShadowWidth(widthBreakedBar);
//
iBarObj.BodyStyle(styleBreakedBar);
iBarObj.LowShadowStyle(styleBreakedBar);
iBarObj.HighShadowStyle(styleBreakedBar);
//
iBarObj.BodyColor(clrBreakedBar);
iBarObj.LowShadowColor(clrBreakedBar);
iBarObj.HighShadowColor(clrBreakedBar);
//
Add(
(XCBaseObject *)iBarObj,
objects //
);
}
}
//
// Worked Bar ...
XOHCL workedBar;
isBodyOut = false;
bool isWorked = zone
.IsWorked(
zoneDir,
workedBar,
isBodyOut,
false, // Ignore Activation ...
false, // Force Body Out Started ...
false // Force Body In Activated ...
);
if (isWorked)
{
//
datetime iBarTo = workedBar.NextAt();
//
XCOHCLObject *iBarObj;
bool isCreated = CreateBar(
workedBar,
iBarObj,
iBarTo //
);
if (isCreated)
{
//
iBarObj.BodyWidth(widthWorkedBar);
iBarObj.LowShadowWidth(widthWorkedBar);
iBarObj.HighShadowWidth(widthWorkedBar);
//
iBarObj.BodyStyle(styleWorkedBar);
iBarObj.LowShadowStyle(styleWorkedBar);
iBarObj.HighShadowStyle(styleWorkedBar);
//
iBarObj.BodyColor(clrWorkedBar);
iBarObj.LowShadowColor(clrWorkedBar);
iBarObj.HighShadowColor(clrWorkedBar);
//
Add(
(XCBaseObject *)iBarObj,
objects //
);
}
}
//
XCBaseObject *iObj;
bool isCreated = CreateFairValueGap(
zone,
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
objects //
);
}
//
result = ArraySize(objects);
//
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
@@ -0,0 +1,543 @@
//
bool HasSenario1Conditions(
ENUM_X_CYCLES cycle,
XBoxZone &box,
XBoxZone &holderBox,
ENUM_X_DIRECTION &dir,
X121SMCStrategySignalProviderData &provider,
ENUM_X_CYCLES holderCycle = X_CYCLE_NONE,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Fil Selected Data ...
XPOIState cState;
X121Conditions cXConditions;
XC121SMCCycleHelper *cHelper;
X121SMCCycleConditions cConditions;
result = provider.SelectCycle(
cycle,
cState,
cXConditions,
cHelper,
cConditions //
);
if (!result)
{
//
cState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
//
return result;
}
Parse(cXConditions);
//
// Fil Selected Data ...
XPOIState chState;
X121Conditions chXConditions;
XC121SMCCycleHelper *chHelper;
X121SMCCycleConditions chConditions;
if (holderCycle != X_CYCLE_NONE)
{
//
result = provider.SelectCycle(
holderCycle,
chState,
chXConditions,
chHelper,
chConditions //
);
if (!result)
{
//
chState.Clean();
ZeroMemory(chHelper);
chConditions.Clean();
chXConditions.Clean();
//
return result;
}
//
Parse(chXConditions);
}
//
// Normalize Args ...
//
box.Clean();
holderBox.Clean();
dir = X_DIRECTION_NONE;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int idx = -1;
int count = 0;
bool has = false;
//
int zIDX = barIndex;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
//
bool isBullish = false;
bool isBearish = false;
//
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
//
// Initial Bars ...
result = zBar.Init(
cState.symbol,
cState.period,
barIndex //
);
result =
result &&
zBar.GetPreviousBar(cBar);
result =
result &&
cBar.GetPreviousBar(pBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
cState.Clean();
chState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
ZeroMemory(chHelper);
chConditions.Clean();
chXConditions.Clean();
//
return result;
}
//
// Detecting Signal Conditions ...
//
bool isX3MAFastRejectUp =
//
cBar.low < cXConditions.x3maFastBuffer[cIDX] &&
cBar.GetDown() > cXConditions.x3maFastBuffer[cIDX]
//
;
//
bool isX3MAFastRejectDown =
//
cBar.high > cXConditions.x3maFastBuffer[cIDX] &&
cBar.GetUp() < cXConditions.x3maFastBuffer[cIDX]
//
;
//
// Find Breaker Bar ...
datetime nearCloseOverX3MAFast = cHelper.GetNearestCloseOverX3MAFast(cBar);
datetime nearCloseUnderX3MAFast = cHelper.GetNearestCloseUnderX3MAFast(cBar);
bool hasNearestCloseOverX3MAFast =
IsValid(nearCloseOverX3MAFast) &&
IsValid(nearCloseUnderX3MAFast)
? nearCloseOverX3MAFast > nearCloseUnderX3MAFast
: IsValid(nearCloseOverX3MAFast)
? true
: false;
bool hasNearestCloseUnderX3MAFast =
IsValid(nearCloseOverX3MAFast) &&
IsValid(nearCloseUnderX3MAFast)
? nearCloseUnderX3MAFast > nearCloseOverX3MAFast
: IsValid(nearCloseUnderX3MAFast)
? true
: false;
//
// Bullish Conditions ...
isBullish =
//
// Base Condition ...
(
//
cBar.IsBullish() &&
isX3MAFastRejectUp &&
cXConditions.isSMHKBullish &&
hasNearestCloseOverX3MAFast &&
cXConditions.xhkSMOpenBuffer[cIDX] < cXConditions.x3maMidBuffer[cIDX]
//
)
//
;
//
// Bearish Conditions ...
isBearish =
//
// Base Condition ...
(
//
cBar.IsBearish() &&
isX3MAFastRejectDown &&
cXConditions.isSMHKBearish &&
hasNearestCloseUnderX3MAFast &&
cXConditions.xhkSMOpenBuffer[cIDX] > cXConditions.x3maMidBuffer[cIDX]
//
)
//
;
//
// Filling Requirements ...
result =
isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
box.dir = dir;
box.to = TimeCurrent();
box.symbol = cXConditions.symbol;
box.period = cXConditions.period;
//
int fromIDX = -1;
if (isBullish)
{
//
fromIDX = GetBarIndex(
cBar.symbol,
cBar.period,
nearCloseOverX3MAFast //
);
}
else
{
//
fromIDX = GetBarIndex(
cBar.symbol,
cBar.period,
nearCloseUnderX3MAFast //
);
}
//
if (IsValidIndex(fromIDX))
{
//
box.from = iTime(
zBar.symbol,
zBar.period,
fromIDX //
);
}
else
{
box.from = pBar.time;
}
//
// Detect Holder Box ...
XBoxZone tmpBoxes[];
if (chState.IsValid())
{
//
if (isBullish)
{
//
// Demand Zones ...
XBoxZone tmp[];
ToBox(
chState.demandZones,
tmp //
);
Copy(
tmp,
tmpBoxes,
false //
);
Clean(tmp);
//
// Bullish Order Blocks ...
ToBox(
chState.bullishOrderBlocks,
tmp //
);
Copy(
tmp,
tmpBoxes,
false //
);
Clean(tmp);
//
// Bullish Fair Value Gaps ...
ToBox(
chState.bullishFairValueGaps,
tmp //
);
Copy(
tmp,
tmpBoxes,
false //
);
Clean(tmp);
}
else
{
//
// Supply Zones ...
XBoxZone tmp[];
ToBox(
chState.supplyZones,
tmp //
);
Copy(
tmp,
tmpBoxes,
false //
);
Clean(tmp);
//
// Bearish Order Blocks ...
ToBox(
chState.bearishOrderBlocks,
tmp //
);
Copy(
tmp,
tmpBoxes,
false //
);
Clean(tmp);
//
// Bearish Fair Value Gaps ...
ToBox(
chState.bearishFairValueGaps,
tmp //
);
Copy(
tmp,
tmpBoxes,
false //
);
Clean(tmp);
}
}
//
has = HasChild(tmpBoxes);
if (has)
{
//
while (HasChild(tmpBoxes))
{
//
idx = GetOldest(tmpBoxes);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
XBoxZone iBox = tmpBoxes[idx];
ArrayRemove(
tmpBoxes,
idx,
1 //
);
//
has = IsBoxInside(
box,
iBox //
);
if (has)
{
//
holderBox = iBox;
holderBox.to = TimeCurrent();
iBox.Clean();
break;
}
//
iBox.Clean();
}
}
//
Clean(tmpBoxes);
//
// Fix Box Upper and Lower based on Strategy ...
//
double points = GetPoints(box.symbol);
double minPointsDiff = points * 20;
//
double prefferSL = 0;
//
// Other SL Conditions ...
if (prefferSL <= 0)
{
//
prefferSL = cHelper
.mX121Helper
.xhkHelper
.GetSMHKOpen(fromIDX);
}
//
if (prefferSL > 0)
{
//
box.upper =
isBullish
? zBar.open
: prefferSL;
//
box.lower =
isBullish
? prefferSL
: zBar.open;
}
//
if (box.IsValid())
{
//
XCBoxObject *iObj;
bool isCreated = cHelper.mPOIDrawer.DrawBox(
box,
iObj //
);
if (isCreated)
{
//
iObj.BoxWidth(2);
iObj.BoxFill(true);
iObj.BoxStyle(STYLE_DOT);
//
Print("Signal ...");
}
}
//
// Validate Conditions to Force Has Holder Box ...
// //
// result =
// result &&
// holderBox.IsValid() &&
// dir == holderBox.dir;
// //
// if (!result)
// {
// //
// isBullish = false;
// isBearish = false;
// }
}
//
// Check All Conditions ...
result =
box.IsValid() &&
HasDirection(dir) &&
(isBullish ||
isBearish);
//
// Cleanup Resources ...
zBar.Clean();
cBar.Clean();
pBar.Clean();
cState.Clean();
chState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
ZeroMemory(chHelper);
chConditions.Clean();
chXConditions.Clean();
//
return result;
}
///////////////////////////////////////////////////////////////
//
// Detecting Signal Conditions ...
//
// Bullish Conditions ...
isBullish =
//
// Base Condition ...
(
//
provider.visionXConditions.isSMHKBullish &&
provider.decisionXConditions.isSarBullish &&
provider.decisionXConditions.isVWapFastBullish &&
provider.decisionXConditions.isX3MaFastBullish &&
provider.consolidationXConditions.isSMHKBullish &&
provider.decisionXConditions.isSMHKSwitchedToBullish
//
)
//
;
//
// Bearish Conditions ...
isBearish =
//
// Base Condition ...
(
//
provider.visionXConditions.isSMHKBearish &&
provider.decisionXConditions.isSarBearish &&
provider.decisionXConditions.isVWapFastBearish &&
provider.decisionXConditions.isX3MaFastBearish &&
provider.consolidationXConditions.isSMHKBearish &&
provider.decisionXConditions.isSMHKSwitchedToBearish
//
)
//
;
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,197 @@
//+------------------------------------------------------------------+
//| Forex Sessions and Day Range Indicator |
//+------------------------------------------------------------------+
#property copyright "Your Name"
#property link "https://www.example.com"
#property version "1.00"
#property indicator_chart_window
#include <Arrays\ArrayObj.mqh>
struct SessionInfo {
string name;
int startHour; // Standard start hour (GMT)
int startMinute;
int endHour; // Standard end hour (GMT)
int endMinute;
bool *isDST(datetime); // DST check function
int dstAdjustment; // Hours to add during DST
};
SessionInfo sessions[] = {
{"Sydney", 21, 0, 5, 0, IsSydneyDST, 1},
{"Tokyo", 23, 0, 8, 0, IsTokyoDST, 0},
{"London", 7, 0, 15, 0, IsLondonDST, 1},
{"New York", 12, 0, 17, 0, IsNewYorkDST, 1}
};
bool sessionActive[];
double sessionHigh[];
double sessionLow[];
datetime sessionStartTime[];
datetime sessionEndTime[];
double dayHigh = 0;
double dayLow = 0;
datetime dayStartTime;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
ArrayResize(sessionActive, ArraySize(sessions));
ArrayResize(sessionHigh, ArraySize(sessions));
ArrayResize(sessionLow, ArraySize(sessions));
ArrayResize(sessionStartTime, ArraySize(sessions));
ArrayResize(sessionEndTime, ArraySize(sessions));
for(int i=0; i<ArraySize(sessions); i++) {
sessionActive[i] = false;
sessionHigh[i] = 0;
sessionLow[i] = 0;
sessionStartTime[i] = 0;
sessionEndTime[i] = 0;
}
dayHigh = 0;
dayLow = 0;
dayStartTime = 0;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[]) {
datetime currentTime = TimeCurrent();
// Check each session
for(int i=0; i<ArraySize(sessions); i++) {
SessionInfo session = sessions[i];
bool dstActive = session.isDST(currentTime);
int adjStartHour = session.startHour + (dstActive ? session.dstAdjustment : 0);
int adjEndHour = session.endHour + (dstActive ? session.dstAdjustment : 0);
datetime todayStart = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
IntegerToString(adjStartHour) + ":" +
IntegerToString(session.startMinute));
datetime todayEnd = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
IntegerToString(adjEndHour) + ":" +
IntegerToString(session.endMinute));
// Handle sessions spanning midnight
if(adjEndHour < adjStartHour) {
todayEnd += 24 * 3600;
}
if(currentTime >= todayStart && currentTime < todayEnd) {
if(!sessionActive[i]) {
sessionActive[i] = true;
sessionStartTime[i] = todayStart;
sessionEndTime[i] = todayEnd;
sessionHigh[i] = Bid;
sessionLow[i] = Ask;
} else {
if(Bid > sessionHigh[i]) sessionHigh[i] = Bid;
if(Ask < sessionLow[i]) sessionLow[i] = Ask;
}
} else {
sessionActive[i] = false;
}
}
// Check day range
bool dstActiveNY = IsNewYorkDST(currentTime);
int dayStartHour = dstActiveNY ? 21 : 22;
datetime todayDayStart = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
IntegerToString(dayStartHour) + ":00");
if(currentTime < todayDayStart) {
todayDayStart -= 24 * 3600;
}
if(dayStartTime != todayDayStart) {
dayStartTime = todayDayStart;
dayHigh = Bid;
dayLow = Ask;
} else {
if(Bid > dayHigh) dayHigh = Bid;
if(Ask < dayLow) dayLow = Ask;
}
// Display information on chart
string comment = "Active Forex Sessions:\n";
for(int i=0; i<ArraySize(sessions); i++) {
if(sessionActive[i]) {
comment += sessions[i].name + " Session\n" +
"High: " + DoubleToString(sessionHigh[i], _Digits) + "\n" +
"Low: " + DoubleToString(sessionLow[i], _Digits) + "\n";
}
}
comment += "\nDay Range:\n" +
"High: " + DoubleToString(dayHigh, _Digits) + "\n" +
"Low: " + DoubleToString(dayLow, _Digits);
Comment(comment);
return(rates_total);
}
//+------------------------------------------------------------------+
//| DST Check Functions |
//+------------------------------------------------------------------+
bool IsLondonDST(datetime time) {
int year = TimeYear(time);
datetime march31 = StringToTime(year + ".03.31 00:00");
int lastSundayMarch = TimeDay(march31) - (TimeDayOfWeek(march31) % 7);
datetime dstStart = StringToTime(year + ".03." + IntegerToString(lastSundayMarch) + " 01:00");
datetime oct31 = StringToTime(year + ".10.31 00:00");
int lastSundayOct = TimeDay(oct31) - (TimeDayOfWeek(oct31) % 7);
datetime dstEnd = StringToTime(year + ".10." + IntegerToString(lastSundayOct) + " 01:00");
return time >= dstStart && time < dstEnd;
}
bool IsNewYorkDST(datetime time) {
int year = TimeYear(time);
datetime march1 = StringToTime(year + ".03.01 00:00");
int dayOfWeekMarch1 = TimeDayOfWeek(march1);
int secondSundayMarch = 1 + (7 - dayOfWeekMarch1) % 7 + 7;
datetime dstStart = StringToTime(year + ".03." + IntegerToString(secondSundayMarch) + " 07:00");
datetime nov1 = StringToTime(year + ".11.01 00:00");
int dayOfWeekNov1 = TimeDayOfWeek(nov1);
int firstSundayNov = 1 + (7 - dayOfWeekNov1) % 7;
datetime dstEnd = StringToTime(year + ".11." + IntegerToString(firstSundayNov) + " 06:00");
return time >= dstStart && time < dstEnd;
}
bool IsSydneyDST(datetime time) {
int year = TimeYear(time);
datetime oct1 = StringToTime(year + ".10.01 00:00");
int dayOfWeekOct1 = TimeDayOfWeek(oct1);
int firstSundayOct = 1 + (7 - dayOfWeekOct1) % 7;
datetime dstStart = StringToTime(year + ".10." + IntegerToString(firstSundayOct) + " 13:00");
datetime apr1 = StringToTime(year + ".04.01 00:00");
int dayOfWeekApr1 = TimeDayOfWeek(apr1);
int firstSundayApr = 1 + (7 - dayOfWeekApr1) % 7;
datetime dstEnd = StringToTime(year + ".04." + IntegerToString(firstSundayApr) + " 15:00");
return time >= dstStart && time < dstEnd;
}
bool IsTokyoDST(datetime time) {
return false;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,377 @@
//+------------------------------------------------------------------+
//| x-saherelm.xpoi.test.ea.mq5 |
//| SaherElm IT Center |
//| https://www.saherelm.ir |
//+------------------------------------------------------------------+
#property copyright "SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
//
#include "../Classes/x-saherelm.x-poi.class.mq5"
#include "../Classes/x-saherelm.x-poi.drawer.class.mq5"
#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
#include "../Libraries/x-saherelm.x-poi.state.lib.mq5"
//
#include "../Classes/x-saherelm.x-bar.analyser.class.mq5"
//
// Global Variables ...
//
XCPOIDrawer *mPOIDrawer;
//
XCPOIDetector *mPOIDetector;
XBarTracker mBarTracker;
XCBarAnalyser *mBarAnalyser;
//
bool useDetector = true;
bool useBarAnalyser = false;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
mPOIDetector = new XCPOIDetector(
_Symbol,
_Period //
);
//
mPOIDrawer = new XCPOIDrawer();
//
mBarAnalyser = new XCBarAnalyser();
//
mBarTracker.Init(
_Symbol,
_Period //
);
//
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//
// ZeroMemory(mPOIDrawer);
// ZeroMemory(mPOIDetector);
ZeroMemory(mBarAnalyser);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//
DetectBarAnalyser();
//
DetectPOIState();
}
//+------------------------------------------------------------------+
//| Custom Functions |
//+------------------------------------------------------------------+
/**
* Detect POI(s) Using Bar Analyser Class ...
*/
void DetectBarAnalyser()
{
//
if (!useBarAnalyser)
{
return;
}
//
if (!mBarTracker.IsNewBar())
{
return;
}
//
XOHCL zBar;
bool isInited = zBar.Init(
_Symbol,
_Period,
0 //
);
if (!isInited)
{
//
zBar.Clean();
return;
}
//
XOHCL cBar;
isInited = zBar.GetPreviousBar(cBar);
if (!isInited)
{
//
zBar.Clean();
cBar.Clean();
return;
}
//
int rootIDX = -1;
XOHCL selectedBar;
ENUM_X_DIRECTION dir;
//
// Check Big Change in Price ...
bool isBigChange = mBarAnalyser.IsSharp(
zBar, // Bar ...
dir, // Change Direction ...
rootIDX, // Change Root IDX ...
X_PRICE_CLOSE, // Price Change Type ...
true, // Force Use Body for Range Calculation ...
1.0 // Range Extend Multiplier ...
);
if (isBigChange)
{
Print("Big Price Change Detected: ", ToString(dir));
}
//
// Check Big Change in Price ...
bool isSpike = mBarAnalyser.IsSpike(
zBar, // Bar ...
dir, // Change Direction ...
rootIDX, // Root Index ...
X_PRICE_CLOSE, // Price Change Type ...
true, // Force Use Body for Range Calculation ...
1.0, // Range Extend Multiplier ...
3 // Same Bars ...
);
if (isSpike)
{
Print("Spike Detected: ", ToString(dir));
}
//
// Check Doji Pattern ...
bool isDoji = mBarAnalyser.IsDoji(
cBar,
dir //
);
if (isDoji)
{
Print(ToString(dir), " Doji Detected ...");
}
//
// Check Hammer Pattern ...
bool isHammer = mBarAnalyser.IsHammer(
cBar,
dir //
);
if (isHammer)
{
Print(ToString(dir), " Hammer Detected ...");
}
//
// Check Engulf Pattern ...
bool isEngulfed = mBarAnalyser.IsEngulfed(
cBar,
dir //
);
if (isEngulfed)
{
Print(ToString(dir), " Engulfed Detected ...");
}
//
// Check Momentum Pattern ...
bool isMomentum = mBarAnalyser.IsMomentum(
cBar,
dir //
);
if (isMomentum)
{
Print(ToString(dir), " Momentum Detected ...");
}
//
// Check Pullback Pattern ...
bool isPullback = mBarAnalyser.IsPullback(
cBar,
dir //
);
if (isMomentum)
{
Print(ToString(dir), " Pullback Detected ...");
}
//
// Check Swing Pattern ...
bool isSwing = mBarAnalyser.IsSwing(
cBar,
dir //
);
if (isSwing)
{
Print(ToString(dir), " Swing Detected ...");
}
//
// Check Swing Pattern ...
bool isRejected = mBarAnalyser.IsRejected(
cBar,
dir //
);
if (isRejected)
{
Print(ToString(dir), " Rejected Detected ...");
}
//
// Check Support ...
bool isSupport = mBarAnalyser.HasSupport(
cBar,
selectedBar //
);
if (isSupport)
{
Print(ToString(dir), " Support Detected ...");
}
//
// Check Resistance ...
bool isResistance = mBarAnalyser.HasResistance(
cBar,
selectedBar //
);
if (isResistance)
{
Print(ToString(dir), " Resistance Detected ...");
}
//
// Check Fair Value Gap ...
XOHCL toBar;
XOHCL fromBar;
bool hasFVG = mBarAnalyser.HasFairValueGap(
zBar,
fromBar,
toBar,
dir,
3 //
);
if (hasFVG)
{
Print(ToString(dir), " FairValueGap Detected ...");
}
//
// Check Order Block ...
bool hasOB = mBarAnalyser.HasOrderBlock(
zBar,
selectedBar,
dir,
true,
true,
true //
);
if (hasOB)
{
Print(ToString(dir), " OrderBlock Detected ...");
}
//
// Cleanup Resources ...
//
zBar.Clean();
cBar.Clean();
}
/**
* Detect POI(s) Using POIDetector Class ...
*/
void DetectPOIState()
{
//
if (!useDetector)
{
return;
}
//
if (!mBarTracker.IsNewBar())
{
return;
}
//
ENUM_XPOI_EVENTS poiEvents[];
XPOIStateEvents poiEventNotifier;
mPOIDetector.Update(
poiEvents,
0 //
);
poiEventNotifier.Init(poiEvents);
//
XPOIState state;
mPOIDetector.GetState(state);
//
bool showBullishPOIs = true;
bool showBearishPOIs = true;
//
XCBaseObject *stateObjects[];
mPOIDrawer.DrawState(
state,
stateObjects,
//
// Bullish ...
showBullishPOIs && false, // SwingLows
showBullishPOIs && false, // DemandZones
showBullishPOIs && false, // SupportZones
showBullishPOIs && false, // BullishSharps
showBullishPOIs && false, // BullishSpikes
showBullishPOIs && false, // BullishPullbacks
showBullishPOIs && false, // BullishMomentums
showBullishPOIs && false, // BullishRejections
showBullishPOIs && false, // BullishOrderBlocks
showBullishPOIs && false, // BullishFairValueGaps
showBullishPOIs && false, // BullishConsolidationZones
//
// Bearish ...
showBearishPOIs && false, // SwingHighs
showBearishPOIs && false, // SupplyZones
showBearishPOIs && false, // ResistanceZones
showBearishPOIs && false, // BearishSharps
showBearishPOIs && false, // BearishSpikes
showBearishPOIs && false, // BearishPullbacks
showBearishPOIs && false, // BearishMomentums
showBearishPOIs && false, // BearishRejections
showBearishPOIs && false, // BearishOrderBlocks
showBearishPOIs && false, // BearishFairValueGaps
showBearishPOIs && false // BearishConsolidationZones
);
//
Clean(poiEvents);
poiEventNotifier.Clean();
}
//
//+------------------------------------------------------------------+
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);
}
}
//
@@ -0,0 +1,187 @@
//
// Senario 3:
// ----------
bool useSenario3 = false;
bool isSenario3Happend = false;
bool isSenario3Bullish = false;
bool isSenario3Bearish = false;
if (useSenario3)
{
//
// Senario 3 Bullish Conditions ...
isSenario3Bullish = false;
//
// Senario 3 Bearish Conditions ...
isSenario3Bearish = false;
//
// Filling Requirements using Senario 3 ...
isSenario3Happend =
isSenario3Bullish ||
isSenario3Bearish;
if (isSenario3Happend)
{
//
dir =
isSenario3Bullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
box.dir = dir;
box.to = TimeCurrent();
box.symbol = provider
.decisionXConditions
.symbol;
box.period = provider
.decisionXConditions
.period;
//
int fromIDX = -1;
if (isSenario3Bullish)
{
//
double vale = provider
.decisionXConditions
.valesBuffer[cIDX];
//
box.lower = vale;
//
box.upper = provider
.decisionXConditions
.valesGoldenBuffer[cIDX];
//
int lowerValeIDX = -1;
double lowerVale = provider
.decisionCycleHelper
.mX121Helper
.xpvHelper
.GetLowerVale(
lowerValeIDX,
vale,
cBar.Index() //
);
//
int higherValeIDX = -1;
double higherVale = provider
.decisionCycleHelper
.mX121Helper
.xpvHelper
.GetHigherVale(
higherValeIDX,
vale,
cBar.Index() //
);
//
if (IsValidIndex(lowerValeIDX) &&
IsValidIndex(higherValeIDX))
{
//
fromIDX =
lowerValeIDX < higherValeIDX
? lowerValeIDX
: higherValeIDX;
}
else if (IsValidIndex(lowerValeIDX) &&
!IsValidIndex(higherValeIDX))
{
//
fromIDX = lowerValeIDX;
}
else if (!IsValidIndex(lowerValeIDX) &&
IsValidIndex(higherValeIDX))
{
//
fromIDX = higherValeIDX;
}
}
else
{
//
double peak = provider
.decisionXConditions
.peaksBuffer[cIDX];
//
box.upper = peak;
//
box.lower = provider
.decisionXConditions
.peaksGoldenBuffer[cIDX];
//
int lowerPeakIDX = -1;
double lowerPeak = provider
.decisionCycleHelper
.mX121Helper
.xpvHelper
.GetLowerPeak(
lowerPeakIDX,
peak,
cBar.Index() //
);
//
int higherPeakIDX = -1;
double higherPeak = provider
.decisionCycleHelper
.mX121Helper
.xpvHelper
.GetHigherPeak(
higherPeakIDX,
peak,
cBar.Index() //
);
//
if (IsValidIndex(lowerPeakIDX) &&
IsValidIndex(higherPeakIDX))
{
//
fromIDX =
lowerPeakIDX < higherPeakIDX
? lowerPeakIDX
: higherPeakIDX;
}
else if (IsValidIndex(lowerPeakIDX) &&
!IsValidIndex(higherPeakIDX))
{
//
fromIDX = lowerPeakIDX;
}
else if (!IsValidIndex(lowerPeakIDX) &&
IsValidIndex(higherPeakIDX))
{
//
fromIDX = higherPeakIDX;
}
}
//
if (IsValidIndex(fromIDX))
{
//
box.from = iTime(
zBar.symbol,
zBar.period,
fromIDX //
);
}
else
{
box.from = pBar.time;
}
//
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_BOX;
}
}