1761 lines
35 KiB
Plaintext
1761 lines
35 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// ----------------------------------------------
|
|
// Name: XSCX121Provider
|
|
// Description: X121 Signal Provider ...
|
|
//
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// START Definitions ...
|
|
//
|
|
|
|
//
|
|
// START Import and Inclused requirements ...
|
|
//
|
|
|
|
//
|
|
// Includes ...
|
|
#include "../Classes/x-saherelm.xprovider.class.mq5"
|
|
#include "../Helpers/x-saherelm.x121.xman.helper.class.mq5"
|
|
|
|
//
|
|
// Library ...
|
|
#include "../Libraries/x-saherelm.seriallizer.lib.mq5"
|
|
|
|
//
|
|
// END Import and Inclused requirements ...
|
|
//
|
|
|
|
//
|
|
// Here we Have to Define an Input Structure Model
|
|
// for Provider Class to Handle Helpers Definitions ...
|
|
struct X121ProviderInputs
|
|
{
|
|
//
|
|
// XMAN ...
|
|
XMANInputs xmanConfig;
|
|
};
|
|
|
|
//
|
|
// Model Market Sense based On Current Captured conditions ...
|
|
struct X121MarketConditions
|
|
{
|
|
//
|
|
// Commonly Used Info ...
|
|
|
|
//
|
|
// Symbol ...
|
|
string symbol;
|
|
|
|
//
|
|
// Period ...
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
// Bar Time ...
|
|
datetime barTime;
|
|
|
|
//
|
|
XCandleRemains barRemains;
|
|
|
|
//
|
|
// Bar Index ...
|
|
int barIndex;
|
|
|
|
//
|
|
// Check Current Market Condition has Signal or not ...
|
|
bool hasSignal;
|
|
|
|
//
|
|
// If has any Signal, Models it's related info here ...
|
|
XSignal signal;
|
|
|
|
//
|
|
// Support and Resistances ...
|
|
// if provides Signal ...
|
|
XOHCLSupRes supportResistances;
|
|
|
|
//
|
|
// Change Price Steps ...
|
|
double momentumStep;
|
|
|
|
//
|
|
XOHCL candles[];
|
|
|
|
//
|
|
// INDICATORS Market Sense ...
|
|
|
|
//
|
|
// XMAN ...
|
|
XMANInfo xmanInfo;
|
|
};
|
|
|
|
//
|
|
#include "../Libraries/x-saherelm.x121.x92.lib.mq5"
|
|
#include "../Libraries/x-saherelm.x121.x786.lib.mq5"
|
|
#include "../Libraries/x-saherelm.x121.xtest.lib.mq5"
|
|
#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5"
|
|
|
|
//
|
|
// Notified a Signal was Appears ...
|
|
typedef void (*TOnSignalConditions)(
|
|
X121MarketConditions &info);
|
|
|
|
//
|
|
// All Available Signal Types ...
|
|
enum ENUM_X121_SIGNAL_PROVIDERS
|
|
{
|
|
NONE, // NONE ...
|
|
XTEST, // TEST ...
|
|
X786, // Hadi Khazaee Asl ...
|
|
X92, // Hadi Khazaee Asl ...
|
|
};
|
|
|
|
//
|
|
// END Definitions ...
|
|
//
|
|
|
|
//
|
|
// START Overrides ...
|
|
//
|
|
|
|
//
|
|
// END Overrides ...
|
|
//
|
|
|
|
//
|
|
// a Base Class for All of our EA's ...
|
|
class XSCX121Provider : public XSCEABaseProvider
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
X121ProviderInputs providedConfig;
|
|
X121ProviderInputs currentConfig;
|
|
X121ProviderInputs cleanConfig;
|
|
|
|
//
|
|
// Indicator Helper Classes Instance ...
|
|
|
|
//
|
|
// XMAN ...
|
|
XSCXMANHelper *mXManHelper;
|
|
|
|
//
|
|
// Pivot Points ...
|
|
|
|
//
|
|
// Hull and SSL Pivot Points ...
|
|
double upZonePivots[];
|
|
double downZonePivots[];
|
|
|
|
//
|
|
// Peaks and Vales Verifications Number ...
|
|
double peakPivots[];
|
|
double valePivots[];
|
|
|
|
//
|
|
double cyclesHHPivots[];
|
|
double cyclesLLPivots[];
|
|
|
|
//
|
|
double fibPivots[];
|
|
|
|
//
|
|
int pivotsSequentialCount;
|
|
|
|
//
|
|
// Constructor ...
|
|
void XSCX121Provider(
|
|
string symbol, // Trading Symbol ...
|
|
ENUM_TIMEFRAMES period, // Trading Time Frame ...
|
|
bool ignoreTicksAfterSignalTillNewCandle // Ignore Ticks after Recieved a Signal Till new Candle ...
|
|
) : XSCEABaseProvider(symbol, period, ignoreTicksAfterSignalTillNewCandle)
|
|
{
|
|
//
|
|
mMinPivots = 200;
|
|
pivotsSequentialCount = 35;
|
|
|
|
//
|
|
PrepareTag();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XSCX121Provider()
|
|
{
|
|
//
|
|
// De construct Helpers ...
|
|
delete mXManHelper;
|
|
}
|
|
|
|
//
|
|
virtual void PrepareTag()
|
|
{
|
|
mTag = "X121Provider((" + mSymbol + ")(" + ToString(mPeriod) + ")";
|
|
}
|
|
|
|
//
|
|
virtual bool Init()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Instantiate all Indicators Helper Classes ...
|
|
|
|
//
|
|
// XMAN ...
|
|
mXManHelper = new XSCXMANHelper(
|
|
mSymbol,
|
|
mPeriod);
|
|
result = mXManHelper.SetConfig(currentConfig.xmanConfig);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
virtual int GetMaxLength()
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
result = MathMax(result, mXManHelper.GetMaxLength());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
virtual int GetCalculatedBars()
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
int mXManBars = mXManHelper.GetCalculatedBars();
|
|
|
|
//
|
|
int min = MathMin(1, mXManBars);
|
|
|
|
//
|
|
int max = MathMax(1, mXManBars);
|
|
|
|
//
|
|
result = min;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
virtual void ProcessBuffers()
|
|
{
|
|
UpdatePivotPoints();
|
|
}
|
|
|
|
//
|
|
virtual bool ProcessTick(X121MarketConditions &conditions)
|
|
{
|
|
//
|
|
if (CanIgnoreTick())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
return ProcessSignals(conditions);
|
|
}
|
|
|
|
//
|
|
int GetMinPivots()
|
|
{
|
|
return mMinPivots;
|
|
}
|
|
|
|
//
|
|
X121ProviderInputs GetConfig()
|
|
{
|
|
//
|
|
X121ProviderInputs result;
|
|
|
|
//
|
|
result = currentConfig;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Set Available Signallers ...
|
|
bool SetSignallers(
|
|
string &signallers[])
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = ArraySize(signallers) > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
Copy(
|
|
signallers,
|
|
mSignallers);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool SetConfig(X121ProviderInputs &config)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
PrepareConfig(config);
|
|
|
|
//
|
|
result = Init();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool ResetDefaultConfig()
|
|
{
|
|
//
|
|
bool result = SetConfig(providedConfig);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool ShowCleanConfig()
|
|
{
|
|
//
|
|
currentConfig = cleanConfig;
|
|
|
|
//
|
|
bool result = Init();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool ShowDefaultConfig()
|
|
{
|
|
//
|
|
currentConfig = providedConfig;
|
|
|
|
//
|
|
bool result = Init();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsAllowedSignaller(
|
|
ENUM_X121_SIGNAL_PROVIDERS provider // Signal Provider
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string providerStr = ToString(provider);
|
|
|
|
//
|
|
result = Contains(
|
|
providerStr,
|
|
mSignallers);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Generate Market Sense ...
|
|
X121MarketConditions GetMarketConditions(
|
|
int barIndex // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
X121MarketConditions result;
|
|
|
|
//
|
|
// Fill Common Data ...
|
|
result.symbol = mSymbol;
|
|
result.period = mPeriod;
|
|
result.barIndex = barIndex;
|
|
|
|
//
|
|
datetime barTime = GetCandleTime(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex);
|
|
result.barTime = barTime;
|
|
|
|
//
|
|
int remainedCandle = barIndex > 0
|
|
? barIndex - 1
|
|
: barIndex;
|
|
GetCandleRemainsTime(
|
|
result.barRemains,
|
|
mSymbol,
|
|
mPeriod,
|
|
remainedCandle);
|
|
|
|
//
|
|
// Attach Candles Info in XOHCL Model to Conditions ...
|
|
int mLoopBackBars = mXManHelper.Loopback();
|
|
XOHCL candles[];
|
|
GetCandles(
|
|
candles,
|
|
mSymbol,
|
|
mPeriod,
|
|
0,
|
|
mLoopBackBars);
|
|
Copy(
|
|
candles,
|
|
result.candles);
|
|
Clean(candles);
|
|
|
|
//
|
|
result.xmanInfo = mXManHelper.GetInfo(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool GuardCheck(XGuard &guards[])
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(guards);
|
|
|
|
//
|
|
// Implement Guards Check ...
|
|
X121MarketConditions mConditions = GetMarketConditions(1);
|
|
|
|
//
|
|
// X786 ...
|
|
bool canCheckX786 = IsAllowedSignaller(X786);
|
|
if (canCheckX786)
|
|
{
|
|
//
|
|
// Check Stop Trailings ...
|
|
|
|
//
|
|
// Longs ...
|
|
double longSL = 0;
|
|
bool canTrailLongStops = CanX786TrailLongsStop(
|
|
mConditions,
|
|
longSL);
|
|
//
|
|
// TODO: Remove this ...
|
|
canTrailLongStops = false;
|
|
if (canTrailLongStops)
|
|
{
|
|
//
|
|
XGuard guard;
|
|
|
|
//
|
|
guard.symbol = mSymbol;
|
|
guard.period = mPeriod;
|
|
guard.provider = ToString(X786);
|
|
guard.type = POSITION_TYPE_BUY;
|
|
guard.action = X_GUARD_ACTION_TRAIL_STOP;
|
|
|
|
//
|
|
guard.dblPayLoad = longSL;
|
|
|
|
//
|
|
Add(
|
|
guard,
|
|
guards);
|
|
}
|
|
|
|
//
|
|
// Shorts ...
|
|
double shortSL = 0;
|
|
bool canTrailShortStops = CanX786TrailShortsStop(
|
|
mConditions,
|
|
shortSL);
|
|
//
|
|
// TODO: Remove this ...
|
|
canTrailShortStops = false;
|
|
if (canTrailShortStops)
|
|
{
|
|
//
|
|
XGuard guard;
|
|
|
|
//
|
|
guard.symbol = mSymbol;
|
|
guard.period = mPeriod;
|
|
guard.provider = ToString(X786);
|
|
guard.type = POSITION_TYPE_SELL;
|
|
guard.action = X_GUARD_ACTION_TRAIL_STOP;
|
|
|
|
//
|
|
guard.dblPayLoad = shortSL;
|
|
|
|
//
|
|
Add(
|
|
guard,
|
|
guards);
|
|
}
|
|
|
|
//
|
|
// Check Force Close ...
|
|
bool canForceCloseLongs = CanX786ForceCloseLongs(mConditions);
|
|
canForceCloseLongs = false;
|
|
if (canForceCloseLongs)
|
|
{
|
|
//
|
|
XGuard guard;
|
|
|
|
//
|
|
guard.symbol = mSymbol;
|
|
guard.period = mPeriod;
|
|
guard.provider = ToString(X786);
|
|
guard.type = POSITION_TYPE_BUY;
|
|
guard.action = X_GUARD_ACTION_FORCE_CLOSE;
|
|
|
|
//
|
|
Add(
|
|
guard,
|
|
guards);
|
|
}
|
|
|
|
//
|
|
// Check Hedghe ...
|
|
bool hedgeX786 = false;
|
|
if (hedgeX786)
|
|
{
|
|
//
|
|
XGuard guard;
|
|
|
|
//
|
|
guard.type = NULL;
|
|
guard.symbol = mSymbol;
|
|
guard.period = mPeriod;
|
|
guard.provider = ToString(X786);
|
|
guard.action = X_GUARD_ACTION_HEDGE;
|
|
|
|
//
|
|
Add(
|
|
guard,
|
|
guards);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(guards) > 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add Specific On SignalConditions Event Handler ...
|
|
int AddOnSignalConditionEventHandler(TOnSignalConditions handler)
|
|
{
|
|
//
|
|
ArrayResize(
|
|
mSignalConditionsEventHandlers,
|
|
ArraySize(mSignalConditionsEventHandlers) + 1);
|
|
|
|
//
|
|
int result = ArraySize(mSignalConditionsEventHandlers) - 1;
|
|
mSignalConditionsEventHandlers[result] = handler;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Remove All On Signal Event Handler ...
|
|
void ReoveOnSignalEventHandlers()
|
|
{
|
|
//
|
|
ArrayFree(mSignalConditionsEventHandlers);
|
|
}
|
|
|
|
//
|
|
// Notify a Signal Found on all Event Listeners ...
|
|
void NotifyOnSignalConditionsEvent(X121MarketConditions &info)
|
|
{
|
|
//
|
|
int listenerCount = ArraySize(mSignalConditionsEventHandlers);
|
|
if (listenerCount <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Loop Through Listeners ...
|
|
for (int i = 0; i < listenerCount; i++)
|
|
{
|
|
//
|
|
TOnSignalConditions listener = mSignalConditionsEventHandlers[i];
|
|
|
|
//
|
|
listener(info);
|
|
}
|
|
}
|
|
|
|
//
|
|
// PIVOTS ...
|
|
|
|
//
|
|
// Start Pivots Scanning on Instance Creation ...
|
|
void ProccessPivotPoints()
|
|
{
|
|
//
|
|
if (mStartPivotScan)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
mStartPivotScan = true;
|
|
|
|
//
|
|
int scanSize = iBars(
|
|
mSymbol,
|
|
mPeriod) -
|
|
500;
|
|
|
|
//
|
|
for (int i = 1; i < scanSize; i++)
|
|
{
|
|
//
|
|
UpdatePivotPoints(i);
|
|
|
|
//
|
|
int pivotsCount = CountPivots();
|
|
if (pivotsCount >= mMinPivots)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Count Current Pivots ...
|
|
int CountPivots()
|
|
{
|
|
//
|
|
int pivotSizes[];
|
|
|
|
//
|
|
int upZoneCount = ArraySize(upZonePivots);
|
|
if (upZoneCount > 0)
|
|
{
|
|
//
|
|
Add(
|
|
upZoneCount,
|
|
pivotSizes);
|
|
}
|
|
|
|
//
|
|
int downZoneCount = ArraySize(downZonePivots);
|
|
if (downZoneCount > 0)
|
|
{
|
|
//
|
|
Add(
|
|
downZoneCount,
|
|
pivotSizes);
|
|
}
|
|
|
|
//
|
|
int peaksCount = ArraySize(peakPivots);
|
|
if (peaksCount > 0)
|
|
{
|
|
//
|
|
Add(
|
|
peaksCount,
|
|
pivotSizes);
|
|
}
|
|
|
|
//
|
|
int valesCount = ArraySize(valePivots);
|
|
if (valesCount > 0)
|
|
{
|
|
//
|
|
Add(
|
|
valesCount,
|
|
pivotSizes);
|
|
}
|
|
|
|
//
|
|
int fibsCount = ArraySize(fibPivots);
|
|
if (fibsCount > 0)
|
|
{
|
|
//
|
|
Add(
|
|
fibsCount,
|
|
pivotSizes);
|
|
}
|
|
|
|
//
|
|
int cyclesHHsCount = ArraySize(cyclesHHPivots);
|
|
if (cyclesHHsCount > 0)
|
|
{
|
|
//
|
|
Add(
|
|
cyclesHHsCount,
|
|
pivotSizes);
|
|
}
|
|
|
|
//
|
|
int cyclesLLsCount = ArraySize(cyclesLLPivots);
|
|
if (cyclesLLsCount > 0)
|
|
{
|
|
//
|
|
Add(
|
|
cyclesHHsCount,
|
|
pivotSizes);
|
|
}
|
|
|
|
//
|
|
int result = ArraySize(pivotSizes) > 0
|
|
? pivotSizes[ArrayMaximum(pivotSizes)]
|
|
: 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Fill Pivot Points ...
|
|
int FillPivotPoints(
|
|
double &result[] // Hold Result
|
|
)
|
|
{
|
|
//
|
|
int mResult = 0;
|
|
|
|
//
|
|
Clean(result);
|
|
|
|
//
|
|
int pCount = CountPivots();
|
|
if (pCount <= 0)
|
|
{
|
|
return mResult;
|
|
}
|
|
|
|
//
|
|
AddsIfNotExists(
|
|
upZonePivots,
|
|
result);
|
|
|
|
//
|
|
AddsIfNotExists(
|
|
downZonePivots,
|
|
result);
|
|
|
|
//
|
|
AddsIfNotExists(
|
|
peakPivots,
|
|
result);
|
|
|
|
//
|
|
AddsIfNotExists(
|
|
valePivots,
|
|
result);
|
|
|
|
//
|
|
AddsIfNotExists(
|
|
fibPivots,
|
|
result);
|
|
|
|
//
|
|
AddsIfNotExists(
|
|
cyclesHHPivots,
|
|
result);
|
|
|
|
//
|
|
AddsIfNotExists(
|
|
cyclesLLPivots,
|
|
result);
|
|
|
|
//
|
|
mResult = ArraySize(result);
|
|
|
|
//
|
|
return mResult;
|
|
}
|
|
|
|
//
|
|
// Generate Exists Support and Resistance based on Given Price ...
|
|
XOHCLSupRes GenerateSupportAndResistance(
|
|
double price, // Specified Price
|
|
int count = 10 // Number of Pivots in Each Side
|
|
)
|
|
{
|
|
//
|
|
XOHCLSupRes result;
|
|
|
|
//
|
|
UpdatePivotPoints(0);
|
|
|
|
//
|
|
double pivots[];
|
|
FillPivotPoints(pivots);
|
|
|
|
//
|
|
// Generate Support and Resistances ...
|
|
result = ExtractSupportAndResistance(
|
|
price,
|
|
pivots,
|
|
count);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// CCandle Timer ...
|
|
int mCTimerHandler;
|
|
|
|
//
|
|
// Signal Event Handlers ...
|
|
TOnSignalConditions mSignalConditionsEventHandlers[];
|
|
|
|
//
|
|
// Make Provided Config in Clean Style ...
|
|
void PrepareConfig(X121ProviderInputs &config)
|
|
{
|
|
//
|
|
cleanConfig = config;
|
|
|
|
//
|
|
// XMAN ...
|
|
cleanConfig.xmanConfig.showCandleTimer = false;
|
|
cleanConfig.xmanConfig.showCandles = false;
|
|
cleanConfig.xmanConfig.showHKCandles = false;
|
|
cleanConfig.xmanConfig.showPeaksAndVales = false;
|
|
cleanConfig.xmanConfig.showTrends = false;
|
|
cleanConfig.xmanConfig.fillTrends = false;
|
|
cleanConfig.xmanConfig.showLevels = false;
|
|
cleanConfig.xmanConfig.showConsolidations = false;
|
|
cleanConfig.xmanConfig.showRibbons = false;
|
|
cleanConfig.xmanConfig.showHull = false;
|
|
cleanConfig.xmanConfig.showSSLChannel = false;
|
|
cleanConfig.xmanConfig.showFibo1Levels = false;
|
|
cleanConfig.xmanConfig.showFibo2Levels = false;
|
|
cleanConfig.xmanConfig.showFibo3Levels = false;
|
|
|
|
//
|
|
providedConfig = config;
|
|
currentConfig = config;
|
|
}
|
|
|
|
//
|
|
void Calculate(int barIndex)
|
|
{
|
|
//
|
|
mXManHelper.Calculate(barIndex);
|
|
}
|
|
|
|
//
|
|
int mMinPivots;
|
|
bool mStartPivotScan;
|
|
double mLastMomentumStep;
|
|
|
|
//
|
|
// Find Required Pivots for Support and Resistance ...
|
|
void UpdatePivotPoints(
|
|
int barIndex = 0 // Specified Candle ...
|
|
)
|
|
{
|
|
//
|
|
Calculate(barIndex);
|
|
|
|
//
|
|
// Detect Peask and Vales Pivots ...
|
|
|
|
//
|
|
// Detect Hull Pivots ...
|
|
// find Hull Trend Changes ...
|
|
int idx = 0;
|
|
|
|
//
|
|
// Retrieve XMan Info ...
|
|
// since it's the only one Indicator which provides Data here ...
|
|
XMANInfo info = mXManHelper.GetInfo(barIndex);
|
|
|
|
//
|
|
// Define some Variable to count Verified Sequences ...
|
|
int fib1Verified = 0;
|
|
int fib2Verified = 0;
|
|
int fib3Verified = 0;
|
|
int peakVerified = 0;
|
|
int valeVerified = 0;
|
|
int scHHVerified = 0;
|
|
int scLLVerified = 0;
|
|
int mcHHVerified = 0;
|
|
int mcLLVerified = 0;
|
|
int lcHHVerified = 0;
|
|
int lcLLVerified = 0;
|
|
int hcHHVerified = 0;
|
|
int hcLLVerified = 0;
|
|
|
|
//
|
|
// Here we have to select Points to verify their Sequential repeats ...
|
|
|
|
//
|
|
// Slect Fibonacci Values ...
|
|
double selectedFib1 = info.fibLevel1s[idx];
|
|
double selectedFib2 = info.fibLevel2s[idx];
|
|
double selectedFib3 = info.fibLevel3s[idx];
|
|
|
|
//
|
|
// Select Peaks and Vales ...
|
|
double selectedPeak = info.peaks[idx];
|
|
double selectedVale = info.vales[idx];
|
|
|
|
//
|
|
// Select Cycles Highest Highs ...
|
|
double selectedSCHH = info.sHHs[idx];
|
|
double selectedMCHH = info.mHHs[idx];
|
|
double selectedLCHH = info.lHHs[idx];
|
|
double selectedHCHH = info.hHHs[idx];
|
|
|
|
//
|
|
// Select Cycles Lowest Lows ...
|
|
double selectedSCLL = info.sLLs[idx];
|
|
double selectedMCLL = info.mLLs[idx];
|
|
double selectedLCLL = info.lLLs[idx];
|
|
double selectedHCLL = info.hLLs[idx];
|
|
|
|
//
|
|
// Now we Have to Loop Bars Until Fillup Required
|
|
// Pivots or END available Bars ...
|
|
int startIndex = idx;
|
|
int endIndex = pivotsSequentialCount + idx + 1;
|
|
for (int i = startIndex; i < endIndex; i++)
|
|
{
|
|
//
|
|
int idx = i - startIndex;
|
|
|
|
//
|
|
// Now We Have to Compare each Selected Value with indexed value ...
|
|
|
|
//
|
|
// Peaks ...
|
|
if (selectedPeak == info.peaks[i])
|
|
{
|
|
peakVerified++;
|
|
}
|
|
else
|
|
{
|
|
peakVerified = 0;
|
|
}
|
|
|
|
//
|
|
// Vales ...
|
|
if (selectedVale == info.vales[i])
|
|
{
|
|
valeVerified++;
|
|
}
|
|
else
|
|
{
|
|
valeVerified = 0;
|
|
}
|
|
|
|
//
|
|
// Fibo 1 ...
|
|
if (selectedFib1 == info.fibLevel1s[i])
|
|
{
|
|
fib1Verified++;
|
|
}
|
|
else
|
|
{
|
|
fib1Verified = 0;
|
|
}
|
|
|
|
//
|
|
// Fibo 2 ...
|
|
if (selectedFib2 == info.fibLevel2s[i])
|
|
{
|
|
fib2Verified++;
|
|
}
|
|
else
|
|
{
|
|
fib2Verified = 0;
|
|
}
|
|
|
|
//
|
|
// Fibo 3 ...
|
|
if (selectedFib3 == info.fibLevel3s[i])
|
|
{
|
|
fib3Verified++;
|
|
}
|
|
else
|
|
{
|
|
fib3Verified = 0;
|
|
}
|
|
|
|
//
|
|
// SCHH ...
|
|
if (selectedSCHH == info.sHHs[i])
|
|
{
|
|
scHHVerified++;
|
|
}
|
|
else
|
|
{
|
|
scHHVerified = 0;
|
|
}
|
|
|
|
//
|
|
// SCLL ...
|
|
if (selectedSCLL == info.sLLs[i])
|
|
{
|
|
scLLVerified++;
|
|
}
|
|
else
|
|
{
|
|
scLLVerified = 0;
|
|
}
|
|
|
|
//
|
|
// MCHH ...
|
|
if (selectedMCHH == info.mHHs[i])
|
|
{
|
|
mcHHVerified++;
|
|
}
|
|
else
|
|
{
|
|
mcHHVerified = 0;
|
|
}
|
|
|
|
//
|
|
// MCLL ...
|
|
if (selectedMCLL == info.mLLs[i])
|
|
{
|
|
mcLLVerified++;
|
|
}
|
|
else
|
|
{
|
|
mcLLVerified = 0;
|
|
}
|
|
|
|
//
|
|
// LCHH ...
|
|
if (selectedLCHH == info.lHHs[i])
|
|
{
|
|
lcHHVerified++;
|
|
}
|
|
else
|
|
{
|
|
lcHHVerified = 0;
|
|
}
|
|
|
|
//
|
|
// LCLL ...
|
|
if (selectedLCLL == info.lLLs[i])
|
|
{
|
|
lcLLVerified++;
|
|
}
|
|
else
|
|
{
|
|
lcLLVerified = 0;
|
|
}
|
|
|
|
//
|
|
// HCHH ...
|
|
if (selectedHCHH == info.hHHs[i])
|
|
{
|
|
hcHHVerified++;
|
|
}
|
|
else
|
|
{
|
|
hcHHVerified = 0;
|
|
}
|
|
|
|
//
|
|
// HCLL ...
|
|
if (selectedHCLL == info.hLLs[i])
|
|
{
|
|
hcLLVerified++;
|
|
}
|
|
else
|
|
{
|
|
hcLLVerified = 0;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now we Have to check Verifications of each
|
|
// Selected Values and if their Passed Sequential Count
|
|
// we add them as Pivot Points ...
|
|
|
|
//
|
|
// Peaks ...
|
|
if (peakVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedPeak,
|
|
peakPivots);
|
|
}
|
|
|
|
//
|
|
// Vales ...
|
|
if (valeVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedVale,
|
|
valePivots);
|
|
}
|
|
|
|
//
|
|
// Fib 1 ...
|
|
if (fib1Verified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedFib1,
|
|
fibPivots);
|
|
}
|
|
|
|
//
|
|
// Fib 2 ...
|
|
if (fib2Verified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedFib2,
|
|
fibPivots);
|
|
}
|
|
|
|
//
|
|
// Fib 3 ...
|
|
if (fib3Verified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedFib3,
|
|
fibPivots);
|
|
}
|
|
|
|
//
|
|
// SCHH ...
|
|
if (scHHVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedSCHH,
|
|
cyclesHHPivots);
|
|
}
|
|
|
|
//
|
|
// SCLL ...
|
|
if (scLLVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedSCLL,
|
|
cyclesLLPivots);
|
|
}
|
|
|
|
//
|
|
// MCHH ...
|
|
if (mcHHVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedMCHH,
|
|
cyclesHHPivots);
|
|
}
|
|
|
|
//
|
|
// MCLL ...
|
|
if (mcLLVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedMCLL,
|
|
cyclesLLPivots);
|
|
}
|
|
|
|
//
|
|
// LCHH ...
|
|
if (lcHHVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedLCHH,
|
|
cyclesHHPivots);
|
|
}
|
|
|
|
//
|
|
// LCLL ...
|
|
if (lcLLVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedLCLL,
|
|
cyclesLLPivots);
|
|
}
|
|
|
|
//
|
|
// HCHH ...
|
|
if (hcHHVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedHCHH,
|
|
cyclesHHPivots);
|
|
}
|
|
|
|
//
|
|
// HCLL ...
|
|
if (hcLLVerified >= pivotsSequentialCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
selectedHCLL,
|
|
cyclesLLPivots);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Available Signallers ...
|
|
string mSignallers[];
|
|
|
|
//
|
|
// Here we are Capture Conditions and Check Signals ...
|
|
// The Signals Must be Unique for each providers ...
|
|
bool ProcessSignals(X121MarketConditions &conditions)
|
|
{
|
|
//
|
|
X121MarketConditions mConditions = GetMarketConditions(1);
|
|
|
|
//
|
|
// BUY ...
|
|
|
|
//
|
|
Clean(mConditions.signal);
|
|
bool hasLongSignal = HasLongSignal(mConditions);
|
|
if (hasLongSignal)
|
|
{
|
|
//
|
|
NotifyOnSignalEvent(
|
|
mConditions.signal);
|
|
NotifyOnSignalConditionsEvent(mConditions);
|
|
mWaitUntilNewCandle = true;
|
|
|
|
//
|
|
conditions = mConditions;
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// SELL ...
|
|
|
|
//
|
|
Clean(mConditions.signal);
|
|
bool hasShortignal = HasShortSignal(mConditions);
|
|
if (hasShortignal)
|
|
{
|
|
//
|
|
NotifyOnSignalEvent(
|
|
mConditions.signal);
|
|
NotifyOnSignalConditionsEvent(mConditions);
|
|
mWaitUntilNewCandle = true;
|
|
|
|
//
|
|
conditions = mConditions;
|
|
return true;
|
|
}
|
|
|
|
//
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Check has Long Signal on Each Strategies ...
|
|
bool HasLongSignal(X121MarketConditions &conditions)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
|
|
|
//
|
|
// Retrieve Pivot Points ...
|
|
double entry = GetEntry(
|
|
conditions.symbol,
|
|
type);
|
|
|
|
double pivots[];
|
|
FillPivotPoints(pivots);
|
|
XOHCLSupRes supRes = ExtractSupportAndResistance(
|
|
entry,
|
|
pivots,
|
|
15);
|
|
|
|
//
|
|
// Cleaning Market Conditions Signal Structure ...
|
|
Clean(conditions.signal);
|
|
conditions.hasSignal = false;
|
|
|
|
//
|
|
// XTEST ...
|
|
bool xTestHasSignal = false;
|
|
bool canCheckXTest = IsAllowedSignaller(XTEST);
|
|
if (canCheckXTest)
|
|
{
|
|
//
|
|
xTestHasSignal =
|
|
//
|
|
GenerateXTESTSignal(
|
|
conditions,
|
|
supRes,
|
|
type)
|
|
//
|
|
;
|
|
}
|
|
|
|
//
|
|
// X786 ...
|
|
bool x786HasSignal = false;
|
|
bool canCheckX786 = IsAllowedSignaller(X786);
|
|
if (canCheckX786)
|
|
{
|
|
//
|
|
x786HasSignal =
|
|
//
|
|
GenerateX786Signal(
|
|
conditions,
|
|
supRes,
|
|
type)
|
|
//
|
|
;
|
|
}
|
|
|
|
//
|
|
// X92 ...
|
|
bool x92HasSignal = false;
|
|
bool canCheckX92 = IsAllowedSignaller(X92);
|
|
if (canCheckX92)
|
|
{
|
|
//
|
|
x92HasSignal =
|
|
//
|
|
GenerateX92Signal(
|
|
conditions,
|
|
supRes,
|
|
type)
|
|
//
|
|
;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
xTestHasSignal
|
|
//
|
|
||
|
|
//
|
|
x786HasSignal
|
|
//
|
|
||
|
|
//
|
|
x92HasSignal
|
|
//
|
|
;
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
conditions.supportResistances = supRes;
|
|
conditions.momentumStep = mLastMomentumStep;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check has Short Signal on Each Strategies ...
|
|
bool HasShortSignal(X121MarketConditions &conditions)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
ENUM_POSITION_TYPE type = POSITION_TYPE_SELL;
|
|
|
|
//
|
|
// Retrieve Pivot Points ...
|
|
double entry = GetEntry(
|
|
conditions.symbol,
|
|
type);
|
|
|
|
double pivots[];
|
|
FillPivotPoints(pivots);
|
|
XOHCLSupRes supRes = ExtractSupportAndResistance(
|
|
entry,
|
|
pivots,
|
|
15);
|
|
|
|
//
|
|
// Cleaning Market Conditions Signal Structure ...
|
|
Clean(conditions.signal);
|
|
conditions.hasSignal = false;
|
|
|
|
//
|
|
// XTEST ...
|
|
bool xTestHasSignal = false;
|
|
bool canCheckXTest = IsAllowedSignaller(XTEST);
|
|
if (canCheckXTest)
|
|
{
|
|
//
|
|
xTestHasSignal =
|
|
//
|
|
GenerateXTESTSignal(
|
|
conditions,
|
|
supRes,
|
|
type)
|
|
//
|
|
;
|
|
}
|
|
|
|
//
|
|
// X786 ...
|
|
bool x786HasSignal = false;
|
|
bool canCheckX786 = IsAllowedSignaller(X786);
|
|
if (canCheckX786)
|
|
{
|
|
//
|
|
x786HasSignal =
|
|
//
|
|
GenerateX786Signal(
|
|
conditions,
|
|
supRes,
|
|
type)
|
|
//
|
|
;
|
|
}
|
|
|
|
//
|
|
// x92 ...
|
|
bool x92HasSignal = false;
|
|
bool canCheckX92 = IsAllowedSignaller(X92);
|
|
if (canCheckX92)
|
|
{
|
|
//
|
|
x92HasSignal =
|
|
//
|
|
GenerateX92Signal(
|
|
conditions,
|
|
supRes,
|
|
type)
|
|
//
|
|
;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
xTestHasSignal
|
|
//
|
|
||
|
|
//
|
|
x786HasSignal
|
|
//
|
|
||
|
|
//
|
|
x92HasSignal
|
|
//
|
|
;
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
conditions.supportResistances = supRes;
|
|
conditions.momentumStep = mLastMomentumStep;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
// START Definitions ...
|
|
//
|
|
|
|
//
|
|
// Model Signal Providers Definitions ...
|
|
struct X121SignalProvider
|
|
{
|
|
//
|
|
// Provider use Which Symbol ...
|
|
string symbol;
|
|
|
|
//
|
|
// Allowed Providers ...
|
|
string providers[];
|
|
|
|
//
|
|
// Provider use Which Time Frame ...
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
// Risk Amount Per Trades Related to Time Frames ...
|
|
// Percent of Available Balance ...
|
|
double riskAmount;
|
|
|
|
//
|
|
// Use Provided Risk Amount as Static Volume ...
|
|
bool useRiskAmountAsStaticVolume;
|
|
|
|
//
|
|
// Provider ...
|
|
XSCX121Provider *provider;
|
|
};
|
|
|
|
//
|
|
// END Definitions ...
|
|
//
|
|
|
|
//
|
|
// START Usefull Functions ...
|
|
//
|
|
|
|
//
|
|
// Add Specific Provider to List ...
|
|
void Add(
|
|
X121SignalProvider &item, // item want to add
|
|
X121SignalProvider &buffer[] // Destination buffer
|
|
)
|
|
{
|
|
//
|
|
ArrayResize(
|
|
buffer,
|
|
ArraySize(buffer) + 1);
|
|
|
|
//
|
|
buffer[ArraySize(buffer) - 1] = item;
|
|
}
|
|
|
|
//
|
|
// Generate Identifier Tag ...
|
|
string GenerateTag(X121SignalProvider &descriptor)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
result = descriptor.symbol + "," + ToString(descriptor.period);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Converts a Signal provider to String ...
|
|
string ToString(ENUM_X121_SIGNAL_PROVIDERS provider)
|
|
{
|
|
return EnumToString(provider);
|
|
}
|
|
|
|
//
|
|
// convert an String to Signal provider ...
|
|
ENUM_X121_SIGNAL_PROVIDERS ToProvider(string provider)
|
|
{
|
|
//
|
|
ENUM_X121_SIGNAL_PROVIDERS result = NONE;
|
|
|
|
//
|
|
if (ToString(NONE) == provider)
|
|
{
|
|
result = NONE;
|
|
}
|
|
else if (ToString(XTEST) == provider)
|
|
{
|
|
result = XTEST;
|
|
}
|
|
else if (ToString(X786) == provider)
|
|
{
|
|
result = X786;
|
|
}
|
|
else if (ToString(X92) == provider)
|
|
{
|
|
result = X92;
|
|
}
|
|
// else if (ToString(X110) == provider)
|
|
// {
|
|
// result = X110;
|
|
// }
|
|
// else if (ToString(X121) == provider)
|
|
// {
|
|
// result = X121;
|
|
// }
|
|
// else if (ToString(X128) == provider)
|
|
// {
|
|
// result = X128;
|
|
// }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Provider Type from Signal Commnet ...
|
|
ENUM_X121_SIGNAL_PROVIDERS ExtractPositionProvider(XPosition &position)
|
|
{
|
|
//
|
|
ENUM_X121_SIGNAL_PROVIDERS result = NONE;
|
|
|
|
//
|
|
string providerStr =
|
|
ExtractString(
|
|
position.comment,
|
|
XProviderToken + "(",
|
|
")");
|
|
if (StringLen(providerStr) <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ToProvider(providerStr);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// List All Available Providers ...
|
|
void GetAllProviders(
|
|
ENUM_X121_SIGNAL_PROVIDERS &result[] // Hold Result ...
|
|
)
|
|
{
|
|
//
|
|
Clean(result);
|
|
|
|
//
|
|
// XTEST ...
|
|
ArrayResize(
|
|
result,
|
|
ArraySize(result) + 1);
|
|
result[ArraySize(result) - 1] = XTEST;
|
|
|
|
//
|
|
// X786 ...
|
|
ArrayResize(
|
|
result,
|
|
ArraySize(result) + 1);
|
|
result[ArraySize(result) - 1] = X786;
|
|
|
|
//
|
|
// X92 ...
|
|
ArrayResize(
|
|
result,
|
|
ArraySize(result) + 1);
|
|
result[ArraySize(result) - 1] = X92;
|
|
|
|
// //
|
|
// // X110 ...
|
|
// ArrayResize(
|
|
// result,
|
|
// ArraySize(result) + 1);
|
|
// result[ArraySize(result) - 1] = X110;
|
|
|
|
// //
|
|
// // X121 ...
|
|
// ArrayResize(
|
|
// result,
|
|
// ArraySize(result) + 1);
|
|
// result[ArraySize(result) - 1] = X121;
|
|
|
|
// //
|
|
// // X128 ...
|
|
// ArrayResize(
|
|
// result,
|
|
// ArraySize(result) + 1);
|
|
// result[ArraySize(result) - 1] = X128;
|
|
}
|
|
|
|
//
|
|
// Lis All Available Providers ...
|
|
void GetAllProviders(
|
|
string &result[] // Hold Result ...
|
|
)
|
|
{
|
|
//
|
|
Clean(result);
|
|
|
|
//
|
|
ENUM_X121_SIGNAL_PROVIDERS providers[];
|
|
GetAllProviders(providers);
|
|
int providersCount = ArraySize(providers);
|
|
if (providersCount <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < providersCount; i++)
|
|
{
|
|
//
|
|
ENUM_X121_SIGNAL_PROVIDERS iProvider = providers[i];
|
|
|
|
//
|
|
Add(
|
|
ToString(iProvider),
|
|
result);
|
|
}
|
|
}
|
|
|
|
//
|
|
// END Usefull Functions ...
|
|
//
|