Files
MQL5Data/X121SMCEA/Libraries/x-121.smc.lib.mq5
T
2025-01-30 03:12:21 +03:30

1709 lines
34 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Common Library
// --------------------------------------
// Name: X121SMCLib
// Description: provide all commonly used functions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.mq5"
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
#include "../../Helpers/x-saherelm.x121.helper.mq5"
#include "../../Libraries/x-saherelm.common.lib.mq5"
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
#include "../../Libraries/x-saherelm.x-trade.lib.mq5"
//
// Definitions ...
//
const string X121SMCStrategyToken = "X121SMC";
//
const string X121SMCXToken = "X121X";
const string X121SMCXHKPVToken = "X121XHKPV";
const string X121SMCXOBPVToken = "X121XOBPV";
//
// X121 SMC Providers ...
enum ENUM_X_121_SMC_PROVIDERS
{
//
X_121_SMC_PROVIDER_NONE,
X_121_SMC_PROVIDER_X,
X_121_SMC_PROVIDER_XHKPV,
X_121_SMC_PROVIDER_XOBPV,
};
//
// Guard Actions ...
enum ENUM_X_121_SMC_GUARD_ACTIONS
{
X_121_SMC_GUARD_ACTION_NONE, // Nothing to Do
X_121_SMC_GUARD_ACTION_CLOSE, // Close Specified Position
X_121_SMC_GUARD_ACTION_CLOSE_ALL, // Close All Positions
X_121_SMC_GUARD_ACTION_CLOSE_LONGS, // Close All Long Positions
X_121_SMC_GUARD_ACTION_CLOSE_SHORTS, // Close All Short Position
X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE, // Partial Close Specified Position
X_121_SMC_GUARD_ACTION_TRAIL_STOP, // Trail Stop of Specified Position
X_121_SMC_GUARD_ACTION_TRAIL_TARGET, // Trail Target of Specified Position
X_121_SMC_GUARD_ACTION_HEDGE, // Hedge Specified Positions
};
//
// Each Market Cycle (Time Frame) Conditions
// Model as this Structure ...
struct X121SMCCycleConditions
{
//
string symbol;
ENUM_TIMEFRAMES period;
datetime time;
//
X121Conditions x121Conditions;
//
XPOIState state;
//
void X121SMCStrategyConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
symbol = NULL;
period = NULL;
time = NULL;
//
state.Clean();
x121Conditions.Clean();
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result = IsSpecifiedValid(symbol) &&
IsSpecifiedValid(period) &&
IsSpecifiedValid(time);
//
;
//
return result;
}
//
// Reporter Functions ...
/**
* Generate Provided Scores ...
*
* @param bullishScore: Integer, reference ...
* @param bearishScore: Integer, referenceF ...
*/
void GenerateScore(
double &bullishScore,
double &bearishScore //
)
{
//
bullishScore = 0;
bearishScore = 0;
//
if (!IsValid())
{
return;
}
//
double bullScore = 0;
double bearScore = 0;
}
/**
* Generate Summary ...
*
* @param onlyCommons: Boolean ...
* @param onlyConditions: Boolean ...
* @param includeScores: Boolean ...
* @param ignoreFalseConditions: Boolean ...
* @param separator: String ...
*
* @return ( string )
*/
string GenerateSummary(
bool onlyCommons = false,
bool onlyConditions = false,
bool includeScores = true,
bool ignoreFalseConditions = true,
string separator = "\n" //
)
{
//
string result = NULL;
//
double bullishScore = 0;
double bearishScore = 0;
GenerateScore(
bullishScore,
bearishScore //
);
//
string commonStr = GenerateSpecifiedCommonSummary(
this,
separator,
includeScores,
true //
);
//
string conditionsStr =
//
""
//
;
//
result =
//
"[" + GetTag() + "]" + separator +
"----------" + separator +
(onlyConditions
? ""
: commonStr) +
" " + separator +
(onlyCommons
? ""
: conditionsStr) +
""
//
;
//
return result;
}
/**
* Get Unique Identifier ...
*
* @param forObject: Boolean ...
*
* @return ( string )
*/
string GetTag(
bool forObject = false //
)
{
//
string result = NULL;
//
string typeName = GetTypeName(this);
//
if (!forObject)
{
result = typeName;
}
else
{
//
result = typeName + "_" +
symbol + "_" + ToString(period) + "_" +
ToMD5(time);
}
//
return result;
}
//
};
//
// Model Signalling Conditions ...
struct X121SMCStrategyConditions
{
//
string symbol;
ENUM_TIMEFRAMES period;
datetime time;
//
double sl;
double tp;
double target;
string provider;
ENUM_X_DIRECTION signalDir;
//
X121Conditions conditions;
// XPriceZones priceZones;
// XPriceZones decisionZones;
// XMarketStructure marketStructure;
//
void X121SMCStrategyConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
symbol = NULL;
period = NULL;
time = NULL;
//
sl = 0;
tp = 0;
provider = NULL;
signalDir = X_DIRECTION_NONE;
//
conditions.Clean();
// priceZones.Clean();
// decisionZones.Clean();
// marketStructure.Clean();
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result = IsSpecifiedValid(symbol) &&
IsSpecifiedValid(period) &&
IsSpecifiedValid(time);
//
return result;
}
/**
* Check Conditions Has Valid Bullish Signal ...
*
* @return ( bool )
*/
bool HasBullishSignal()
{
//
bool result = false;
//
result =
(sl > 0 ||
tp > 0) &&
IsValid() &&
HasDirection(signalDir);
if (!result)
{
return result;
}
//
result =
IsBullish(signalDir);
//
return result;
}
/**
* Check Conditions Has Valid Bearish Signal ...
*
* @return ( bool )
*/
bool HasBearishSignal()
{
//
bool result = false;
//
result =
(sl > 0 ||
tp > 0) &&
IsValid() &&
HasDirection(signalDir);
if (!result)
{
return result;
}
//
result =
IsBearish(signalDir);
//
return result;
}
//
// Reporter Functions ...
/**
* Generate Provided Scores ...
*
* @param bullishScore: Integer, reference ...
* @param bearishScore: Integer, referenceF ...
*/
void GenerateScore(
double &bullishScore,
double &bearishScore //
)
{
//
bullishScore = 0;
bearishScore = 0;
//
if (!IsValid())
{
return;
}
//
double bullScore = 0;
double bearScore = 0;
}
/**
* Generate Summary ...
*
* @param onlyCommons: Boolean ...
* @param onlyConditions: Boolean ...
* @param includeScores: Boolean ...
* @param ignoreFalseConditions: Boolean ...
* @param separator: String ...
*
* @return ( string )
*/
string GenerateSummary(
bool onlyCommons = false,
bool onlyConditions = false,
bool includeScores = true,
bool ignoreFalseConditions = true,
string separator = "\n" //
)
{
//
string result = NULL;
//
double bullishScore = 0;
double bearishScore = 0;
GenerateScore(
bullishScore,
bearishScore //
);
//
string commonStr = GenerateSpecifiedCommonSummary(
this,
separator,
includeScores,
true //
);
//
string conditionsStr =
//
""
//
;
//
result =
//
"[" + GetTag() + "]" + separator +
"----------" + separator +
(onlyConditions
? ""
: commonStr) +
" " + separator +
(onlyCommons
? ""
: conditionsStr) +
""
//
;
//
return result;
}
/**
* Get Unique Identifier ...
*
* @param forObject: Boolean ...
*
* @return ( string )
*/
string GetTag(
bool forObject = false //
)
{
//
string result = NULL;
//
string typeName = GetTypeName(this);
//
if (!forObject)
{
result = typeName;
}
else
{
//
result = typeName + "_" +
symbol + "_" + ToString(period) + "_" +
ToMD5(time);
}
//
return result;
}
//
};
//
// Model a Guard Action ...
struct X121SMCGuard
{
//
// Props ...
ENUM_X_121_SMC_GUARD_ACTIONS action;
datetime time;
//
string symbol;
string provider;
//
// Specified Position ...
ulong ticket;
//
// Partial Close ...
double volumeMultiplier;
//
// SL Trial ...
double sl;
//
// TP Trial ...
double tp;
//
// Constructor ...
X121SMCGuard()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
time = NULL;
action = X_121_SMC_GUARD_ACTION_NONE;
//
symbol = NULL;
provider = NULL;
//
ticket = 0;
//
volumeMultiplier = 0;
//
sl = 0;
tp = 0;
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(time) &&
IsValid(symbol) &&
IsValid(provider) &&
action != X_121_SMC_GUARD_ACTION_NONE
//
;
if (!result)
{
return result;
}
//
// Validate Model Based On Specified Guard Actions ...
//
return result;
}
};
//
// Model Cycle State ...
struct X121SMCCycleState
{
//
// Props ...
string symbol;
ENUM_TIMEFRAMES period;
//
// Bullish ...
XCFVG *bullishFVGs[];
XCOrderBlock *bullishOBs[];
XCDemandZone *demandZones[];
XCSupportZone *supportZones[];
//
// Bearish ...
XCFVG *bearishFVGs[];
XCOrderBlock *bearishOBs[];
XCSupplyZone *supplyZones[];
XCResistanceZone *resistanceZones[];
//
// Constructor ...
X121SMCCycleState()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
symbol = NULL;
period = NULL;
//
Clean(bullishFVGs);
Clean(bullishOBs);
Clean(demandZones);
Clean(supportZones);
//
Clean(bearishFVGs);
Clean(bearishOBs);
Clean(supplyZones);
Clean(resistanceZones);
}
/**
* Validate Model ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(symbol) &&
IsValid(period) &&
(
//
(HasBullishOBs() &&
(HasBullishFVGs() ||
HasSupportZones() ||
HasDemandZones()))
//
||
(HasBearishOBs() &&
(HasSupplyZones() ||
HasBearishFVGs() ||
HasResistanceZones()))
//
)
//
;
//
return result;
}
//
int CountBullishOBs()
{
return ArraySize(bullishOBs);
}
//
bool HasBullishOBs()
{
return IsValidSize(CountBullishOBs());
}
//
int CountBearishOBs()
{
return ArraySize(bearishOBs);
}
//
bool HasBearishOBs()
{
return IsValidSize(CountBearishOBs());
}
//
int CountSupportZones()
{
return ArraySize(supportZones);
}
//
bool HasSupportZones()
{
return IsValidSize(CountSupportZones());
}
//
int CountResistanceZones()
{
return ArraySize(resistanceZones);
}
//
bool HasResistanceZones()
{
return IsValidSize(CountResistanceZones());
}
//
int CountDemandZones()
{
return ArraySize(demandZones);
}
//
bool HasDemandZones()
{
return IsValidSize(CountDemandZones());
}
//
int CountSupplyZones()
{
return ArraySize(supplyZones);
}
//
bool HasSupplyZones()
{
return IsValidSize(CountSupplyZones());
}
//
int CountBullishFVGs()
{
return ArraySize(bullishFVGs);
}
//
bool HasBullishFVGs()
{
return IsValidSize(CountBullishFVGs());
}
//
int CountBearishFVGs()
{
return ArraySize(bearishFVGs);
}
//
bool HasBearishFVGs()
{
return IsValidSize(CountBearishFVGs());
}
//
bool GetOldestOB(
XCOrderBlock *&orderBlock //
)
{
//
bool result = false;
//
orderBlock = NULL;
//
bool hasBullishOB = HasBullishOBs();
bool hasBearishOB = HasBearishOBs();
result = hasBullishOB ||
hasBearishOB;
if (!result)
{
return result;
}
//
int iBullOBIDX = -1;
bool iHasBullOB = false;
XCOrderBlock *iBullOB = NULL;
if (hasBullishOB)
{
//
XCZone* iZones[];
ToZone(
bullishOBs,
iZones //
);
//
iBullOBIDX = GetOldest(
iZones //
);
//
iHasBullOB = IsValidIndex(iBullOBIDX);
if (iHasBullOB)
{
iBullOB = bullishOBs[iBullOBIDX];
}
}
//
int iBearOBIDX = -1;
bool iHasBearOB = false;
XCOrderBlock *iBearOB = NULL;
if (hasBearishOB)
{
//
XCZone* iZones[];
ToZone(
bearishOBs,
iZones //
);
//
iBearOBIDX = GetOldest(
iZones //
);
//
iHasBearOB = IsValidIndex(iBearOBIDX);
if (iHasBearOB)
{
iBearOB = bearishOBs[iBearOBIDX];
}
}
//
if (iHasBullOB)
{
orderBlock = iBullOB;
}
//
if (iHasBearOB)
{
//
bool canSet = orderBlock == NULL ||
orderBlock.From() > iBearOB.From();
if (canSet)
{
orderBlock = iBearOB;
}
}
//
result = orderBlock != NULL &&
orderBlock.IsValid();
//
return result;
}
//
bool GetYoungestOB(
XCOrderBlock *&orderBlock //
)
{
//
bool result = false;
//
orderBlock = NULL;
//
bool hasBullishOB = HasBullishOBs();
bool hasBearishOB = HasBearishOBs();
result = hasBullishOB ||
hasBearishOB;
if (!result)
{
return result;
}
//
int iBullOBIDX = -1;
bool iHasBullOB = false;
XCOrderBlock *iBullOB = NULL;
if (hasBullishOB)
{
//
XCZone* iZones[];
ToZone(
bullishOBs,
iZones //
);
//
iBullOBIDX = GetYoungest(
iZones //
);
//
iHasBullOB = IsValidIndex(iBullOBIDX);
if (iHasBullOB)
{
iBullOB = bullishOBs[iBullOBIDX];
}
}
//
int iBearOBIDX = -1;
bool iHasBearOB = false;
XCOrderBlock *iBearOB = NULL;
if (hasBearishOB)
{
//
XCZone* iZones[];
ToZone(
bearishOBs,
iZones //
);
//
iBearOBIDX = GetYoungest(
iZones //
);
//
iHasBearOB = IsValidIndex(iBearOBIDX);
if (iHasBearOB)
{
iBearOB = bearishOBs[iBearOBIDX];
}
}
//
if (iHasBullOB)
{
orderBlock = iBullOB;
}
//
if (iHasBearOB)
{
//
bool canSet = orderBlock == NULL ||
orderBlock.From() < iBearOB.From();
if (canSet)
{
orderBlock = iBearOB;
}
}
//
result = orderBlock != NULL &&
orderBlock.IsValid();
//
return result;
}
//
};
/**
* Detect Price inside Box ...
*
* @param box: XBoxZone instance Reference, Founded Price Inside Box ...
* @param orderBlock: XCOrderBlock pointer Reference, Founded Price Inside Order Block ...
* @param xConditions: X121Conditions instance Reference, provides Market Conditions ...
* @param state: X121SMCCycleState instance Reference ...
*
* @return ( bool )
*/
bool DetectPriceInsideBox(
XBoxZone &box, // Price Inside Bo ...
XCOrderBlock *&orderBlock, // Price Inside Order Block ...
X121Conditions &xConditions, // X121Conditions for Validation ...
X121SMCCycleState &state // Cycle State ...
)
{
//
bool result = false;
//
box.Clean();
//
string symbol = state.symbol;
ENUM_TIMEFRAMES period = state.period;
//
box.symbol = symbol;
box.period = period;
//
result = state.IsValid();
if (!result)
{
return result;
}
//
// Detect Price Inside Order Block ...
//
bool hasBullishOBs = state.HasBullishOBs();
int bullishOBsCount = state.CountBullishOBs();
//
bool hasBearishOBs = state.HasBearishOBs();
int bearishOBsCount = state.CountBearishOBs();
//
bool hasOBs =
//
hasBullishOBs ||
hasBearishOBs
//
;
result = hasOBs;
if (!result)
{
return result;
}
//
bool hasPriceInsideOB = false;
XCOrderBlock *priceInsideOB = NULL;
ENUM_X_DIRECTION boxDir = X_DIRECTION_NONE;
//
if (hasBullishOBs &&
!hasPriceInsideOB)
{
//
for (int i = 0; i < bullishOBsCount; i++)
{
//
XCOrderBlock *iOb = state.bullishOBs[i];
//
bool isInside = IsPriceInsideZone(
xConditions.valesBuffer[1],
(XCZone *)iOb //
);
if (isInside)
{
//
priceInsideOB = iOb;
hasPriceInsideOB = true;
boxDir = X_DIRECTION_BULLISH;
break;
}
}
}
//
if (hasBearishOBs &&
!hasPriceInsideOB)
{
//
for (int i = 0; i < bearishOBsCount; i++)
{
//
XCOrderBlock *iOb = state.bearishOBs[i];
//
bool isInside = IsPriceInsideZone(
xConditions.peaksBuffer[1],
(XCZone *)iOb //
);
if (isInside)
{
//
priceInsideOB = iOb;
hasPriceInsideOB = true;
boxDir = X_DIRECTION_BEARISH;
break;
}
}
}
//
if (hasPriceInsideOB)
{
//
orderBlock = priceInsideOB;
boxDir = priceInsideOB.IsBullish()
? X_DIRECTION_BULLISH
: priceInsideOB.IsBearish()
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
}
//
bool hasBullishFVGs = state.HasBullishFVGs();
bool hasBearishFVGs = state.HasBearishFVGs();
bool hasDemandZones = state.HasDemandZones();
bool hasSupplyZones = state.HasSupplyZones();
bool hasSupportZones = state.HasSupportZones();
bool hasResistanceZones = state.HasResistanceZones();
//
bool hasBullishZones =
//
hasBullishFVGs ||
hasDemandZones ||
hasSupportZones
//
;
//
bool hasBearishZones =
//
hasBearishFVGs ||
hasSupplyZones ||
hasResistanceZones
//
;
//
bool hasPropperZones =
//
IsBullish(boxDir)
? hasBullishZones
: IsBearish(boxDir)
? hasBearishZones
: false
//
;
//
if (!hasPropperZones &&
hasPriceInsideOB)
{
//
// Use Price Inside OB as Box ...
box.dir = boxDir;
box.to = priceInsideOB.To();
box.from = priceInsideOB.From();
box.upper = priceInsideOB.Upper();
box.lower = priceInsideOB.Lower();
}
else if (hasPropperZones &&
hasPriceInsideOB)
{
//
// Detect Validate Zones ...
int count = 0;
XBoxZone boxes[];
double upper = 0;
double lower = 0;
double price = 0;
datetime to = NULL;
datetime from = NULL;
ENUM_X_DIRECTION dir = X_DIRECTION_NONE;
if (IsBullish(boxDir))
{
//
double price = xConditions.valesBuffer[1];
dir = X_DIRECTION_BULLISH;
//
// Bullish FVG ...
count = state.CountBullishFVGs();
for (int i = 0; i < count; i++)
{
//
XCFVG *iFVG = state.bullishFVGs[i];
//
to = iFVG.To();
from = iFVG.From();
upper = iFVG.Upper();
lower = iFVG.Lower();
//
bool isInside = IsPriceInsideZone(
price,
upper,
lower //
);
if (isInside)
{
//
XBoxZone iBox;
//
iBox.dir = dir;
iBox.symbol = symbol;
iBox.period = period;
//
iBox.to = to;
iBox.from = from;
iBox.upper = upper;
iBox.lower = lower;
//
if (iBox.IsValid())
{
//
AddRef(
iBox,
boxes //
);
}
}
}
//
// Demand Zones ...
count = state.CountDemandZones();
for (int i = 0; i < count; i++)
{
//
XCDemandZone *iDemand = state.demandZones[i];
//
to = iDemand.To();
from = iDemand.From();
upper = iDemand.Upper();
lower = iDemand.Lower();
//
bool isInside = IsPriceInsideZone(
price,
upper,
lower //
);
if (isInside)
{
//
XBoxZone iBox;
//
iBox.dir = dir;
iBox.symbol = symbol;
iBox.period = period;
//
iBox.to = to;
iBox.from = from;
iBox.upper = upper;
iBox.lower = lower;
//
if (iBox.IsValid())
{
//
AddRef(
iBox,
boxes //
);
}
}
}
//
// Support Zones ...
count = state.CountSupportZones();
for (int i = 0; i < count; i++)
{
//
XCSupportZone *iSupport = state.supportZones[i];
//
to = iSupport.To();
from = iSupport.From();
upper = iSupport.Upper();
lower = iSupport.Lower();
//
bool isInside = IsPriceInsideZone(
price,
upper,
lower //
);
if (isInside)
{
//
XBoxZone iBox;
//
iBox.dir = dir;
iBox.symbol = symbol;
iBox.period = period;
//
iBox.to = to;
iBox.from = from;
iBox.upper = upper;
iBox.lower = lower;
//
if (iBox.IsValid())
{
//
AddRef(
iBox,
boxes //
);
}
}
}
}
else
{
//
double price = xConditions.peaksBuffer[1];
dir = X_DIRECTION_BEARISH;
//
// Bearish FVG ...
count = state.CountBearishFVGs();
for (int i = 0; i < count; i++)
{
//
XCFVG *iFVG = state.bearishFVGs[i];
//
to = iFVG.To();
from = iFVG.From();
upper = iFVG.Upper();
lower = iFVG.Lower();
//
bool isInside = IsPriceInsideZone(
price,
upper,
lower //
);
if (isInside)
{
//
XBoxZone iBox;
//
iBox.dir = dir;
iBox.symbol = symbol;
iBox.period = period;
//
iBox.to = to;
iBox.from = from;
iBox.upper = upper;
iBox.lower = lower;
//
if (iBox.IsValid())
{
//
AddRef(
iBox,
boxes //
);
}
}
}
//
// Supply Zones ...
count = state.CountSupplyZones();
for (int i = 0; i < count; i++)
{
//
XCSupplyZone *iSupply = state.supplyZones[i];
//
to = iSupply.To();
from = iSupply.From();
upper = iSupply.Upper();
lower = iSupply.Lower();
//
bool isInside = IsPriceInsideZone(
price,
upper,
lower //
);
if (isInside)
{
//
XBoxZone iBox;
//
iBox.dir = dir;
iBox.symbol = symbol;
iBox.period = period;
//
iBox.to = to;
iBox.from = from;
iBox.upper = upper;
iBox.lower = lower;
//
if (iBox.IsValid())
{
//
AddRef(
iBox,
boxes //
);
}
}
}
//
// Demand Zones ...
count = state.CountResistanceZones();
for (int i = 0; i < count; i++)
{
//
XCResistanceZone *iResistance = state.resistanceZones[i];
//
to = iResistance.To();
from = iResistance.From();
upper = iResistance.Upper();
lower = iResistance.Lower();
//
bool isInside = IsPriceInsideZone(
price,
upper,
lower //
);
if (isInside)
{
//
XBoxZone iBox;
//
iBox.dir = dir;
iBox.symbol = symbol;
iBox.period = period;
//
iBox.to = to;
iBox.from = from;
iBox.upper = upper;
iBox.lower = lower;
//
if (iBox.IsValid())
{
//
AddRef(
iBox,
boxes //
);
}
}
}
}
//
int boxesCount = ArraySize(boxes);
bool hasBoxes = IsValidSize(boxes);
if (hasBoxes)
{
//
// Filter Boxes ...
for (int i = 0; i < boxesCount; i++)
{
//
XBoxZone iBox = boxes[i];
//
// Direction ...
if (!HasDirection(box.dir) || box.dir != iBox.dir)
{
box.dir = iBox.dir;
}
//
// Upper ...
if (box.upper == 0 || box.upper < iBox.upper)
{
box.upper = iBox.upper;
}
//
// Lower ...
if (box.lower == 0 || box.lower < iBox.lower)
{
box.lower = iBox.lower;
}
//
// To ...
if (!IsValid(box.to) || box.to < iBox.to)
{
box.to = iBox.to;
}
//
// From ...
if (!IsValid(box.from) || box.from > iBox.from)
{
box.from = iBox.from;
}
}
}
else
{
//
// Use Price Inside OB as Box ...
box.dir = boxDir;
box.to = priceInsideOB.To();
box.from = priceInsideOB.From();
box.upper = priceInsideOB.Upper();
box.lower = priceInsideOB.Lower();
}
}
//
result = box.IsValid();
//
return result;
}
/**
* Add Guard to Collection ...
*
* @param guard: X121SMCGuard instance ...
* @param guards: X121SMCGuard instance Collection ...
*
* @return ( int )
*/
int AddGuard(
X121SMCGuard &guard,
X121SMCGuard &guards[] //
)
{
//
int result = 0;
//
if (!guard.IsValid())
{
return result;
}
//
AddRef(
guard,
guards //
);
//
result = ArraySize(guards);
//
return result;
}
//
//
//
typedef void (*TOnX121SMCSignal)(
XSignal &signal,
X121SMCStrategyConditions &conditions //
);
//
// Extentions ...
/**
* Validate a Signal Provider ...
*
* @param value: ENUM_X_121_SMC_PROVIDERS member ...
*
* @return ( bool )
*/
bool IsValid(ENUM_X_121_SMC_PROVIDERS value)
{
//
bool result = false;
//
result = value != X_121_SMC_PROVIDER_NONE;
//
return result;
}
/**
* Converts a Signal Provider to String ...
*
* @param value: ENUM_X_121_SMC_PROVIDERS member ...
*
* @return ( string )
*/
string ToString(ENUM_X_121_SMC_PROVIDERS value)
{
//
string result = NULL;
//
if (!IsValid(value))
{
return result;
}
//
switch (value)
{
//
case X_121_SMC_PROVIDER_X:
result = X121SMCXToken;
break;
//
case X_121_SMC_PROVIDER_XHKPV:
result = X121SMCXHKPVToken;
break;
//
case X_121_SMC_PROVIDER_XOBPV:
result = X121SMCXOBPVToken;
break;
}
//
return result;
}
/**
* Parse Specified String as a Signal Provider ...
*
* @param value: String ...
*
* @return ( ENUM_X_121_SMC_PROVIDERS )
*/
ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
{
//
ENUM_X_121_SMC_PROVIDERS result = X_121_SMC_PROVIDER_NONE;
//
if (!IsValid(value))
{
return result;
}
//
if (Contains(X121SMCXToken, value))
{
result = X_121_SMC_PROVIDER_X;
}
else if (Contains(X121SMCXHKPVToken, value))
{
result = X_121_SMC_PROVIDER_XHKPV;
}
else if (Contains(X121SMCXOBPVToken, value))
{
result = X_121_SMC_PROVIDER_XOBPV;
}
//
return result;
}
//