last works ...
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.x-signaller.class.mq5"
|
||||
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
|
||||
#include "../Classes/x-saherelm.xfima.x-poi.detector.class.mq5"
|
||||
|
||||
//
|
||||
// Implementation ...
|
||||
@@ -39,8 +40,9 @@ class XCXFIMABaseSignaller : public XCBaseSignaller
|
||||
// Props ...
|
||||
|
||||
//
|
||||
XFIMAInputs fimaInputs; // XFIMA Inputs ...
|
||||
XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ...
|
||||
XFIMAInputs fimaInputs; // XFIMA Inputs ...
|
||||
XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ...
|
||||
XCXFIMAPOIDetector *fimaPOIDetector; // XFIMA POI Detector ...
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
@@ -84,6 +86,9 @@ class XCXFIMABaseSignaller : public XCBaseSignaller
|
||||
ZeroMemory(fimaHelper);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
fimaPOIDetector = new XCXFIMAPOIDetector();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -113,6 +118,10 @@ class XCXFIMABaseSignaller : public XCBaseSignaller
|
||||
//
|
||||
delete fimaHelper;
|
||||
ZeroMemory(fimaHelper);
|
||||
|
||||
//
|
||||
delete fimaPOIDetector;
|
||||
ZeroMemory(fimaPOIDetector);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -182,7 +191,8 @@ class XCXFIMABaseSignaller : public XCBaseSignaller
|
||||
//
|
||||
// Validate Fima Helper Requirements ...
|
||||
result = fimaInputs.IsValid() &&
|
||||
fimaHelper != NULL;
|
||||
fimaHelper != NULL &&
|
||||
fimaPOIDetector != NULL;
|
||||
|
||||
//
|
||||
return result;
|
||||
@@ -518,4 +528,246 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
// XFIMA Strategy 2 Signaller Class ...
|
||||
class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XCXFIMAStrategy2Signaller(
|
||||
string _symbol, // Symbol ...
|
||||
ENUM_TIMEFRAMES _period, // Period ...
|
||||
XFIMAInputs &_fimaInputs, // XFIMAInputs ...
|
||||
bool _processAllTicks = false, // Process All Ticks ...
|
||||
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
|
||||
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
|
||||
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
|
||||
) : XCXFIMABaseSignaller("XFIMA2",
|
||||
_symbol,
|
||||
_period,
|
||||
_fimaInputs,
|
||||
_processAllTicks,
|
||||
_defaultSignalR2R,
|
||||
_defaultSignalRiskInPoint,
|
||||
_defaultSignalVolume //
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Reading ZigZag ...
|
||||
|
||||
//
|
||||
bool GetZigZagPoint()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Overrides ...
|
||||
|
||||
/**
|
||||
* Processing Tick ...
|
||||
*
|
||||
* @param barIndex: int, Specified Bar Index ...
|
||||
*/
|
||||
virtual void ProcessTick(int barIndex = 0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Processing New Bar ...
|
||||
*
|
||||
* @param barIndex: int, Specified Bar Index ...
|
||||
*/
|
||||
virtual void ProcessNewBar(int barIndex = 0)
|
||||
{
|
||||
//
|
||||
// Normalize ...
|
||||
barIndex = NormalizeInt(barIndex, 0);
|
||||
|
||||
//
|
||||
// Update Helper ...
|
||||
fimaHelper.Update(barIndex);
|
||||
|
||||
//
|
||||
XOHCL bar;
|
||||
XSignal signal;
|
||||
bool has = false;
|
||||
int cIdx = barIndex + 1;
|
||||
int pIdx = cIdx + 1;
|
||||
ENUM_X_DIRECTION signalDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
// Initialize Bar as CBar ...
|
||||
has = bar.Init(
|
||||
symbol,
|
||||
period,
|
||||
cIdx //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
bar.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Conditions ...
|
||||
XFIMAConditions fimaConditions;
|
||||
has = fimaHelper.GetConditions(
|
||||
fimaConditions,
|
||||
barIndex,
|
||||
10 // Loopback ...
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
bar.Clean();
|
||||
fimaConditions.Clean();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Analyse Conditions for Finding Signal ...
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
|
||||
//
|
||||
// Chekc Bullish or Bearish Starter Conditions ...
|
||||
has =
|
||||
isBullish ||
|
||||
isBearish;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Do Conditions Validating ...
|
||||
|
||||
//
|
||||
// Bullish Validation ...
|
||||
isBullish =
|
||||
//
|
||||
isBullish
|
||||
//
|
||||
&&
|
||||
//
|
||||
// Validations ...
|
||||
(
|
||||
//
|
||||
false
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Bearish Validation ...
|
||||
isBearish =
|
||||
//
|
||||
isBearish
|
||||
//
|
||||
&&
|
||||
//
|
||||
// Validations ...
|
||||
(
|
||||
//
|
||||
false
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
has =
|
||||
(isBullish && !isBearish) ||
|
||||
(isBearish && !isBullish);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Specified Signal Directions ...
|
||||
signalDir =
|
||||
isBullish
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal Founded ...
|
||||
has = HasDirection(signalDir);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// TODO: Provided SL ...
|
||||
|
||||
//
|
||||
// Prepare Founded Signal ...
|
||||
XTarget targets[];
|
||||
has = PrepareSignal(
|
||||
signal,
|
||||
signalDir,
|
||||
targets //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Notify On Signal Event ...
|
||||
NotifySignalEventListeners(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
bar.Clean();
|
||||
signal.Clean();
|
||||
fimaConditions.Clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Guards Based on MarketConditions ...
|
||||
*
|
||||
* @param guards: XGuard[]
|
||||
* @param barIndex: int
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int virtual CheckForGuard(
|
||||
XGuard &guards[],
|
||||
int barIndex = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
SpecifiedClean(guards);
|
||||
|
||||
//
|
||||
result = ArraySize(guards);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
@@ -0,0 +1,442 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class
|
||||
// -------------------------------------------------
|
||||
// Name: XCXFIMAPoiDetector ...
|
||||
// Description: XFIMA POI Detector Class ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XFIMA POI Detector Class"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.base.class.mq5"
|
||||
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
||||
#include "../../Classes/x-saherelm.x-market.pattern.class.mq5"
|
||||
#include "../Libraries/x-saherelm.xfima.lib.mq5"
|
||||
|
||||
//
|
||||
// Implementation ...
|
||||
class XCXFIMAPOIDetector : public XCBase
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Props ...
|
||||
XCBarAnalyser *barAnalyser; // Bar Analyser ...
|
||||
XCMarketPatternDetector *patternDetector; // Bar Analyser ...
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XCXFIMAPOIDetector()
|
||||
{
|
||||
//
|
||||
barAnalyser = new XCBarAnalyser();
|
||||
patternDetector = new XCMarketPatternDetector();
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
~XCXFIMAPOIDetector()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Implementing Parren Detector ...
|
||||
|
||||
/**
|
||||
* Check Specified Bar is Momentum Bar or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
* @param requiredBars: int, bar range for approve Momentum ...
|
||||
* @param approvedMultiplier: int, a Multipler for approve Momentum ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsMomentumBar(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
int requiredBars = 3,
|
||||
int approvedMultiplier = 2 //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsMomentumBar(
|
||||
bar,
|
||||
dir,
|
||||
requiredBars,
|
||||
approvedMultiplier //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar is Engulfed Bar or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsEngulfedBar(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsEngulfedBar(
|
||||
bar,
|
||||
dir //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar is True Gapped Bar or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
* @param approvedPointMultiplier: double, Gap Validation Multiplier in Point ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsTrueGapedBar(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
double approvedPointMultiplier = 1 //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsTrueGapedBar(
|
||||
bar,
|
||||
dir,
|
||||
approvedPointMultiplier //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar is Pinned Bar or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
* @param shadowApprovedMultiplier: int, Shadow Size Approve Multiplier ...
|
||||
* @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ...
|
||||
* @param forceDirection: bool, Apply Force Bar Type ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsPinnedBar(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
int shadowApprovedMultiplier = 3,
|
||||
double minimumPinBarRangeMultiplier = 4,
|
||||
bool forceDirection = false //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsPinnedBar(
|
||||
bar,
|
||||
dir,
|
||||
shadowApprovedMultiplier,
|
||||
minimumPinBarRangeMultiplier,
|
||||
forceDirection //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar has Star Pattern or not ...
|
||||
* Morning Star => Bullish
|
||||
* Evening Star => Bearish
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsStartPattern(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsStartPattern(
|
||||
bar,
|
||||
dir //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar has Pirecing Pattern or not ...
|
||||
* Piercing => Bullish
|
||||
* Dark Cloud Cover => Bearish
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsPiercingPattern(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsPiercingPattern(
|
||||
bar,
|
||||
dir //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar has Rising Pattern or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsRisingPattern(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsRisingPattern(
|
||||
bar,
|
||||
dir //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar has Flag Pattern or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
* @param swingBar: XOHCL, Detected Swing Bar ...
|
||||
* @param minimumPullbackBars: int, Minimum Shoulders of Swing Bar ...
|
||||
* @param minimumPullbackBars: int, Minimum Shoulders of Swing Bar ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsFlagPattern(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
XOHCL &swingBar,
|
||||
int minimumPullbackBars = 3 //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsFlagPattern(
|
||||
bar,
|
||||
dir,
|
||||
swingBar,
|
||||
minimumPullbackBars //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar has SignalKey Bar Pattern or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
* @param shadowApprovedMultiplier: int, Shadow Size Approve Multiplier ...
|
||||
* @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ...
|
||||
* @param forceDirection: bool, Apply Force Bar Type ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsSignalKeyBarPattern(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
int shadowApprovedMultiplier = 3,
|
||||
double minimumPinBarRangeMultiplier = 4,
|
||||
bool forceDirection = false //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.IsSignalKeyBarPattern(
|
||||
bar,
|
||||
dir,
|
||||
shadowApprovedMultiplier,
|
||||
minimumPinBarRangeMultiplier,
|
||||
forceDirection //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check For FVG Exists in Specified Loopback Period ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
* @param fvg: XBoxZone, reference for Holding FVG ...
|
||||
* @param maxLoopback: int, Max Allowed Loopback to Lookup FVG ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool HasFVG(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
XBoxZone &fvg,
|
||||
int maxLoopback = 5 //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.HasFVG(
|
||||
bar,
|
||||
dir,
|
||||
fvg,
|
||||
maxLoopback //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check For OB Exists in Specified Loopback Period ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
* @param ob: XBoxZone, reference for Holding OB ...
|
||||
* @param maxLoopback: int, Max Allowed Loopback to Lookup OB ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool HasOB(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
XBoxZone &ob,
|
||||
int maxLoopback = 5 //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.HasOB(
|
||||
bar,
|
||||
dir,
|
||||
ob,
|
||||
maxLoopback //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Trend Exists Based on Swings ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
|
||||
* @param swings: XOHCL Array, Holds Swings ...
|
||||
* @param numberOfSwings: int, Number of Swing Points for Detect Trend ...
|
||||
* @param swingShoulders: int, Swing Shoulders Approvement Length ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool HasSwingTrend(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
XOHCL &swings[],
|
||||
int numberOfSwings = 3,
|
||||
int swingShoulders = 7 //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.HasSwingTrend(
|
||||
bar,
|
||||
dir,
|
||||
swings,
|
||||
numberOfSwings,
|
||||
swingShoulders //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar Has Support or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param support: XOHCL, Supported Bar ...
|
||||
* @param validationLength: int, Validation Length ...
|
||||
* @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool HasSupport(
|
||||
XOHCL &bar,
|
||||
XOHCL &support,
|
||||
int validationLength = 21,
|
||||
int maxAllowedLoopback = 1500 //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.HasSupport(
|
||||
bar,
|
||||
support,
|
||||
validationLength,
|
||||
maxAllowedLoopback //
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Bar Has Resistance or not ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param resistence: XOHCL, Resistanced Bar ...
|
||||
* @param validationLength: int, Validation Length ...
|
||||
* @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool HasResistance(
|
||||
XOHCL &bar,
|
||||
XOHCL &resistence,
|
||||
int validationLength = 21,
|
||||
int maxAllowedLoopback = 1500 //
|
||||
)
|
||||
{
|
||||
//
|
||||
return patternDetector.HasResistance(
|
||||
bar,
|
||||
resistence,
|
||||
validationLength,
|
||||
maxAllowedLoopback //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Destroy ...
|
||||
*/
|
||||
void Destroy()
|
||||
{
|
||||
//
|
||||
delete barAnalyser;
|
||||
ZeroMemory(barAnalyser);
|
||||
|
||||
//
|
||||
delete patternDetector;
|
||||
ZeroMemory(patternDetector);
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
Reference in New Issue
Block a user